Program: 108585
Project: 108585
Buggy source:
@Override @SuppressWarnings("String_Node_Str") protected AbstractGroup[][] prepareGroups(){
  String valid=isValid();
  if (valid != null) {
    throw new IllegalArgumentException(valid);
  }
  Range<T> tempLower=new Range<T>(null,null,null);
  Range<T> tempUpper=new Range<T>(null,null,null);
  if (lowerRange.getRepeatBound() != null) {
    tempLower.setRepeatBound(lowerRange.getRepeatBound());
  }
 else {
    tempLower.setRepeatBound(intervals.get(0).min);
  }
  if (lowerRange.getSnapBound() != null) {
    tempLower.setSnapBound(lowerRange.getSnapBound());
  }
 else {
    tempLower.setSnapBound(tempLower.getRepeatBound());
  }
  if (lowerRange.getLabelBound() != null) {
    tempLower.setLabelBound(lowerRange.getLabelBound());
  }
 else {
    tempLower.setLabelBound(tempLower.getSnapBound());
  }
  if (upperRange.getRepeatBound() != null) {
    tempUpper.setRepeatBound(upperRange.getRepeatBound());
  }
 else {
    tempUpper.setRepeatBound(intervals.get(intervals.size() - 1).max);
  }
  if (upperRange.getSnapBound() != null) {
    tempUpper.setSnapBound(upperRange.getSnapBound());
  }
 else {
    tempUpper.setSnapBound(tempUpper.getRepeatBound());
  }
  if (upperRange.getLabelBound() != null) {
    tempUpper.setLabelBound(upperRange.getLabelBound());
  }
 else {
    tempUpper.setLabelBound(tempUpper.getSnapBound());
  }
  ArrayList<IndexNode> nodes=new ArrayList<IndexNode>();
  for (int i=0, len=intervals.size(); i < len; i+=INDEX_FANOUT) {
    int min=i;
    int max=Math.min(i + INDEX_FANOUT - 1,len - 1);
    List<Interval<T>> leafs=new ArrayList<Interval<T>>();
    for (int j=min; j <= max; j++) {
      leafs.add(intervals.get(j));
    }
    nodes.add(new IndexNode(intervals.get(min).min,intervals.get(max).max,leafs.toArray(new Interval[leafs.size()])));
  }
  while (nodes.size() > 1) {
    List<IndexNode> current=(List<IndexNode>)nodes.clone();
    nodes.clear();
    for (int i=0, len=current.size(); i < len; i+=INDEX_FANOUT) {
      int min=i;
      int max=Math.min(i + INDEX_FANOUT - 1,len - 1);
      List<IndexNode> temp=new ArrayList<IndexNode>();
      for (int j=min; j <= max; j++) {
        temp.add(current.get(j));
      }
      nodes.add(new IndexNode(current.get(min).min,current.get(max).max,temp.toArray(new HierarchyBuilderIntervalBased.IndexNode[temp.size()])));
    }
  }
  String[] data=getData();
  List<AbstractGroup[]> result=new ArrayList<AbstractGroup[]>();
  IndexNode index=nodes.get(0);
  DataTypeWithRatioScale<T> type=(DataTypeWithRatioScale<T>)getDataType();
  Map<AbstractGroup,AbstractGroup> cache=new HashMap<AbstractGroup,AbstractGroup>();
  AbstractGroup[] first=new AbstractGroup[data.length];
  for (int i=0; i < data.length; i++) {
    T value=type.parse(data[i]);
    Interval<T> interval=getInterval(index,type,value);
    if (type.compare(value,tempLower.labelBound) < 0) {
      throw new IllegalArgumentException(type.format(value) + "String_Node_Str");
    }
 else     if (type.compare(value,tempLower.snapBound) < 0) {
      interval=new Interval<T>(this,true,tempLower.snapBound);
    }
    if (type.compare(value,tempUpper.labelBound) >= 0) {
      throw new IllegalArgumentException(type.format(value) + "String_Node_Str");
    }
 else     if (type.compare(value,tempUpper.snapBound) >= 0) {
      interval=new Interval<T>(this,false,tempUpper.snapBound);
    }
    if (interval.min != null && interval.max != null) {
      if (type.compare(interval.min,tempLower.repeatBound) < 0) {
        interval=new Interval<T>(this,getDataType(),tempLower.repeatBound,interval.max,interval.function);
      }
      if (type.compare(interval.max,tempUpper.repeatBound) >= 0) {
        interval=new Interval<T>(this,getDataType(),interval.min,tempUpper.repeatBound,interval.function);
      }
    }
    first[i]=getGroup(cache,interval);
  }
  result.add(first);
  index=null;
  List<Group<T>> groups=super.getLevel(0).getGroups();
  if (cache.size() > 1 && !groups.isEmpty()) {
    List<Interval<T>> newIntervals=new ArrayList<Interval<T>>();
    int intervalIndex=0;
    int multiplier=0;
    T width=type.subtract(intervals.get(intervals.size() - 1).max,intervals.get(0).min);
    for (    Group<T> group : groups) {
      T min=null;
      T max=null;
      for (int i=0; i < group.getSize(); i++) {
        Interval<T> current=intervals.get(intervalIndex++);
        T offset=type.multiply(width,multiplier);
        T cMin=type.add(current.min,offset);
        T cMax=type.add(current.max,offset);
        if (min == null || type.compare(min,cMin) > 0) {
          min=cMin;
        }
        if (max == null || type.compare(max,cMax) < 0) {
          max=cMax;
        }
        if (intervalIndex == intervals.size()) {
          intervalIndex=0;
          multiplier++;
        }
      }
      newIntervals.add(new Interval<T>(this,getDataType(),min,max,group.getFunction()));
    }
    HierarchyBuilderIntervalBased<T> builder=new HierarchyBuilderIntervalBased<T>(getDataType(),lowerRange,upperRange);
    for (    Interval<T> interval : newIntervals) {
      builder.addInterval(interval.min,interval.max,interval.function);
    }
    for (int i=1; i < super.getLevels().size(); i++) {
      for (      Group<T> sgroup : super.getLevel(i).getGroups()) {
        builder.getLevel(i - 1).addGroup(sgroup.getSize(),sgroup.getFunction());
      }
    }
    builder.prepare(data);
    AbstractGroup[][] columns=builder.prepareGroups();
    for (    AbstractGroup[] column : columns) {
      result.add(column);
    }
  }
 else   if (cache.size() > 1) {
    AbstractGroup[] column=new AbstractGroup[data.length];
    @SuppressWarnings("String_Node_Str") AbstractGroup element=new AbstractGroup("String_Node_Str"){
    }
;
    for (int i=0; i < column.length; i++) {
      column[i]=element;
    }
    result.add(column);
  }
  return result.toArray(new AbstractGroup[0][0]);
}

Fixed version (ground truth):
@Override @SuppressWarnings("String_Node_Str") protected AbstractGroup[][] prepareGroups(){
  String valid=isValid();
  if (valid != null) {
    throw new IllegalArgumentException(valid);
  }
  Range<T> tempLower=new Range<T>(null,null,null);
  Range<T> tempUpper=new Range<T>(null,null,null);
  if (lowerRange.getRepeatBound() != null) {
    tempLower.setRepeatBound(lowerRange.getRepeatBound());
  }
 else {
    tempLower.setRepeatBound(intervals.get(0).min);
  }
  if (lowerRange.getSnapBound() != null) {
    tempLower.setSnapBound(lowerRange.getSnapBound());
  }
 else {
    tempLower.setSnapBound(tempLower.getRepeatBound());
  }
  if (lowerRange.getLabelBound() != null) {
    tempLower.setLabelBound(lowerRange.getLabelBound());
  }
 else {
    tempLower.setLabelBound(tempLower.getSnapBound());
  }
  if (upperRange.getRepeatBound() != null) {
    tempUpper.setRepeatBound(upperRange.getRepeatBound());
  }
 else {
    tempUpper.setRepeatBound(intervals.get(intervals.size() - 1).max);
  }
  if (upperRange.getSnapBound() != null) {
    tempUpper.setSnapBound(upperRange.getSnapBound());
  }
 else {
    tempUpper.setSnapBound(tempUpper.getRepeatBound());
  }
  if (upperRange.getLabelBound() != null) {
    tempUpper.setLabelBound(upperRange.getLabelBound());
  }
 else {
    tempUpper.setLabelBound(tempUpper.getSnapBound());
  }
  ArrayList<IndexNode> nodes=new ArrayList<IndexNode>();
  for (int i=0, len=intervals.size(); i < len; i+=INDEX_FANOUT) {
    int min=i;
    int max=Math.min(i + INDEX_FANOUT - 1,len - 1);
    List<Interval<T>> leafs=new ArrayList<Interval<T>>();
    for (int j=min; j <= max; j++) {
      leafs.add(intervals.get(j));
    }
    nodes.add(new IndexNode(intervals.get(min).min,intervals.get(max).max,leafs.toArray(new Interval[leafs.size()])));
  }
  while (nodes.size() > 1) {
    List<IndexNode> current=(List<IndexNode>)nodes.clone();
    nodes.clear();
    for (int i=0, len=current.size(); i < len; i+=INDEX_FANOUT) {
      int min=i;
      int max=Math.min(i + INDEX_FANOUT - 1,len - 1);
      List<IndexNode> temp=new ArrayList<IndexNode>();
      for (int j=min; j <= max; j++) {
        temp.add(current.get(j));
      }
      nodes.add(new IndexNode(current.get(min).min,current.get(max).max,temp.toArray(new HierarchyBuilderIntervalBased.IndexNode[temp.size()])));
    }
  }
  String[] data=getData();
  List<AbstractGroup[]> result=new ArrayList<AbstractGroup[]>();
  IndexNode index=nodes.get(0);
  DataTypeWithRatioScale<T> type=(DataTypeWithRatioScale<T>)getDataType();
  Map<AbstractGroup,AbstractGroup> cache=new HashMap<AbstractGroup,AbstractGroup>();
  Interval<T> lowerSnap=getInterval(index,type,tempLower.repeatBound);
  lowerSnap=new Interval<T>(this,getDataType(),tempLower.snapBound,lowerSnap.max,lowerSnap.function);
  Interval<T> upperSnap=getIntervalSnap(index,type,tempUpper.repeatBound);
  upperSnap=new Interval<T>(this,getDataType(),upperSnap.min,tempUpper.snapBound,upperSnap.function);
  AbstractGroup[] first=new AbstractGroup[data.length];
  for (int i=0; i < data.length; i++) {
    T value=type.parse(data[i]);
    Interval<T> interval=getInterval(index,type,value);
    if (type.compare(value,tempLower.labelBound) < 0) {
      throw new IllegalArgumentException(type.format(value) + "String_Node_Str");
    }
 else     if (type.compare(value,tempLower.snapBound) < 0) {
      interval=new Interval<T>(this,true,tempLower.snapBound);
    }
    if (type.compare(value,tempUpper.labelBound) >= 0) {
      throw new IllegalArgumentException(type.format(value) + "String_Node_Str");
    }
 else     if (type.compare(value,tempUpper.snapBound) >= 0) {
      interval=new Interval<T>(this,false,tempUpper.snapBound);
    }
    if (interval.min != null && interval.max != null) {
      if (type.compare(interval.min,tempLower.repeatBound) < 0) {
        interval=lowerSnap;
      }
      if (type.compare(interval.max,tempUpper.repeatBound) >= 0) {
        interval=upperSnap;
      }
    }
    first[i]=getGroup(cache,interval);
  }
  result.add(first);
  index=null;
  List<Group<T>> groups=super.getLevel(0).getGroups();
  if (cache.size() > 1 && !groups.isEmpty()) {
    List<Interval<T>> newIntervals=new ArrayList<Interval<T>>();
    int intervalIndex=0;
    int multiplier=0;
    T width=type.subtract(intervals.get(intervals.size() - 1).max,intervals.get(0).min);
    for (    Group<T> group : groups) {
      T min=null;
      T max=null;
      for (int i=0; i < group.getSize(); i++) {
        Interval<T> current=intervals.get(intervalIndex++);
        T offset=type.multiply(width,multiplier);
        T cMin=type.add(current.min,offset);
        T cMax=type.add(current.max,offset);
        if (min == null || type.compare(min,cMin) > 0) {
          min=cMin;
        }
        if (max == null || type.compare(max,cMax) < 0) {
          max=cMax;
        }
        if (intervalIndex == intervals.size()) {
          intervalIndex=0;
          multiplier++;
        }
      }
      newIntervals.add(new Interval<T>(this,getDataType(),min,max,group.getFunction()));
    }
    HierarchyBuilderIntervalBased<T> builder=new HierarchyBuilderIntervalBased<T>(getDataType(),lowerRange,upperRange);
    for (    Interval<T> interval : newIntervals) {
      builder.addInterval(interval.min,interval.max,interval.function);
    }
    for (int i=1; i < super.getLevels().size(); i++) {
      for (      Group<T> sgroup : super.getLevel(i).getGroups()) {
        builder.getLevel(i - 1).addGroup(sgroup.getSize(),sgroup.getFunction());
      }
    }
    builder.prepare(data);
    AbstractGroup[][] columns=builder.prepareGroups();
    for (    AbstractGroup[] column : columns) {
      result.add(column);
    }
  }
 else   if (cache.size() > 1) {
    AbstractGroup[] column=new AbstractGroup[data.length];
    @SuppressWarnings("String_Node_Str") AbstractGroup element=new AbstractGroup("String_Node_Str"){
    }
;
    for (int i=0; i < column.length; i++) {
      column[i]=element;
    }
    result.add(column);
  }
  return result.toArray(new AbstractGroup[0][0]);
}