// POST api/Book
 public async Task<IHttpActionResult> PostBook(BookDto bookDto) {
     if (ModelState.IsValid) {
         LanguageType bookLanguage;
         if (!Enum.TryParse<LanguageType>(bookDto.language, out bookLanguage)) {
             return BadRequest("Invalid book language");
         }
         var userId = User.Identity.GetUserId();
         UserBook userBook = await db.FindUserBookAsync(userId, bookDto.name, bookLanguage);
         if (userBook != null) {
             ModelState.AddModelError("name", string.Format("You already have book \"{0}\"", bookDto.name));
         } else {
             userBook = await db.CreateUserBookAsync(User.Identity.GetUserId(), bookLanguage, bookDto.name);
             var userBookDto = new UserBookDto(userBook);
             return CreatedAtRoute("DefaultApi", new { id = userBook.Id },
                 new {
                     emberDataFormat = true,
                     books = new List<dynamic> { userBookDto.BookDto },
                     userBooks = new List<dynamic> { userBookDto }
                 });
         }
     }
     return new EmberDSErrorsResult(this);
 }
        // PUT api/UserBook/5
        public async Task<IHttpActionResult> PutUserBook(int id, UserBookDto userBookDto) {
            if (!ModelState.IsValid) {
                return BadRequest(ModelState);
            }

            var userBook = db.UserBooks.Find(id);
            userBookDto.Update(userBook);
            //userBook.Name = bookDto.name;
            //db.Entry(userBook.ToBookEntity()).State = EntityState.Modified;

            try {
                await db.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException) {
                if (!UserBookExists(id)) {
                    return NotFound();
                } else {
                    throw;
                }
            }

            return StatusCode(HttpStatusCode.NoContent);
        }
        // POST api/Translation
        public async Task<IHttpActionResult> PostTranslation(TranslationData data) {
            try {
                if (!ModelState.IsValid) {
                    return BadRequest(ModelState);
                }
                LanguageType wordLanguage;
                LanguageType translationLanguage;
                if (!Enum.TryParse<LanguageType>(data.wordLanguage, out wordLanguage)) {
                    return BadRequest("Invalid word language");
                }
                if (!Enum.TryParse<LanguageType>(data.translationLanguage, out translationLanguage)) {
                    return BadRequest("Invalid translation language");
                }

                var user = this.GetUser();

                // . add word
                SpeachPartType sp = GetSpeachPart(data.translationWords, data.translationWord);
                LanguageFormatter languageFormatter = new LanguageFormatter(wordLanguage);
                Word word = await db.AddWord(languageFormatter.FormatWord(data.word, sp),
                    wordLanguage,
                    data.wordPronunciation,
                    data.wordSoundUrls,
                    data.wordPictureUrls);
                // . add word translations to mongo
                await mongoDb.AddTranslations(
                    data.word.ToLower(),
                    data.wordLanguage,
                    data.translationLanguage,
                    data.translationWords,
                    data.translationCards);
                // . if book id is not specified - add translation to 'Cool Translator' book
                UserBook userBook;
                if (data.bookId == 0) {
                    userBook = await db.GetCTUserBook(User.Identity.GetUserId(), wordLanguage);
                    data.bookId = userBook.BookId;
                } else {
                    userBook = await db.FindUserBookAsync(user.Id, data.bookId);
                    if (userBook == null) {
                        return BadRequest("Invalid bookId");
                    }
                    if (!userBook.Book.CanBeUpdatedBy(user.Id)) {
                        return BadRequest(string.Format("User {0} is not author of the book", user.DisplayName));
                    }
                }

                // . add translation
                Tuple<BookWord, Translation> bwt = await db.AddTranslation(data.bookId, word.Id, data.translationWord, translationLanguage, sp);

                Redis.PushWord(wordLanguage, sp, word.Value);
                Redis.PushWord(translationLanguage, sp, bwt.Item2.Value);

                var userBookDto = new UserBookDto(userBook);
                return CreatedAtRoute("DefaultApi", new { id = bwt.Item2.Id }, new {
                    userBook = userBookDto,
                    book = userBookDto.BookDto,
                    word = new WordDto(word),
                    bookWord = new BookWordDto(bwt.Item1),
                    translation = new TranslationDto(bwt.Item2)
                });
            } catch (Exception e) {
                _logger.Error(e, "Unable to add translation");
                throw;
            }
        }