/**
  * @param clsInfo
  * @param referencee
  * @param toWrite
  * @return true if header already wrote object
  * @throws IOException
  */
 protected boolean writeObjectHeader(
     final FSTClazzInfo clsInfo, final FSTClazzInfo.FSTFieldInfo referencee, final Object toWrite)
     throws IOException {
   if (toWrite.getClass() == referencee.getType() && !clsInfo.useCompatibleMode()) {
     return codec.writeTag(TYPED, clsInfo, 0, toWrite);
   } else {
     final Class[] possibleClasses = referencee.getPossibleClasses();
     if (possibleClasses == null) {
       if (!codec.writeTag(OBJECT, clsInfo, 0, toWrite)) {
         codec.writeClass(clsInfo);
         return false;
       } else {
         return true;
       }
     } else {
       final int length = possibleClasses.length;
       for (int j = 0; j < length; j++) {
         final Class possibleClass = possibleClasses[j];
         if (possibleClass == toWrite.getClass()) {
           codec.writeFByte(j + 1);
           return false;
         }
       }
       if (!codec.writeTag(OBJECT, clsInfo, 0, toWrite)) {
         codec.writeClass(clsInfo);
         return false;
       } else {
         return true;
       }
     }
   }
 }
 // incoming array is already registered
 protected void writeArray(FSTClazzInfo.FSTFieldInfo referencee, Object array) throws IOException {
   if (array == null) {
     codec.writeClass(Object.class);
     codec.writeFInt(-1);
     return;
   }
   final int len = Array.getLength(array);
   Class<?> componentType = array.getClass().getComponentType();
   codec.writeClass(array.getClass());
   codec.writeFInt(len);
   if (!componentType.isArray()) {
     if (codec.isPrimitiveArray(array, componentType)) {
       codec.writePrimitiveArray(array, 0, len);
     } else { // objects
       Object arr[] = (Object[]) array;
       for (int i = 0; i < len; i++) {
         Object toWrite = arr[i];
         writeObjectWithContext(referencee, toWrite);
       }
     }
   } else { // multidim array. FIXME shared refs to subarrays are not tested !!!
     Object[] arr = (Object[]) array;
     FSTClazzInfo.FSTFieldInfo ref1 =
         new FSTClazzInfo.FSTFieldInfo(
             referencee.getPossibleClasses(),
             null,
             conf.getCLInfoRegistry().isIgnoreAnnotations());
     for (int i = 0; i < len; i++) {
       Object subArr = arr[i];
       boolean needsWrite = true;
       if (codec.isTagMultiDimSubArrays()) {
         if (subArr == null) {
           needsWrite = !codec.writeTag(NULL, null, 0, null);
         } else {
           needsWrite = !codec.writeTag(ARRAY, subArr, 0, subArr);
         }
       }
       if (needsWrite) writeArray(ref1, subArr);
     }
   }
 }