class TikaConfigurationReader {

    public static TikaConfiguration readTikaConfiguration(Configuration configuration) {
        Optional<Boolean> enabled = Optional.ofNullable(
            configuration.getBoolean(TIKA_ENABLED, null));

        Optional<Boolean> cacheEnabled = Optional.ofNullable(
            configuration.getBoolean(TIKA_CACHE_ENABLED, null));

        Optional<String> host = Optional.ofNullable(
            configuration.getString(TIKA_HOST, null));

        Optional<Integer> port = Optional.ofNullable(
            configuration.getInteger(TIKA_PORT, null));

        Optional<Integer> timeoutInMillis = Optional.ofNullable(
            configuration.getInteger(TIKA_TIMEOUT_IN_MS, null));

        Optional<Duration> cacheEvictionPeriod = Optional.ofNullable(
            configuration.getString(TIKA_CACHE_EVICTION_PERIOD,
                null))
            .map(rawString -> DurationParser.parse(rawString, ChronoUnit.SECONDS));

        Optional<Long> cacheWeight = Optional.ofNullable(
            configuration.getString(TIKA_CACHE_WEIGHT_MAX, null))
            .map(Throwing.function(Size::parse))
            .map(Size::asBytes);

        Set<MimeType> contentTypeBlacklist = StreamUtils
            .ofNullable(configuration.getStringArray(TIKA_CONTENT_TYPE_BLACKLIST))
            .map(String::trim)
            .map(MimeType::of)
            .collect(ImmutableSet.toImmutableSet());

        return TikaConfiguration.builder()
            .enable(enabled)
            .host(host)
            .port(port)
            .timeoutInMillis(timeoutInMillis)
            .cacheEnable(cacheEnabled)
            .cacheEvictionPeriod(cacheEvictionPeriod)
            .cacheWeightInBytes(cacheWeight)
            .contentTypeBlacklist(contentTypeBlacklist)
            .build();
    }

}