/**
 * 
 */
package com.github.phantomthief.util;

import static com.google.common.base.Preconditions.checkNotNull;

import java.io.Serializable;
import java.util.function.Supplier;

/**
 * @author w.vela
 */
public class MoreSuppliers {

    public static <T> CloseableSupplier<T> lazy(Supplier<T> delegate) {
        if (delegate instanceof CloseableSupplier) {
            return (CloseableSupplier<T>) delegate;
        } else {
            return new CloseableSupplier<T>(checkNotNull(delegate));
        }
    }

    public static class CloseableSupplier<T> implements Supplier<T>, Serializable {

        private final Supplier<T> delegate;
        private volatile transient boolean initialized;
        private transient T value;
        private static final long serialVersionUID = 0L;

        private CloseableSupplier(Supplier<T> delegate) {
            this.delegate = delegate;
        }

        public T get() {
            if (!(this.initialized)) {
                synchronized (this) {
                    if (!(this.initialized)) {
                        T t = this.delegate.get();
                        this.value = t;
                        this.initialized = true;
                        return t;
                    }
                }
            }
            return this.value;
        }

        public boolean isInitialized() {
            return initialized;
        }

        public <X extends Throwable> void ifPresent(ThrowableConsumer<T, X> consumer) throws X {
            synchronized (this) {
                if (initialized && this.value != null) {
                    consumer.accept(this.value);
                }
            }
        }

        public <X extends Throwable> void tryClose(ThrowableConsumer<T, X> close) throws X {
            synchronized (this) {
                if (initialized && this.value != null) {
                    close.accept(value);
                    this.value = null;
                    initialized = false;
                }
            }
        }

        public String toString() {
            return "MoreSuppliers.lazy(" + this.delegate + ")";
        }
    }
}

@@ -113,36 +113,184 @@
 ll;%0A
-%0Aimport java.io.Serializable
+import static java.util.Optional.empty;%0Aimport static java.util.Optional.ofNullable;%0A%0Aimport java.io.Serializable;%0Aimport java.util.Optional;%0Aimport java.util.function.Function
 ;%0Aim
@@ -1820,32 +1820,399 @@
    %7D%0A        %7D%0A%0A
+        public %3CU%3E Optional%3CU%3E map(Function%3C? super T, ? extends U%3E mapper) %7B%0A            checkNotNull(mapper);%0A            synchronized (this) %7B%0A                if (initialized && this.value != null) %7B%0A                    return ofNullable(mapper.apply(value));%0A                %7D else %7B%0A                    return empty();%0A                %7D%0A            %7D%0A        %7D%0A%0A
         public %3C

add map for supplier.