/**
   * Check if a resource request/response overlaps with the display window. If no end time for the
   * resource exists, it is treated as Double.MAX_VALUE
   *
   * @param resource the resource to check
   * @param left the left boundary of the window
   * @param right the right boundary of the window
   * @return true if some portion of the request falls in the window
   */
  protected boolean isResourceInWindow(NetworkResource resource, double left, double right) {
    double startTime = resource.getStartTime();
    double endTime = resource.getEndTime();

    // A version we can use to compare to our left bound
    double comparableEndTime = endTime;

    if (Double.isNaN(endTime)) {
      // We assume the request simply has not terminated, so we set the
      // comparable version to something big.
      comparableEndTime = Double.MAX_VALUE;
    }

    return (startTime < right && comparableEndTime > left);
  }
  /**
   * Display all resources that fall in the given window.
   *
   * @param left the left boundary
   * @param right the right boundary
   */
  protected void displayResourcesInWindow(double left, double right) {
    NetworkVisualizationModel model = getModel();
    // We dont need to update if we
    // have not shifted bounds.
    if ((displayed.size() > 0) && (left == oldLeft) && (right == oldRight)) {
      return;
    } else {
      oldLeft = left;
      oldRight = right;
    }

    // clean up Event Hookups
    for (int i = 0; i < displayed.size(); i++) {
      ResourceRow row = displayed.get(i);
      row.cleanUp();
    }

    // blank the resource Panel
    displayed.clear();
    getContentElement().setInnerHTML("");

    // We do a naive linear search until the kinks can be ironed
    // out of more sophisticated search.
    List<NetworkResource> networkResources = model.getSortedResources();
    for (int i = 0; i < networkResources.size(); i++) {
      NetworkResource resource = networkResources.get(i);
      if (isResourceInWindow(resource, left, right)) {
        displayResource(left, right, resource);
      }

      // Bail once we've hit the right edge
      if (resource.getStartTime() >= right) {
        break;
      }
    }

    if (shouldFlash) {
      CssTransitionFloat.get().transition(getElement(), "opacity", 0, 1, 200);
      shouldFlash = false;
    }
  }
  /**
   * Display a resource in the window.
   *
   * @param left the left boundary
   * @param right the right boundary
   * @param resource the resource to display
   */
  protected void displayResource(double left, double right, NetworkResource resource) {
    String lastPathComponent = resource.getLastPathComponent();
    lastPathComponent = (lastPathComponent == null) ? "" : lastPathComponent;
    int dotIndex = lastPathComponent.lastIndexOf(".");
    String fileExtension = (dotIndex < 0) ? ".html" : lastPathComponent.substring(dotIndex);

    final ResourceRow row =
        new ResourceRow(
            getContentContainer(),
            resource,
            fileExtension,
            left,
            right,
            this,
            resources,
            serverEventController);

    displayed.add(row);
  }