/*
   * This function is strictly for use by internal APIs. Not that we have
   * anything external but there is some trickery here! The getBitmap function
   * cannot be invoked from the UI thread. Having to deal with complexity of
   * when & how to call this API is too much for those who just want to have
   * the bitmap. This is a utility function and is public because it is to be
   * shared by other components in the internal implementation.
   */
  public Bitmap getBitmap(
      String serverUrl, boolean cacheBitmap, int bestWidth, int bestHeight, String source) {
    File f = mFileCache.getFile(serverUrl);
    // from SD cache
    Bitmap b = decodeFile(f, bestHeight, bestWidth, source);
    if (b != null) {
      Logging.i(TAG, "Image Available in SD card: ", false, classLevelLogEnabled);
      if (cacheBitmap) mAisleImagesCache.putBitmap(serverUrl, b);
      return b;
    }

    // from web
    try {
      if (serverUrl == null || serverUrl.length() < 1) {

        return null;
      }
      Logging.i(
          TAG,
          "Image DownLoad Time starts At: " + System.currentTimeMillis(),
          false,
          classLevelLogEnabled);
      Bitmap bitmap = null;
      URL imageUrl = new URL(serverUrl);
      HttpURLConnection conn = (HttpURLConnection) imageUrl.openConnection();
      conn.setConnectTimeout(30000);
      conn.setReadTimeout(30000);
      conn.setInstanceFollowRedirects(true);
      InputStream is = conn.getInputStream();
      int hashCode = serverUrl.hashCode();
      String filename = String.valueOf(hashCode);
      OutputStream os = new FileOutputStream(f);
      Utils.CopyStream(is, os);
      os.close();
      Logging.i(
          TAG,
          "Image DownLoad Time Ends At: " + System.currentTimeMillis(),
          false,
          classLevelLogEnabled);
      Logging.i(
          TAG,
          "Bitmap Decode Time Starts At: " + System.currentTimeMillis(),
          false,
          classLevelLogEnabled);
      bitmap = decodeFile(f, bestHeight, bestWidth, source);
      Logging.i(
          TAG,
          "Bitmap Decode Time Ends At: " + System.currentTimeMillis(),
          false,
          classLevelLogEnabled);
      if (cacheBitmap) mAisleImagesCache.putBitmap(serverUrl, bitmap);
      return bitmap;
    } catch (Throwable ex) {
      ex.printStackTrace();
      if (ex instanceof OutOfMemoryError) {
        // mAisleImagesCache.evictAll();
      }
      return null;
    }
  }