@Path("devices/{deviceLibraryIdentifier}/registrations/{passTypeIdentifier}/{serialNumber}")
  @DELETE
  public Response unregisterDevice(
      @PathParam("deviceLibraryIdentifier") String deviceLibraryIdentifier,
      @PathParam("passTypeIdentifier") String passTypeIdentifier,
      @PathParam("serialNumber") String serialNumber,
      @HeaderParam("Authorization") @DefaultValue("") String authorization) {

    PassDAO pass = new PassDAO(passTypeIdentifier, serialNumber);
    if (!pass.retrieve()) {
      // pass not found
      // response is UNAUTHORIZED in order to prevent trial/error/guessing for passes
      log.warn("pass does not exist: {}", serialNumber);
      return Response.status(Response.Status.UNAUTHORIZED).build();
    }

    if (!AuthUtil.isAuthorized(authorization, pass.getAuthenticationToken())) {
      log.warn("invalid authorization: {}", authorization);
      return Response.status(Response.Status.UNAUTHORIZED).build();
    }

    DeviceDAO device = new DeviceDAO(deviceLibraryIdentifier);
    if (device.retrieve()) {
      device.removeRegistration(passTypeIdentifier, serialNumber);
      if (device.store()) {
        return Response.status(Response.Status.OK).build();
      } else {
        return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
      }
    }
    return Response.status(Response.Status.NOT_FOUND).build();
  }
 @Path("devices/{deviceLibraryIdentifier}/registrations/{passTypeIdentifier}")
 @GET
 public Response getSerialNumbersOfPassesAssociatedWithDevice(
     @PathParam("deviceLibraryIdentifier") String deviceLibraryIdentifier,
     @PathParam("passTypeIdentifier") String passTypeIdentifier,
     @QueryParam("passesUpdatedSince") @DefaultValue("") String passesUpdatedSince) {
   DeviceDAO device = new DeviceDAO(deviceLibraryIdentifier);
   ListOfPasses passes = new ListOfPasses();
   passes.setLastUpdated(DateUtil.getTimeStamp());
   if (device.retrieve()) {
     for (Registration reg : device.getRegistrations()) {
       if (passTypeIdentifier.equals(reg.getPassTypeIdentifier())) {
         passes.addSerialNumber(reg.getSerialNumber());
       }
     }
   }
   if (passes.getSerialNumbers().size() > 0) {
     return Response.status(Response.Status.OK).entity(passes.toJson(Pass.PRETTY)).build();
   }
   return Response.status(Response.Status.NO_CONTENT).build();
 }
 @Path("version")
 @GET
 @Produces(MediaType.APPLICATION_JSON)
 public Response getServiceVersion() {
   return Response.status(Response.Status.OK)
       .entity(
           "mobile-passes service version "
               + String.valueOf(ServiceConst.MAJOR_VERSION)
               + "."
               + String.valueOf(ServiceConst.MINOR_VERSION))
       .build();
 }
  @Path("passes/{passTypeIdentifier}/{serialNumber}")
  @GET
  public Response getLatestVersionOfPass(
      @PathParam("passTypeIdentifier") String passTypeIdentifier,
      @PathParam("serialNumber") String serialNumber,
      @HeaderParam("Authorization") @DefaultValue("") String authorization,
      @HeaderParam("If-Modified-Since") @DefaultValue("") String ifModifedSince) {

    PassDAO pass = new PassDAO(serialNumber);
    if (!pass.retrieve()) {
      // pass not found
      // response is UNAUTHORIZED in order to prevent trial/error/guessing for passes
      log.warn("pass does not exist: {}", serialNumber);
      return Response.status(Response.Status.UNAUTHORIZED).build();
    }

    if (!AuthUtil.isAuthorized(authorization, pass.getAuthenticationToken())) {
      log.warn("invalid authorization: {}", authorization);
      return Response.status(Response.Status.UNAUTHORIZED).build();
    }
    return Response.status(Response.Status.OK).entity(pass.toJson()).build();
  }
  @Path("log")
  @POST
  @Consumes(MediaType.APPLICATION_JSON)
  public Response doLog(String logsAsJson) {

    ServiceLogs logs = ServiceLogs.fromJson(logsAsJson);
    LogDAO logger = new LogDAO();
    log.info("Apple wants to tell us something:");
    for (String line : logs.getLogs()) {
      logger.store(line);
      log.info("{}", line);
    }
    return Response.status(Response.Status.OK).build();
  }
  @Path("/devices/{deviceLibraryIdentifier}/registrations/{passTypeIdentifier}/{serialNumber}")
  @POST
  public Response registerDeviceForPassPushNotifications(
      @PathParam("deviceLibraryIdentifier") String deviceLibraryIdentifier,
      @PathParam("passTypeIdentifier") String passTypeIdentifier,
      @PathParam("serialNumber") String serialNumber,
      @HeaderParam("Authorization") @DefaultValue("") String authorization,
      String jsonDictionaryWithPushToken) {

    PassDAO pass = new PassDAO(serialNumber);
    if (!pass.retrieve()) {
      // pass not found
      // response is UNAUTHORIZED in order to prevent trial/error/guessing for passes
      log.warn("pass does not exist: {}", serialNumber);
      return Response.status(Response.Status.UNAUTHORIZED).build();
    }

    if (!AuthUtil.isAuthorized(authorization, pass.getAuthenticationToken())) {
      log.warn("invalid authorization: {}", authorization);
      return Response.status(Response.Status.UNAUTHORIZED).build();
    }

    String pushToken = ServiceUtil.getPushTokenFromBody(jsonDictionaryWithPushToken);

    DeviceDAO device = new DeviceDAO(deviceLibraryIdentifier);
    device.retrieve();
    if (device.addRegistration(passTypeIdentifier, serialNumber, pushToken) == 1) {
      // really added a new record
      if (device.store()) {
        return Response.status(Response.Status.CREATED).build();
      }
    } else {
      // nothing added, was already in list
      return Response.status(Response.Status.OK).build();
    }
    return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
  }