docs: protected void writeObject(String key, Object object, CharBuf buffer) {
  
          if (isExcludingValues(object)) {
              return;
          }
  
          if (object == null) {
              buffer.addNull();
              return;
          }
  
          Class<?> objectClass = object.getClass();
  
          Converter converter = findConverter(objectClass);
          if (converter != null) {
              object = converter.convert(object, key);
              objectClass = object.getClass();
          }
  
          if (CharSequence.class.isAssignableFrom(objectClass)) { // Handle String, StringBuilder, GString and other CharSequence implementations
              writeCharSequence((CharSequence) object, buffer);
          } else if (objectClass == Boolean.class) {
              buffer.addBoolean((Boolean) object);
          } else if (Number.class.isAssignableFrom(objectClass)) {
              writeNumber(objectClass, (Number) object, buffer);
          } else if (Date.class.isAssignableFrom(objectClass)) {
              writeDate((Date) object, buffer);
          } else if (Calendar.class.isAssignableFrom(objectClass)) {
              writeDate(((Calendar) object).getTime(), buffer);
          } else if (Map.class.isAssignableFrom(objectClass)) {
              writeMap((Map) object, buffer);
          } else if (Iterable.class.isAssignableFrom(objectClass)) {
              writeIterator(((Iterable<?>) object).iterator(), buffer);
          } else if (Iterator.class.isAssignableFrom(objectClass)) {
              writeIterator((Iterator) object, buffer);
          } else if (objectClass == Character.class) {
              buffer.addJsonEscapedString(Chr.array((Character) object), disableUnicodeEscaping);
          } else if (objectClass == URL.class) {
              buffer.addJsonEscapedString(object.toString(), disableUnicodeEscaping);
          } else if (objectClass == UUID.class) {
              buffer.addQuoted(object.toString());
          } else if (objectClass == JsonOutput.JsonUnescaped.class) {
              buffer.add(object.toString());
          } else if (Closure.class.isAssignableFrom(objectClass)) {
              writeMap(JsonDelegate.cloneDelegateAndGetContent((Closure<?>) object), buffer);
          } else if (Expando.class.isAssignableFrom(objectClass)) {
              writeMap(((Expando) object).getProperties(), buffer);
          } else if (Enumeration.class.isAssignableFrom(objectClass)) {
              List<?> list = Collections.list((Enumeration<?>) object);
              writeIterator(list.iterator(), buffer);
          } else if (objectClass.isArray()) {
              writeArray(objectClass, object, buffer);
          } else if (Enum.class.isAssignableFrom(objectClass)) {
              buffer.addQuoted(((Enum<?>) object).name());
          } else if (File.class.isAssignableFrom(objectClass)) {
              Map<?, ?> properties = getObjectProperties(object);
              //Clean up all recursive references to File objects
              Iterator<? extends Map.Entry<?, ?>> iterator = properties.entrySet().iterator();
              while(iterator.hasNext()) {
                  Map.Entry<?,?> entry = iterator.next();
                  if(entry.getValue() instanceof File) {
                      iterator.remove();
                  }
              }
              writeMap(properties, buffer);
          } else {
              Map<?, ?> properties = getObjectProperties(object);
              writeMap(properties, buffer);
          }
      }