Program: 33692
Project: 33692
Buggy source:
/** 
 * This is the method that, when given an API url, checks the database to see when it was last updated (if event), and tells its calling query what action to take. If the url has not yet been queried or is in need of update, then download (or update) the data from the internet and record the Last-Modified header for future use. This method also implements a rate limit on how often you can hit a single API endpoint, which is defined in Constants.API_HIT_TIMEOUT <p/> About the return values. The 'data' field of the resulting APIResponse is only going to have actual data if we needed to load something from the internet (thus, the accompanying CODE will either be Code.WEBLOAD or Code.UPDATED). If the CODE is anything else, then the 'data' field will be null - so check the code before assuming it's set.
 * @param c              Calling context - used to query the database for the Last-Update time for a URL
 * @param URL            API URL to check and see if an update is required
 * @param params Parameters associated with this requestcacheLocally: Option to save the fact that we hit this URL in the database. Setting this parameter to TRUE allows us to use If-Modified-Since headers, reducing overhead forceFromCache: When this parameter is true, we won't make any web requests and just return Code.LOCAL, telling the caller to use whatever it has cached locally forceFromWeb: When this parameter is true, the API timeout is greatly reduced so we can force (not exactly, but close enough) a web refresh. The timeout still exists for the poor server's sake
 * @return APIResponse containing the data we fetched (if necessary) and the response code for how we obtained that data.
 * @throws DataManager.NoDataException
 */
public static APIResponse<String> getResponseFromURLOrThrow(Context c,final String URL,RequestParams params) throws DataManager.NoDataException {
  if (c == null) {
    Log.d(Constants.DATAMANAGER_LOG,"String_Node_Str");
    throw new DataManager.NoDataException("String_Node_Str");
  }
  boolean existsInDb=Database.getInstance(c).getResponseTable().responseExists(URL);
  boolean connectedToInternet=ConnectionDetector.isConnectedToInternet(c);
  if (existsInDb) {
    if (connectedToInternet) {
      APIResponse<String> cachedData;
      cachedData=Database.getInstance(c).getResponseTable().getResponse(URL);
      Date now=new Date();
      long timeout=params.forceFromWeb ? Constants.API_HIT_TIMEOUT_LONG : Constants.API_HIT_TIMEOUT_SHORT;
      Date futureTime=new Date(cachedData.lastHit.getTime() + timeout);
      if (now.before(futureTime) && !params.forceFromWeb) {
        return cachedData.updateCode(APIResponse.CODE.CACHED304);
      }
      if (params.forceFromCache) {
        return cachedData;
      }
      HttpResponse cachedResponse=HTTP.getRequest(URL,params.forceFromWeb ? null : cachedData.getLastUpdate());
      if (cachedResponse != null) {
        int responseStatus=cachedResponse.getStatusLine().getStatusCode();
        if (responseStatus / 100 == 4 || responseStatus / 100 == 5) {
          String responseData=HTTP.dataFromResponse(cachedResponse);
          Log.e(Constants.DATAMANAGER_LOG,"String_Node_Str" + responseStatus + "String_Node_Str"+ responseData+ "String_Node_Str"+ URL);
          return new APIResponse<>("String_Node_Str",responseData);
        }
        boolean dataRequiresUpdate=(responseStatus == 200);
        if (dataRequiresUpdate) {
          String response=HTTP.dataFromResponse(cachedResponse), lastUpdate="String_Node_Str";
          Header lastModified=cachedResponse.getFirstHeader("String_Node_Str");
          if (lastModified != null) {
            lastUpdate=lastModified.getValue();
          }
          int apiVersion;
          if (cachedResponse.containsHeader("String_Node_Str")) {
            apiVersion=Integer.parseInt(cachedResponse.getFirstHeader("String_Node_Str").getValue());
          }
 else {
            apiVersion=0;
          }
          Database.getInstance(c).getResponseTable().updateResponse(URL,lastUpdate);
          Log.d(Constants.DATAMANAGER_LOG,"String_Node_Str" + apiVersion + "String_Node_Str"+ URL);
          return new APIResponse<>(response,APIResponse.CODE.UPDATED,apiVersion);
        }
 else {
          Database.getInstance(c).getResponseTable().touchResponse(URL);
          return cachedData.updateCode(APIResponse.CODE.CACHED304);
        }
      }
 else {
        Log.e(Constants.DATAMANAGER_LOG,"String_Node_Str");
        return new APIResponse<String>(null,APIResponse.CODE.NODATA);
      }
    }
 else {
      Log.d(Constants.DATAMANAGER_LOG,"String_Node_Str" + URL);
      return Database.getInstance(c).getResponseTable().getResponse(URL).updateCode(APIResponse.CODE.OFFLINECACHE);
    }
  }
 else {
    if (connectedToInternet) {
      HttpResponse webResponse=HTTP.getRequest(URL);
      if (webResponse != null) {
        int responseStatus=webResponse.getStatusLine().getStatusCode();
        if (responseStatus / 100 == 4 || responseStatus / 100 == 5) {
          String responseData=HTTP.dataFromResponse(webResponse);
          Log.e(Constants.DATAMANAGER_LOG,"String_Node_Str" + responseStatus + "String_Node_Str"+ responseData+ "String_Node_Str"+ URL);
          return new APIResponse<>("String_Node_Str",responseData);
        }
        String response=HTTP.dataFromResponse(webResponse), lastUpdate="String_Node_Str";
        Header lastModified=webResponse.getFirstHeader("String_Node_Str");
        if (lastModified != null) {
          lastUpdate=lastModified.getValue();
        }
        if (params.cacheLocally) {
          Database.getInstance(c).getResponseTable().storeResponse(URL,lastUpdate);
        }
        int apiVersion;
        if (webResponse.containsHeader("String_Node_Str")) {
          apiVersion=Integer.parseInt(webResponse.getFirstHeader("String_Node_Str").getValue());
        }
 else {
          apiVersion=0;
        }
        Log.d(Constants.DATAMANAGER_LOG,"String_Node_Str" + apiVersion + "String_Node_Str"+ URL);
        return new APIResponse<>(response,APIResponse.CODE.WEBLOAD,apiVersion);
      }
 else {
        Log.e(Constants.DATAMANAGER_LOG,"String_Node_Str");
        return new APIResponse<String>(null,APIResponse.CODE.NODATA);
      }
    }
 else {
      Log.d(Constants.DATAMANAGER_LOG,"String_Node_Str" + URL);
      throw new DataManager.NoDataException("String_Node_Str");
    }
  }
}

Fixed version (ground truth):
/** 
 * This is the method that, when given an API url, checks the database to see when it was last updated (if event), and tells its calling query what action to take. If the url has not yet been queried or is in need of update, then download (or update) the data from the internet and record the Last-Modified header for future use. This method also implements a rate limit on how often you can hit a single API endpoint, which is defined in Constants.API_HIT_TIMEOUT <p/> About the return values. The 'data' field of the resulting APIResponse is only going to have actual data if we needed to load something from the internet (thus, the accompanying CODE will either be Code.WEBLOAD or Code.UPDATED). If the CODE is anything else, then the 'data' field will be null - so check the code before assuming it's set.
 * @param c              Calling context - used to query the database for the Last-Update time for a URL
 * @param URL            API URL to check and see if an update is required
 * @param params Parameters associated with this requestcacheLocally: Option to save the fact that we hit this URL in the database. Setting this parameter to TRUE allows us to use If-Modified-Since headers, reducing overhead forceFromCache: When this parameter is true, we won't make any web requests and just return Code.LOCAL, telling the caller to use whatever it has cached locally forceFromWeb: When this parameter is true, the API timeout is greatly reduced so we can force (not exactly, but close enough) a web refresh. The timeout still exists for the poor server's sake
 * @return APIResponse containing the data we fetched (if necessary) and the response code for how we obtained that data.
 * @throws DataManager.NoDataException
 */
public static APIResponse<String> getResponseFromURLOrThrow(Context c,final String URL,RequestParams params) throws DataManager.NoDataException {
  if (c == null) {
    Log.d(Constants.DATAMANAGER_LOG,"String_Node_Str");
    throw new DataManager.NoDataException("String_Node_Str");
  }
  boolean existsInDb=Database.getInstance(c).getResponseTable().responseExists(URL);
  boolean connectedToInternet=ConnectionDetector.isConnectedToInternet(c);
  if (existsInDb) {
    if (connectedToInternet) {
      APIResponse<String> cachedData;
      cachedData=Database.getInstance(c).getResponseTable().getResponse(URL);
      Date now=new Date();
      long timeout=params.forceFromWeb ? Constants.API_HIT_TIMEOUT_LONG : Constants.API_HIT_TIMEOUT_SHORT;
      Date futureTime=new Date(cachedData.lastHit.getTime() + timeout);
      if (now.before(futureTime) && !params.forceFromWeb) {
        return cachedData.updateCode(APIResponse.CODE.CACHED304);
      }
      if (params.forceFromCache) {
        return cachedData;
      }
      HttpResponse cachedResponse=HTTP.getRequest(URL,cachedData.getLastUpdate());
      if (cachedResponse != null) {
        int responseStatus=cachedResponse.getStatusLine().getStatusCode();
        if (responseStatus / 100 == 4 || responseStatus / 100 == 5) {
          String responseData=HTTP.dataFromResponse(cachedResponse);
          Log.e(Constants.DATAMANAGER_LOG,"String_Node_Str" + responseStatus + "String_Node_Str"+ responseData+ "String_Node_Str"+ URL);
          return new APIResponse<>("String_Node_Str",responseData);
        }
        boolean dataRequiresUpdate=(responseStatus == 200);
        if (dataRequiresUpdate) {
          String response=HTTP.dataFromResponse(cachedResponse), lastUpdate="String_Node_Str";
          Header lastModified=cachedResponse.getFirstHeader("String_Node_Str");
          if (lastModified != null) {
            lastUpdate=lastModified.getValue();
          }
          int apiVersion;
          if (cachedResponse.containsHeader("String_Node_Str")) {
            apiVersion=Integer.parseInt(cachedResponse.getFirstHeader("String_Node_Str").getValue());
          }
 else {
            apiVersion=0;
          }
          Database.getInstance(c).getResponseTable().updateResponse(URL,lastUpdate);
          Log.d(Constants.DATAMANAGER_LOG,"String_Node_Str" + apiVersion + "String_Node_Str"+ URL);
          return new APIResponse<>(response,APIResponse.CODE.UPDATED,apiVersion);
        }
 else {
          Database.getInstance(c).getResponseTable().touchResponse(URL);
          return cachedData.updateCode(APIResponse.CODE.CACHED304);
        }
      }
 else {
        Log.e(Constants.DATAMANAGER_LOG,"String_Node_Str");
        return new APIResponse<String>(null,APIResponse.CODE.NODATA);
      }
    }
 else {
      Log.d(Constants.DATAMANAGER_LOG,"String_Node_Str" + URL);
      return Database.getInstance(c).getResponseTable().getResponse(URL).updateCode(APIResponse.CODE.OFFLINECACHE);
    }
  }
 else {
    if (connectedToInternet) {
      HttpResponse webResponse=HTTP.getRequest(URL);
      if (webResponse != null) {
        int responseStatus=webResponse.getStatusLine().getStatusCode();
        if (responseStatus / 100 == 4 || responseStatus / 100 == 5) {
          String responseData=HTTP.dataFromResponse(webResponse);
          Log.e(Constants.DATAMANAGER_LOG,"String_Node_Str" + responseStatus + "String_Node_Str"+ responseData+ "String_Node_Str"+ URL);
          return new APIResponse<>("String_Node_Str",responseData);
        }
        String response=HTTP.dataFromResponse(webResponse), lastUpdate="String_Node_Str";
        Header lastModified=webResponse.getFirstHeader("String_Node_Str");
        if (lastModified != null) {
          lastUpdate=lastModified.getValue();
        }
        if (params.cacheLocally) {
          Database.getInstance(c).getResponseTable().storeResponse(URL,lastUpdate);
        }
        int apiVersion;
        if (webResponse.containsHeader("String_Node_Str")) {
          apiVersion=Integer.parseInt(webResponse.getFirstHeader("String_Node_Str").getValue());
        }
 else {
          apiVersion=0;
        }
        Log.d(Constants.DATAMANAGER_LOG,"String_Node_Str" + apiVersion + "String_Node_Str"+ URL);
        return new APIResponse<>(response,APIResponse.CODE.WEBLOAD,apiVersion);
      }
 else {
        Log.e(Constants.DATAMANAGER_LOG,"String_Node_Str");
        return new APIResponse<String>(null,APIResponse.CODE.NODATA);
      }
    }
 else {
      Log.d(Constants.DATAMANAGER_LOG,"String_Node_Str" + URL);
      throw new DataManager.NoDataException("String_Node_Str");
    }
  }
}