/**
 * 
 */
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) {
        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 String toString() {
            return "MoreSuppliers.lazy(" + this.delegate + ")";
        }

        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;
                }
            }
        }
    }
}

@@ -296,32 +296,158 @@
 %3CT%3E delegate) %7B%0A
+        if (delegate instanceof CloseableSupplier) %7B%0A            return (CloseableSupplier%3CT%3E) delegate;%0A        %7D else %7B%0A    
         return n
@@ -495,16 +495,26 @@
 gate));%0A
+        %7D%0A
     %7D%0A%0A 
@@ -1335,23 +1335,29 @@
 lic 
-String toString
+boolean isInitialized
 () %7B
@@ -1380,52 +1380,300 @@
 urn 
-%22MoreSuppliers.lazy(%22 + this.delegate + %22)%22;
+initialized;%0A        %7D%0A%0A        public %3CX extends Throwable%3E void ifPresent(ThrowableConsumer%3CT, X%3E consumer) throws X %7B%0A            synchronized (this) %7B%0A                if (initialized && this.value != null) %7B%0A                    consumer.accept(this.value);%0A                %7D%0A            %7D
 %0A   
@@ -1995,32 +1995,32 @@
               %7D%0A
-
             %7D%0A  
@@ -2022,21 +2022,131 @@
  %7D%0A        %7D
+%0A%0A        public String toString() %7B%0A            return %22MoreSuppliers.lazy(%22 + this.delegate + %22)%22;%0A        %7D
 %0A    %7D%0A%7D%0A

add ifPresent