code: @Override
      public <T> ParamConverter<T> getConverter(final Class<T> rawType, final Type genericType, final Annotation[] annotations) {
          if (Optional.class.equals(rawType)) {
              final List<ClassTypePair> ctps = ReflectionHelper.getTypeArgumentAndClass(genericType);
              final ClassTypePair ctp = (ctps.size() == 1) ? ctps.get(0) : null;
  
              if (ctp == null || ctp.rawClass() == String.class) {
                  return new ParamConverter<T>() {
                      @Override
                      public T fromString(final String value) {
                          return rawType.cast(Optional.ofNullable(value));
                      }
  
                      @Override
                      public String toString(final T value) {
                          return value.toString();
                      }
                  };
              }
  
              final Set<ParamConverterProvider> converterProviders = Providers.getProviders(locator, ParamConverterProvider.class);
              for (ParamConverterProvider provider : converterProviders) {
                  final ParamConverter<?> converter = provider.getConverter(ctp.rawClass(), ctp.type(), annotations);
                  if (converter != null) {
                      return new ParamConverter<T>() {
                          @Override
                          public T fromString(final String value) {
                              return rawType.cast(Optional.ofNullable(value).map(s -> converter.fromString(value)));
                          }
  
                          @Override
                          public String toString(final T value) {
                              return value.toString();
                          }
                      };
                  }
              }
          }
  
          return null;
      }
docs: {@inheritDoc}