private void checkVariance(
     boolean covariant,
     boolean contravariant,
     Declaration declaration,
     List<TypeParameter> errors) {
   // TODO: fix this to allow reporting multiple errors!
   if (getDeclaration() instanceof TypeParameter) {
     TypeParameter tp = (TypeParameter) getDeclaration();
     boolean ok =
         tp.getDeclaration().equals(declaration)
             || ((covariant || !tp.isCovariant()) && (contravariant || !tp.isContravariant()));
     if (!ok) {
       // a covariant type parameter appears in a contravariant location, or
       // a contravariant type parameter appears in a covariant location.
       errors.add(tp);
     }
   } else if (getDeclaration() instanceof UnionType) {
     for (ProducedType ct : getCaseTypes()) {
       ct.checkVariance(covariant, contravariant, declaration, errors);
     }
   } else if (getDeclaration() instanceof IntersectionType) {
     for (ProducedType ct : getSatisfiedTypes()) {
       ct.checkVariance(covariant, contravariant, declaration, errors);
     }
   } else {
     for (TypeParameter tp : getDeclaration().getTypeParameters()) {
       ProducedType pt = getTypeArguments().get(tp);
       if (pt != null) {
         if (tp.isCovariant()) {
           pt.checkVariance(covariant, contravariant, declaration, errors);
         } else if (tp.isContravariant()) {
           if (covariant | contravariant) {
             pt.checkVariance(!covariant, !contravariant, declaration, errors);
           } else {
             // else if we are in a nonvariant position, it stays nonvariant
             pt.checkVariance(covariant, contravariant, declaration, errors);
           }
         } else {
           pt.checkVariance(false, false, declaration, errors);
         }
       }
     }
   }
 }
 /**
  * Check that this type can appear at a position, given the variance of the position (covariant,
  * contravariant, or invariant.)
  *
  * @param covariant true for a covariant position
  * @param contravariant true for a contravariant position
  * @param declaration TODO!
  * @return a list of type parameters which appear in illegal positions
  */
 public List<TypeParameter> checkVariance(
     boolean covariant, boolean contravariant, Declaration declaration) {
   List<TypeParameter> errors = new ArrayList<TypeParameter>();
   checkVariance(covariant, contravariant, declaration, errors);
   return errors;
 }