public void setModelContext(InstancesHeader ih) {
   if ((ih != null) && (ih.classIndex() < 0)) {
     throw new IllegalArgumentException("Context for a classifier must include a class to learn");
   }
   if (trainingHasStarted()
       && (this.modelContext != null)
       && ((ih == null) || !contextIsCompatible(this.modelContext, ih))) {
     throw new IllegalArgumentException("New context is not compatible with existing model");
   }
   this.modelContext = ih;
 }
 // originalContext notnull
 // newContext notnull
 public static boolean contextIsCompatible(
     InstancesHeader originalContext, InstancesHeader newContext) {
   // rule 1: num classes can increase but never decrease
   // rule 2: num attributes can increase but never decrease
   // rule 3: num nominal attribute values can increase but never decrease
   // rule 4: attribute types must stay in the same order (although class
   // can
   // move; is always skipped over)
   // attribute names are free to change, but should always still represent
   // the original attributes
   if (newContext.numClasses() < originalContext.numClasses()) {
     return false; // rule 1
   }
   if (newContext.numAttributes() < originalContext.numAttributes()) {
     return false; // rule 2
   }
   int oPos = 0;
   int nPos = 0;
   while (oPos < originalContext.numAttributes()) {
     if (oPos == originalContext.classIndex()) {
       oPos++;
       if (!(oPos < originalContext.numAttributes())) {
         break;
       }
     }
     if (nPos == newContext.classIndex()) {
       nPos++;
     }
     if (originalContext.attribute(oPos).isNominal()) {
       if (!newContext.attribute(nPos).isNominal()) {
         return false; // rule 4
       }
       if (newContext.attribute(nPos).numValues() < originalContext.attribute(oPos).numValues()) {
         return false; // rule 3
       }
     } else {
       assert (originalContext.attribute(oPos).isNumeric());
       if (!newContext.attribute(nPos).isNumeric()) {
         return false; // rule 4
       }
     }
     oPos++;
     nPos++;
   }
   return true; // all checks clear
 }
 public String getNominalValueString(int attIndex, int valIndex) {
   return InstancesHeader.getNominalValueString(this.modelContext, attIndex, valIndex);
 }
 public String getAttributeNameString(int attIndex) {
   return InstancesHeader.getAttributeNameString(this.modelContext, attIndex);
 }
 public String getClassLabelString(int classLabelIndex) {
   return InstancesHeader.getClassLabelString(this.modelContext, classLabelIndex);
 }
 public String getClassNameString() {
   return InstancesHeader.getClassNameString(this.modelContext);
 }