package com.aol.cyclops.closures;

import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;
import java.util.function.Supplier;
import java.util.stream.Stream;

/**
 * Interface that represents a single value that can be converted into a List, Stream or Optional
 * 
 * @author johnmcclean
 *
 * @param <T>
 */
public interface Convertable<T> extends Iterable<T>{

	public T get();
	default Optional<T> toOptional(){
		return Optional.ofNullable(get());
	}
	
	default Stream<T> toStream(){
		return Stream.of(get()).filter(v->v!=null);
	}
	
	/**Get the contained value or else the provided alternative
	 * 
	 * @param value
	 * @return
	 */
	default T orElse(T value){
		return toOptional().orElse(value);
	}
	
	/**
	 * Get the contained value or throw an exception if null
	 * 
	 * @param ex
	 * @return
	 * @throws X
	 */
	default <X extends Throwable> T getOrElseThrow(Supplier<? extends X> ex) throws X{
		return toOptional().orElseThrow(ex);
	}
	
	default List<T> toList(){
		return Arrays.asList(get());
	}
	
	default Iterator<T> iterator(){
		return toList().iterator();
	}
}

@@ -130,16 +130,68 @@
 tional;%0A
+import java.util.concurrent.atomic.AtomicReference;%0A
 import j
@@ -627,24 +627,245 @@
 null);%0A%09%7D%0A%09%0A
+%09default AtomicReference%3CT%3E toAtomicReference()%7B%0A%09%09return new AtomicReference%3CT%3E(get());%0A%09%7D%0A%09default Optional%3CAtomicReference%3CT%3E%3E toOptionalAtomicReference()%7B%0A%09%09return toOptional().map(u-%3Enew AtomicReference%3CT%3E(u));%0A%09%7D%0A%09%0A
 %09/**Get the 

Convertable to AtomicReference