code: public <T> void registerMethods(final Class<T> cls, String toStringMethodName, String fromStringMethodName) {
          if (cls == null) {
              throw new IllegalArgumentException("Class must not be null");
          }
          if (toStringMethodName == null || fromStringMethodName == null) {
              throw new IllegalArgumentException("Method names must not be null");
          }
          if (this == INSTANCE) {
              throw new IllegalStateException("Global singleton cannot be extended");
          }
          Method toString = findToStringMethod(cls, toStringMethodName);
          Method fromString = findFromStringMethod(cls, fromStringMethodName);
          MethodsStringConverter<T> converter = new MethodsStringConverter<T>(cls, toString, fromString, cls);
          registered.putIfAbsent(cls, converter);
      }
docs: Registers a converter for a specific type by method names.
  <p>
  This method allows the converter to be used when the target class cannot have annotations added.
  The two method names must obey the same rules as defined by the annotations
  {@link ToString} and {@link FromString}.
  The converter will be used for subclasses unless overidden.
  <p>
  No new converters may be registered for the global singleton.
  <p>
  For example, {@code convert.registerMethods(Distance.class, "toString", "parse");}
  
  @param <T>  the type of the converter
  @param cls  the class to register a converter for, not null
  @param toStringMethodName  the name of the method converting to a string, not null
  @param fromStringMethodName  the name of the method converting from a string, not null
  @throws IllegalArgumentException if the class or method name are null or invalid
  @throws IllegalStateException if trying to alter the global singleton