public HttpResponseMessage RegisterUser([FromBody]UserModel model)
        {
            var responseMsg = this.PerformOperationAndHandleExceptions(
                () =>
                {
                    var context = new BGNewsDB();
                    using (context)
                    {
                        UserPersister.ValidateUsername(model.Username);
                        UserPersister.ValidateNickname(model.DisplayName);
                        UserPersister.ValidateAuthCode(model.AuthCode);

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

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

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

                        user = new User()
                        {
                            Username = usernameToLower,
                            DisplayName = model.DisplayName,
                            AuthCode = model.AuthCode,
                            ProfilePictureUrlMedium = "http://farm6.static.flickr.com/5505/9654705460_5a5026dc3e_m.jpg",
                            ProfilePictureUrlThumbnail = "http://static.flickr.com/5505/9654705460_5a5026dc3e_s.jpg"
                        };

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

                        user.SessionKey = UserPersister.GenerateSessionKey(user.UserId);
                        context.SaveChanges();

                        var loggedModel = new UserLoggedModel()
                        {
                            DisplayName = user.DisplayName,
                            SessionKey = user.SessionKey,
                            ProfilePictureMediumUrl = user.ProfilePictureUrlMedium,
                            ProfilePictureThumbnailUrl = user.ProfilePictureUrlThumbnail
                        };

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

            return responseMsg;
        }
        public HttpResponseMessage PostLoginUser(UserModel model)
        {
            var responseMsg = this.PerformOperationAndHandleExceptions(
                () =>
                {
                    var context = new BGNewsDB();
                    using (context)
                    {
                        UserPersister.ValidateUsername(model.Username);
                        UserPersister.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");
                        }
                        if (user.SessionKey == null)
                        {
                            user.SessionKey = UserPersister.GenerateSessionKey(user.UserId);
                            context.SaveChanges();
                        }

                        var loggedModel = new UserLoggedModel()
                        {
                            DisplayName = user.DisplayName,
                            SessionKey = user.SessionKey,
                            ProfilePictureMediumUrl = "http://farm6.static.flickr.com/5505/9654705460_5a5026dc3e_m.jpg",
                            ProfilePictureThumbnailUrl = "http://static.flickr.com/5505/9654705460_5a5026dc3e_s.jpg"
                        };

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

            return responseMsg;
        }
        public async Task<HttpResponseMessage> PostImage([ValueProvider(typeof(HeaderValueProviderFactory<string>))]
          string sessionKey)
        {
            if (!Request.Content.IsMimeMultipartContent())
            {
                throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
            }

            // Read the file

            string root = HttpContext.Current.Server.MapPath("~/App_Data");
            var provider = new MultipartFormDataStreamProvider(root);


                if (!Request.Content.IsMimeMultipartContent())
                {
                    throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
                }
                using (var db = new BGNewsDB())
                {
                    var user = db.Users.FirstOrDefault(x => x.SessionKey == sessionKey);
                    if (user == null)
                    {
                        return Request.CreateResponse(HttpStatusCode.Unauthorized);
                    }

                    try
                    {
                        // Read the form data.
                        await Request.Content.ReadAsMultipartAsync(provider);

                        // This illustrates how to get the file names.
                        foreach (MultipartFileData file in provider.FileData)
                        {
                            Trace.WriteLine(file.Headers.ContentDisposition.FileName);
                            Trace.WriteLine("Server file path: " + file.LocalFileName);
                            string fileName = file.LocalFileName;
                            Flickr flickr = new Flickr("8429718a57e817718d524ea6366b5b42", "3504e68e5812b923", "72157635282605625-a5feb0f5a53c4467");
                            var result = flickr.UploadPicture(fileName);
                            System.IO.File.Delete(file.LocalFileName);


                            // Take the image urls from flickr

                            Auth auth = flickr.AuthCheckToken("72157635282605625-a5feb0f5a53c4467");
                            PhotoSearchOptions options = new PhotoSearchOptions(auth.User.UserId);
                            options.SortOrder = PhotoSearchSortOrder.DatePostedDescending;
                            options.PerPage = 1;

                            ICollection<Photo> photos = flickr.PhotosSearch(options);

                            Flickr.FlushCache(flickr.LastRequest);

                            Photo photo = photos.First();
                               user.ProfilePictureUrlMedium = photo.MediumUrl;
                               user.ProfilePictureUrlThumbnail = photo.SquareThumbnailUrl;
                            break;

                        }
                       
                     
                        return Request.CreateResponse(HttpStatusCode.Created);
                    }

                    catch (System.Exception e)
                    {
                        return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e);
                    }
                }
            
        }
        public HttpResponseMessage PutLogoutUser([ValueProvider(typeof(HeaderValueProviderFactory<string>))]
                                                 string sessionKey)
        {
            var responseMsg = this.PerformOperationAndHandleExceptions(
                () =>
                {
                    var context = new BGNewsDB();
                    using (context)
                    {
                        UserPersister.ValidateSessionKey(sessionKey);

                        var user = context.Users.FirstOrDefault(usr => usr.SessionKey == sessionKey);
                        if (user == null)
                        {
                            throw new InvalidOperationException("Invalid session key.");
                        }
                        else
                        {
                            user.SessionKey = null;
                            context.SaveChanges();
                        }
                    }

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

                    return response;
                });

            return responseMsg;
        }
        public IQueryable<CreatedCommentModel> GetAllComments()
        {
            using (var db = new BGNewsDB())
            {
                var comments = db.Comments.Select(x => new CreatedCommentModel()
                {
                    CommentId = x.CommentId,
                    Text = x.Text,
                    DateCreated = x.DateCreated,
                    UserId = x.User.UserId,
                    UserDisplayName = x.User.DisplayName,
                    ArticleUrl = x.ArticleUrl,
                    UserThumbnailUrl = x.User.ProfilePictureUrlThumbnail
                }).ToList().AsQueryable();

                return comments;
            }
        }
        public HttpResponseMessage CreateComment([ValueProvider(typeof(HeaderValueProviderFactory<string>))]string sessionKey,
            [FromBody]CommentModel model)
        {
            var responseMsg = this.PerformOperationAndHandleExceptions(
                () =>
                {
                    var context = new BGNewsDB();
                    using (context)
                    {
                        UserPersister.ValidateSessionKey(sessionKey);
                        var user = context.Users.FirstOrDefault(x => x.SessionKey == sessionKey);
                        if (user == null)
                        {
                            return Request.CreateResponse(HttpStatusCode.Unauthorized, "Invalid session key");
                        }

                        Comment newComment = new Comment();
                        newComment.DateCreated = DateTime.Now;
                        newComment.Text = model.Content;
                        newComment.User = user;
                        newComment.ArticleUrl = model.ArticleUrl;

                        context.Comments.Add(newComment);
                        context.SaveChanges();
                        CreatedCommentModel createdCommentModel = new CreatedCommentModel()
                        {
                             CommentId = newComment.CommentId,
                             ArticleUrl = newComment.ArticleUrl.Trim(),
                             DateCreated = newComment.DateCreated,
                             Text = newComment.Text,
                             UserId = newComment.User.UserId,
                             UserDisplayName = newComment.User.DisplayName,
                             UserThumbnailUrl = newComment.User.ProfilePictureUrlThumbnail

                        };
                        var userCommentedBefore = GetCommentsByArticle(newComment.ArticleUrl).
                            ToList().Select(x=>x.UserDisplayName);

                        Dictionary<string, bool> usersCommented = new Dictionary<string, bool>(50);

                        foreach (var comment in userCommentedBefore)
                        {
                            if (comment != user.DisplayName)
                            {
                                string userDisplayName = comment;
                                if (!usersCommented.ContainsKey(userDisplayName))
                                {

                                    PubnubPublisher.Publish(userDisplayName, user.DisplayName +
                                        " replayed to your comment in article with link: " + newComment.ArticleUrl);
                                    usersCommented.Add(userDisplayName, true);
                                }

                            }

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

            return responseMsg;
        }