// Path: src/main/java/cn/xdean/jex/lang/ExceptionUtil.java
// public class ExceptionUtil {
//   public static <T extends Throwable, R> R throwIt(T t) throws T {
//     throw t;
//   }
// 
//   @SuppressWarnings("unchecked")
//   public static <T extends Throwable, R> R throwAsUncheck(Throwable t) throws T {
//     throw (T) t;
//   }
// 
//   public static void uncheck(ActionE0<?> task) {
//     try {
//       task.call();
//     } catch (Exception t) {
//       throwAsUncheck(t);
//     }
//   }
// 
//   public static <T> T uncheck(FuncE0<T, ?> task) {
//     return supplierToRunnable(task, r -> uncheck(r));
//   }
// 
//   public static boolean uncatch(ActionE0<?> task) {
//     try {
//       task.call();
//       return true;
//     } catch (Exception t) {
//       LogFactory.from(ExceptionUtil.class).trace("Dont catch", t);
//       return false;
//     }
//   }
// 
//   /**
//    * @param task
//    * @return can be null
//    */
//   public static <T> T uncatch(FuncE0<T, ?> task) {
//     return supplierToRunnable(task, r -> uncatch(r));
//   }
// 
//   @SuppressWarnings("unchecked")
//   public static <E extends Exception> Optional<E> throwToReturn(ActionE0<E> task) {
//     try {
//       task.call();
//     } catch (Exception t) {
//       try {
//         return Optional.of((E) t);
//       } catch (ClassCastException cce) {
//         throw new RuntimeException("An unexcepted exception thrown.", t);
//       }
//     }
//     return Optional.empty();
//   }
// 
//   public static <T, E extends Exception> Either<T, E> throwToReturn(FuncE0<T, E> task) {
//     Wrapper<T> w = new Wrapper<>(null);
//     return Either.rightOrDefault(throwToReturn(() -> w.set(task.call())), w.get());
//   }
// 
//   public static String getStackTraceString(Throwable tr) {
//     if (tr == null) {
//       return "";
//     }
//     Throwable t = tr;
//     while (t.getCause() != null) {
//       t = t.getCause();
//     }
//     StringWriter sw = new StringWriter();
//     PrintWriter pw = new PrintWriter(sw);
//     t.printStackTrace(pw);
//     pw.flush();
//     return sw.toString();
//   }
// 
//   public static <E extends Exception> void wrapException(Function<Exception, E> wrapper, ActionE0<?> task)
//       throws E {
//     try {
//       task.call();
//     } catch (Exception e) {
//       throw wrapper.apply(e);
//     }
//   }
// 
//   public static <E extends Exception, T> T wrapException(Function<Exception, E> wrapper, FuncE0<T, ?> task)
//       throws E {
//     try {
//       return task.call();
//     } catch (Exception e) {
//       throw wrapper.apply(e);
//     }
//   }
// }
// 
// Path: src/main/java/cn/xdean/jex/lang/function/type/ActionE0.java
// @FunctionalInterface
// public interface ActionE0<E extends Exception> {
//   void call() throws E;
// }


import cn.xdean.jex.lang.ExceptionUtil;
import cn.xdean.jex.lang.function.type.ActionE0;
import org.junit.Assert;
import org.junit.Test;
import java.util.NoSuchElementException;
import static org.junit.Assert.*;
    Assert.assertEquals(left, Either.left(1));
    assertEquals("left(1)", left.toString());
  }

  @Test
  public void testRight() throws Exception {
    Either<Integer, Integer> right = Either.right(1);
    assertTrue(right.isRight());
    assertFalse(right.isLeft());
    assertEquals(1, right.getRight().intValue());
    assertThrow(NoSuchElementException.class, () -> right.getLeft());
    assertEquals(1, right.toRight(i -> 2).intValue());
    assertEquals(2, right.toLeft(i -> 2).intValue());
    assertTrue(right.asRight().isPresent());
    assertFalse(right.asLeft().isPresent());
    assertReach(() -> right.ifRight(l -> here()));
    assertNotReach(() -> right.ifLeft(l -> here()));
    assertReach(() -> right.exec(i -> fail(), i -> here()));
    assertEquals(2, right.mapRight(i -> 2).getRight().intValue());
    assertEquals(1, right.mapLeft(i -> 2).getRight().intValue());
    assertEquals(2, right.map(i -> fail(), i -> 2).getRight().intValue());
    Assert.assertEquals(2, right.flatMapRight(i -> Either.right(2)).getRight().intValue());
    assertEquals(1, right.flatMapLeft(i -> Either.right(2)).getRight().intValue());
    Assert.assertEquals(2, right.flatMap(i -> fail(), i -> Either.right(2)).getRight().intValue());
    assertEquals(2, right.unify(i -> 1, i -> 2).intValue());
    Assert.assertEquals(right, Either.right(1));
    assertEquals("right(1)", right.toString());
  }

  private static void assertThrow(Class<? extends Exception> ex, ActionE0<?> a) {
// Path: src/main/java/cn/xdean/jex/lang/ExceptionUtil.java
// public class ExceptionUtil {
//   public static <T extends Throwable, R> R throwIt(T t) throws T {
//     throw t;
//   }
// 
//   @SuppressWarnings("unchecked")
//   public static <T extends Throwable, R> R throwAsUncheck(Throwable t) throws T {
//     throw (T) t;
//   }
// 
//   public static void uncheck(ActionE0<?> task) {
//     try {
//       task.call();
//     } catch (Exception t) {
//       throwAsUncheck(t);
//     }
//   }
// 
//   public static <T> T uncheck(FuncE0<T, ?> task) {
//     return supplierToRunnable(task, r -> uncheck(r));
//   }
// 
//   public static boolean uncatch(ActionE0<?> task) {
//     try {
//       task.call();
//       return true;
//     } catch (Exception t) {
//       LogFactory.from(ExceptionUtil.class).trace("Dont catch", t);
//       return false;
//     }
//   }
// 
//   /**
//    * @param task
//    * @return can be null
//    */
//   public static <T> T uncatch(FuncE0<T, ?> task) {
//     return supplierToRunnable(task, r -> uncatch(r));
//   }
// 
//   @SuppressWarnings("unchecked")
//   public static <E extends Exception> Optional<E> throwToReturn(ActionE0<E> task) {
//     try {
//       task.call();
//     } catch (Exception t) {
//       try {
//         return Optional.of((E) t);
//       } catch (ClassCastException cce) {
//         throw new RuntimeException("An unexcepted exception thrown.", t);
//       }
//     }
//     return Optional.empty();
//   }
// 
//   public static <T, E extends Exception> Either<T, E> throwToReturn(FuncE0<T, E> task) {
//     Wrapper<T> w = new Wrapper<>(null);
//     return Either.rightOrDefault(throwToReturn(() -> w.set(task.call())), w.get());
//   }
// 
//   public static String getStackTraceString(Throwable tr) {
//     if (tr == null) {
//       return "";
//     }
//     Throwable t = tr;
//     while (t.getCause() != null) {
//       t = t.getCause();
//     }
//     StringWriter sw = new StringWriter();
//     PrintWriter pw = new PrintWriter(sw);
//     t.printStackTrace(pw);
//     pw.flush();
//     return sw.toString();
//   }
// 
//   public static <E extends Exception> void wrapException(Function<Exception, E> wrapper, ActionE0<?> task)
//       throws E {
//     try {
//       task.call();
//     } catch (Exception e) {
//       throw wrapper.apply(e);
//     }
//   }
// 
//   public static <E extends Exception, T> T wrapException(Function<Exception, E> wrapper, FuncE0<T, ?> task)
//       throws E {
//     try {
//       return task.call();
//     } catch (Exception e) {
//       throw wrapper.apply(e);
//     }
//   }
// }
// 
// Path: src/main/java/cn/xdean/jex/lang/function/type/ActionE0.java
// @FunctionalInterface
// public interface ActionE0<E extends Exception> {
//   void call() throws E;
// }


// Path: src/test/java/cn/xdean/jex/lang/collection/EitherTest.java
import cn.xdean.jex.lang.ExceptionUtil;
import cn.xdean.jex.lang.function.type.ActionE0;
import org.junit.Assert;
import org.junit.Test;
import java.util.NoSuchElementException;
import static org.junit.Assert.*;

    Assert.assertEquals(left, Either.left(1));
    assertEquals("left(1)", left.toString());
  }

  @Test
  public void testRight() throws Exception {
    Either<Integer, Integer> right = Either.right(1);
    assertTrue(right.isRight());
    assertFalse(right.isLeft());
    assertEquals(1, right.getRight().intValue());
    assertThrow(NoSuchElementException.class, () -> right.getLeft());
    assertEquals(1, right.toRight(i -> 2).intValue());
    assertEquals(2, right.toLeft(i -> 2).intValue());
    assertTrue(right.asRight().isPresent());
    assertFalse(right.asLeft().isPresent());
    assertReach(() -> right.ifRight(l -> here()));
    assertNotReach(() -> right.ifLeft(l -> here()));
    assertReach(() -> right.exec(i -> fail(), i -> here()));
    assertEquals(2, right.mapRight(i -> 2).getRight().intValue());
    assertEquals(1, right.mapLeft(i -> 2).getRight().intValue());
    assertEquals(2, right.map(i -> fail(), i -> 2).getRight().intValue());
    Assert.assertEquals(2, right.flatMapRight(i -> Either.right(2)).getRight().intValue());
    assertEquals(1, right.flatMapLeft(i -> Either.right(2)).getRight().intValue());
    Assert.assertEquals(2, right.flatMap(i -> fail(), i -> Either.right(2)).getRight().intValue());
    assertEquals(2, right.unify(i -> 1, i -> 2).intValue());
    Assert.assertEquals(right, Either.right(1));
    assertEquals("right(1)", right.toString());
  }

  private static void assertThrow(Class<? extends Exception> ex, ActionE0<?> a) {
    try {