public IEnumerator GetFriendListRecordCoroutine(uLobby.AccountID accountID, uLobby.Request <uLobby.FriendListRecord> request)
    {
        FriendListRecord friendList = StorageLayerUtility.FriendListRecordUtility.CreateFriendListRecord();
        //read friend list
        var operation = ExecuteDataReaderAsync.BeginInvoke(storageManager.connectionString, "SELECT accounts.id,accounts.name,password,LENGTH(password),salt,LENGTH(salt),data,LENGTH(data) FROM accounts INNER JOIN friends ON accounts.id = friends.friend WHERE owner = @id", new MySqlParameter[] { new MySqlParameter("id", int.Parse(accountID.value)) }, null, null);

        while (!operation.IsCompleted)
        {
            yield return(null);
        }
        var dr = ExecuteDataReaderAsync.EndInvoke(operation);

        while (dr.Read())
        {
            AccountRecord accountRecord = ReadAccountRecordFromDataReader(dr);
            Account       account       = StorageLayerUtility.CreateAccount(accountRecord);
            StorageLayerUtility.FriendListRecordUtility.AddFriend(friendList, StorageLayerUtility.CreateFriendInfo(account));
        }
        dr.Close();
        //read the original account owning the list.
        operation = ExecuteDataReaderAsync.BeginInvoke(storageManager.connectionString, "SELECT id,name,password,LENGTH(password),salt,LENGTH(salt),data,LENGTH(data) FROM accounts WHERE id = @id", new MySqlParameter[] { new MySqlParameter("id", int.Parse(accountID.value)) }, null, null);
        while (!operation.IsCompleted)
        {
            yield return(null);
        }
        dr = ExecuteDataReaderAsync.EndInvoke(operation);
        dr.Read();
        Account originalAccount = StorageLayerUtility.CreateAccount(ReadAccountRecordFromDataReader(dr));

        dr.Close();

        //read invitations
        operation = ExecuteDataReaderAsync.BeginInvoke(storageManager.connectionString, "SELECT accounts.id,name,password,LENGTH(password),salt,LENGTH(salt),data,LENGTH(data) FROM accounts INNER JOIN invitations ON accounts.id = invitations.sender WHERE invitations.receiver = @id", new MySqlParameter[] { new MySqlParameter("id", int.Parse(accountID.value)) }, null, null);
        while (!operation.IsCompleted)
        {
            yield return(null);
        }
        dr = ExecuteDataReaderAsync.EndInvoke(operation);
        while (dr.Read())
        {
            Account account = StorageLayerUtility.CreateAccount(ReadAccountRecordFromDataReader(dr));
            StorageLayerUtility.FriendListRecordUtility.AddFriendInvitation(friendList, StorageLayerUtility.CreateFriendInvitation(account, originalAccount));
        }
        dr.Close();
        StorageLayerUtility.RequestUtility.SetResult(request, friendList);
        yield break;
    }
    public IEnumerator SetFriendListRecordCoroutine(uLobby.AccountID accountID, uLobby.FriendListRecord record, uLobby.Request request)
    {
        var operation = ExecuteNonQueryAsync.BeginInvoke(storageManager.connectionString, "DELETE FROM friends WHERE owner = @id", new MySqlParameter[] { new MySqlParameter("id", int.Parse(accountID.value)) }, null, null);

        while (!operation.IsCompleted)
        {
            yield return(null);
        }
        ExecuteNonQueryAsync.EndInvoke(operation);
        operation = ExecuteNonQueryAsync.BeginInvoke(storageManager.connectionString, "DELETE FROM invitations WHERE sender = @id", new MySqlParameter[] { new MySqlParameter("id", int.Parse(accountID.value)) }, null, null);
        while (!operation.IsCompleted)
        {
            yield return(null);
        }
        ExecuteNonQueryAsync.EndInvoke(operation);
        foreach (AccountID friend in StorageLayerUtility.FriendListRecordUtility.GetFriendIDs(record))
        {
            MySqlParameter[] paramsArray = new MySqlParameter[2];
            paramsArray[0] = new MySqlParameter("owner", int.Parse(accountID.value));
            paramsArray[1] = new MySqlParameter("friend", int.Parse(friend.value));
            operation      = ExecuteNonQueryAsync.BeginInvoke(storageManager.connectionString, "INSERT INTO friends (owner,friend) VALUES(@owner,@friend)", paramsArray, null, null);
            while (!operation.IsCompleted)
            {
                yield return(null);
            }
            ExecuteNonQueryAsync.EndInvoke(operation);
        }
        foreach (var inviter in StorageLayerUtility.FriendListRecordUtility.GetInviterIDs(record))
        {
            MySqlParameter[] paramsArray = new MySqlParameter[2];
            paramsArray[0] = new MySqlParameter("sender", int.Parse(inviter.value));
            paramsArray[1] = new MySqlParameter("receiver", int.Parse(accountID.value));
            operation      = ExecuteNonQueryAsync.BeginInvoke(storageManager.connectionString, "INSERT INTO invitations (sender,receiver) VALUES(@sender,@receiver)", paramsArray, null, null);
            while (!operation.IsCompleted)
            {
                yield return(null);
            }
            ExecuteNonQueryAsync.EndInvoke(operation);
        }
        yield break;
    }
    public IEnumerator GetAccountRecordCoroutine(uLobby.AccountID accountID, uLobby.Request <uLobby.AccountRecord> request)
    {
        var operation = ExecuteDataReaderAsync.BeginInvoke(storageManager.connectionString, "SELECT id,name,password,LENGTH(password),salt,LENGTH(salt),data,LENGTH(data) FROM accounts WHERE id = @id", new MySqlParameter[] { new MySqlParameter("id", int.Parse(accountID.value)) }, null, null);

        while (!operation.IsCompleted)
        {
            yield return(null);
        }
        var dr = ExecuteDataReaderAsync.EndInvoke(operation);

        if (dr.HasRows)
        {
            dr.Read();
            StorageLayerUtility.RequestUtility.SetResult(request, ReadAccountRecordFromDataReader(dr));
        }
        else
        {
            StorageLayerUtility.RequestUtility.SetResult(request, null);
        }
        dr.Close();
    }
    public IEnumerator GetAccountCoroutine(uLobby.AccountID accountID, string accountName, bool exceptionIfInvalid, uLobby.Request <uLobby.Account> request)
    {
        MySqlDataReader dr;

        if (accountID == null)
        {
            var operation = ExecuteDataReaderAsync.BeginInvoke(storageManager.connectionString, "SELECT id,name,password,LENGTH(password),salt,LENGTH(salt),data,LENGTH(data) FROM accounts WHERE name = @name;", new MySqlParameter[] { new MySqlParameter("name", accountName) }, null, null);
            while (!operation.IsCompleted)
            {
                yield return(null);
            }
            dr = ExecuteDataReaderAsync.EndInvoke(operation);
        }
        else
        {
            var operation = ExecuteDataReaderAsync.BeginInvoke(storageManager.connectionString, "SELECT id,name,password,LENGTH(password),salt,LENGTH(salt),data,LENGTH(data) FROM accounts WHERE id = @id;", new MySqlParameter[] { new MySqlParameter("id", int.Parse(accountID.value)) }, null, null);
            while (!operation.IsCompleted)
            {
                yield return(null);
            }
            dr = ExecuteDataReaderAsync.EndInvoke(operation);
        }
        if (dr.HasRows)
        {
            dr.Read();
            Account account = StorageLayerUtility.CreateAccount(ReadAccountRecordFromDataReader(dr));
            StorageLayerUtility.RequestUtility.SetResult(request, account);
        }
        else
        {
            StorageLayerUtility.RequestUtility.SetResult(request, null);
            if (exceptionIfInvalid)
            {
                StorageLayerUtility.RequestUtility.ThrowException(request, StorageLayerUtility.Exceptions.CreateAccountException("Account with id " + accountID + " and name " + accountName + " does not exist."));
            }
        }
        dr.Close();
    }