/// <summary>
        /// Speichere die Daten des übergebenen Moderator-Objekt in der Datenbank ab.
        /// </summary>
        /// <param name="moderator">Das Objekt mit den Daten des Moderators.</param>
        /// <exception cref="DatabaseException">Wirft DatabaseException, wenn Speicherung fehlschlägt.</exception>
        public void StoreModerator(Moderator moderator)
        {
            if(moderator == null)
            {
                Debug.WriteLine("No valid moderator object is passed to the StoreModerator method.");
                return;
            }

            // Frage das Mutex Objekt ab.
            Mutex mutex = DatabaseManager.GetDatabaseAccessMutexObject();

            // Fordere Zugriff auf die Datenbank an.
            if (mutex.WaitOne(DatabaseManager.MutexTimeoutValue))
            {
                using (SQLiteConnection conn = DatabaseManager.GetConnection())
                {
                    try
                    {
                        using (var insertStmt = conn.Prepare(@"INSERT INTO Moderator (Id, FirstName, LastName, Email) 
                            VALUES (?,?,?,?);"))
                        {
                            insertStmt.Bind(1, moderator.Id);
                            insertStmt.Bind(2, moderator.FirstName);
                            insertStmt.Bind(3, moderator.LastName);
                            insertStmt.Bind(4, moderator.Email);

                            insertStmt.Step();
                        }
                    }
                    catch (SQLiteException sqlEx)
                    {
                        Debug.WriteLine("SQLiteException occurred in StoreModerator. The message is: {0}.", sqlEx.Message);
                        throw new DatabaseException("Moderator could not be stored.");
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine("Exception occurred in StoreModerator. The message is: {0} and the stack trace is {1}.",
                            ex.Message,
                            ex.StackTrace);
                        throw new DatabaseException("Moderator could not be stored.");
                    }
                    finally
                    {
                        mutex.ReleaseMutex();
                    }
                }   // Ende des using Block.
            }
            else
            {
                Debug.WriteLine("Couldn't get access to database. Time out.");
                throw new DatabaseException("Could not get access to the database.");
            }    
        }
        /// <summary>
        /// Liefert eine Liste an Moderatoren, die in der Datenbank als aktive Verantwortliche des Kanals
        /// eingetragen sind.
        /// </summary>
        /// <param name="channelId">Die Id des Kanals, zu dem die verantwortlichen Moderatoren abgefragt werden sollen.</param>
        /// <returns>Eine Liste von Moderator Objekten.</returns>
        /// <exception cref="DatabaseException">Wirft eine DatabaseException, wenn die Ausführung fehlschlägt.</exception>
        public List<Moderator> GetResponsibleModeratorsForChannel(int channelId)
        {
            List<Moderator> responsibleModerators = new List<Moderator>();

            // Frage das Mutex Objekt ab.
            Mutex mutex = DatabaseManager.GetDatabaseAccessMutexObject();

            // Fordere Zugriff auf die Datenbank an.
            if (mutex.WaitOne(DatabaseManager.MutexTimeoutValue))
            {
                using (SQLiteConnection conn = DatabaseManager.GetConnection())
                {
                    try
                    {
                        using (var stmt = conn.Prepare(@"SELECT * 
                            FROM Moderator AS m JOIN ModeratorChannel AS mc ON m.Id=mc.Moderator_Id 
                            WHERE mc.Channel_Id=? AND mc.Active=?;"))
                        {
                            stmt.Bind(1, channelId);
                            stmt.Bind(2, 1);

                            while (stmt.Step() == SQLiteResult.ROW)
                            {
                                int id = Convert.ToInt32(stmt["Id"]);
                                string firstName = (string)stmt["FirstName"];
                                string lastName = (string)stmt["LastName"];
                                string email = (string)stmt["Email"];

                                Moderator moderator = new Moderator()
                                {
                                    Id = id,
                                    FirstName = firstName,
                                    LastName = lastName,
                                    Email = email
                                };
                                responsibleModerators.Add(moderator);
                            }
                        }
                    }
                    catch (SQLiteException sqlEx)
                    {
                        Debug.WriteLine("SQLiteException has occurred in GetResponsibleModeratorsForChannel. The message is: {0}.", sqlEx.Message);
                        throw new DatabaseException("GetResponsibleModeratorsForChannel channel has failed.");
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine("Exception has occurred in GetResponsibleModeratorsForChannel. The message is: {0}, " +
                            "and the stack trace: {1}.", ex.Message, ex.StackTrace);
                        throw new DatabaseException("GetResponsibleModeratorsForChannel channel has failed.");
                    }
                    finally
                    {
                        mutex.ReleaseMutex();
                    }
                }
            }
            else
            {
                Debug.WriteLine("Couldn't get access to database. Time out.");
                throw new DatabaseException("Could not get access to the database.");
            }
            
            return responsibleModerators;
        }
        /// <summary>
        /// Aktualisiert den Datensatz des Moderators, der durch das übergebene Moderatorenobjekt
        /// identifiziert wird. Das übergebene Moderatorenobjekt enthält die neuen Daten des Moderators.
        /// </summary>
        /// <param name="newModerator">Das Moderator Objekt mit den neuen Daten.</param>
        /// <exception cref="DatabaseException">Wirft eine DatabaseException, wenn die Aktualisierung fehlschlägt.</exception>
        public void UpdateModerator(Moderator newModerator)
        {
            if (newModerator == null)
                return;

            // Frage das Mutex Objekt ab.
            Mutex mutex = DatabaseManager.GetDatabaseAccessMutexObject();

            // Fordere Zugriff auf die Datenbank an.
            if (mutex.WaitOne(DatabaseManager.MutexTimeoutValue))
            {
                using (SQLiteConnection conn = DatabaseManager.GetConnection())
                {
                    try
                    {
                        string sql = @"UPDATE Moderator 
                            SET FirstName=?, LastName=?, Email=? 
                            WHERE Id=?;";

                        using (var stmt = conn.Prepare(sql))
                        {
                            stmt.Bind(1, newModerator.FirstName);
                            stmt.Bind(2, newModerator.LastName);
                            stmt.Bind(3, newModerator.Email);
                            stmt.Bind(4, newModerator.Id);

                            if (stmt.Step() == SQLiteResult.DONE)
                                Debug.WriteLine("Updated moderator with id {0}.", newModerator.Id);
                        }
                    }
                    catch (SQLiteException sqlEx)
                    {
                        Debug.WriteLine("SQLiteException occurred in UpdateModerator. The message is: {0}.", sqlEx.Message);
                        throw new DatabaseException("Could not update Moderator. Msg is: " + sqlEx.Message);
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine("Exception occurred in UpdateModerator. The message is: {0} and the stack trace is {1}.",
                            ex.Message,
                            ex.StackTrace);
                        throw new DatabaseException("Could not update Moderator. Msg is: " + ex.Message);
                    }
                    finally
                    {
                        mutex.ReleaseMutex();
                    }
                }
            }
            else
            {
                Debug.WriteLine("Couldn't get access to database. Time out.");
                throw new DatabaseException("Could not get access to the database.");
            }
        }
 /// <summary>
 /// Fügt das übergebene Moderatorenobjekt dem durch die Singleton Klasse repräsentierten 
 /// Cache hinzu.
 /// </summary>
 /// <param name="moderator">Das zu speichernde Moderatorenobjekt.</param>
 public void CacheModeratorObject(Moderator moderator)
 {
     this.moderator = moderator;
 }
        /// <summary>
        /// Holt die Daten des Moderators mit der angegebenen Id aus der Datenbank und gibt sie zurück.
        /// </summary>
        /// <param name="channelId">Die Id des Moderators, der abgerufen werden soll.</param>
        /// <returns>Ein Objekt der Klasse Moderator, oder null falls der Eintrag nicht in der Datenbank ist.</returns>
        /// <exception cref="DatabaseException">Wirft DatabaseException, wenn Abruf des Datensatzes fehlschlägt.</exception>
        public Moderator GetModerator(int moderatorId)
        {
            Moderator moderator = null;

            // Frage das Mutex Objekt ab.
            Mutex mutex = DatabaseManager.GetDatabaseAccessMutexObject();

            // Fordere Zugriff auf die Datenbank an.
            if (mutex.WaitOne(DatabaseManager.MutexTimeoutValue))
            {
                using (SQLiteConnection conn = DatabaseManager.GetConnection())
                {
                    try
                    {
                        using (var stmt = conn.Prepare(@"SELECT * FROM Moderator WHERE Id=?;"))
                        {
                            stmt.Bind(1, moderatorId);

                            if (stmt.Step() == SQLiteResult.ROW)
                            {
                                int id = Convert.ToInt32(stmt["Id"]);
                                string firstName = (string)stmt["FirstName"];
                                string lastName = (string)stmt["LastName"];
                                string email = (string)stmt["Email"];

                                moderator = new Moderator()
                                {
                                    Id = id,
                                    FirstName = firstName,
                                    LastName = lastName,
                                    Email = email
                                };
                            }
                        }
                    }
                    catch (SQLiteException sqlEx)
                    {
                        Debug.WriteLine("SQLiteException occurred in GetModerator. The message is: {0}.", sqlEx.Message);
                        throw new DatabaseException("Could not retrieve Moderator.");
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine("Exception occurred in GetModerator. The message is: {0} and the stack trace is {1}.",
                            ex.Message,
                            ex.StackTrace);
                        throw new DatabaseException("Could not retrieve Moderator.");
                    }
                    finally
                    {
                        mutex.ReleaseMutex();
                    }
                }   // Ende des using Block.
            }
            else
            {
                Debug.WriteLine("Couldn't get access to database. Time out.");
                throw new DatabaseException("Could not get access to the database.");
            }

            return moderator;
        }
        /// <summary>
        /// Hilfsmethode zur Unterstützung der Synchronistation der verwalteten Kanäle.
        /// Ruft Daten zu dem Kanal mit der angegebenen Id vom Server ab. Dazu gehören
        /// die verantwortlichen Moderatoren und die Reminder. Speichert die Daten für den
        /// Kanal in der lokalen Datenbank ab. Ruft jedoch nicht die eigentlichen Kanaldaten ab.
        /// </summary>
        /// <param name="activeModerator">Der Moderator, der für den Kanal als Verantwortlicher eingetragen ist.
        ///     Ist der lokal eingeloggte Moderator.</param>
        /// <param name="channelId">Die Id des Kanals, für den die Daten abgerufen werden sollen.</param>
        private async Task retrieveAndStoreManagedChannelInfoAsync(Moderator activeModerator, int channelId)
        {
            Debug.WriteLine("retrieveAndStoreManagedChannelInfoAsync: Started method.");
            if (activeModerator == null)
                return;

            // Rufe alle Moderatoren zu dem Kanal ab.
            try
            {
                List<Moderator> moderators = await GetResponsibleModeratorsAsync(channelId);
                if (moderators == null)
                    return;
 
                foreach (Moderator moderator in moderators)
                {
                    if (!moderatorDatabaseManager.IsModeratorStored(moderator.Id))
                    {
                        Debug.WriteLine("retrieveAndStoreManagedChannelInfoAsync: Need to store the " + 
                            "moderator with id {0} in local DB.", moderator.Id);
                        moderatorDatabaseManager.StoreModerator(moderator);
                    }

                    if (!channelDatabaseManager.IsResponsibleForChannel(channelId, moderator.Id))
                    {
                        Debug.WriteLine("retrieveAndStoreManagedChannelInfoAsync: Add moderator with id {0} to " + 
                            "channel with id {1}.", channelId, moderator.Id);
                        channelDatabaseManager.AddModeratorToChannel(channelId, moderator.Id, moderator.IsActive);
                    }
                }
            }
            catch (DatabaseException ex)
            {
                Debug.WriteLine("retrieveAndStoreManagedChannelInfoAsync: Storing of the responsible moderators has failed.");
                Debug.WriteLine("retrieveAndStoreManagedChannelInfoAsync: Message is: {0}.", ex.Message);
            }
            catch (ClientException ex)
            {
                Debug.WriteLine("retrieveAndStoreManagedChannelInfoAsync: Retrieval of the responsible moderators has failed.");
                Debug.WriteLine("retrieveAndStoreManagedChannelInfoAsync: " +
                    "Message is: {0} and error code is {1}.", ex.Message, ex.ErrorCode);
            }
            
            // Rufe Reminder zu dem Kanal ab.
            try
            {
                List<Reminder> reminders = await GetRemindersOfChannelAsync(channelId, false);
                channelDatabaseManager.BulkInsertReminder(reminders);
            }
            catch (DatabaseException ex)
            {
                Debug.WriteLine("retrieveAndStoreManagedChannelInfoAsync: Storing of the reminders has failed.");
                Debug.WriteLine("retrieveAndStoreManagedChannelInfoAsync: Message is: {0}.", ex.Message);
            }
            catch (ClientException ex)
            {
                Debug.WriteLine("retrieveAndStoreManagedChannelInfoAsync: Retrieval of the reminders has failed.");
                Debug.WriteLine("retrieveAndStoreManagedChannelInfoAsync: " + 
                    "Message is: {0} and error code is {1}.", ex.Message, ex.ErrorCode);
            }

            // Rufe Announcements zu dem Kanal ab.
            try
            {
                int msgNr = GetHighestMsgNrForChannel(channelId);
                List<Announcement> announcements = await GetAnnouncementsOfChannelAsync(channelId, msgNr, false);
                channelDatabaseManager.BulkInsertOfAnnouncements(announcements);
            }
            catch (DatabaseException ex)
            {
                Debug.WriteLine("retrieveAndStoreManagedChannelInfoAsync: Storing of the announcements has failed.");
                Debug.WriteLine("retrieveAndStoreManagedChannelInfoAsync: Message is: {0}.", ex.Message);
            }
            catch (ClientException ex)
            {
                Debug.WriteLine("retrieveAndStoreManagedChannelInfoAsync: Retrieval of the announcements has failed.");
                Debug.WriteLine("retrieveAndStoreManagedChannelInfoAsync: " +
                    "Message is: {0} and error code is {1}.", ex.Message, ex.ErrorCode);
            }

            Debug.WriteLine("retrieveAndStoreManagedChannelInfoAsync: Finished method.");
        }
        /// <summary>
        /// Fügt einen Moderator dem Kanal mit der angegebenen Id hinzu. 
        /// </summary>
        /// <param name="channelId">Die Id des Kanals, zu dem der Moderator hinzugefügt werden soll.</param>
        /// <param name="newModerator">Der Moderator, der dem Kanal hinzugefügt werden soll.</param>
        /// <exception cref="ClientException">Wirft ClientException, wenn Moderator nicht zum Kanal hinzugefügt werden konnte.</exception>
        public void AddModeratorToChannel(int channelId, Moderator newModerator)
        {
            if (newModerator == null)
                return;

            try
            {
                channelDatabaseManager.AddModeratorToChannel(channelId,
                    newModerator.Id,
                    newModerator.IsActive);
            }
            catch (ClientException ex)
            {
                Debug.WriteLine("AddModeratorToChannel: Failed to add moderator to channel with id {0}.", channelId);
                throw new ClientException(ErrorCodes.LocalDatabaseException, ex.Message);
            }
        }
        /// <summary>
        /// Prüft, ob alle Beziehungen zwischen Kanalressourcen und dem aktuell eingeloggten
        /// Moderator aktuell sind und aktualisiert diese falls notwendig. 
        /// </summary>
        /// <param name="managedChannels">Liste von aktuell verwalteten Kanälen des Moderators.</param>
        /// <exception cref="ClientException">Wirft ClientException, wenn Aktualisierung fehlschlägt.</exception>
        //public void UpdateManagedChannelsRelationships(List<Channel> managedChannels)
        //{
        //    Moderator activeModerator = GetLocalModerator();
        //    if (activeModerator == null)
        //        return;

        //    try
        //    {
        //        // Prüfe, ob der aktuell eingeloggte Moderator schon in der Datenbank enthalten ist.
        //        if (!moderatorDatabaseManager.IsModeratorStored(activeModerator.Id))
        //        {
        //            Debug.WriteLine("Need to store the moderator with id {0} in local DB.", activeModerator.Id);
        //            moderatorDatabaseManager.StoreModerator(activeModerator);
        //        }

        //        // Prüfe, ob Moderator auch lokal als Verantwortlicher für Kanäle eingetragen ist.
        //        foreach (Channel channel in managedChannels)
        //        {
        //            if (!channelDatabaseManager.IsResponsibleForChannel(channel.Id, activeModerator.Id))
        //            {
        //                // Kanal gefunden, der vorher noch nicht von diesem Moderator verwaltet wurde.
        //                // Trage Moderator ein.
        //                Debug.WriteLine("Need to add the moderator with id {0} as a responsible moderator " +
        //                    "for the channel with id {1}.", activeModerator.Id, channel.Id);
        //                channelDatabaseManager.AddModeratorToChannel(channel.Id, activeModerator.Id, true);

        //                // Stoße das Herunterladen der für den neu hinzugekommenen Kanal relevanten Daten an.
        //                // Bemerkung: Falls das fehlschlägt wird kein Fehler geworfen. Die Daten können auch im Fehlerfall später nachgeladen werden.
        //                Task.Run(() => retrieveAndStoreManagedChannelInfoAsync(activeModerator, channel.Id));
        //            }
        //        }

        //        // Frage verwaltete Kanäle aus der DB ab.
        //        List<Channel> managedChannelsFromDB = channelDatabaseManager.GetManagedChannels(activeModerator.Id);
        //        // Prüfe, ob es darin noch einen Kanal gibt, der nicht mehr in der aktuellen Liste von Kanälen steht.
        //        for (int i = 0; i < managedChannelsFromDB.Count; i++)
        //        {
        //            bool isContained = false;

        //            foreach (Channel channel in managedChannels)
        //            {
        //                if (channel.Id == managedChannelsFromDB[i].Id)
        //                {
        //                    isContained = true;
        //                }
        //            }

        //            if (!isContained)
        //            {
        //                RemoveChannelFromManagedChannels(activeModerator, managedChannelsFromDB[i]);
        //            }
        //        }

        //    }
        //    catch (DatabaseException ex)
        //    {
        //        Debug.WriteLine("Database exception occurred in UpdateManagedChannelsRelationships. Msg is {0}.", ex.Message);
        //        throw new ClientException(ErrorCodes.LocalDatabaseException, "Failed to update managed channels relationships.");
        //    }
        //}

        /// <summary>
        /// Nimmt einen Kanal aus der Liste der verwalteten Kanäle raus und räumt
        /// mit diesem Kanal in Verbindung stehende Ressourcen weg, die dann nicht mehr
        /// benötigt werden. 
        /// </summary>
        /// <param name="activeModerator">Der gerade aktive Moderator, für den der Kanal aus der Liste der
        ///     verwalteten Kanäle ausgetragen wird.</param>
        /// <param name="channel">Der Kanal, der aus der Liste genommen wird.</param>
        public void RemoveChannelFromManagedChannels(Moderator activeModerator, Channel channel)
        {
            try
            {
                // Setzte Verantwortlichkeit auf inaktiv für diesen Kanal.
                Debug.WriteLine("Need to set moderator isActive to false for channel with id {0}.", channel.Id);
                channelDatabaseManager.AddModeratorToChannel(
                    channel.Id,
                    activeModerator.Id,
                    false);

                // Prüfe, ob der Kanal abonniert ist.
                bool isSubscribed = channelDatabaseManager.IsChannelSubscribed(channel.Id);
                if (!isSubscribed)
                {
                    // Kanal nicht noch vom lokalen Nutzer abonniert. Lösche Announcements und Moderator-Info.
                    Debug.WriteLine("Channel with id {0} not subscribed. Delete announcements and moderator info.", channel.Id);
                    channelDatabaseManager.DeleteAllAnnouncementsOfChannel(channel.Id);
                    channelDatabaseManager.RemoveAllModeratorsFromChannel(channel.Id);
                }

                // Lösche in jedem Fall die Reminder.
                Debug.WriteLine("Deleting reminders for channel with id {0}.", channel.Id);
                channelDatabaseManager.DeleteRemindersForChannel(channel.Id);
            }
            catch (DatabaseException ex)
            {
                // Keine weitere Aktion, da diese Funktionalität im Hintergrund abläuft und
                // nicht vom Nutzer aktiv ausgelöst wird.
                Debug.WriteLine("Error during removal of managed channel. No further action is taken." + 
                    "Error message is: {0}.", ex.Message);
            }
        }
        /// <summary>
        /// Führe eine Synchronisation der lokalen Menge an Kanälen, für die der übergebene
        /// Moderator als Verantwortlicher eingetragen ist, mit der übergebenen Liste an Kanalressourcen
        /// durch. Die Methode prüft, ob die übergebene Menge an Kanalressourcen noch mit den aktuell lokal
        /// gehaltenen Kanalressourcen übereinstimmt und fügt der lokal verwalteten Liste fehlende Kanäle
        /// hinzu. Es können auch Kanäle aus der Liste rausgenommen werden, wenn diese nicht mehr vom übergebenen
        /// Moderator verwaltet werden. Bereits lokal vorhanden Kanäle werden falls notwendig mit den aktuelleren
        /// Daten der Referenzliste aktualisiert.
        /// </summary>
        /// <param name="activeModerator">Der Moderator, der für die zu synchronisierenden Kanäle als Verantwortlicher eingetragen ist.</param>
        /// <param name="referenceList">Die Liste an Kanalressourcen, gegen die die lokal verwaltete Liste synchronisiert wird.</param>
        public void SynchronizeLocalManagedChannels(Moderator activeModerator, List<Channel> referenceList)
        {
            if (activeModerator == null)
                return;

            try
            {
                // Prüfe, ob der aktuell eingeloggte Moderator schon in der Datenbank enthalten ist.
                // Falls nicht, speichere ihn ab.
                if (!moderatorDatabaseManager.IsModeratorStored(activeModerator.Id))
                {
                    Debug.WriteLine("SynchronizeLocalManagedChannels: Need to store the moderator with id {0} in local DB.",
                        activeModerator.Id);
                    moderatorDatabaseManager.StoreModerator(activeModerator);
                }
                
                // Frage verwaltete Kanäle aus der DB ab.
                List<Channel> managedChannelsFromDB = channelDatabaseManager.GetManagedChannels(activeModerator.Id);

                // Vergleiche beide Listen. Wenn Kanal in der Referenzliste ist, der noch nicht in den lokalen 
                // Datensätzen vorhanden ist, dann füge ihn hinzu. Wenn ein Kanal schon lokal vorhanden ist, dann prüfe,
                // ob eine Aktualisierung des lokalen Datensatzes notwendig ist.
                foreach (Channel referenceChannel in referenceList)
                {
                    bool isContained = false;

                    for (int i = 0; i < managedChannelsFromDB.Count; i++)
                    {
                        Channel localChannel = managedChannelsFromDB[i];

                        // Prüfe Ids.
                        if (referenceChannel.Id == localChannel.Id)
                        {
                            isContained = true;

                            // Prüfe, ob Aktualisierung erforderlich.
                            if (DateTimeOffset.Compare(localChannel.ModificationDate, referenceChannel.ModificationDate) < 0)
                            {
                                Debug.WriteLine("SynchronizeLocalManagedChannels: Need to update channel with id {0}.",
                                    localChannel.Id);
                                // Übernehme NotificationSettings von lokalem Kanal.
                                referenceChannel.AnnouncementNotificationSetting = localChannel.AnnouncementNotificationSetting;
                                // Ersetze lokalen Datensatz durch neuen Datensatz.
                                ReplaceLocalChannel(referenceChannel);
                            }

                            // Beende Schleife, wenn Treffer gefunden.
                            break;
                        }
                    }

                    if (!isContained)
                    {
                        // Füge Kanal hinzu.
                        Debug.WriteLine("SynchronizeLocalManagedChannels: Need to add channel with id {0} to managed channels.",
                                    referenceChannel.Id);
                        AddToLocalChannels(referenceChannel);

                        // Füge den Moderator als Verantwortlichen für den Kanal hinzu.
                        channelDatabaseManager.AddModeratorToChannel(referenceChannel.Id, activeModerator.Id, true);

                        // Stoße das Herunterladen der für den neu hinzugekommenen Kanal relevanten Daten an.
                        // Bemerkung: Falls das fehlschlägt wird kein Fehler geworfen. Die Daten können auch im Fehlerfall später nachgeladen werden.
                        Task.Run(() => retrieveAndStoreManagedChannelInfoAsync(activeModerator, referenceChannel.Id));
                    }
                }


                // Prüfe, ob ein Kanal nicht mehr vom Moderator verwaltet wird.
                // Prüfe hierzu, ob in der Liste der lokalen verwalteten Kanäle einer steht, 
                // der nicht mehr in der Referenz-Liste von Kanälen steht.
                for (int i = 0; i < managedChannelsFromDB.Count; i++)
                {
                    bool isContained = false;

                    foreach (Channel referenceChannel in referenceList)
                    {
                        if (referenceChannel.Id == managedChannelsFromDB[i].Id)
                        {
                            isContained = true;
                        }
                    }

                    if (!isContained)
                    {
                        RemoveChannelFromManagedChannels(activeModerator, managedChannelsFromDB[i]);
                    }
                }
            }
            catch (DatabaseException ex)
            {
                Debug.WriteLine("SynchronizeLocalManagedChannels: Database exception occurred in " + 
                    "SynchronizeLocalManagedChannels. Msg is {0}.", ex.Message);
                throw new ClientException(ErrorCodes.LocalDatabaseException, "Failed to update managed channels relationships.");
            }

        }
        /// <summary>
        /// Fügt den übergebenen Kanal der Liste der verwalteten Kanäle hinzu für den übergebenen
        /// Moderator. Trägt dabei den übergebenen Moderator als Verantwortlichen für den übergebenen Kanal
        /// ein und schaut ob der lokale Datensatz des Kanals hinzugefügt oder aktualisiert werden muss. 
        /// </summary>
        /// <param name="moderator">Der Moderator, für den der Kanal zur Liste der verwalteten Kanäle hinzukommt.</param>
        /// <param name="newManagedChannel">Der hinzuzufügende Kanal.</param>
        public void AddChannelToLocalManagedChannels(Moderator moderator, Channel newManagedChannel)
        {
            if (moderator == null || newManagedChannel == null)
                return;

            try
            {
                // Prüfe, ob der aktuell eingeloggte Moderator schon in der Datenbank enthalten ist.
                // Falls nicht, speichere ihn ab.
                if (!moderatorDatabaseManager.IsModeratorStored(moderator.Id))
                {
                    Debug.WriteLine("SynchronizeLocalManagedChannels: Need to store the moderator with id {0} in local DB.",
                        moderator.Id);
                    moderatorDatabaseManager.StoreModerator(moderator);
                }

                // Prüfe ob Kanal schon in lokalen Datensätzen vorhanden ist.
                if (!channelDatabaseManager.IsChannelContained(newManagedChannel.Id))
                {
                    Debug.WriteLine("AddChannelToLocalManagedChannels: Adding channel with id {0} to local channels.",
                        newManagedChannel.Id);
                    // Wenn nicht, füge Kanal hinzu. 
                    AddToLocalChannels(newManagedChannel);
                }
                else
                {
                    // Frage lokale Version ab und prüfe, ob diese aktualisiert werden muss.
                    Channel localChannel = GetChannel(newManagedChannel.Id);

                    if (DateTimeOffset.Compare(localChannel.ModificationDate, newManagedChannel.ModificationDate) < 0)
                    {
                        Debug.WriteLine("SynchronizeLocalManagedChannels: Need to update channel with id {0}.",
                            localChannel.Id);
                        // Übernehme NotificationSettings von lokalem Kanal.
                        newManagedChannel.AnnouncementNotificationSetting = localChannel.AnnouncementNotificationSetting;
                        // Ersetze lokalen Datensatz durch neuen Datensatz.
                        ReplaceLocalChannel(newManagedChannel);
                    }
                }

                // Füge den Moderator als Verantwortlichen für den Kanal hinzu.
                channelDatabaseManager.AddModeratorToChannel(newManagedChannel.Id, moderator.Id, true);

                // Stoße das Herunterladen der für den neu hinzugekommenen Kanal relevanten Daten an.
                // Bemerkung: Falls das fehlschlägt wird kein Fehler geworfen. Die Daten können auch im Fehlerfall später nachgeladen werden.
                Task.Run(() => retrieveAndStoreManagedChannelInfoAsync(moderator, newManagedChannel.Id));
            }
            catch (DatabaseException ex)
            {
                Debug.WriteLine("Couldn't add channel to local managed channels. Msg is {0}.",
                    ex.Message);
                throw new ClientException(ErrorCodes.LocalDatabaseException, ex.Message);
            }
        }
 /// <summary>
 /// Wandelt ein Objekt vom Typ Moderator in eine JSON Repräsentation um.
 /// </summary>
 /// <param name="moderator">Das umzuwandelnde Objekt.</param>
 /// <returns>Ein JSON-Dokument, welches das übergebene Objekt repräsentiert. Null falls Umwandlung fehlschlägt.</returns>
 public string ParseModeratorToJson(Moderator moderator)
 {
     string jsonContent = null;
     try
     {
         jsonContent = JsonConvert.SerializeObject(moderator);
     }
     catch (Exception ex)
     {
         Debug.WriteLine("JsonParsingManager: Exception occurred during json parsing of moderator. " +
             "Msg is {0}.", ex.Message);
     }
     return jsonContent;
 }
        /// <summary>
        /// Speichert den Moderator in den lokalen Datensätzen ab.
        /// </summary>
        /// <param name="moderator">Der zu speichernde Datensatz in Form eines Moderator Objekts.</param>
        /// <exception cref="ClientException">Wirft ClientException, wenn Speicherung fehlschlägt.</exception>
        public void StoreModerator(Moderator moderator)
        {
            if (moderator == null)
                return;

            try
            {
                moderatorDatabaseManager.StoreModerator(moderator);
            }
            catch (ClientException ex)
            {
                Debug.WriteLine("IsModeratorStored: Database failure. Couldn't store moderator. " +
                    "Message is: {0}", ex.Message);
                throw new ClientException(ErrorCodes.LocalDatabaseException, ex.Message);
            }
        }