private boolean checkDone(String url) {

      if (url.startsWith(REDIRECT_URI)) {

        Bundle values = parseUrl(url);

        String error = values.getString("error_reason");

        AQUtility.debug("error", error);

        if (error == null) {
          token = extractToken(url);
        }

        if (token != null) {
          dismiss();
          storeToken(token, permissions);
          first = false;
          authenticated(token);
          success(act);
        } else {
          failure();
        }

        return true;
      } else if (url.startsWith(CANCEL_URI)) {
        AQUtility.debug("cancelled");
        failure();
        return true;
      }

      return false;
    }
  private void webAuth() {

    AQUtility.debug("web auth");

    Bundle parameters = new Bundle();
    parameters.putString("client_id", appId);
    parameters.putString("type", "user_agent");
    if (permissions != null) {
      parameters.putString("scope", permissions);
    }

    parameters.putString("redirect_uri", REDIRECT_URI);
    String url = OAUTH_ENDPOINT + "?" + encodeUrl(parameters);

    FbWebViewClient client = new FbWebViewClient();

    dialog = new WebDialog(act, url, client);
    dialog.setLoadingMessage(message);
    dialog.setOnCancelListener(client);

    show();

    if (!first || token != null) {

      AQUtility.debug("auth hide");
      hide();
    }

    dialog.load();

    AQUtility.debug("auth started");
  }
  @Override
  public boolean expired(AbstractAjaxCallback<?, ?> cb, AjaxStatus status) {

    int code = status.getCode();
    if (code == 200) return false;

    String error = status.getError();
    if (error != null && error.contains("OAuthException")) {
      AQUtility.debug("fb token expired");
      return true;
    }

    String url = cb.getUrl();

    if (code == 400
        && (url.endsWith("/likes") || url.endsWith("/comments") || url.endsWith("/checkins"))) {
      return false;
    }

    if (code == 403 && (url.endsWith("/feed") || url.contains("method=delete"))) {
      return false;
    }

    return code == 400 || code == 401 || code == 403;
  }
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {

      AQUtility.debug("return url: " + url);

      return checkDone(url);
    }
  public void onActivityResult(int requestCode, int resultCode, Intent data) {

    AQUtility.debug("on result", resultCode);

    // Successfully redirected.
    if (resultCode == Activity.RESULT_OK) {

      // Check OAuth 2.0/2.10 error code.
      String error = data.getStringExtra("error");
      if (error == null) {
        error = data.getStringExtra("error_type");
      }

      // A Facebook error occurred.
      if (error != null) {
        AQUtility.debug("error", error);
        if (error.equals("service_disabled") || error.equals("AndroidAuthKillSwitchException")) {
          webAuth();
        } else {

          String description = data.getStringExtra("error_description");
          AQUtility.debug("fb error", description);

          failure();
        }
        // No errors.
      } else {

        token = data.getStringExtra("access_token");

        AQUtility.debug("onComplete", token);
        if (token != null) {
          storeToken(token, permissions);
          first = false;
          authenticated(token);
          success(act);
        } else {
          failure();
        }
      }

      // An error occurred before we could be redirected.
    } else if (resultCode == Activity.RESULT_CANCELED) {
      failure();
    }
  }
    @Override
    public void onPageFinished(WebView view, String url) {

      super.onPageFinished(view, url);
      show();

      AQUtility.debug("finished", url);
    }
 private void hide() {
   if (dialog != null) {
     try {
       dialog.hide();
     } catch (Exception e) {
       AQUtility.debug(e);
     }
   }
 }
  private String extractToken(String url) {

    Uri uri = Uri.parse(url.replace('#', '?'));

    String token = uri.getQueryParameter("access_token");

    AQUtility.debug("token", token);

    return token;
  }
    @Override
    public void onPageStarted(WebView view, String url, Bitmap favicon) {

      AQUtility.debug("started", url);

      if (checkDone(url)) {
      } else {
        super.onPageStarted(view, url, favicon);
      }
    }
  protected void auth() {

    if (act.isFinishing()) return;

    boolean ok = sso();

    AQUtility.debug("authing", ok);

    if (!ok) {
      webAuth();
    }
  }
  @Override
  public boolean reauth(final AbstractAjaxCallback<?, ?> cb) {

    AQUtility.debug("reauth requested");

    token = null;

    AQUtility.post(
        new Runnable() {

          @Override
          public void run() {
            auth(cb);
          }
        });

    return false;
  }
  private boolean permissionOk(String permissions, String old) {

    if (permissions == null) return true;
    if (old == null) return false;

    String[] splits = old.split("[,\\s]+");
    Set<String> oldSet = new HashSet<String>(Arrays.asList(splits));

    splits = permissions.split("[,\\s]+");

    for (int i = 0; i < splits.length; i++) {
      if (!oldSet.contains(splits[i])) {
        AQUtility.debug("perm mismatch");
        return false;
      }
    }

    return true;
  }
  private void render(List<Photo> entries) {

    AQUtility.debug("render setup");

    ArrayAdapter<Photo> aa =
        new ArrayAdapter<Photo>(getActivity(), R.layout.grid_item2, entries) {

          public View getView(int position, View convertView, ViewGroup parent) {

            if (convertView == null) {
              convertView = aq.inflate(convertView, R.layout.grid_item2, parent);
            }

            Photo photo = getItem(position);

            AQuery aq = aq2.recycle(convertView);

            String tbUrl = photo.tb;

            // Bitmap placeholder = aq.getCachedImage(R.drawable.image_ph);

            if (aq.shouldDelay(position, convertView, parent, tbUrl)) {

              // aq.id(R.id.tb).image(placeholder);
              aq.id(R.id.tb).clear();

            } else {

              aq.id(R.id.tb).image(tbUrl, true, true, 200, R.drawable.image_missing, null, 0, 0);
            }

            return convertView;
          }
        };

    aq.id(R.id.grid).adapter(aa);
  }