private LegendItem createFlankedShapeLegendItem(
      String label,
      double minValue,
      double maxValue,
      Shape itemShape,
      Paint shapeFillPaint,
      boolean shapeOutlineVisible,
      DateFormat dateFormat) {
    // configure legend item
    String description = "";
    String toolTipText = "";
    String urlText = "";
    boolean shapeVisible = true;
    boolean shapeFilled = true;
    Paint outlinePaint = Color.BLACK;
    Stroke outlineStroke = DEFAULT_OUTLINE_STROKE;
    boolean lineVisible = false;
    Shape line = new Line2D.Float();
    Stroke lineStroke = new BasicStroke(); // basic stroke is fine here, since continuous legend
    // item does not show a line
    Paint linePaint = Color.BLACK;

    // create legend item
    FlankedShapeLegendItem legendItem =
        new FlankedShapeLegendItem(
            label,
            description,
            toolTipText,
            urlText,
            shapeVisible,
            itemShape,
            shapeFilled,
            shapeFillPaint,
            shapeOutlineVisible,
            outlinePaint,
            outlineStroke,
            lineVisible,
            line,
            lineStroke,
            linePaint);

    if (dateFormat != null) {
      legendItem.setLeftShapeLabel(dateFormat.format(new Date((long) minValue)));
      legendItem.setRightShapeLabel(dateFormat.format(new Date((long) maxValue)));
    } else {
      // set intelligently rounded strings as labels
      int powerOf10 = DataStructureUtils.getOptimalPrecision(minValue, maxValue);
      legendItem.setLeftShapeLabel(DataStructureUtils.getRoundedString(minValue, powerOf10 - 1));
      legendItem.setRightShapeLabel(DataStructureUtils.getRoundedString(maxValue, powerOf10 - 1));
    }

    return legendItem;
  }
  /**
   * @param valueGroups
   * @param valuesAreDates
   *     <p>TODO use param valuesAreDates
   */
  protected void applyAdaptiveVisualRounding(List<ValueRange> valueGroups, boolean valuesAreDates) {
    if (valuesAreDates) {
      DateFormat dateFormat = getDateFormat();
      for (ValueRange range : valueGroups) {
        NumericalValueRange numericalValueRange = (NumericalValueRange) range;
        numericalValueRange.setDateFormat(dateFormat);
      }
    } else {
      // values are not dates

      // first pass
      NumericalValueRange previous = null;
      NumericalValueRange current = null;
      NumericalValueRange next = null;
      for (ValueRange valueGroup : valueGroups) {
        next = (NumericalValueRange) valueGroup;
        if (previous != null) {
          int precisionLower =
              Math.min(
                  DataStructureUtils.getOptimalPrecision(
                      current.getLowerBound(), current.getUpperBound()),
                  DataStructureUtils.getOptimalPrecision(
                      previous.getLowerBound(), current.getLowerBound()));
          int precisionUpper =
              Math.min(
                  DataStructureUtils.getOptimalPrecision(
                      current.getLowerBound(), current.getUpperBound()),
                  DataStructureUtils.getOptimalPrecision(
                      current.getUpperBound(), next.getUpperBound()));
          if (precisionUpper >= Integer.MAX_VALUE) {
            precisionUpper = precisionLower;
          }
          current.setVisualPrecision(precisionLower, precisionUpper);
        } else if (current != null) {
          int precisionLower =
              DataStructureUtils.getOptimalPrecision(
                  current.getLowerBound(), current.getUpperBound());
          int precisionUpper =
              Math.min(
                  DataStructureUtils.getOptimalPrecision(
                      current.getLowerBound(), current.getUpperBound()),
                  DataStructureUtils.getOptimalPrecision(
                      current.getUpperBound(), next.getUpperBound()));
          if (precisionUpper >= Integer.MAX_VALUE) {
            precisionUpper = precisionLower;
          }
          current.setVisualPrecision(precisionLower, precisionUpper);
        }
        previous = current;
        current = next;
      }
      if (previous != null) {
        // even if eclipse states that this code is dead, it is not! (eclipse bug)
        int precisionLower =
            Math.min(
                DataStructureUtils.getOptimalPrecision(
                    current.getLowerBound(), current.getUpperBound()),
                DataStructureUtils.getOptimalPrecision(
                    previous.getLowerBound(), current.getLowerBound()));
        int precisionUpper =
            DataStructureUtils.getOptimalPrecision(
                current.getLowerBound(), current.getUpperBound());
        if (precisionUpper >= Integer.MAX_VALUE) {
          precisionUpper = precisionLower;
        }
        current.setVisualPrecision(precisionLower, precisionUpper);
      } else if (current != null) {
        int precision =
            DataStructureUtils.getOptimalPrecision(
                current.getLowerBound(), current.getUpperBound());
        current.setVisualPrecision(precision, precision);
      }

      //		// second pass
      //		current = null;
      //		next = null;
      //		for (ValueRange valueGroup : valueGroups ) {
      //			next = (NumericalValueRange)valueGroup;
      //			if (current != null) {
      //				int currentPrecision = current.getUpperPrecision();
      //				int nextPrecision = next.getLowerPrecision();
      //				int precision = Math.min(nextPrecision, currentPrecision);
      //				current.setUpperPrecision(precision);
      //				next.setLowerPrecision(precision);
      //			}
      //			current = next;
      //		}
    }
  }