@SuppressWarnings("unchecked")
  public SumResult<T> extendedDensity(double p) {
    T emptyTarget = (T) _bins.first().getTarget().init();
    double countDensity;
    T targetDensity;

    Bin<T> exact = _bins.get(p);
    if (p < _minimum || p > _maximum) {
      countDensity = 0;
      targetDensity = (T) emptyTarget.clone();
    } else if (p == _minimum && p == _maximum) {
      countDensity = Double.POSITIVE_INFINITY;
      targetDensity = emptyTarget;
    } else if (exact != null) {
      double higher = Math.nextAfter(p, Double.POSITIVE_INFINITY);
      double lower = Math.nextAfter(p, Double.NEGATIVE_INFINITY);

      SumResult<T> lowerResult = extendedDensity(lower);
      SumResult<T> higherResult = extendedDensity(higher);
      countDensity = (lowerResult.getCount() + higherResult.getCount()) / 2;
      targetDensity = (T) lowerResult.getTargetSum().clone().sum(higherResult.getTargetSum()).mult(0.5);
    } else {
      Bin<T> lowerBin = _bins.lower(p);
      if (lowerBin == null) {
        lowerBin = new Bin<T>(_minimum, 0, (T) emptyTarget.clone());
      }
        
      Bin<T> higherBin = _bins.higher(p);
      if (higherBin == null) {
        higherBin = new Bin<T>(_maximum, 0, (T) emptyTarget.clone());
      }

      double bDiff = p - lowerBin.getMean();
      double pDiff = higherBin.getMean() - lowerBin.getMean();
      double bpRatio = bDiff / pDiff;
      
      NumericTarget countTarget = 
              (NumericTarget) computeDensity(bpRatio, lowerBin.getMean(), higherBin.getMean(),
              new NumericTarget(lowerBin.getCount()), new NumericTarget(higherBin.getCount()));
      countDensity = countTarget.getSum();

      targetDensity = 
              (T) computeDensity(bpRatio, lowerBin.getMean(), higherBin.getMean(),
              lowerBin.getTarget(), higherBin.getTarget());      
    }

    return new SumResult<T>(countDensity, targetDensity);
  }