/**
  * Convert an object to the desired type. Throws an exception if conversion could not take place
  * for any reason.
  *
  * @param <T> The desired return type.
  * @param obj The object that is to be converted.
  * @param returnType The desired return type.
  * @return The converted object.
  * @throws ConversionException
  */
 public <T> T convert(Object obj, Class<T> returnType) throws ConversionException {
   checkNotNull(obj);
   checkNotNull(returnType);
   // Look for a weak converter first, return if succesful.
   for (DataConversionOverride converter : getWeakConverters()) {
     T returnObject = converter.convert(obj, returnType);
     if (returnObject != null) {
       return returnObject;
     }
   }
   // Return is object can be cast to desired type.
   if (returnType.isAssignableFrom(obj.getClass())) {
     return (T) obj; // Safe cast ensured
   } else {
     // Look for a regular DataConverter and convert if found.
     DataConverter<T> dataConverter = getConverter(returnType);
     if (dataConverter != null) {
       return dataConverter.convert(obj);
     } else {
       // Look if a converter is registered for any of the return type's
       // super types, otherwise throw an exception.
       SuperTypeDataConverter<? super T> superTypeConverter = getSuperConverter(returnType);
       if (superTypeConverter != null) {
         return superTypeConverter.convert(obj, returnType);
       } else {
         throw new ConversionException(
             "Did not find any Converter for class: " + returnType.getName());
       }
     }
   }
 }
 public <T> boolean registerConverter(DataConverter<T> converter) {
   Class<T> clazz = converter.getReturnType();
   if (!converters.containsKey(clazz)) {
     converters.put(clazz, converter);
     return true;
   } else {
     return false;
   }
 }