// Path: src/main/java/org/letustakearest/application/service/BookingService.java
// public interface BookingService {
// 
//     Booking create(Long roomId, BookingTransition data) throws EntityNotFoundException;
// 
//     Booking create(CreateBookingAsPlaceTransition data) throws EntityNotFoundException;
// 
//     Booking update(Booking booking, BookingTransition data) throws EntityNotFoundException;
// 
//     Booking findById(Long id) throws EntityNotFoundException;
// 
//     Collection<Booking> findAll();
// 
//     Booking pay(Booking booking, PayForBookingTransition data);
// 
//     void delete(Long id);
// 
// }
// 
// Path: src/main/java/org/letustakearest/domain/Booking.java
// @Getter
// @Setter
// public final class Booking extends IdentifiableAndVersioned {
// 
//     private User user;
// 
//     private Place place;
// 
//     private LocalDate checkIn;
// 
//     private LocalDate checkOut;
// 
//     private boolean includeBreakfast;
// 
//     private BigDecimal price;
// 
//     private State state;
// 
//     private Payment payment;
// 
//     /**
//      * @author volodymyr.tsukur
//      */
//     public enum State {
// 
//         CREATED,
// 
//         PAID,
// 
//         SERVED,
// 
//         CANCELLED
// 
//     }
// 
// }
// 
// Path: src/main/java/org/letustakearest/domain/EntityNotFoundException.java
// public class EntityNotFoundException extends Exception {
// 
//     public EntityNotFoundException() {
//         super();
//     }
// 
//     public EntityNotFoundException(final String message) {
//         super(message);
//     }
// 
//     public EntityNotFoundException(final String message, final Throwable cause) {
//         super(message, cause);
//     }
// 
//     public EntityNotFoundException(final Throwable cause) {
//         super(cause);
//     }
// 
//     protected EntityNotFoundException(final String message, final Throwable cause, final boolean enableSuppression,
//                                       final boolean writableStackTrace) {
//         super(message, cause, enableSuppression, writableStackTrace);
//     }
// 
// }
// 
// Path: src/main/java/org/letustakearest/presentation/representations/BookingRepresentationAssembler.java
// public interface BookingRepresentationAssembler {
// 
//     Object from(Booking booking);
// 
// }
// 
// Path: src/main/java/org/letustakearest/presentation/transitions/BookingTransition.java
// @Getter
// @Setter
// public class BookingTransition {
// 
//     @NotNull
//     private LocalDate checkIn;
// 
//     @NotNull
//     private LocalDate checkOut;
// 
//     private Boolean includeBreakfast;
// 
// }
// 
// Path: src/main/java/org/letustakearest/presentation/transitions/PayForBookingTransition.java
// @Getter
// @Setter
// public final class PayForBookingTransition {
// 
//     private String cardholdersName;
// 
//     private String creditCardNumber;
// 
//     private String cvv;
// 
// }


import com.google.code.siren4j.Siren4J;
import com.theoryinpractise.halbuilder.api.RepresentationFactory;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.letustakearest.application.service.BookingService;
import org.letustakearest.domain.Booking;
import org.letustakearest.domain.EntityNotFoundException;
import org.letustakearest.presentation.representations.BookingRepresentationAssembler;
import org.letustakearest.presentation.representations.cdi.SelectByAcceptHeader;
import org.letustakearest.presentation.transitions.BookingTransition;
import org.letustakearest.presentation.transitions.PayForBookingTransition;
import javax.inject.Inject;
import javax.servlet.ServletContext;
import javax.ws.rs.*;
import javax.ws.rs.container.AsyncResponse;
import javax.ws.rs.container.Suspended;
import javax.ws.rs.core.*;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;
            final PayForBookingTransition transition,
            @Context final Request request) {
        try {
            Booking booking = bookingService.findById(id);
            final Response.ResponseBuilder responseBuilder = request.evaluatePreconditions(entityTag(booking));

            if (responseBuilder == null) {
                booking = bookingService.pay(booking, transition);
                return Response.ok(bookingRepresentationAssembler.from(booking)).
                        tag(entityTag(booking)).
                        build();
            }
            else {
                return responseBuilder.build();
            }
        }
        catch (final EntityNotFoundException e) {
            throw new WebApplicationException(Response.Status.NOT_FOUND);
        }
    }

    @POST
    @Path("/payment-async")
    @Produces({ RepresentationFactory.HAL_JSON, Siren4J.JSON_MEDIATYPE })
    @Consumes(MediaType.APPLICATION_JSON)
    public void pay(
            final PayForBookingTransition transition,
            @Suspended final AsyncResponse asyncResponse,
            @Context final Request request) {
        try {
// Path: src/main/java/org/letustakearest/application/service/BookingService.java
// public interface BookingService {
// 
//     Booking create(Long roomId, BookingTransition data) throws EntityNotFoundException;
// 
//     Booking create(CreateBookingAsPlaceTransition data) throws EntityNotFoundException;
// 
//     Booking update(Booking booking, BookingTransition data) throws EntityNotFoundException;
// 
//     Booking findById(Long id) throws EntityNotFoundException;
// 
//     Collection<Booking> findAll();
// 
//     Booking pay(Booking booking, PayForBookingTransition data);
// 
//     void delete(Long id);
// 
// }
// 
// Path: src/main/java/org/letustakearest/domain/Booking.java
// @Getter
// @Setter
// public final class Booking extends IdentifiableAndVersioned {
// 
//     private User user;
// 
//     private Place place;
// 
//     private LocalDate checkIn;
// 
//     private LocalDate checkOut;
// 
//     private boolean includeBreakfast;
// 
//     private BigDecimal price;
// 
//     private State state;
// 
//     private Payment payment;
// 
//     /**
//      * @author volodymyr.tsukur
//      */
//     public enum State {
// 
//         CREATED,
// 
//         PAID,
// 
//         SERVED,
// 
//         CANCELLED
// 
//     }
// 
// }
// 
// Path: src/main/java/org/letustakearest/domain/EntityNotFoundException.java
// public class EntityNotFoundException extends Exception {
// 
//     public EntityNotFoundException() {
//         super();
//     }
// 
//     public EntityNotFoundException(final String message) {
//         super(message);
//     }
// 
//     public EntityNotFoundException(final String message, final Throwable cause) {
//         super(message, cause);
//     }
// 
//     public EntityNotFoundException(final Throwable cause) {
//         super(cause);
//     }
// 
//     protected EntityNotFoundException(final String message, final Throwable cause, final boolean enableSuppression,
//                                       final boolean writableStackTrace) {
//         super(message, cause, enableSuppression, writableStackTrace);
//     }
// 
// }
// 
// Path: src/main/java/org/letustakearest/presentation/representations/BookingRepresentationAssembler.java
// public interface BookingRepresentationAssembler {
// 
//     Object from(Booking booking);
// 
// }
// 
// Path: src/main/java/org/letustakearest/presentation/transitions/BookingTransition.java
// @Getter
// @Setter
// public class BookingTransition {
// 
//     @NotNull
//     private LocalDate checkIn;
// 
//     @NotNull
//     private LocalDate checkOut;
// 
//     private Boolean includeBreakfast;
// 
// }
// 
// Path: src/main/java/org/letustakearest/presentation/transitions/PayForBookingTransition.java
// @Getter
// @Setter
// public final class PayForBookingTransition {
// 
//     private String cardholdersName;
// 
//     private String creditCardNumber;
// 
//     private String cvv;
// 
// }


// Path: src/main/java/org/letustakearest/presentation/resources/BookingResource.java
import com.google.code.siren4j.Siren4J;
import com.theoryinpractise.halbuilder.api.RepresentationFactory;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.letustakearest.application.service.BookingService;
import org.letustakearest.domain.Booking;
import org.letustakearest.domain.EntityNotFoundException;
import org.letustakearest.presentation.representations.BookingRepresentationAssembler;
import org.letustakearest.presentation.representations.cdi.SelectByAcceptHeader;
import org.letustakearest.presentation.transitions.BookingTransition;
import org.letustakearest.presentation.transitions.PayForBookingTransition;
import javax.inject.Inject;
import javax.servlet.ServletContext;
import javax.ws.rs.*;
import javax.ws.rs.container.AsyncResponse;
import javax.ws.rs.container.Suspended;
import javax.ws.rs.core.*;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;

            final PayForBookingTransition transition,
            @Context final Request request) {
        try {
            Booking booking = bookingService.findById(id);
            final Response.ResponseBuilder responseBuilder = request.evaluatePreconditions(entityTag(booking));

            if (responseBuilder == null) {
                booking = bookingService.pay(booking, transition);
                return Response.ok(bookingRepresentationAssembler.from(booking)).
                        tag(entityTag(booking)).
                        build();
            }
            else {
                return responseBuilder.build();
            }
        }
        catch (final EntityNotFoundException e) {
            throw new WebApplicationException(Response.Status.NOT_FOUND);
        }
    }

    @POST
    @Path("/payment-async")
    @Produces({ RepresentationFactory.HAL_JSON, Siren4J.JSON_MEDIATYPE })
    @Consumes(MediaType.APPLICATION_JSON)
    public void pay(
            final PayForBookingTransition transition,
            @Suspended final AsyncResponse asyncResponse,
            @Context final Request request) {
        try {
            Booking booking = bookingService.findById(id);