// Path: src/main/java/com/plexobject/rx/util/Tuple.java
// public class Tuple implements Serializable, Iterable<Object>,
//         IntFunction<Object> {
//     private static final long serialVersionUID = 1L;
//     private final List<Object> objects = new ArrayList<>();
// 
//     @SuppressWarnings("unchecked")
//     public Tuple(Object... objs) {
//         Objects.requireNonNull(objs);
//         for (Object o : objs) {
//             if (o instanceof Collection) {
//                 Collection<Object> collection = (Collection<Object>) o;
//                 this.objects.addAll(collection);
//             } else if (o.getClass().isArray()) {
//                 Object[] arr = (Object[]) o;
//                 this.objects.addAll(Arrays.asList(arr));
//             } else if (o instanceof Tuple) {
//                 Tuple tuple = (Tuple) o;
//                 this.objects.addAll(tuple.objects);
//             } else {
//                 this.objects.add(o);
//             }
//         }
//     }
// 
//     @Override
//     public int hashCode() {
//         final int prime = 31;
//         int result = 1;
//         result = prime * result + ((objects == null) ? 0 : objects.hashCode());
//         return result;
//     }
// 
//     @Override
//     public boolean equals(Object obj) {
//         if (this == obj)
//             return true;
//         if (obj == null)
//             return false;
//         if (getClass() != obj.getClass())
//             return false;
//         Tuple other = (Tuple) obj;
//         if (objects == null) {
//             if (other.objects != null)
//                 return false;
//         } else if (!objects.equals(other.objects))
//             return false;
//         return true;
//     }
// 
//     public <T> T getFirst() {
//         return get(0);
//     }
// 
//     public <T> T getSecond() {
//         return get(1);
//     }
// 
//     public <T> T getThird() {
//         return get(1);
//     }
// 
//     public <T> T getLast() {
//         return get(objects.size() - 1);
//     }
// 
//     @SuppressWarnings("unchecked")
//     public <T> T get(int index) {
//         return (T) objects.get(index);
//     }
// 
//     @Override
//     public Iterator<Object> iterator() {
//         return objects.iterator();
//     }
// 
//     @Override
//     public Object apply(int index) {
//         return get(index);
//     }
// 
//     @Override
//     public String toString() {
//         return objects.toString();
//     }
// 
// }


import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.junit.Test;
import com.plexobject.rx.util.Tuple;
        assertNull(onError.get());
        assertEquals(1, onCompleted.get());
    }

    @Test
    public void testMergeToList() {
        List<Integer> list = Observable.from(1, 2).merge(Observable.from(3, 4))
                .toList();

        assertEquals(new Integer(1), list.get(0));
        assertEquals(new Integer(2), list.get(1));
        assertEquals(new Integer(3), list.get(2));
        assertEquals(new Integer(4), list.get(3));
    }

    @Test
    public void testMergeToSet() {
        Set<Integer> set = Observable.from(1, 2).merge(Observable.from(3, 4))
                .merge(Observable.just(3)).toSet();
        assertEquals(4, set.size());
        assertTrue(set.contains(1));
        assertTrue(set.contains(2));
        assertTrue(set.contains(3));
        assertTrue(set.contains(4));
    }

    @Test
    public void testSubscribeZip() throws Exception {
        Observable<String> observable1 = Observable.from("One", "Two", "Three");
        Observable<Integer> observable2 = Observable.from(1, 2, 3);
// Path: src/main/java/com/plexobject/rx/util/Tuple.java
// public class Tuple implements Serializable, Iterable<Object>,
//         IntFunction<Object> {
//     private static final long serialVersionUID = 1L;
//     private final List<Object> objects = new ArrayList<>();
// 
//     @SuppressWarnings("unchecked")
//     public Tuple(Object... objs) {
//         Objects.requireNonNull(objs);
//         for (Object o : objs) {
//             if (o instanceof Collection) {
//                 Collection<Object> collection = (Collection<Object>) o;
//                 this.objects.addAll(collection);
//             } else if (o.getClass().isArray()) {
//                 Object[] arr = (Object[]) o;
//                 this.objects.addAll(Arrays.asList(arr));
//             } else if (o instanceof Tuple) {
//                 Tuple tuple = (Tuple) o;
//                 this.objects.addAll(tuple.objects);
//             } else {
//                 this.objects.add(o);
//             }
//         }
//     }
// 
//     @Override
//     public int hashCode() {
//         final int prime = 31;
//         int result = 1;
//         result = prime * result + ((objects == null) ? 0 : objects.hashCode());
//         return result;
//     }
// 
//     @Override
//     public boolean equals(Object obj) {
//         if (this == obj)
//             return true;
//         if (obj == null)
//             return false;
//         if (getClass() != obj.getClass())
//             return false;
//         Tuple other = (Tuple) obj;
//         if (objects == null) {
//             if (other.objects != null)
//                 return false;
//         } else if (!objects.equals(other.objects))
//             return false;
//         return true;
//     }
// 
//     public <T> T getFirst() {
//         return get(0);
//     }
// 
//     public <T> T getSecond() {
//         return get(1);
//     }
// 
//     public <T> T getThird() {
//         return get(1);
//     }
// 
//     public <T> T getLast() {
//         return get(objects.size() - 1);
//     }
// 
//     @SuppressWarnings("unchecked")
//     public <T> T get(int index) {
//         return (T) objects.get(index);
//     }
// 
//     @Override
//     public Iterator<Object> iterator() {
//         return objects.iterator();
//     }
// 
//     @Override
//     public Object apply(int index) {
//         return get(index);
//     }
// 
//     @Override
//     public String toString() {
//         return objects.toString();
//     }
// 
// }


// Path: src/test/java/com/plexobject/rx/ObservableMergeZipTest.java
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.junit.Test;
import com.plexobject.rx.util.Tuple;

        assertNull(onError.get());
        assertEquals(1, onCompleted.get());
    }

    @Test
    public void testMergeToList() {
        List<Integer> list = Observable.from(1, 2).merge(Observable.from(3, 4))
                .toList();

        assertEquals(new Integer(1), list.get(0));
        assertEquals(new Integer(2), list.get(1));
        assertEquals(new Integer(3), list.get(2));
        assertEquals(new Integer(4), list.get(3));
    }

    @Test
    public void testMergeToSet() {
        Set<Integer> set = Observable.from(1, 2).merge(Observable.from(3, 4))
                .merge(Observable.just(3)).toSet();
        assertEquals(4, set.size());
        assertTrue(set.contains(1));
        assertTrue(set.contains(2));
        assertTrue(set.contains(3));
        assertTrue(set.contains(4));
    }

    @Test
    public void testSubscribeZip() throws Exception {
        Observable<String> observable1 = Observable.from("One", "Two", "Three");
        Observable<Integer> observable2 = Observable.from(1, 2, 3);
        List<Tuple> expectedTuples = Arrays.asList(new Tuple("One", 1),