Program: 20614
Project: 20614
Buggy source:
public Color findColor(SceneObject o,double d,Ray r,int recursion){
  Color color, reflectColor, refractColor;
  color=reflectColor=refractColor=o.getMaterial().getColor();
  Vector intersection=r.getPoint(d);
  Vector normal=o.getNormal(intersection);
  double diffuse=o.getMaterial().getDiffuse();
  double reflection=o.getMaterial().getReflection();
  double refraction=o.getMaterial().getRefraction();
  double shade=0.0;
  for (int k=0; k < scene.getNumLights(); k++) {
    SceneObject light=scene.getLight(k);
    Vector posLight=light.getPos();
    posLight.normalize();
    shade=posLight.dot(normal);
    if (shade < 0) {
      shade=0;
    }
    color=color.multiply((float)((1 - diffuse) + diffuse * shade));
  }
  double c1=-normal.dot(r.getDirection());
  if (recursion < RECURSION_LIMIT && reflection > 0.01) {
    Vector reflectDirection=r.getDirection().add(normal.multiply(2 * c1));
    reflectColor=intersectObject(new Ray(intersection,reflectDirection),++recursion);
    reflectColor=reflectColor.multiply((float)o.getMaterial().getReflection());
  }
  if (recursion < RECURSION_LIMIT && refraction > 0.01) {
    double n=1 / refraction;
    double c2=1 - Math.pow(n,2) * (1 - Math.pow(c1,2));
    if (c2 > 0.0) {
      c2=Math.sqrt(c2);
      Vector refractDirection=r.getDirection().multiply(n).add(normal.multiply(n * c1 - c2));
      refractColor=intersectObject(new Ray(intersection,refractDirection),++recursion);
      refractColor=refractColor.multiply((float)o.getMaterial().getDiffuse());
    }
  }
  Color[] colors={color,reflectColor};
  return Color.combine(colors);
}

Fixed version (ground truth):
public Color findColor(SceneObject o,double d,Ray r,int recursion){
  Color color, reflectColor, refractColor;
  color=reflectColor=refractColor=o.getMaterial().getColor();
  Vector intersection=r.getPoint(d);
  Vector normal=o.getNormal(intersection);
  double diffuse=o.getMaterial().getDiffuse();
  double reflection=o.getMaterial().getReflection();
  double refraction=o.getMaterial().getRefraction();
  double shade=0.0;
  for (int k=0; k < scene.getNumLights(); k++) {
    SceneObject light=scene.getLight(k);
    Vector posLight=light.getPos();
    posLight.normalize();
    shade=posLight.dot(normal);
    if (shade < 0) {
      shade=0;
    }
    color=color.multiply((float)((1 - diffuse) + diffuse * shade));
  }
  double c1=-normal.dot(r.getDirection());
  if (recursion < RECURSION_LIMIT && reflection > 0.01) {
    Vector reflectDirection=r.getDirection().add(normal.multiply(2 * c1));
    reflectColor=intersectObject(new Ray(intersection,reflectDirection),++recursion);
    reflectColor=reflectColor.multiply((float)reflection);
  }
  if (recursion < RECURSION_LIMIT && refraction > 0.01) {
    double n=1 / refraction;
    double c2=1 - Math.pow(n,2) * (1 - Math.pow(c1,2));
    if (c2 > 0.0) {
      c2=Math.sqrt(c2);
      Vector refractDirection=r.getDirection().multiply(n).add(normal.multiply(n * c1 - c2));
      refractColor=intersectObject(new Ray(intersection,refractDirection),++recursion);
      refractColor=refractColor.multiply((float)refraction);
    }
  }
  Color[] colors={color,reflectColor};
  return Color.combine(colors);
}