public interface Builder<T> {
    T build();
} public class ListBuilder<T> extends CollectionBuilder<T, List<T>> {
    public ListBuilder(List<T> collection, T... items) {
        super(collection, items);
    }
} public class MapBuilder<K,V> implements Builder<Map<K,V>> {
    private final Map<K,V> map;

    public MapBuilder(final Map<K, V> map, Map.Entry<K,V>... entries) {
        this.map = map;
        for (Map.Entry<K, V> entry : entries)
            map.put(entry.getKey(), entry.getValue());
    }

    @Override
    public Map<K, V> build() {
        return map;
    }
} public class MapEntryBuilder<K,V> implements Builder<Map.Entry<K,V>> {
    private final Map.Entry<K,V> entry;

    public MapEntryBuilder(final K key, final V value) {
        this.entry = new Entry<K, V>(key, value);
    }

    @Override
    public Map.Entry<K, V> build() {
        return entry;
    }

    class Entry<K,V> implements Map.Entry<K,V>{
        private final K key;
        private V value;

        Entry(final K key, final V value) {
            this.key = key;
            this.value = value;
        }

        @Override
        public K getKey() {
            return key;
        }

        @Override
        public V getValue() {
            return value;
        }

        @Override
        public V setValue(final V value) {
            return this.value = value;
        }
    }
} public class SetBuilder<T> extends CollectionBuilder<T, Set<T>> {
    public SetBuilder(Set<T> collection, T... items) {
        super(collection, items);
    }
} public class FileBuilder implements Builder<File> {
    private String resource;

    public FileBuilder withResource(String resource) {
        this.resource = resource;
        if (resource == null) {
            throw new NullPointerException("Resource may not be null.");
        }
        return this;
    }

    @Override
    public File build() {
        if (resource == null) {
            return new File("");
        }

        URL url = Thread.currentThread().getContextClassLoader().getResource(resource);
        if (url == null) {
            throw new BuilderException("Resource " + resource + " not found.");
        }

        try {
            return new File(url.toURI());
        } catch (URISyntaxException e) {
            throw new BuilderException("Resource " + resource + " not found.", e);
        }
    }
} public class PathBuilder implements Builder<Path> {
    private String resource;

    public PathBuilder withResource(String resource) {
        this.resource = resource;
        if (resource == null) {
            throw new NullPointerException("Resource may not be null.");
        }
        return this;
    }

    @Override
    public Path build() {
        if (resource == null) {
            return Paths.get("");
        }

        URL url = Thread.currentThread().getContextClassLoader().getResource(resource);
        if (url == null) {
            throw new BuilderException("Resource " + resource + " not found.");
        }

        try {
            return Paths.get(url.toURI());
        } catch (URISyntaxException e) {
            throw new BuilderException("Resource " + resource + " not found.", e);
        }
    }
} public class InputStreamBuilder implements Builder<InputStream> {

    private Builder<InputStream> concreteBuilder;

    public InputStreamBuilder() {
        concreteBuilder = new StringInputStreamBuilder();
    }

    public InputStreamBuilder withString(String content) {
        concreteBuilder = new StringInputStreamBuilder(content);
        return this;
    }

    public InputStreamBuilder withResource(String resource) {
        concreteBuilder = new ResourceInputStreamBuilder(resource);
        return this;
    }

    @Override
    public InputStream build() {
        return concreteBuilder.build();
    }
} public class ArrayBuilder<T> implements Builder<T[]> {
    private final T[] array;

    public ArrayBuilder(final T[] array) {
        this.array = array;
    }

    public ArrayBuilder<T> copy(){
        return new ArrayBuilder<T>(array.clone());
    }

    public T[] build() {
        return this.array;
    }
} public class DateBuilder implements Builder<Date> {
    private static final String DEFAULT_FORMAT_STRING = "yyyy-MM-dd HH:mm:ss";
    private static final String SHORT_FORMAT_STRING = "yyyy-MM-dd";

    private String string;
    private String formatString;
    private String timeZone = "UTC";
    private SimpleDateFormat format;

    public DateBuilder() {
        this.string = "2015-10-21 07:28:00";
    }

    public DateBuilder now() {
        this.string = null;
        return this;
    }

    public DateBuilder with(String string) {
        this.string = string;
        return this;
    }

    public DateBuilder withFormat(String format) {
        this.formatString = format;
        this.format = null;
        return this;
    }

    public DateBuilder withFormat(SimpleDateFormat format) {
        this.formatString = null;
        this.format = format;
        return this;
    }

    public DateBuilder withTimezone(String timeZone) {
        this.timeZone = timeZone;
        return this;
    }

    /**
     * Use withFormat() instead
     */
    @Deprecated
    public DateBuilder with(String string, String format) {
        return this.with(string).withFormat(format);
    }

    /**
     * Use withFormat() instead
     */
    @Deprecated
    public DateBuilder with(String string, SimpleDateFormat format) {
        return this.with(string).withFormat(format);
    }

    public Date build() {
        if (string == null) {
            return new Date();
        }

        if (formatString == null && string.length() <= SHORT_FORMAT_STRING.length() ) {
            formatString = SHORT_FORMAT_STRING;
        }

        try {
            return getFormat().parse(string);
        } catch (ParseException e) {
            throw new BuilderException("Failed to parse date from string.", e);
        }
    }

    private SimpleDateFormat getFormat() {
        if (format == null) {
            format = new SimpleDateFormat(formatString == null ? DEFAULT_FORMAT_STRING : formatString);
            format.setTimeZone(TimeZone.getTimeZone(timeZone));
        }
        return format;
    }
} public class LocalDateBuilder implements Builder<LocalDate> {

    private String string;

    public LocalDateBuilder() {
        this("2015-10-21");
    }

    public LocalDateBuilder(String string) {
        this.string = string;
    }

    @Override
    public LocalDate build() {
        try {
            return LocalDate.parse(string);
        } catch (Exception e) {
            throw new BuilderException("Failed to parse date from string.", e);
        }
    }
} public class LocalDateTimeBuilder implements Builder<LocalDateTime> {

    private static final String FORMAT = "yyyy-MM-dd HH:mm:ss";
    private static final String SHORT_FORMAT = "yyyy-MM-dd";

    private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern(FORMAT);

    private String string;

    public LocalDateTimeBuilder() {
        this("2015-10-21 07:28:00");
    }

    public LocalDateTimeBuilder(String string) {
        this.string = string;
    }

    @Override
    public LocalDateTime build() {
        try {
            return parse();
        } catch (Exception e) {
            throw new BuilderException("Failed to parse date from string.", e);
        }
    }

    private LocalDateTime parse() {
        if ( string.length() <= SHORT_FORMAT.length() ) {
            LocalDate localDate = a(localDate(string));
            return LocalDateTime.of(localDate.getYear(), localDate.getMonth(), localDate.getDayOfMonth(), 0, 0);
        }
        return LocalDateTime.parse(string, FORMATTER);
    }

} public class ZonedDateTimeBuilder implements Builder<ZonedDateTime> {

    private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss z");

    private String string;

    public ZonedDateTimeBuilder() {
        this("2015-10-21 07:28:00 Europe/Berlin");
    }

    public ZonedDateTimeBuilder(String string) {
        this.string = string;
    }

    @Override
    public ZonedDateTime build() {
        try {
            return ZonedDateTime.parse(string, FORMATTER);
        } catch (Exception e) {
            throw new BuilderException("Failed to parse date from string.", e);
        }
    }

}
import org.jusecase.builders.Builder;
import org.jusecase.builders.collections.ListBuilder;
import org.jusecase.builders.collections.MapBuilder;
import org.jusecase.builders.collections.MapEntryBuilder;
import org.jusecase.builders.collections.SetBuilder;
import org.jusecase.builders.io.FileBuilder;
import org.jusecase.builders.io.PathBuilder;
import org.jusecase.builders.streams.InputStreamBuilder;
import org.jusecase.builders.structures.ArrayBuilder;
import org.jusecase.builders.time.DateBuilder;
import org.jusecase.builders.time.LocalDateBuilder;
import org.jusecase.builders.time.LocalDateTimeBuilder;
import org.jusecase.builders.time.ZonedDateTimeBuilder;
import java.util.*;
package org.jusecase;



public class Builders {

    public static <T> T a(final Builder<T> builder) {
        return builder.build();
    }

    public static <T> T an(final Builder<T> builder) {
        return builder.build();
    }

    public static <T> T of(final T entity) {
        return entity;
    }

    @SafeVarargs
    public static <T> T[] of(final T... entities) {
        return entities;
    }

    @SafeVarargs
    public static <T> Builder<T[]> array(final T... items) {
        return new ArrayBuilder<T>(items);
    }

    @SafeVarargs
    public static <T> Builder<List<T>> list(final T... items) {
        return arrayList(items);
    }

    @SafeVarargs
    public static <T> Builder<List<T>> arrayList(final T... items) {
        return new ListBuilder<T>(new ArrayList<T>(), items);
    }

    @SafeVarargs
    public static <T> Builder<List<T>> linkedList(final T... items) {
        return new ListBuilder<T>(new LinkedList<T>(), items);
    }

    @SafeVarargs
    public static <T> Builder<Set<T>> set(final T... items) {
        return hashSet(items);
    }

    @SafeVarargs
    public static <T> Builder<Set<T>> hashSet(final T... items) {
        return new SetBuilder<T>(new HashSet<T>(), items);
    }

    @SafeVarargs
    public static <T> Builder<Set<T>> sortedSet(final T... items) {
        return new SetBuilder<T>(new TreeSet<T>(), items);
    }

    public static DateBuilder date() {
        return new DateBuilder();
    }

    public static DateBuilder date(String string) {
        return new DateBuilder().with(string);
    }

    public static LocalDateBuilder localDate() {
        return new LocalDateBuilder();
    }

    public static LocalDateBuilder localDate(String string) {
        return new LocalDateBuilder(string);
    }

    public static LocalDateTimeBuilder localDateTime() {
        return new LocalDateTimeBuilder();
    }

    public static LocalDateTimeBuilder localDateTime(String string) {
        return new LocalDateTimeBuilder(string);
    }

    public static ZonedDateTimeBuilder zonedDateTime() {
        return new ZonedDateTimeBuilder();
    }

    public static ZonedDateTimeBuilder zonedDateTime(String string) {
        return new ZonedDateTimeBuilder(string);
    }

    public static InputStreamBuilder inputStream() {
        return new InputStreamBuilder();
    }

    public static PathBuilder path() {
        return new PathBuilder();
    }

    public static FileBuilder file() {