// GET: api/Books/5
        /// <summary>
        /// Information for one book
        /// </summary>
        /// <param name="id">Book identifier (int)</param>
        /// <returns>Book object</returns>
        public IHttpActionResult Get(int? id)
        {
            // Fetch the object
            var fetchedObject = w.Books.GetById(id.GetValueOrDefault());

            // Continue?
            if (fetchedObject == null) { return NotFound(); }

            BookLinked result = new BookLinked
                (Mapper.Map<BookWithLink>(fetchedObject));

            // Get the request URI path
            string self = Request.RequestUri.AbsolutePath;

            // Add a link relation to indicate a command that can be performed
            result.Links.Add(new Link() { Rel = "edit", Href = self + "/setphoto", ContentType = "image/*", Method = "PUT" });

            return Ok(result);
        }
        // POST: api/Books
        /// <summary>
        /// Add a new book
        /// </summary>
        /// <param name="newItem">New book object (the template has the object schema)</param>
        /// <returns>New book object</returns>
        public IHttpActionResult Post([FromBody]BookAdd newItem)
        {
            // Ensure that the URI is clean (and does not have an id parameter)
            if (Request.GetRouteData().Values["id"] != null) { return BadRequest("Invalid request URI"); }

            // Ensure that a "newItem" is in the entity body
            if (newItem == null) { return BadRequest("Must send an entity body with the request"); }

            // Ensure that we can use the incoming data
            if (!ModelState.IsValid) { return BadRequest(ModelState); }

            // Attempt to add the new object
            var addedItem = w.Books.Add(newItem);

            // Continue?
            if (addedItem == null) { return BadRequest("Cannot add the object"); }

            // HTTP 201 with the new object in the entity body
            // Notice how to create the URI for the Location header
            var uri = Url.Link("DefaultApi", new { id = addedItem.Id });

            // Use the factory constructor for the "add new" use case
            BookLinked result = new BookLinked
                (Mapper.Map<BookWithLink>(addedItem), addedItem.Id);

            return Created(uri, result);
        }
        // PUT: api/Books/5
        public IHttpActionResult Put(int id, [FromBody] BookEdit editedItem)
        {
            // Ensure that an "editedItem" is in the entity body
            if (editedItem == null)
            {
                return(BadRequest("Must send an entity body with the request"));
            }

            // Ensure that the id value in the URI matches the id value in the entity body
            if (id != editedItem.Id)
            {
                return(BadRequest("Invalid data in the entity body"));
            }

            // Ensure that we can use the incoming data
            if (ModelState.IsValid)
            {
                // Attempt to update the item
                var changedItem = m.Books.EditExisting(editedItem);

                // Notice the ApiController convenience methods
                if (changedItem == null)
                {
                    // HTTP 400
                    return(BadRequest("Cannot edit the object"));
                }
                else
                {
                    // From RFC 7231...
                    // http://tools.ietf.org/html/rfc7231#section-4.3.4

                    // "the origin server MUST send either a 200 (OK)
                    // or a 204 (No Content) response to indicate
                    // successful completion of the request"

                    // So, we have a choice...

                    // To send HTTP 204...
                    // return StatusCode(HttpStatusCode.NoContent);

                    // To send HTTP 200...
                    // Include the changed item in the entity body, as seen below

                    // Create an object to be returned
                    BookLinked book = new BookLinked();

                    // Set its item property
                    book.Item = Mapper.Map <BookWithLink>(changedItem);

                    // Get the request URI path
                    Uri uri = new Uri(Url.Link("DefaultApi", new { id = book.Item.Id }));

                    // Add a link relation for 'self'
                    book.Links.Add(new Link()
                    {
                        Rel = "self", Href = uri.AbsolutePath
                    });

                    // Add a link relation for the parent 'collection'
                    List <string> u = Request.RequestUri.Segments.ToList();
                    book.Links.Add(new Link()
                    {
                        Rel = "collection", Href = u[0] + u[1] + u[2]
                    });

                    // Add a link relation for 'self' in the item
                    book.Item.Link = new Link()
                    {
                        Rel = "self", Href = uri.AbsolutePath
                    };

                    // Return the response
                    return(Ok <BookLinked>(book));
                }
            }
            else
            {
                return(BadRequest(ModelState));
            }
        }
        // GET: api/Books/5
        public HttpResponseMessage Get(int id)
        {
            var fetchedObject = m.Books.GetById(id);

            if (fetchedObject == null)
            {
                return(Request.CreateResponse(HttpStatusCode.NotFound));
            }
            else
            {
                // Create an object to be returned
                BookLinked book = new BookLinked();

                // Set its item property
                book.Item = Mapper.Map <BookWithLink>(fetchedObject);

                // Get the request URI path
                string self = Request.RequestUri.AbsolutePath;

                // Add a link relation for 'self'
                book.Links.Add(new Link()
                {
                    Rel = "self", Href = self
                });

                // Add a link relation for the parent 'collection'
                List <string> u = Request.RequestUri.Segments.ToList();
                book.Links.Add(new Link()
                {
                    Rel = "collection", Href = u[0] + u[1] + u[2]
                });

                // ############################################################
                // New on Wed Oct 8 2014...

                // Add a link relation to indicate that an alternate representation is available
                book.Links.Add(new Link()
                {
                    Rel = "self", Href = self, ContentType = "image/*", Title = "Book cover photo"
                });

                // Add a link relation to indicate a command that can be performed
                book.Links.Add(new Link()
                {
                    Rel = "edit", Href = self + "/setphoto", ContentType = "image/*", Method = "PUT"
                });

                // ############################################################

                // Add a link relation for 'self' in the item
                book.Item.Link = new Link()
                {
                    Rel = "self", Href = self
                };

                // Build a response object
                var response = Request.CreateResponse(HttpStatusCode.OK, book);

                // The repository method has returned a BookLinked object
                // We need to know if the request asked for an image to be returned.
                // If so, we need to configure the Content-Type header BEFORE the object
                // is passed on to the 'image' media formatter.
                // Unfortunately, the current design of the media formatter does not
                // allow us to dynamically set the response's Content-Type header.
                // See this post - http://stackoverflow.com/a/12565530

                // Step 1 - look for an Accept header that starts with 'image'
                var imageHeader = Request.Headers.Accept
                                  .SingleOrDefault(a => a.MediaType.ToLower().StartsWith("image/"));
                // Step 2 - if found, set the Content-Type header value
                if (imageHeader != null)
                {
                    if (string.IsNullOrEmpty(book.Item.ContentType))
                    {
                        response.StatusCode = HttpStatusCode.NoContent;
                    }
                    else
                    {
                        response.Content.Headers.ContentType =
                            new System.Net.Http.Headers.MediaTypeHeaderValue(book.Item.ContentType);
                    }
                }

                // Return the result
                return(response);
            }
        }
        // POST: api/Books
        public HttpResponseMessage Post([FromBody] BookAdd newItem)
        {
            // Ensure that the URI is clean (and does not have an id parameter)
            if (Request.GetRouteData().Values["id"] != null)
            {
                return(Request.CreateErrorResponse
                           (HttpStatusCode.BadRequest, "Invalid request URI"));
            }

            // Ensure that a "newItem" is in the entity body
            if (newItem == null)
            {
                return(Request.CreateErrorResponse
                           (HttpStatusCode.BadRequest, "Must send an entity body with the request"));
            }

            // Ensure that we can use the incoming data
            if (ModelState.IsValid)
            {
                // Attempt to add the new object
                var addedItem = m.Books.AddNew(newItem);

                if (addedItem == null)
                {
                    // HTTP 400
                    return(Request.CreateErrorResponse
                               (HttpStatusCode.BadRequest, "Cannot add the object"));
                }
                else
                {
                    // HTTP 201 with the new object in the entity body
                    // Notice how to create the URI for the Location header

                    // Create an object to be returned
                    BookLinked book = new BookLinked();

                    // Set its item property
                    book.Item = Mapper.Map <BookWithLink>(addedItem);

                    // Get the request URI path
                    Uri uri = new Uri(Url.Link("DefaultApi", new { id = book.Item.Id }));

                    // Add a link relation for 'self'
                    book.Links.Add(new Link()
                    {
                        Rel = "self", Href = uri.AbsolutePath
                    });

                    // Add a link relation for the parent 'collection'
                    List <string> u = Request.RequestUri.Segments.ToList();
                    book.Links.Add(new Link()
                    {
                        Rel = "collection", Href = u[0] + u[1] + u[2]
                    });

                    // Add a link relation for 'self' in the item
                    book.Item.Link = new Link()
                    {
                        Rel = "self", Href = uri.AbsolutePath
                    };

                    // Build the response object
                    var response = Request.CreateResponse <BookLinked>(HttpStatusCode.Created, book);

                    // Set the Location header
                    response.Headers.Location = uri;

                    // Return the response
                    return(response);
                }
            }
            else
            {
                // HTTP 400
                return(Request.CreateErrorResponse
                           (HttpStatusCode.BadRequest, ModelState));
            }
        }
        // GET: api/Books/5
        public HttpResponseMessage Get(int id)
        {
            var fetchedObject = m.Books.GetById(id);

            if (fetchedObject == null)
            {
                return Request.CreateResponse(HttpStatusCode.NotFound);
            }
            else
            {
                // Create an object to be returned
                BookLinked book = new BookLinked();

                // Set its item property
                book.Item = Mapper.Map<BookWithLink>(fetchedObject);

                // Get the request URI path
                string self = Request.RequestUri.AbsolutePath;

                // Add a link relation for 'self'
                book.Links.Add(new Link() { Rel = "self", Href = self });

                // Add a link relation for the parent 'collection'
                List<string> u = Request.RequestUri.Segments.ToList();
                book.Links.Add(new Link() { Rel = "collection", Href = u[0] + u[1] + u[2] });

                // ############################################################
                // New on Wed Oct 8 2014...

                // Add a link relation to indicate that an alternate representation is available
                book.Links.Add(new Link() { Rel = "self", Href = self, ContentType = "image/*", Title = "Book cover photo" });

                // Add a link relation to indicate a command that can be performed
                book.Links.Add(new Link() { Rel = "edit", Href = self + "/setphoto", ContentType = "image/*", Method = "PUT" });

                // ############################################################

                // Add a link relation for 'self' in the item 
                book.Item.Link = new Link() { Rel = "self", Href = self };

                // Build a response object
                var response = Request.CreateResponse(HttpStatusCode.OK, book);

                // The repository method has returned a BookLinked object 
                // We need to know if the request asked for an image to be returned.
                // If so, we need to configure the Content-Type header BEFORE the object
                // is passed on to the 'image' media formatter.
                // Unfortunately, the current design of the media formatter does not
                // allow us to dynamically set the response's Content-Type header.
                // See this post - http://stackoverflow.com/a/12565530 

                // Step 1 - look for an Accept header that starts with 'image'
                var imageHeader = Request.Headers.Accept
                    .SingleOrDefault(a => a.MediaType.ToLower().StartsWith("image/"));
                // Step 2 - if found, set the Content-Type header value
                if (imageHeader != null)
                {
                    if (string.IsNullOrEmpty(book.Item.ContentType))
                    {
                        response.StatusCode = HttpStatusCode.NoContent;
                    }
                    else
                    {
                        response.Content.Headers.ContentType =
                            new System.Net.Http.Headers.MediaTypeHeaderValue(book.Item.ContentType);
                    }
                }

                // Return the result
                return response;
            }
        }
        // PUT: api/Books/5
        public IHttpActionResult Put(int id, [FromBody]BookEdit editedItem)
        {
            // Ensure that an "editedItem" is in the entity body
            if (editedItem == null)
            {
                return BadRequest("Must send an entity body with the request");
            }

            // Ensure that the id value in the URI matches the id value in the entity body
            if (id != editedItem.Id)
            {
                return BadRequest("Invalid data in the entity body");
            }

            // Ensure that we can use the incoming data
            if (ModelState.IsValid)
            {
                // Attempt to update the item
                var changedItem = m.Books.EditExisting(editedItem);

                // Notice the ApiController convenience methods
                if (changedItem == null)
                {
                    // HTTP 400
                    return BadRequest("Cannot edit the object");
                }
                else
                {
                    // From RFC 7231...
                    // http://tools.ietf.org/html/rfc7231#section-4.3.4

                    // "the origin server MUST send either a 200 (OK) 
                    // or a 204 (No Content) response to indicate 
                    // successful completion of the request"

                    // So, we have a choice...

                    // To send HTTP 204...
                    // return StatusCode(HttpStatusCode.NoContent);

                    // To send HTTP 200...
                    // Include the changed item in the entity body, as seen below

                    // Create an object to be returned
                    BookLinked book = new BookLinked();

                    // Set its item property
                    book.Item = Mapper.Map<BookWithLink>(changedItem);

                    // Get the request URI path
                    Uri uri = new Uri(Url.Link("DefaultApi", new { id = book.Item.Id }));

                    // Add a link relation for 'self'
                    book.Links.Add(new Link() { Rel = "self", Href = uri.AbsolutePath });

                    // Add a link relation for the parent 'collection'
                    List<string> u = Request.RequestUri.Segments.ToList();
                    book.Links.Add(new Link() { Rel = "collection", Href = u[0] + u[1] + u[2] });

                    // Add a link relation for 'self' in the item 
                    book.Item.Link = new Link() { Rel = "self", Href = uri.AbsolutePath };

                    // Return the response
                    return Ok<BookLinked>(book);
                }
            }
            else
            {
                return BadRequest(ModelState);
            }
        }
        // POST: api/Books
        public HttpResponseMessage Post([FromBody]BookAdd newItem)
        {
            // Ensure that the URI is clean (and does not have an id parameter)
            if (Request.GetRouteData().Values["id"] != null)
            {
                return Request.CreateErrorResponse
                    (HttpStatusCode.BadRequest, "Invalid request URI");
            }

            // Ensure that a "newItem" is in the entity body
            if (newItem == null)
            {
                return Request.CreateErrorResponse
                    (HttpStatusCode.BadRequest, "Must send an entity body with the request");
            }

            // Ensure that we can use the incoming data
            if (ModelState.IsValid)
            {
                // Attempt to add the new object
                var addedItem = m.Books.AddNew(newItem);

                if (addedItem == null)
                {
                    // HTTP 400
                    return Request.CreateErrorResponse
                        (HttpStatusCode.BadRequest, "Cannot add the object");
                }
                else
                {
                    // HTTP 201 with the new object in the entity body
                    // Notice how to create the URI for the Location header

                    // Create an object to be returned
                    BookLinked book = new BookLinked();

                    // Set its item property
                    book.Item = Mapper.Map<BookWithLink>(addedItem);

                    // Get the request URI path
                    Uri uri = new Uri(Url.Link("DefaultApi", new { id = book.Item.Id }));

                    // Add a link relation for 'self'
                    book.Links.Add(new Link() { Rel = "self", Href = uri.AbsolutePath });

                    // Add a link relation for the parent 'collection'
                    List<string> u = Request.RequestUri.Segments.ToList();
                    book.Links.Add(new Link() { Rel = "collection", Href = u[0] + u[1] + u[2] });

                    // Add a link relation for 'self' in the item 
                    book.Item.Link = new Link() { Rel = "self", Href = uri.AbsolutePath };

                    // Build the response object
                    var response = Request.CreateResponse<BookLinked>(HttpStatusCode.Created, book);

                    // Set the Location header
                    response.Headers.Location = uri;

                    // Return the response
                    return response;
                }
            }
            else
            {
                // HTTP 400
                return Request.CreateErrorResponse
                    (HttpStatusCode.BadRequest, ModelState);
            }
        }
        // GET: api/Books/5
        /// <summary>
        /// Information for one book
        /// </summary>
        /// <param name="id">Book identifier (int)</param>
        /// <returns>Book object</returns>
        public IHttpActionResult Get(int? id)
        {
            // Attention - This method DOES use content negotiation (aka conneg) 

            // Fetch the object
            var fetchedObject = w.Books.GetById(id.GetValueOrDefault());

            // Continue?
            if (fetchedObject == null) { return NotFound(); }

            // Attention - Here is the content negotiation code

            // Look for an Accept header that starts with 'image'

            var imageHeader = Request.Headers.Accept
                .SingleOrDefault(a => a.MediaType.ToLower().StartsWith("image/"));

            if (imageHeader == null)
            {
                // Normal processing for a JSON result

                BookLinked result = new BookLinked(Mapper.Map<BookWithLink>(fetchedObject));

                // Get the request URI path
                string self = Request.RequestUri.AbsolutePath;

                // Add a link relation to indicate a command that can be performed
                result.Links.Add(new Link() { Rel = "edit", Href = self + "/setphoto", ContentType = "image/*", Method = "PUT" });

                // If a media item exists, add some custom links...
                if (result.Item.PhotoLength > 0)
                {
                    // Add a link relation to indicate that an alternate representation is available
                    result.Links.Add(new Link() { Rel = "self", Href = self, ContentType = "image/*", Title = "Book cover photo", Method = "GET" });

                    // Add a link relation to indicate that an alternate representation is available
                    result.Links.Add(new Link() { Rel = "self", Href = self + "/photo", ContentType = "image/*", Title = "Book cover photo", Method = "GET" });
                }

                // Return the result, using the built-in media formatters (JSON, XML)
                return Ok(result);
            }
            else
            {
                // Special processing for an image result

                // Confirm that a media item exists
                if (fetchedObject.PhotoLength > 0)
                {
                    // Return the result, using the custom media formatter
                    return Ok(fetchedObject.Photo);
                }
                else
                {
                    // Otherwise, return "not found"
                    // Yes, this is correct. Read the RFC: https://tools.ietf.org/html/rfc7231#section-6.5.4
                    return NotFound();
                }
            }

        }