void IrreducibleDecomFacade::
printLabels(BigIdeal& bigIdeal, FILE* out, const string& format) {
  Ideal ideal(bigIdeal.getVarCount());
  TermTranslator translator(bigIdeal, ideal);

  Ideal idealCopy(ideal);
  Ideal decom(ideal.getVarCount());

  if (idealCopy.getGeneratorCount() > 0)
	translator.addArtinianPowers(idealCopy);

  computeIrreducibleDecom(idealCopy, new DecomRecorder(&decom));
  // idealCopy gets cleared here, which is why we make a copy.

  beginAction("Computing labels");

  IdealWriter* writer =
	IOHandler::getIOHandler(format)->createWriter(out, &translator);

  size_t varCount = decom.getVarCount();
  Ideal::const_iterator decomEnd = decom.end();
  for (Ideal::const_iterator d = decom.begin(); d != decomEnd; ++d) {
	Term de(*d, varCount);
	fputc('*', out);
	writer->writeJustATerm(de);
	fputc('\n', out);
	for (size_t var = 0; var < varCount; ++var)
	  if (de[var] == 0)
		de[var] = translator.getMaxId(var);

	vector<vector<const Exponent*> > labels(varCount + 1);
	Ideal::const_iterator end = ideal.end();
	for (Ideal::const_iterator it = ideal.begin(); it != end; ++it) {
	  if (de.dominates(*it)) {
		size_t equalVar = 0;
		size_t equalCount = 0;
		for (size_t var = 0; var < varCount; ++var) {
		  if (de[var] == (*it)[var]) {
			equalVar = var;
			++equalCount;
		  }
		}
		if (equalCount == 1)
		  labels[equalVar].push_back(*it);
		else
		  labels[varCount].push_back(*it);
	  }
	}

	for (size_t var = 0; var <= varCount; ++var) {
	  if (var == varCount && labels[var].empty())
		continue;

	  if (var < varCount)
		fprintf(out, " %s:", translator.getNames().getName(var).c_str());
	  else
		fputs(" other:", out);

	  if (var < varCount && de[var] == translator.getMaxId(var))
		fputs(" unbounded", out);

	  for (size_t i = 0; i < labels[var].size(); ++i) {
		if (i != 0)
		  fputc(',', out);
		writer->writeJustATerm(Term(labels[var][i], varCount));
	  }
	  fputc('\n', out);
	}
	fputc('\n', out);
  }

  endAction();
}
