@RequestMapping(
      value = "devices/{deviceId}/registrations/{passTypeId}/{serialNo}",
      method = RequestMethod.DELETE,
      headers = {"Authorization"})
  public ResponseEntity unregister(
      @PathVariable String deviceId,
      @PathVariable String passTypeId,
      @PathVariable String serialNo,
      @RequestHeader(value = "Authorization") String authorization) {

    // extract authToken
    final String authToken = getAuthToken(authorization);
    if (null == authToken) {
      return new ResponseEntity(HttpStatus.UNAUTHORIZED);
    }

    try {
      passbookService.unregister(deviceId, passTypeId, serialNo, authToken);
    } catch (NoSuchPassException ex) {
      return new ResponseEntity(HttpStatus.GONE);
    } catch (NoSuchRegistrationException ex) {
      return new ResponseEntity(HttpStatus.NOT_FOUND);
    } catch (NoSuchPassTypeException ex) {
      return new ResponseEntity(HttpStatus.UNPROCESSABLE_ENTITY);
    } catch (InvalidAuthTokenException ex) {
      return new ResponseEntity(HttpStatus.UNAUTHORIZED);
    }

    return new ResponseEntity(HttpStatus.OK);
  }
  @RequestMapping(value = "passes/{passTypeId}/{serialNo}", method = RequestMethod.GET)
  public void getPass(
      WebRequest webRequest,
      HttpServletResponse response,
      @PathVariable String passTypeId,
      @PathVariable String serialNo,
      @RequestHeader(value = "Authorization", defaultValue = "not_provided") String authorization)
      throws IOException {

    final String authToken = getAuthToken(authorization);
    //        if (null == authToken) {
    //            response.sendError(HttpStatus.UNAUTHORIZED.value());
    //            return;
    //        }

    try {
      //            final AbstractPassEntity pass = passbookService.getPass(passTypeId, serialNo,
      // authToken);
      //
      //            final long lastModified = pass.getUpdatedDate().getTime();
      //            if (webRequest.checkNotModified(lastModified)) {
      //                // shortcut exit - no further processing necessary
      //                return;
      //            }

      // write the .pkpass to the response
      ServletOutputStream out = response.getOutputStream();
      response.setContentType(CONTENT_TYPE_PASS);
      response.setHeader(CONTENT_DISPOSITION__NAME, CONTENT_DISPOSITION_VALUE);
      int length = passbookService.writePass(out, passTypeId, serialNo);
      out.flush();
      out.close();
      response.setStatus(HttpStatus.OK.value());
      LOG.info("Wrote pass of {} bytes", length);
      return;

      //        } catch (NoSuchPassException ex) {
      //            response.sendError(HttpStatus.NOT_FOUND.value());
      //            return;
    } catch (NoSuchPassTypeException ex) {
      response.sendError(HttpStatus.UNPROCESSABLE_ENTITY.value());
      return;
      //        } catch (InvalidAuthTokenException ex) {
      //            response.sendError(HttpStatus.UNAUTHORIZED.value());
      //            return;
    } catch (Exception ex) {
      LOG.error("Exception thrown by Service.writePass", ex);
      response.sendError(HttpStatus.INTERNAL_SERVER_ERROR.value());
      return;
    }
  }
  @RequestMapping(
      value = "devices/{deviceId}/registrations/{passTypeId:.+}",
      method = RequestMethod.GET)
  public ResponseEntity<JWhatChanged> whatChanged(
      @PathVariable String deviceId,
      @PathVariable String passTypeId,
      @RequestParam(value = "passesUpdatedSince", defaultValue = "-1") Long passesUpdatedSince) {
    LOG.debug("deviceId={}, passTypeId={}", deviceId, passTypeId);

    try {
      JWhatChanged passIds = passbookService.whatChanged(deviceId, passTypeId, passesUpdatedSince);
      return new ResponseEntity<JWhatChanged>(passIds, HttpStatus.OK);
    } catch (NoSuchPassTypeException ex) {
      return new ResponseEntity(HttpStatus.UNPROCESSABLE_ENTITY);
    } catch (PassbookException ex) {
      return new ResponseEntity(HttpStatus.NOT_FOUND);
    }
  }