Program: 70875
Project: 70875
Buggy source:
private void drawColoredCylinder(GL2 gl,int nslices,double base,double top,float[] coords0,byte[] color0,float[] coords1,byte[] color1,boolean capped,boolean useHSV){
  utmp.set(coords1[0] - coords0[0],coords1[1] - coords0[1],coords1[2] - coords0[2]);
  Xtmp.p.set(coords0[0],coords0[1],coords0[2]);
  Xtmp.R.setZDirection(utmp);
  gl.glPushMatrix();
  GL2Viewer.mulTransform(gl,Xtmp);
  double h=utmp.norm();
  if (nslices + 1 != cosBuff.length) {
    cosBuff=new double[nslices + 1];
    sinBuff=new double[nslices + 1];
    cosBuff[0]=1;
    sinBuff[0]=0;
    cosBuff[nslices]=1;
    sinBuff[nslices]=0;
    for (int i=1; i < nslices; i++) {
      double ang=i / (double)nslices * 2 * Math.PI;
      cosBuff[i]=Math.cos(ang);
      sinBuff[i]=Math.sin(ang);
    }
  }
  gl.glBegin(GL2.GL_QUAD_STRIP);
  double c1, s1;
  for (int i=0; i <= nslices; i++) {
    c1=cosBuff[i];
    s1=sinBuff[i];
    gl.glNormal3d(c1,s1,(base - top) / h);
    setVertexColor(gl,color0,useHSV);
    gl.glColor4ubv(color0,0);
    gl.glVertex3d(base * c1,base * s1,0);
    setVertexColor(gl,color1,useHSV);
    gl.glVertex3d(top * c1,top * s1,h);
  }
  gl.glEnd();
  if (capped) {
    gl.glColor4ubv(color1,0);
    if (top > 0) {
      gl.glBegin(GL2.GL_POLYGON);
      gl.glNormal3d(0,0,1);
      for (int i=0; i < nslices; i++) {
        gl.glVertex3d(top * cosBuff[i],top * sinBuff[i],h);
      }
      gl.glEnd();
    }
    gl.glColor4ubv(color0,0);
    if (base > 0) {
      gl.glBegin(GL2.GL_POLYGON);
      gl.glNormal3d(0,0,-1);
      for (int i=0; i < nslices; i++) {
        gl.glVertex3d(base * cosBuff[i],base * sinBuff[i],0);
      }
      gl.glEnd();
    }
  }
  gl.glPopMatrix();
}

Fixed version (ground truth):
private void drawColoredCylinder(GL2 gl,int nslices,double base,double top,float[] coords0,byte[] color0,float[] coords1,byte[] color1,boolean capped,boolean useHSV){
  utmp.set(coords1[0] - coords0[0],coords1[1] - coords0[1],coords1[2] - coords0[2]);
  Xtmp.p.set(coords0[0],coords0[1],coords0[2]);
  Xtmp.R.setZDirection(utmp);
  gl.glPushMatrix();
  GL2Viewer.mulTransform(gl,Xtmp);
  double h=utmp.norm();
  if (nslices + 1 != cosBuff.length) {
    cosBuff=new double[nslices + 1];
    sinBuff=new double[nslices + 1];
    cosBuff[0]=1;
    sinBuff[0]=0;
    cosBuff[nslices]=1;
    sinBuff[nslices]=0;
    for (int i=1; i < nslices; i++) {
      double ang=i / (double)nslices * 2 * Math.PI;
      cosBuff[i]=Math.cos(ang);
      sinBuff[i]=Math.sin(ang);
    }
  }
  double nz=(base - top) / h;
  double nscale=1.0 / Math.sqrt(1 + nz * nz);
  gl.glBegin(GL2.GL_QUAD_STRIP);
  double c1, s1;
  for (int i=0; i <= nslices; i++) {
    c1=cosBuff[i];
    s1=sinBuff[i];
    gl.glNormal3d(nscale * c1,nscale * s1,nscale * nz);
    setVertexColor(gl,color1,useHSV);
    gl.glVertex3d(top * c1,top * s1,h);
    setVertexColor(gl,color0,useHSV);
    gl.glVertex3d(base * c1,base * s1,0);
  }
  gl.glEnd();
  if (capped) {
    if (top > 0) {
      setVertexColor(gl,color1,useHSV);
      gl.glBegin(GL2.GL_POLYGON);
      gl.glNormal3d(0,0,1);
      for (int i=0; i < nslices; i++) {
        gl.glVertex3d(top * cosBuff[i],top * sinBuff[i],h);
      }
      gl.glEnd();
    }
    if (base > 0) {
      setVertexColor(gl,color0,useHSV);
      gl.glBegin(GL2.GL_POLYGON);
      gl.glNormal3d(0,0,-1);
      for (int i=nslices - 1; i >= 0; i--) {
        gl.glVertex3d(base * cosBuff[i],base * sinBuff[i],0);
      }
      gl.glEnd();
    }
  }
  gl.glPopMatrix();
}