private void addData(
      JFreeChart chart,
      DSLAMSource source,
      Timeinterval time,
      Serializable filter,
      Properties properties,
      Map<String, Object> colorScheme,
      Properties outputProperties)
      throws IOException {
    if (chart != null) {
      PerformanceCounterDataCollection cData = null;

      long dataSize = 0;

      try {
        cData =
            getPerformanceCounterDataCollection(source, time, filter, properties, outputProperties);
        Collection<PerformanceCounterData> data = null;

        Date d0 = null; // first timestamp for data
        Date d1 = null; // last timestamp for data
        RegularTimePeriod time0 = null;

        if (cData != null) {
          data = cData.getData();

          {
            int l = data.size();
            outputProperties.setProperty("data.count", Integer.toString(l));
          }

          if (data != null && data.size() > 0) {
            dataSize = data.size();

            // Set 'd0':
            {
              // TODO: Avoid assumption "data is sorted"!
              PerformanceCounterData e = data.iterator().next();
              d0 = e.getTimestamp();
            }

            // Set 'd1':
            {
              // TODO: Avoid assumption "data is sorted"!
              for (PerformanceCounterData e : data) {
                d1 = e.getTimestamp();
              }
            }

            time0 = createRegularTimePeriod(d0);
          }
        }

        XYPlot plot = chart.getXYPlot();

        // Set the first dataset:
        {
          TimeSeriesCollection dataset = new TimeSeriesCollection();

          List<Paint> seriesPaint = new ArrayList<Paint>();
          List<Stroke> seriesStroke = new ArrayList<Stroke>();

          // Add series 'ES':
          {
            if (data != null && data.size() > 0) {
              TimeSeries series = new TimeSeries("ES", time0.getClass());

              for (PerformanceCounterData e : data) {
                Date d = e.getTimestamp();
                RegularTimePeriod timePeriod = createRegularTimePeriod(d);

                // Add point:
                {
                  int value = getES(e);

                  addOrUpdate(series, timePeriod, (double) value);
                }
              }

              seriesPaint.add((Paint) colorScheme.get("color.counter.es"));
              seriesStroke.add(STROKE_COUNTER_ES);

              dataset.addSeries(series);
            }
          }

          // Add series 'SES':
          {
            if (data != null && data.size() > 0) {
              TimeSeries series = new TimeSeries("SES", time0.getClass());

              for (PerformanceCounterData e : data) {
                Date d = e.getTimestamp();
                RegularTimePeriod timePeriod = createRegularTimePeriod(d);

                // Add point:
                {
                  int value = getSES(e);

                  addOrUpdate(series, timePeriod, (double) value);
                }
              }

              seriesPaint.add((Paint) colorScheme.get("color.counter.ses"));
              seriesStroke.add(STROKE_COUNTER_SES);

              dataset.addSeries(series);
            }
          }

          // Add series 'US':
          {
            if (data != null && data.size() > 0) {
              TimeSeries series = new TimeSeries("US", time0.getClass());

              for (PerformanceCounterData e : data) {
                Date d = e.getTimestamp();
                RegularTimePeriod timePeriod = createRegularTimePeriod(d);

                // Add point:
                {
                  int value = getUS(e);

                  addOrUpdate(series, timePeriod, (double) value);
                }
              }

              seriesPaint.add((Paint) colorScheme.get("color.counter.us"));
              seriesStroke.add(STROKE_COUNTER_US);

              dataset.addSeries(series);
            }
          }

          // superspeed
          {
            if (data != null && data.size() > 0) {
              TimeSeries series = new TimeSeries("LEFTRS", time0.getClass());
              for (PerformanceCounterData e : data) {
                Date d = e.getTimestamp();
                RegularTimePeriod timePeriod = createRegularTimePeriod(d);
                {
                  int value = getPreviousLEFTRS(e);
                  addOrUpdate(series, timePeriod, (double) value);
                }
              }
              seriesPaint.add((Paint) colorScheme.get("color.counter.previousleftrs"));
              seriesStroke.add(STROKE_COUNTER_US);
              dataset.addSeries(series);
            }
          }
          // ends
          {
            if (data != null && data.size() > 0) {
              boolean showLinearCurve = getShowLinearCurve();

              if (showLinearCurve) {
                // Add series for a linear curve:
                {
                  TimeSeries series = new TimeSeries("Linear", time0.getClass());

                  long t0 = d0.getTime();
                  long t1 = d1.getTime();

                  if (t0 < t1) {
                    long timeX = 15 * 60 * 1000; // 15 minutes intervals
                    // TODO: Read length of intervals from obtained data!

                    double value0 = 0;
                    double value1 = 900;
                    // TODO: Read '900' from obtained data!

                    long timeDelta = t1 - t0;
                    double valueDelta = value1 - value0;

                    long t = t0;
                    int i = 0;

                    while (t <= t1) {
                      Date d = new Date(t);

                      RegularTimePeriod timePeriod = createRegularTimePeriod(d);
                      double value = value0 + ((t - t0) * valueDelta) / timeDelta;

                      // Add point:
                      {
                        addOrUpdate(series, timePeriod, (double) value);
                      }

                      t += timeX;
                      i += 1;
                    }
                  }

                  seriesPaint.add(Color.red);
                  seriesStroke.add(STROKE_COUNTER_DEFAULT);

                  dataset.addSeries(series);
                }
              }
            }
          }

          setDefaultRenderer(chart, colorScheme, 0, seriesPaint, seriesStroke);
          plot.setDataset(0, dataset);
          plot.mapDatasetToRangeAxis(0, 0);
        }
      } finally {
        if (cData != null) {
          cData.dispose();
          cData = null;
        }
      }

      if (outputProperties != null) {
        outputProperties.setProperty("data.count", Long.toString(dataSize));
      }
    }
  }
  protected JFreeChart createChart(
      DSLAMSource source,
      String LID,
      Timeinterval time,
      Properties properties,
      GraphRenderingInput input,
      Map<String, Object> colorScheme,
      Properties outputProperties)
      throws IOException {
    JFreeChart res = null;

    {
      JFreeChart chart = null;

      Timeinterval domainAxisTime = null;

      // Set 'chart':
      {
        String domainAxisTitle = null;

        // Set 'domainAxisTime':
        {
          DateFormat format = (DateFormat) colorScheme.get("date.format");

          domainAxisTitle = "Time (" + time.toString(format) + ")";
        }

        chart =
            ChartFactory.createTimeSeriesChart(
                null, // chart-title
                domainAxisTitle, // domain-axis label
                null, // value-axis label
                null, // dataset
                true, // legends required
                true, // generate tooltips
                false // generate URLs
                );
      }

      XYPlot plot = chart.getXYPlot();

      plot.setOrientation(PlotOrientation.VERTICAL);
      plot.setAxisOffset(new RectangleInsets(5.0, 5.0, 5.0, 5.0));
      plot.getRangeAxis().setFixedDimension(15.0);

      // Fix the domain axis:
      {
        fixDateAxisToTimeinterval(plot, time);
        domainAxisTime = time;
      }

      // Set the y-axis:
      {
        String axisTitle = "Count (/900s)";

        ValueAxis a = new LogarithmicAxis(axisTitle);
        a.setLowerBound(0);
        a.setUpperBound(1000); // TODO: '1000' is '900' rounded up to nearest power of 10!
        // TODO: Get unit from data-model!
        // TODO: Get upper bound from data-model!

        plot.setRangeAxis(a);
      }

      String title = getTitle();
      setDefaults(chart, colorScheme);
      setTitle(chart, LID, colorScheme, title, source, time);

      String filter = ""; // an empty string implies the default filter!

      // Set 'filter':
      {
        if (input != null) {
          Properties p = input.getProperties();
          if (p != null) {
            String v = p.getProperty("data.filter");
            if (v != null) {
              filter = v;
            }
          }
        }
      }

      addData(chart, source, time, filter, properties, colorScheme, outputProperties);

      if (outputProperties != null) {
        if (domainAxisTime != null) {
          outputProperties.setProperty("axis.domain.time", time.toString());
        }
      }

      res = chart;
    }

    return res;
  }