@Override
    public ListenableFuture<ServiceFilterResponse> handleRequest(
        final ServiceFilterRequest request,
        final NextServiceFilterCallback nextServiceFilterCallback) {
      // In this example, if authentication is already in progress we block the request
      // until authentication is complete to avoid unnecessary authentications as
      // a result of HTTP status code 401.
      // If authentication was detected, add the token to the request.
      waitAndUpdateRequestToken(request);

      // Send the request down the filter chain
      // retrying up to 5 times on 401 response codes.
      ListenableFuture<ServiceFilterResponse> future = null;
      ServiceFilterResponse response = null;
      int responseCode = 401;
      for (int i = 0; (i < 5) && (responseCode == 401); i++) {
        future = nextServiceFilterCallback.onNext(request);
        try {
          response = future.get();
          responseCode = response.getStatus().getStatusCode();
        } catch (InterruptedException e) {
          e.printStackTrace();
        } catch (ExecutionException e) {
          if (e.getCause().getClass() == MobileServiceException.class) {
            MobileServiceException mEx = (MobileServiceException) e.getCause();
            responseCode = mEx.getResponse().getStatus().getStatusCode();
            if (responseCode == 401) {
              // Two simultaneous requests from independent threads could get HTTP status 401.
              // Protecting against that right here so multiple authentication requests are
              // not setup to run on the UI thread.
              // We only want to authenticate once. Requests should just wait and retry
              // with the new token.
              if (mAtomicAuthenticatingFlag.compareAndSet(false, true)) {
                // Authenticate on UI thread
                runOnUiThread(
                    new Runnable() {
                      @Override
                      public void run() {
                        // Force a token refresh during authentication.
                        authenticate(true);
                      }
                    });
              }

              // Wait for authentication to complete then update the token in the request.
              waitAndUpdateRequestToken(request);
              mAtomicAuthenticatingFlag.set(false);
            }
          }
        }
      }
      return future;
    }
  private boolean ExceptionIs404NotFound(ExecutionException ex) {

    MobileServiceException mse = (MobileServiceException) ex.getCause();

    if (ex == null) {
      return false;
    }

    int statusCode = mse.getResponse().getStatus().getStatusCode();

    if (statusCode != 404) {
      return false;
    }

    return true;
  }