class FetchHistoryHelper {
  private static final Log logger = LogFactory.getLog(FetchHistoryHelper.class);
  /**
   * key for storing timestamp in crawl history map.
   */
  public static final String A_TIMESTAMP = ".ts";

  /**
   * returns a Map to store recrawl data, positioned properly in CrawlURI's
   * fetch history array, according to {@code timestamp}. this makes it possible
   * to import crawl history data from multiple sources.
   * @param uri target {@link CrawlURI}
   * @param timestamp timestamp (in ms) of crawl history to be added.
   * @return Map object to store recrawl data, or null if {@code timestamp} is older
   * than existing crawl history entry and there's no room for it.
   */
  @SuppressWarnings("unchecked")
  public static Map<String, Object> getFetchHistory(CrawlURI uri, long timestamp, int historyLength) {<FILL_FUNCTION_BODY>}

  protected static final DateFormat HTTP_DATE_FORMAT = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz");

  protected FetchHistoryHelper() {
  }

  /**
   * converts time in HTTP Date format {@code dateStr} to seconds
   * since epoch. 
   * @param dateStr time in HTTP Date format.
   * @return seconds since epoch
   */
  public static long parseHttpDate(String dateStr) {
      synchronized (HTTP_DATE_FORMAT) {
          try {
              Date d = HTTP_DATE_FORMAT.parse(dateStr);
              return d.getTime() / 1000;
          } catch (ParseException ex) {
            if (logger.isDebugEnabled())
              logger.debug("bad HTTP DATE: " + dateStr);
              return 0;
          }
      }
  }

  public static String formatHttpDate(long time) {
      synchronized (HTTP_DATE_FORMAT) {
          // format(Date) is not thread safe either
          return HTTP_DATE_FORMAT.format(new Date(time * 1000));
      }
  }

}

    Map<String, Object>[] history = uri.getFetchHistory();
    if (history == null) {
      // there's no history records at all.
      // FetchHistoryProcessor assumes history is HashMap[], not Map[].
      history = new HashMap[historyLength];
      uri.setFetchHistory(history);
    }
    for (int i = 0; i < history.length; i++) {
      if (history[i] == null) {
        history[i] = new HashMap<String, Object>();
        history[i].put(A_TIMESTAMP, timestamp);
        return history[i];
      }
      Object ts = history[i].get(A_TIMESTAMP);
      // no timestamp value is regarded as older than anything.
      if (!(ts instanceof Long) || timestamp > (Long)ts) {
        if (i < history.length - 2) {
          System.arraycopy(history, i, history, i + 1, history.length - i - 1);
        } else if (i == history.length - 2) {
          history[i + 1] = history[i];
        }
        history[i] = new HashMap<String, Object>();
        history[i].put(A_TIMESTAMP, timestamp);
        return history[i];
      }
    }
    return null;
  
<no_super_class>