public HttpResponseMessage PostRegisterUser(UserModel model)
        {
            return this.PerformOperationAndHandleExceptions(() =>
            {
                var usernameToLower = model.Username.ToLower();
                var context = new ForumContext();
                using (context)
                {
                    var entity = context.Users.FirstOrDefault(u => u.Username == usernameToLower);
                    if (entity != null)
                    {
                        string responseMessage = "Username already taken";

                        HttpResponseMessage errResponse =
                            this.Request.CreateErrorResponse(HttpStatusCode.Conflict, responseMessage);
                        throw new HttpResponseException(errResponse);
                    }

                    var user = new User()
                    {
                        Username = model.Username.ToLower(),
                        AuthCode = model.AuthCode
                    };

                    context.Users.Add(user);
                    context.SaveChanges();
                    return this.PostLoginUser(model);
                }
            });
        }
        public IEnumerable<PostModel> GetPostsByThreadId(int threadId,
             [ValueProvider(typeof(HeaderValueProviderFactory<string>))] string sessionKey)
        {
            var responseMsg = ExceptionHandler(
            () =>
            {
                var context = new ForumContext();

                var user = context.Users.FirstOrDefault(u => u.SessionKey == sessionKey);
                if (user == null)
                {
                    throw new InvalidOperationException("Invalid username or password");
                }

                var postEntities = context.Threads.Where(thr => thr.Id == threadId).FirstOrDefault().Posts;
                var models =
                   (from postEntity in postEntities
                    select new PostModel 
                    {
                        Content = postEntity.Content,
                        PostDate = postEntity.PostDate,
                        PostedBy = postEntity.PostedBy.Nickname
                    });

                return models;
            });

            return responseMsg;
        }
        public HttpResponseMessage getUsers(string sessionKey)
        {
            HttpResponseMessage responseMessage = this.PerformOperationAndHandleExceptions(
              () =>
              {
                  ForumContext context = new ForumContext();
                  var user = context.Users.FirstOrDefault(u => u.SessionKey == sessionKey);

                  if (user == null)
                  {
                      throw new ArgumentException("Invalid user data!");
                  }

                  var chatUsers = context.Users.Where(u => u.RecievedMessages.Any(x => x.Sender.Id == user.Id) ||
                      u.SentMessages.Any(x => x.Reciever.Id == user.Id));

                  var users = from u in chatUsers
                              select new UserChatModel
                              {
                                  Id = u.Id,
                                  Username = u.Username
                              };

                  //var messages = user.RecievedMessages.Union(user.SentMessages);
                  //IEnumerable<User> users = messages.Select(return x => new User {
                  //    Id = x.Receiver.Id == user.Id ? x.Receiver.Id : x.Sender.Id,
                  //    AuthCode = x.Receiver.Id == user.Id ? x.Receiver.AuthCode : x.Sender.AuthCode };);

                  var response = this.Request.CreateResponse(HttpStatusCode.OK);

                  return response;
              });

            return responseMessage;
        }
        public HttpResponseMessage GetMessagesWithUser(string sessionKey, int userId)
        {
            HttpResponseMessage responseMessage = this.PerformOperationAndHandleExceptions(
              () =>
              {
                  ForumContext context = new ForumContext();
                  var user = context.Users.FirstOrDefault(u => u.SessionKey == sessionKey);

                  if (user == null)
                  {
                      throw new ArgumentException("Invalid user data!");
                  }

                  var allMessages = user.RecievedMessages.Where(m => m.Sender.Id == userId)
                      .Union(user.SentMessages.Where(m => m.Reciever.Id == userId).OrderBy(m => m.CreationDate));

                  var messages = from m in allMessages
                                 select new MessageModel
                                 {
                                     Content = m.Content,
                                     CreationDate = m.CreationDate,
                                     ReceiverId = m.Reciever.Id,
                                     SenderId = m.Sender.Id
                                 };

                  var response = this.Request.CreateResponse(HttpStatusCode.OK, messages);

                  return response;
              });

            return responseMessage;
        }
        public HttpResponseMessage PostLoginUser(UserModel model)
        {
            return this.PerformOperationAndHandleExceptions(() =>
            {
                var context = new ForumContext();
                using (context)
                {
                    var usernameToLower = model.Username.ToLower();
                    var entity = context.Users.SingleOrDefault(u => u.Username == usernameToLower &&
                        u.AuthCode == model.AuthCode);
                    if (entity == null)
                    {
                        var errResponse = this.Request.CreateErrorResponse(HttpStatusCode.BadRequest,
                            "Invalid username or password");
                        throw new HttpResponseException(errResponse);
                    }

                    entity.SessionKey = this.GenerateSessionKey(entity.Id);

                    context.SaveChanges();
                    var responseModel = new UserLoggedModel()
                    {
                        Username = entity.Username,
                        SessionKey = entity.SessionKey
                    };

                    var response = this.Request.CreateResponse(HttpStatusCode.Accepted, responseModel);
                    return response;
                }
            });
        }
        public HttpResponseMessage RegisterUser(UserRegisterModel model)
        {
            var responseMsg = this.ExceptionHandler(
                () =>
                {
                    var context = new ForumContext();

                    using (context)
                    {
                        UserDataPersister.ValidateUsername(model.Username);
                        UserDataPersister.ValidateNickname(model.Nickname);
                        UserDataPersister.ValidateAuthCode(model.AuthCode);

                        var usernameToLower = model.Username.ToLower();
                        var nicknameToLower = model.Nickname.ToLower();

                        var user = context.Users.FirstOrDefault(
                            usr => usr.Username == usernameToLower || usr.Nickname.ToLower() == nicknameToLower);

                        if (user != null)
                        {
                            throw new InvalidOperationException("Invalid Username or Password");
                        }

                        var newUser = new User
                        {
                            Username = usernameToLower,
                            Nickname = model.Nickname,
                            AuthCode = model.AuthCode
                        };

                        context.Users.Add(newUser);
                        context.SaveChanges();

                        newUser.SessionKey = UserDataPersister.GenerateSessionKey(newUser.Id);
                        context.SaveChanges();


                        var loggedModel = new LoggedUserModel
                        {
                            Nickname = newUser.Nickname,
                            SessionKey = newUser.SessionKey
                        };

                        var response = this.Request.CreateResponse(HttpStatusCode.Created, loggedModel);
                        response.Headers.Location = new Uri(Url.Link("DefaultApi", new { id = newUser.Id }));

                        return response;
                    }
                });

            return responseMsg;
        }
        public HttpResponseMessage PostRegisterUser(UserModel model)
        {
            var responseMsg = this.PerformOperationAndHandleExceptions(() =>
                {

                    var context = new ForumContext();

                    using (context)
                    {
                        this.ValidateUserName(model.UserName);
                        this.ValidateNickName(model.NickName);
                        this.ValidateAuthCode(model.AuthCode);

                        var userNameToLower = model.UserName.ToLower();
                        var nickNameToLower = model.NickName.ToLower();

                        var user = context.Users.FirstOrDefault(
                            usr => usr.UserName == userNameToLower &&
                                usr.NickName == usr.NickName);

                        if (user != null)
                        {
                            throw new InvalidOperationException("User exists!");
                        }

                        user = new User()
                        {
                            UserName = userNameToLower,
                            NickName = model.NickName,
                            AuthCode = model.AuthCode
                        };

                        context.Users.Add(user);
                        context.SaveChanges();

                        user.SessionKey = this.GenerateSessionKey(user.Id);
                        context.SaveChanges();

                        var loggedModel = new UserLoggedModel()
                        {
                            Nickname = user.NickName,
                            SessionKey = user.SessionKey
                        };

                        var response = this.Request.CreateResponse(HttpStatusCode.Created,
                            loggedModel);

                        return response;
                    }
                });

            return responseMsg;
            }
        public IQueryable<ThreadModel> GetAll(
            [ValueProvider(typeof(HeaderValueProviderFactory<string>))] string sessionKey)
        {
            var responseMsg = this.PerformOperationAndHandleExceptions(() =>
            {
                var context = new ForumContext();

                var user = context.Users.FirstOrDefault(
                    usr => usr.SessionKey == sessionKey);

                if (user == null)
                {
                    throw new InvalidOperationException("Invalid username or password");
                }

                var threadEntities = context.Threads;

                var models = 
                    (from entityEntry in threadEntities
                    select new ThreadModel()
                    {
                        Id = entityEntry.Id,
                        Title = entityEntry.Title,
                        DateCreated = entityEntry.DateCreated,
                        Content = entityEntry.Content,
                        Categories = (from categoryEntry in entityEntry.Categories
                                      select categoryEntry.Name),
                        Posts = (from postEntry in entityEntry.Posts
                                 select new PostModel()
                                 {
                                    Content = postEntry.Content,
                                    PostDate = postEntry.DatePosted,
                                    PostedBy = postEntry.PostedBy.NickName
                                 })
                    });

                return models.OrderByDescending(thr => thr.DateCreated);
            });

            return responseMsg;
        }
        public HttpResponseMessage DeletePostById(string sessionKey, int id)
        {
            HttpResponseMessage responseMessage = this.PerformOperationAndHandleExceptions(
               () =>
               {
               ForumContext context = new ForumContext();

               User adminUser = context.Users.FirstOrDefault(usr => usr.SessionKey == sessionKey);

               if (adminUser == null)
               {
                   throw new ArgumentNullException("If you want to edit users, you have to login or register first.");
               }

               if (adminUser.IsAdmin == false)
               {
                   throw new ArgumentException("You have to be admin, to edit users.");
               }

               Post currentPost = context.Posts.FirstOrDefault(pst => pst.Id == id);

               if (currentPost == null)
               {
                   throw new ArgumentNullException("Post you want to edit, doesn't exist.");
               }

               context.Posts.Remove(currentPost);

               context.SaveChanges();

               //UserModel result = UserModel.Parse(currentUser);

               var response = this.Request.CreateResponse(HttpStatusCode.NoContent);

               return response;

               });

            return responseMessage;
        }
        public HttpResponseMessage EditCategoryById(string sessionKey, CategoryEditModel newComment)
        {
            HttpResponseMessage responseMessage = this.PerformOperationAndHandleExceptions(
             () =>
             {
                 ForumContext context = new ForumContext();

                 User adminUser = context.Users.FirstOrDefault(usr => usr.SessionKey == sessionKey);

                 if (adminUser == null)
                 {
                     throw new ArgumentNullException("If you want to edit users, you have to login or register first.");
                 }

                 if (adminUser.IsAdmin == false)
                 {
                     throw new ArgumentException("You have to be admin, to edit users.");
                 }

                 Comment currentComment = context.Comments.FirstOrDefault(comment => comment.Id == newComment.Id);

                 if (currentComment == null)
                 {
                     throw new ArgumentNullException("Comment you want to edit, doesn't exist.");
                 }

                 currentComment.Content = newComment.Content;

                 context.SaveChanges();

                 //TODO yoan change model from commentCreateModel to commentCreatedModel
                 var response = this.Request.CreateResponse(HttpStatusCode.OK, newComment);

                 return response;

             });

            return responseMessage;
        }
        public HttpResponseMessage DeleteCategoryById(string sessionKey, int id)
        {
            HttpResponseMessage responseMessage = this.PerformOperationAndHandleExceptions(
               () =>
               {
               ForumContext context = new ForumContext();

               User adminUser = context.Users.FirstOrDefault(usr => usr.SessionKey == sessionKey);

               if (adminUser == null)
               {
                   throw new ArgumentNullException("If you want to edit users, you have to login or register first.");
               }

               if (adminUser.IsAdmin == false)
               {
                   throw new ArgumentException("You have to be admin, to edit users.");
               }

               Category currentCategory = context.Categories.FirstOrDefault(cat => cat.Id == id);

               if (currentCategory == null)
               {
                   throw new ArgumentNullException("Category you want to remove, doesn't exist.");
               }

               context.Categories.Remove(currentCategory);

               context.SaveChanges();

               var response = this.Request.CreateResponse(HttpStatusCode.OK);

               return response;

               });

            return responseMessage;
        }
        public HttpResponseMessage PostCreateThread(ThreadModel model,
            [ValueProvider(typeof(HeaderValueProviderFactory<string>))] string sessionKey)
        {
            var responseMsg = this.PerformOperationAndHandleExceptions(() =>
            {
                if (model == null)
                {
                    throw new InvalidOperationException("Thread cannot be null");
                }

                var context = new ForumContext();
                using (context)
                {
                    User user = context.Users.Where(usr => usr.SessionKey == sessionKey).FirstOrDefault();
                    if (user == null)
                    {
                        throw new InvalidOperationException("Invalid sessionkey");
                    }

                    var thread = new Thread()
                    {
                        Title = model.Title,
                        DateCreated = model.DateCreated,
                        Content = model.Content
                    };

                    user.Threads.Add(thread);
                    context.SaveChanges();

                    var response = this.Request.CreateResponse(HttpStatusCode.Created, model);

                    return response;
                }
            });

            return responseMsg;
        }
        public PostModel Get(int id)
        {
            var responseMsg = this.PerformOperationAndHandleExceptions(() =>
            {
                var context = new ForumContext();

                var postEntity = context.Posts.FirstOrDefault(x => x.Id == id);

                if (postEntity == null)
                {
                    throw new InvalidOperationException("Invalid id");
                }

                var model = new PostFullModel()
                     {
                         Id = postEntity.Id,
                         Title = postEntity.Title,
                         CreatedOn = postEntity.CreatedOn,
                         Creator = postEntity.Creator.Username,
                         NumberComments = postEntity.Comments.Count,
                         Content = postEntity.Content,
                         Tags = (from tagEntity in postEntity.Tags
                                 select tagEntity.Name),
                         Comments = (from commentEntity in postEntity.Comments
                                  select new CommentFullModel()
                                  {
                                      Text = commentEntity.Text,
                                      CreatedOn = commentEntity.CreatedOn,
                                      Creator = commentEntity.Creator.Username
                                  })
                     };
                return model;
            });

            return responseMsg;
        }
        public IQueryable<PostModel> GetAll()
        {
            var responseMsg = this.PerformOperationAndHandleExceptions(() =>
            {
                var context = new ForumContext();

                var postEntities = context.Posts;
                var models =
                    (from postEntity in postEntities
                     select new PostModel()
                     {
                         Id = postEntity.Id,
                         Title = postEntity.Title,
                         CreatedOn = postEntity.CreatedOn,
                         Creator = postEntity.Creator.Username,
                         Tags = (from tagEntity in postEntity.Tags
                                 select tagEntity.Name),
                         NumberComments = postEntity.Comments.Count
                     });
                return models.OrderByDescending(p => p.CreatedOn);
            });

            return responseMsg;
        }
        public void LogoutUser(
             [ValueProvider(typeof(HeaderValueProviderFactory<string>))] string sessionKey)
        {
            this.ExceptionHandler(
            () =>
            {
                var context = new ForumContext();

                using (context)
                {
                    var user = context.Users.FirstOrDefault(
                        usr => usr.SessionKey == sessionKey);

                    if (user == null)
                    {
                        throw new InvalidOperationException("Invalid Username or Password");
                    }

                    user.SessionKey = null;
                    context.SaveChanges();

                    var loggedModel = new LoggedUserModel
                    {
                        Nickname = user.Nickname,
                        SessionKey = user.SessionKey
                    };

                    var response = this.Request.CreateResponse(HttpStatusCode.Created, loggedModel);

                    return response;
                }
            });
        }
        public IQueryable<CommentModel> GetAll()
        {
            ForumContext context = new ForumContext();

            var allComments =
                from commentEntity in context.Comments
                select new CommentModel()
                {
                    Author = commentEntity.Author.Username,
                    Content = commentEntity.Content,
                    CreationDate = commentEntity.CreationDate
                };

            return allComments;
        }
        public IQueryable<UserModel> GetAll()
        {
            ForumContext context = new ForumContext();

            var allUsers =
                from UserEntity in context.Users
                select new UserModel()
                {
                    AuthCode = UserEntity.AuthCode,
                    IsAdmin = UserEntity.IsAdmin,
                    CreationDate = UserEntity.CreationDate,
                    SessionKey = UserEntity.SessionKey,
                    Username = UserEntity.Username,
                    Id = UserEntity.Id,
                    IsBanned = UserEntity.IsBanned
                };

            return allUsers;
        }
        public HttpResponseMessage PostCreate(PostRegisterModel inputPost, string sessionKey)
        {
            HttpResponseMessage responseMessage = this.PerformOperationAndHandleExceptions(
                () =>
                {
                    ForumContext context = new ForumContext();

                    using(context)
                    {
                        User currentUser = context.Users.FirstOrDefault(usr => usr.SessionKey == sessionKey);

                        int currentCategoryId = inputPost.CurrentCategoryId;

                        Category currentCategory = context.Categories.FirstOrDefault(cat => cat.Id == currentCategoryId);

                        if(currentUser == null)
                        {
                            throw new ArgumentNullException("You should be logged or registered to create new posts.");
                        }

                        if(currentCategory == null)
                        {
                            throw new ArgumentNullException("You try to create post in non-existing category.");
                        }

                        Post newPost = new Post()
                        {
                            Author = currentUser,
                            Category = currentCategory,
                            Content = inputPost.Content,
                            CreationDate = DateTime.Now,
                            Title = inputPost.Title
                        };

                        foreach(string tagName in inputPost.Tags)
                        {
                            Tag currentTag = context.Tags.FirstOrDefault(t => t.Name == tagName);

                            if(currentTag == null)
                            {
                                currentTag = new Tag()
                                {
                                    Name = tagName
                                };

                                context.Tags.Add(currentTag);
                                context.SaveChanges();

                                newPost.Tags.Add(currentTag);
                            }
                            else
                            {
                                newPost.Tags.Add(currentTag);
                            }
                        }

                        context.Posts.Add(newPost);
                        context.SaveChanges();

                        var resultPost = new PostModel
                        {
                            Id = newPost.Id,
                            Content = newPost.Content,
                            CategoryName = newPost.Category.Title,
                            CategoryId = newPost.Category.Id,
                            CreationDate = newPost.CreationDate,
                            Tags = (from t in newPost.Tags
                                   select t.Name),
                            Title = newPost.Title,
                            Author = newPost.Author.Username
                        };

                        HttpResponseMessage response = this.Request.CreateResponse(HttpStatusCode.Created, resultPost);

                        return response;
                    }
                });

            return responseMessage;
        }
        public HttpResponseMessage GetByCategoryId(int id)
        {
            HttpResponseMessage responseMessage = this.PerformOperationAndHandleExceptions(
                () =>
                {
                    ForumContext context = new ForumContext();

                    Category currentCategory = context.Categories.FirstOrDefault(cat => cat.Id == id);

                    if (currentCategory == null)
                    {
                        throw new ArgumentNullException(string.Format("Category with id: {0} doesn't exist.", id));
                    }

                    var filteredPosts = GetAll().Where(pst => pst.CategoryId == id);

                    CategoryWithPostsModel result = new CategoryWithPostsModel()
                    {
                        Title = currentCategory.Title,
                        Posts = filteredPosts,
                        Description = currentCategory.Description
                    };

                    HttpResponseMessage response = this.Request.CreateResponse(HttpStatusCode.OK, result);

                    return response;
                });

            return responseMessage;
        }
        public IEnumerable<PostModel> GetAll()
        {
            ForumContext context = new ForumContext();

            var allPosts =
                from postEntity in context.Posts
                select new PostModel()
                {
                    Author = postEntity.Author.Username,
                    Id = postEntity.Id,
                    CategoryId = postEntity.Category.Id,
                    CategoryName = postEntity.Category.Title,
                    Title = postEntity.Title,
                    CreationDate = postEntity.CreationDate,
                    Content = postEntity.Content,
                    Comments =
                        from commentEntity in postEntity.Comments
                        select new CommentModel()
                        {
                            Author = commentEntity.Author.Username,
                            Content = commentEntity.Content,
                            CreationDate = commentEntity.CreationDate
                        },
                    Tags =
                        from tagEntity in postEntity.Tags
                        select tagEntity.Name
                };

            return allPosts;
        }
        public HttpResponseMessage PutUserLogout(string sessionKey)
        {
            var responseMsg = this.PerformOperationAndHandleExceptions(() =>
                {
                    this.ValidateSessionKey(sessionKey);
                    var context = new ForumContext();
                    using (context)
                    {
                        var user = context.Users.FirstOrDefault(usr => usr.SessionKey == sessionKey);
                        if (user == null)
                        {
                            throw new InvalidOperationException("Invalid user authentication");
                        }
                        user.SessionKey = null;
                        context.SaveChanges();

                        var response = this.Request.CreateResponse(HttpStatusCode.OK);

                        return response;
                    }
                });

            return responseMsg;
        }
        public HttpResponseMessage PostLoginUser(UserFlatModel inputUser)
        {
            HttpResponseMessage responseMessage = this.PerformOperationAndHandleExceptions(
              () =>
              {
                  ForumContext context = new ForumContext();

                  using (context)
                  {
                      this.ValidateUsername(inputUser.Username);
                      this.ValidateAuthCode(inputUser.AuthCode);

                      var usernameToLower = inputUser.Username.ToLower();

                      User user = context.Users.FirstOrDefault(
                          usr => usr.Username == usernameToLower
                          && usr.AuthCode == inputUser.AuthCode);

                      if (user == null)
                      {
                          throw new InvalidOperationException("Invalid username or password");
                      }
                      if (user.SessionKey == null)
                      {
                          user.SessionKey = this.GenerateSessionKey(user.Id);
                          context.SaveChanges();
                      }
                      if (user.IsBanned == true)
                      {
                          throw new ArgumentException("User is banned.");
                      }

                      UserLoggedModel loggedModel = new UserLoggedModel()
                      {
                          Username = user.Username,
                          SessionKey = user.SessionKey
                      };

                      var response =
                          this.Request.CreateResponse(HttpStatusCode.Created,
                                          loggedModel);
                      return response;
                  }
              });

            return responseMessage;
        }
        public IQueryable<CategoryModel> GetAll()
        {
            ForumContext context = new ForumContext();

            var allCategories =
                from categoryEntity in context.Categories
                select new CategoryModel()
                {
                    Id = categoryEntity.Id,
                    Title = categoryEntity.Title,
                    Description = categoryEntity.Description
                };
            return allCategories;
        }
        public HttpResponseMessage PostRegisterUser(UserFlatModel inputUser)
        {
            HttpResponseMessage responseMessage = this.PerformOperationAndHandleExceptions(
                 () =>
                 {
                     ForumContext context = new ForumContext();

                     using (context)
                     {
                         this.ValidateUsername(inputUser.Username);
                         this.ValidateAuthCode(inputUser.AuthCode);

                         var usernameToLower = inputUser.Username.ToLower();

                         User user = context.Users.FirstOrDefault(
                             usr => usr.Username == usernameToLower);
                         if (user != null)
                         {
                             throw new InvalidOperationException("User already exists");
                         }

                         user = new User()
                         {
                             Username = usernameToLower,
                             AuthCode = inputUser.AuthCode,
                             CreationDate = DateTime.Now
                         };

                         context.Users.Add(user);
                         context.SaveChanges();

                         user.SessionKey = this.GenerateSessionKey(user.Id);
                         context.SaveChanges();

                         UserLoggedModel loggedModel = new UserLoggedModel()
                         {
                             Username = user.Username,
                             SessionKey = user.SessionKey
                         };

                         HttpResponseMessage response =
                             this.Request.CreateResponse(HttpStatusCode.Created,
                                             loggedModel);
                         return response;
                     }
                 });

            return responseMessage;
        }
        public HttpResponseMessage PutLogoutUser(string sessionKey)
        {
            HttpResponseMessage responseMessage = this.PerformOperationAndHandleExceptions(
              () =>
              {
                  ForumContext context = new ForumContext();

                  using (context)
                  {
                      User currentUser = context.Users.FirstOrDefault(usr => usr.SessionKey == sessionKey);

                      if (currentUser == null)
                      {
                          throw new ArgumentException("User is not registered or not logged in.");
                      }

                      currentUser.SessionKey = null;

                      context.SaveChanges();

                      string logoutText = "You successfully have logged out.";

                      var response = this.Request.CreateResponse(HttpStatusCode.Accepted, logoutText);

                      return response;
                  }
              });

            return responseMessage;
        }
        public HttpResponseMessage PutLogoutUser(
            [ValueProvider(typeof(HeaderValueProviderFactory<string>))] string sessionKey)
        {
            var responseMsg = this.PerformOperationAndHandleExceptions(
              () =>
              {
                  var context = new ForumContext();
                  using (context)
                  {
                      var user = context.Users.FirstOrDefault(
                          u => u.SessionKey == sessionKey);

                      if (user == null)
                      {
                          throw new InvalidOperationException("Invalid sessionKey");
                      }

                      user.SessionKey = null;
                      context.SaveChanges();

                      var response =
                          this.Request.CreateResponse(HttpStatusCode.OK);
                      return response;
                  }
              });

            return responseMsg;
        }
        public HttpResponseMessage PostCreateComment(CommentCreateModel inputComment, string sessionKey)
        {
            HttpResponseMessage responseMessage = this.PerformOperationAndHandleExceptions(
              () =>
              {
                  ForumContext context = new ForumContext();

                  User currentUser = context.Users.FirstOrDefault(usr => usr.SessionKey == sessionKey);

                  Post currentPost = context.Posts.FirstOrDefault(pst => pst.Id == inputComment.PostId);

                  if (currentUser == null)
                  {
                      throw new ArgumentNullException("If you want to comment posts, you should be logged or registered.");
                  }

                  if (currentPost == null)
                  {
                      throw new ArgumentNullException("The post you are trying to comment, doesn't exist.");
                  }

                  Comment newComment = new Comment()
                  {
                      Author = currentUser,
                      Post = currentPost,
                      Content = inputComment.Content,
                      CreationDate = DateTime.Now
                  };

                  context.Comments.Add(newComment);
                  context.SaveChanges();

                  CommentModel createdComment = new CommentModel()
                  {
                      Author = newComment.Author.Username,
                      Content = newComment.Content,
                      CreationDate = newComment.CreationDate
                  };

                  return this.Request.CreateResponse(HttpStatusCode.Created, createdComment);
              });

            return responseMessage;
        }
        public HttpResponseMessage GetById(string sessionKey)
        {
            HttpResponseMessage responseMessage = this.PerformOperationAndHandleExceptions(
              () =>
              {
                  ForumContext context = new ForumContext();

                  using (context)
                  {

                      User currentUser = context.Users.FirstOrDefault(usr => usr.SessionKey == sessionKey);

                      if (currentUser == null)
                      {
                          throw new ArgumentNullException("User you are looking for is not logged or doesn't exist.");
                      }

                      var response = this.Request.CreateResponse(HttpStatusCode.OK, currentUser);

                      return response;
                  }
              });

            return responseMessage;
        }
        public HttpResponseMessage LoginUser(UserLoginModel model)
        {
            var responseMsg = this.ExceptionHandler(
                () =>
                {
                    var context = new ForumContext();

                    using (context)
                    {
                        UserDataPersister.ValidateUsername(model.Username);
                        UserDataPersister.ValidateAuthCode(model.AuthCode);

                        var usernameToLower = model.Username.ToLower();

                        var user = context.Users.FirstOrDefault(
                            usr => usr.Username == usernameToLower && usr.AuthCode == model.AuthCode);

                        if (user == null)
                        {
                            throw new InvalidOperationException("Invalid Username or Password");
                        }

                        user.SessionKey = UserDataPersister.GenerateSessionKey(user.Id);
                        context.SaveChanges();

                        var loggedModel = new LoggedUserModel
                        {
                            Nickname = user.Nickname,
                            SessionKey = user.SessionKey
                        };

                        var response = this.Request.CreateResponse(HttpStatusCode.Created, loggedModel);

                        return response;
                    }
                });

            return responseMsg;
        }
        public HttpResponseMessage EditUserById(string sessionKey, UserEditModel newUser)
        {
            HttpResponseMessage responseMessage = this.PerformOperationAndHandleExceptions(
             () =>
             {
                 ForumContext context =new ForumContext();

                 User adminUser = context.Users.FirstOrDefault(usr => usr.SessionKey == sessionKey);

                 if (adminUser == null)
                 {
                     throw new ArgumentNullException("If you want to edit users, you have to login or register first.");
                 }

                 if(adminUser.IsAdmin == false)
                 {
                     throw new ArgumentException("You have to be admin, to edit users.");
                 }

                 User currentUser = context.Users.FirstOrDefault(usr => usr.Id == newUser.Id);

                 if (currentUser == null)
                 {
                     throw new ArgumentNullException("User you want to edit, doesn't exist.");
                 }

                 //currentUser.Username = newUser.Username;
                 currentUser.IsBanned = newUser.IsBanned;

                 context.SaveChanges();

                 UserModel result = UserModel.Parse(currentUser);

                 var response = this.Request.CreateResponse(HttpStatusCode.OK, result);

                 return response;

             });

            return responseMessage;
        }