/**
  * Adds a data item to the series and, if requested, sends a {@link SeriesChangeEvent} to all
  * registered listeners.
  *
  * @param item the (x, y) item (<code>null</code> not permitted).
  * @param notify a flag that controls whether or not a {@link SeriesChangeEvent} is sent to all
  *     registered listeners.
  */
 public void add(XYDataItem item, boolean notify) {
   ParamChecks.nullNotPermitted(item, "item");
   item = (XYDataItem) item.clone();
   if (this.autoSort) {
     int index = Collections.binarySearch(this.data, item);
     if (index < 0) {
       this.data.add(-index - 1, item);
     } else {
       if (this.allowDuplicateXValues) {
         // need to make sure we are adding *after* any duplicates
         int size = this.data.size();
         while (index < size && item.compareTo(this.data.get(index)) == 0) {
           index++;
         }
         if (index < this.data.size()) {
           this.data.add(index, item);
         } else {
           this.data.add(item);
         }
       } else {
         throw new SeriesException("X-value already exists.");
       }
     }
   } else {
     if (!this.allowDuplicateXValues) {
       // can't allow duplicate values, so we need to check whether
       // there is an item with the given x-value already
       int index = indexOf(item.getX());
       if (index >= 0) {
         throw new SeriesException("X-value already exists.");
       }
     }
     this.data.add(item);
   }
   updateBoundsForAddedItem(item);
   if (getItemCount() > this.maximumItemCount) {
     XYDataItem removed = (XYDataItem) this.data.remove(0);
     updateBoundsForRemovedItem(removed);
   }
   if (notify) {
     fireSeriesChanged();
   }
 }