/// <summary>
        /// Updates the item
        /// </summary>
        /// <param name="item">
        /// Item to update
        /// </param>
        public void Update(UsersDB item)
        {
            using (SqlCeCommand command = EntityBase.CreateCommand(this.Transaction))
            {
                command.CommandText =
                    "UPDATE [Users_DB] SET UserName = @UserName, PassHash = @PassHash, Friends = @Friends WHERE UserID = @UserID";

                command.Parameters.Add("@UserID", SqlDbType.Int);
                command.Parameters["@UserID"].Value = item.UserId;
                command.Parameters.Add("@UserName", SqlDbType.NVarChar);
                command.Parameters["@UserName"].Value = item.UserName != null ? (object)item.UserName : DBNull.Value;
                command.Parameters.Add("@PassHash", SqlDbType.NVarChar);
                command.Parameters["@PassHash"].Value = item.PassHash != null ? (object)item.PassHash : DBNull.Value;
                command.Parameters.Add("@Friends", SqlDbType.Image);
                command.Parameters["@Friends"].Value = item.Friends != null ? (object)item.Friends : DBNull.Value;
                command.ExecuteNonQuery();
            }
        }
        /// <summary>
        /// Retrieves the first set of items specified by count by UserName
        /// </summary>
        /// <param name="userName">
        /// UserName value
        /// </param>
        /// <param name="count">
        /// Number of records to be retrieved
        /// </param>
        /// <returns>
        /// The
        ///     <see>
        ///         <cref>List</cref>
        ///     </see>
        ///     .
        /// </returns>
        public List<UsersDB> SelectByUserName(string userName, int count)
        {
            mutex.WaitOne();
            var list = new List<UsersDB>();
            using (var command = EntityBase.CreateCommand(this.Transaction))
            {
                if (userName != null)
                {
                    command.CommandText = "SELECT TOP(" + count + ") * FROM Users_DB WHERE UserName=@UserName";
                    command.Parameters.Add("@UserName", SqlDbType.NVarChar);
                    command.Parameters["@UserName"].Value = userName;
                }
                else
                {
                    command.CommandText = "SELECT TOP(" + count + ") * FROM Users_DB WHERE UserName IS NULL";
                }

                using (var reader = command.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        var item = new UsersDB
                                       {
                                           UserId = (int)reader["UserID"],
                                           UserName = reader.IsDBNull(1) ? null : reader["UserName"] as string,
                                           PassHash = reader.IsDBNull(2) ? null : reader["PassHash"] as string,
                                           Friends =
                                               reader.IsDBNull(3) ? null : reader["Friends"] as List<UserClass>
                                       };
                        list.Add(item);
                    }
                }
            }

            mutex.ReleaseMutex();
            return list.Count > 0 ? list : null;
        }
        /// <summary>
        /// Retrieves the first set of items specified by count as a generic collection
        /// </summary>
        /// <param name="count">
        /// Number of records to be retrieved
        /// </param>
        /// <returns>
        /// The
        ///     <see>
        ///         <cref>List</cref>
        ///     </see>
        ///     .
        /// </returns>
        public List<UsersDB> ToList(int count)
        {
            mutex.WaitOne();
            var list = new List<UsersDB>();
            using (var command = EntityBase.CreateCommand(this.Transaction))
            {
                command.CommandText = string.Format("SELECT TOP({0}) * FROM Users_DB", count);
                using (var reader = command.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        var item = new UsersDB
                                       {
                                           UserId = (int)reader["UserID"],
                                           UserName = reader.IsDBNull(1) ? null : reader["UserName"] as string,
                                           PassHash = reader.IsDBNull(2) ? null : reader["PassHash"] as string,
                                           Friends =
                                               reader.IsDBNull(3) ? null : reader["Friends"] as List<UserClass>
                                       };
                        list.Add(item);
                    }
                }
            }

            mutex.ReleaseMutex();

            return list.Count > 0 ? list : null;
        }
        /// <summary>
        /// Retrieves a collection of items by UserName
        /// </summary>
        /// <param name="userName">
        /// UserName value
        /// </param>
        /// <returns>
        /// The
        ///     <see>
        ///         <cref>List</cref>
        ///     </see>
        ///     .
        /// </returns>
        public List<UsersDB> SelectByUserName(string userName)
        {
            mutex.WaitOne();
            var list = new List<UsersDB>();
            using (SqlCeCommand command = EntityBase.CreateCommand(this.Transaction))
            {
                if (userName != null)
                {
                    command.CommandText = "SELECT * FROM Users_DB WHERE UserName=@UserName";
                    command.Parameters.Add("@UserName", SqlDbType.NVarChar);
                    command.Parameters["@UserName"].Value = userName;
                }
                else
                {
                    command.CommandText = "SELECT * FROM Users_DB WHERE UserName IS NULL";
                }

                using (SqlCeDataReader reader = command.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        var item = new UsersDB();
                        item.UserId = (int)reader["UserID"];
                        item.UserName = reader["UserName"] as string;
                        item.PasswordHash = reader["PassHash"] as string;
                        // item.Friends = reader.IsDBNull(3) ? new List<UserClass>() : UserClass.RestoreFriends(reader["Friends"] as byte[]);
                        var taco = reader["Friends"] as byte[];
                        var taco2 = UserClass.RestoreFriends(taco);
                        item.Friends = taco2;
                        list.Add(item);
                    }
                }
            }

            mutex.ReleaseMutex();
            return list.Count > 0 ? list : null;
        }
        public List<UsersDB> SelectByUserId(int? userID, int count)
        {
            var list = new List<UsersDB>();
            using (SqlCeCommand command = EntityBase.CreateCommand(this.Transaction))
            {
                if (userID != null)
                {
                    command.CommandText = "SELECT TOP(" + count + ") * FROM Users_DB WHERE UserID=@UserID";
                    command.Parameters.Add("@UserID", SqlDbType.Int);
                    command.Parameters["@UserID"].Value = userID;
                }
                else
                {
                    command.CommandText = "SELECT TOP(" + count + ") * FROM Users_DB WHERE UserID IS NULL";
                }

                using (SqlCeDataReader reader = command.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        var item = new UsersDB
                                       {
                                           UserId = (int)reader["UserID"],
                                           UserName = reader.IsDBNull(1) ? null : reader["UserName"] as string,
                                           PassHash = reader.IsDBNull(2) ? null : reader["PassHash"] as string,
                                           Friends =
                                               reader.IsDBNull(3) ? null : reader["Friends"] as List<UserClass>
                                       };
                        list.Add(item);
                    }
                }
            }

            return list.Count > 0 ? list : null;
        }
 /// <summary>
 /// Inserts the item to the table
 /// </summary>
 /// <param name="item">
 /// Item to insert to the database
 /// </param>
 public void Create(UsersDB item)
 {
     this.Create(item.UserName, item.PassHash, item.Friends);
 }
        /// <summary>
        /// Deletes the item
        /// </summary>
        /// <param name="item">
        /// Item to delete
        /// </param>
        public void Delete(UsersDB item)
        {
            using (var command = EntityBase.CreateCommand(this.Transaction))
            {
                command.CommandText = "DELETE FROM [Users_DB] WHERE UserID = @UserID";

                command.Parameters.Add("@UserID", SqlDbType.Int);
                command.Parameters["@UserID"].Value = item.UserId;
                command.ExecuteNonQuery();
            }
        }
        // Setup connection and login or register.
        /// <summary>
        /// The setup connection.
        /// </summary>
        internal void SetupConn()
        {
            try
            {
                EventLogging.WriteEvent("New connection!", EventLogEntryType.Information);
                this.netStream = this.client.GetStream();
                this.ssl = new SslStream(this.netStream, false);
                this.ssl.AuthenticateAsServer(this.Prog.Cert, false, SslProtocols.Tls, true);
                EventLogging.WriteEvent("Connection authenticated!", EventLogEntryType.SuccessAudit);

                // Now we have encrypted connection.
                this.reader = new BinaryReader(this.ssl, Encoding.UTF8);
                this.writer = new BinaryWriter(this.ssl, Encoding.UTF8);

                // Say "hello".
                this.writer.Write(ImStatuses.ImHello);
                this.writer.Flush();
                var hello = this.reader.ReadInt32();
                if (hello == ImStatuses.ImHello)
                {
                    // Writer.Write(ImStatuses.IM_Login);
                    // Writer.Flush();
                    var action = this.reader.ReadByte();

                    int length;
                    byte[] use;
                    UserClass user;

                    switch (action)
                    {
                        case ImStatuses.ImLogin:
                            // Get the length of the incoming byte array
                            length = this.reader.ReadInt32();

                            // Read said byte array
                            use = this.reader.ReadBytes(length);

                            // Convert that array into a user.
                            user = UserClass.Deserialize(use);

                            // TODO: research mutex
                            // lock (this.Prog.DBRepository)
                            // {
                            var list = this.Prog.DBRepository.SelectByUserName(user.UserName);

                            if (list.Count < 1)
                            {
                                this.writer.Write(ImStatuses.ImNoExists);
                                this.writer.Flush();
                                break;
                            }

                            var tempUse = list[0];
                            if (user.PasswordHash == tempUse.PasswordHash)
                            {
                                // User logged in so return their account to them
                                this.writer.Write(ImStatuses.ImOk);
                                var temp2 = new UserClass(
                                    tempUse.UserName,
                                    tempUse.UserId,
                                    tempUse.PasswordHash,
                                    true)
                                                {
                                                    Friends = tempUse.Friends
                                                };
                                var logg = UserClass.Serialize(temp2);
                                this.writer.Write(logg.Length);
                                this.writer.Write(logg);
                                this.writer.Flush();

                                // Add the connection to the database
                                lock (this.Prog.UserConnections)
                                {
                                    if (this.Prog.UserConnections.ContainsKey(tempUse.UserId))
                                    {
                                        this.Prog.UserConnections.Remove(tempUse.UserId);
                                    }

                                    this.Prog.UserConnections.Add(tempUse.UserId, this.client);
                                }

                                // With the call going to the receiver the
                                // temp should still be in scope
                                // this.userInfo = temp.Clone() as UserInfo;

                                // TODO check which of these actually work
                                this.userInfo = tempUse.Clone() as UserInfo;
                                if (this.userInfo == null)
                                {
                                    this.userInfo = new UserInfo
                                                        {
                                                            Connection = this,
                                                            UserId = tempUse.UserId,
                                                            UserName = tempUse.UserName,
                                                            PasswordHash = tempUse.PasswordHash,
                                                            Friends = tempUse.Friends
                                                        };

                                    // this.userInfo.Connection = this;
                                }

                                this.Receiver();
                            }
                            else
                            {
                                this.writer.Write(ImStatuses.ImWrongPass);
                                this.writer.Flush();

                                // this.CloseConn();
                            }

                            // }
                            break;

                        case ImStatuses.ImRegister:
                            // Get the length of the incoming byte array
                            length = this.reader.ReadInt32();

                            // Read said byte array
                            use = this.reader.ReadBytes(length);

                            // Convert that array into a user.
                            user = UserClass.Deserialize(use);

                            // lock (this.Prog.DBRepository)
                            // {
                            if (this.Prog.DBRepository.SelectByUserName(user.UserName) == null)
                            {
                                var temp = new UsersDB();
                                temp.UserName = user.UserName;
                                temp.PassHash = user.PasswordHash;
                                temp.Friends = user.Friends;
                                this.Prog.DBRepository.Create(temp);
                                this.writer.Write(ImStatuses.ImOk);
                                this.writer.Flush();
                            }
                            else
                            {
                                this.writer.Write(ImStatuses.ImExists);
                                this.writer.Flush();

                                // this.CloseConn();
                            }

                            // }
                            break;
                        default:
                            this.CloseConn();
                            break;
                    }
                }

                this.CloseConn();
            }
            catch (Exception ex)
            {
                EventLogging.WriteError(ex, "An error has occurred trying to setup the connection.");
                this.writer.Write(ImStatuses.ImError);
                this.CloseConn();
            }
        }