// Path: src/main/java/me/itzg/mccy/services/WebServerPortProvider.java
// public interface WebServerPortProvider {
//     int getPort();
// }
// 
// Path: src/main/java/me/itzg/mccy/types/FreemarkerVariable.java
// public class FreemarkerVariable {
//     private String name;
// 
//     private Object value;
// 
//     public FreemarkerVariable(String name, Object value) {
//         this.name = name;
//         this.value = value;
//     }
// 
//     public String getName() {
//         return name;
//     }
// 
//     public void setName(String name) {
//         this.name = name;
//     }
// 
//     public Object getValue() {
//         return value;
//     }
// 
//     public void setValue(Object value) {
//         this.value = value;
//     }
// }
// 
// Path: src/main/java/me/itzg/mccy/types/UUIDGenerator.java
// public interface UUIDGenerator {
//     UUID generate();
// }


import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import com.google.common.hash.HashFunction;
import com.google.common.hash.Hashing;
import me.itzg.mccy.services.WebServerPortProvider;
import me.itzg.mccy.types.FreemarkerVariable;
import me.itzg.mccy.types.UUIDGenerator;
import me.itzg.mccy.types.YamlMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.jackson.JacksonProperties;
import org.springframework.boot.context.embedded.EmbeddedWebApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.support.ConfigurableConversionService;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.core.env.Environment;
import org.springframework.core.io.Resource;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.scheduling.concurrent.ConcurrentTaskExecutor;
import org.springframework.scheduling.concurrent.CustomizableThreadFactory;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.URI;
import java.net.UnknownHostException;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;
import java.util.UUID;
import java.util.concurrent.Executors;
                return URI.create(s);
            }
        };
    }

    @Bean
    @Autowired
    public ConfigurableConversionService conversionService(Converter[] converters) {
        final ConfigurableConversionService ours = new DefaultConversionService();

        for (Converter converter : converters) {
            ours.addConverter(converter);
        }

        return ours;
    }

    @Bean
    public ConcurrentTaskExecutor remoteInvocationExecutor() {
        final CustomizableThreadFactory threadFactory = new CustomizableThreadFactory("remoteInv-");

        return new ConcurrentTaskExecutor(Executors.newCachedThreadPool(threadFactory));
    }

    @Bean
    public UUIDGenerator uuidGenerator() {
        return UUID::randomUUID;
    }

    @Bean
// Path: src/main/java/me/itzg/mccy/services/WebServerPortProvider.java
// public interface WebServerPortProvider {
//     int getPort();
// }
// 
// Path: src/main/java/me/itzg/mccy/types/FreemarkerVariable.java
// public class FreemarkerVariable {
//     private String name;
// 
//     private Object value;
// 
//     public FreemarkerVariable(String name, Object value) {
//         this.name = name;
//         this.value = value;
//     }
// 
//     public String getName() {
//         return name;
//     }
// 
//     public void setName(String name) {
//         this.name = name;
//     }
// 
//     public Object getValue() {
//         return value;
//     }
// 
//     public void setValue(Object value) {
//         this.value = value;
//     }
// }
// 
// Path: src/main/java/me/itzg/mccy/types/UUIDGenerator.java
// public interface UUIDGenerator {
//     UUID generate();
// }


// Path: src/main/java/me/itzg/mccy/config/GeneralConfig.java
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import com.google.common.hash.HashFunction;
import com.google.common.hash.Hashing;
import me.itzg.mccy.services.WebServerPortProvider;
import me.itzg.mccy.types.FreemarkerVariable;
import me.itzg.mccy.types.UUIDGenerator;
import me.itzg.mccy.types.YamlMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.jackson.JacksonProperties;
import org.springframework.boot.context.embedded.EmbeddedWebApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.support.ConfigurableConversionService;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.core.env.Environment;
import org.springframework.core.io.Resource;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.scheduling.concurrent.ConcurrentTaskExecutor;
import org.springframework.scheduling.concurrent.CustomizableThreadFactory;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.URI;
import java.net.UnknownHostException;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;
import java.util.UUID;
import java.util.concurrent.Executors;

                return URI.create(s);
            }
        };
    }

    @Bean
    @Autowired
    public ConfigurableConversionService conversionService(Converter[] converters) {
        final ConfigurableConversionService ours = new DefaultConversionService();

        for (Converter converter : converters) {
            ours.addConverter(converter);
        }

        return ours;
    }

    @Bean
    public ConcurrentTaskExecutor remoteInvocationExecutor() {
        final CustomizableThreadFactory threadFactory = new CustomizableThreadFactory("remoteInv-");

        return new ConcurrentTaskExecutor(Executors.newCachedThreadPool(threadFactory));
    }

    @Bean
    public UUIDGenerator uuidGenerator() {
        return UUID::randomUUID;
    }

    @Bean
    public FreemarkerVariable buildProperties(@Value("classpath:build.properties") Resource propsResource) throws IOException {