public void restoreSessionTotals(
      long _saved_data_bytes_downloaded,
      long _saved_data_bytes_uploaded,
      long _saved_discarded,
      long _saved_hashfails,
      long _saved_SecondsDownloading,
      long _saved_SecondsOnlySeeding) {
    saved_data_bytes_downloaded = _saved_data_bytes_downloaded;
    saved_data_bytes_uploaded = _saved_data_bytes_uploaded;
    saved_discarded = _saved_discarded;
    saved_hashfails = _saved_hashfails;
    saved_SecondsDownloading = _saved_SecondsDownloading;
    saved_SecondsOnlySeeding = _saved_SecondsOnlySeeding;

    session_start_data_bytes_downloaded = saved_data_bytes_downloaded;
    session_start_data_bytes_uploaded = _saved_data_bytes_uploaded;

    DownloadManagerState state = download_manager.getDownloadState();

    saved_SecondsSinceDownload = state.getIntAttribute(DownloadManagerState.AT_TIME_SINCE_DOWNLOAD);
    saved_SecondsSinceUpload = state.getIntAttribute(DownloadManagerState.AT_TIME_SINCE_UPLOAD);

    saved_peak_receive_rate = state.getLongAttribute(DownloadManagerState.AT_PEAK_RECEIVE_RATE);
    saved_peak_send_rate = state.getLongAttribute(DownloadManagerState.AT_PEAK_SEND_RATE);
  }
  public long getAvailWentBadTime() {
    PEPeerManager pm = download_manager.getPeerManager();

    if (pm != null) {

      long bad_time = pm.getAvailWentBadTime();

      if (bad_time > 0) {

        // valid last bad time

        return (bad_time);
      }

      if (pm.getMinAvailability() >= 1.0) {

        // we can believe the fact that it isn't bad (we want to ignore 0 results from
        // downloads that never get to a 1.0 availbility)

        return (0);
      }
    }

    DownloadManagerState state = download_manager.getDownloadState();

    return (state.getLongAttribute(DownloadManagerState.AT_AVAIL_BAD_TIME));
  }
  protected void saveSessionTotals() {
    // re-base the totals from current totals and session totals

    saved_data_bytes_downloaded = getTotalDataBytesReceived();
    saved_data_bytes_uploaded = getTotalDataBytesSent();

    saved_protocol_bytes_downloaded = getTotalProtocolBytesReceived();
    saved_protocol_bytes_uploaded = getTotalProtocolBytesSent();

    saved_discarded = getDiscarded();
    saved_hashfails = getHashFailBytes();

    saved_SecondsDownloading = getSecondsDownloading();
    saved_SecondsOnlySeeding = getSecondsOnlySeeding();

    saved_SecondsSinceDownload = getTimeSinceLastDataReceivedInSeconds();
    saved_SecondsSinceUpload = getTimeSinceLastDataSentInSeconds();

    saved_peak_receive_rate = getPeakDataReceiveRate();
    saved_peak_send_rate = getPeakDataSendRate();

    DownloadManagerState state = download_manager.getDownloadState();

    state.setIntAttribute(DownloadManagerState.AT_TIME_SINCE_DOWNLOAD, saved_SecondsSinceDownload);
    state.setIntAttribute(DownloadManagerState.AT_TIME_SINCE_UPLOAD, saved_SecondsSinceUpload);

    state.setLongAttribute(DownloadManagerState.AT_AVAIL_BAD_TIME, getAvailWentBadTime());

    state.setLongAttribute(DownloadManagerState.AT_PEAK_RECEIVE_RATE, saved_peak_receive_rate);
    state.setLongAttribute(DownloadManagerState.AT_PEAK_SEND_RATE, saved_peak_send_rate);
  }
  protected void timerTick(int tick_count) {
    if (tick_count % 15 == 0) {

      if (last_sr_progress == -1) {

        long temp =
            download_manager
                .getDownloadState()
                .getLongAttribute(DownloadManagerState.AT_SHARE_RATIO_PROGRESS);

        last_sr_progress = (int) temp;
      }

      if (share_ratio_progress_interval <= 0) {

        // reset

        if (last_sr_progress != 0) {

          last_sr_progress = 0;

          download_manager
              .getDownloadState()
              .setLongAttribute(DownloadManagerState.AT_SHARE_RATIO_PROGRESS, 0);
        }
      } else {

        int current_sr = getShareRatio();

        current_sr = (current_sr / share_ratio_progress_interval) * share_ratio_progress_interval;

        if (current_sr != last_sr_progress) {

          last_sr_progress = current_sr;

          long data = ((SystemTime.getCurrentTime() / 1000) << 32) + last_sr_progress;

          download_manager
              .getDownloadState()
              .setLongAttribute(DownloadManagerState.AT_SHARE_RATIO_PROGRESS, data);
        }
      }
    }

    if (!history_retention_required) {

      return;
    }

    PEPeerManager pm = download_manager.getPeerManager();

    if (pm == null) {

      return;
    }

    PEPeerManagerStats stats = pm.getStats();

    long send_rate = stats.getDataSendRate() + stats.getProtocolSendRate();
    long receive_rate = stats.getDataReceiveRate() + stats.getProtocolReceiveRate();
    long peer_swarm_average = getTotalAveragePerPeer();

    long entry =
        ((((send_rate - 1 + HISTORY_DIV / 2) / HISTORY_DIV) << 42) & 0x7ffffc0000000000L)
            | ((((receive_rate - 1 + HISTORY_DIV / 2) / HISTORY_DIV) << 21) & 0x000003ffffe00000L)
            | ((((peer_swarm_average - 1 + HISTORY_DIV / 2) / HISTORY_DIV)) & 0x00000000001fffffL);

    synchronized (this) {
      if (history != null) {

        history[history_pos++] = entry;

        if (history_pos == HISTORY_MAX_SECS) {

          history_pos = 0;
          history_wrapped = true;
        }
      }
    }
  }