// Path: lib/src/main/java/com/mindbodyonline/ironhide/Infrastructure/Extensions/SwipeAction.java
// public class SwipeAction {
// 
//     /**
//      * Initial size is the number of combination of most used swipe speeds
//      *  (from {@link android.support.test.espresso.action.Swipe}) and the number of
//      *  {@link com.mindbodyonline.ironhide.Infrastructure.Extensions.SwipeAction.SwipeDirection}s
//      */
//     private static final HashMap<Pair<Swiper, SwipeDirection>, GeneralSwipeAction> bufferedSwipeActions
//             = new HashMap<>(SwipeDirection.values().length * Swipe.values().length);
//     
// 
//     /**
//      * Gets a swipe action.
//      *
//      * @param speed the speed of the swipe
//      * @param direction the direction of the swipe
//      * @return  the swipe action requested
//      */
//     public static GeneralSwipeAction getSwipe(Swiper speed, SwipeDirection direction) {
//         Pair<Swiper, SwipeDirection> key = new Pair<>(speed, direction);
// 
//         if (!bufferedSwipeActions.containsKey(key))
//             bufferedSwipeActions.put(key, generateSwipe(speed, direction));
// 
//         return bufferedSwipeActions.get(key);
//     }
// 
//     /**
//      * Creates a new swipe action.
//      *
//      * @param speed the speed of the swipe
//      * @param direction the direction of the swipe
//      * @return  the swipe action requested
//      */
//     private static GeneralSwipeAction generateSwipe(Swiper speed, SwipeDirection direction) {
//         return new GeneralSwipeAction(speed, direction.start, direction.end, Press.FINGER);
//     }
// 
//     /**
//      * An enum to associate directions with start and end locations on a screen.
//      */
//     public enum SwipeDirection {
//         UP      (BOTTOM_CENTER, TOP_CENTER),
//         DOWN    (TOP_CENTER, BOTTOM_CENTER),
//         LEFT    (CENTER_RIGHT, CENTER_LEFT),
//         RIGHT   (CENTER_LEFT, CENTER_RIGHT);
// 
//         public final CoordinatesProvider start, end;
// 
//         private SwipeDirection(CoordinatesProvider start, CoordinatesProvider end) {
//             this.start = start;
//             this.end = end;
//         }
//     }
// }
// 
// Path: lib/src/main/java/com/mindbodyonline/ironhide/PageObjects/PageObject.java
// public class PageObject {
// 
//     public static final int DEFAULT_PAUSE_TIME = 2000;
// 
//     /**
//      * Pause the test run for {@link PageObject#DEFAULT_PAUSE_TIME} milliseconds
//      * @return A generic of the passed in type
//      */
//     public <T extends PageObject> T pause(Class<T> type) {
//         return pause(type, DEFAULT_PAUSE_TIME);
//     }
// 
//     /**
//      * Pause the test run for a given amount of time(in milliseconds).
//      * @param timeInMillis Time, in milliseconds, to pause for.
//      * @return A generic of the passed in type.                     
//      */
//     public <T extends PageObject> T pause(Class<T> type, int timeInMillis) {
//         try {
//             Thread.sleep(timeInMillis);
//             return type.newInstance();
//         } catch (InstantiationException | IllegalAccessException | InterruptedException e) {
//             e.printStackTrace();
//         }
//         return null;
//     }
// }
// 
// Path: lib/src/main/java/com/mindbodyonline/ironhide/Infrastructure/Extensions/SwipeAction.java
// public static GeneralSwipeAction getSwipe(Swiper speed, SwipeDirection direction) {
//     Pair<Swiper, SwipeDirection> key = new Pair<>(speed, direction);
// 
//     if (!bufferedSwipeActions.containsKey(key))
//         bufferedSwipeActions.put(key, generateSwipe(speed, direction));
// 
//     return bufferedSwipeActions.get(key);
// }


import android.support.test.espresso.Root;
import android.support.test.espresso.ViewAction;
import android.support.test.espresso.action.Swiper;
import android.view.View;
import com.mindbodyonline.ironhide.Infrastructure.Extensions.SwipeAction;
import com.mindbodyonline.ironhide.PageObjects.PageObject;
import org.hamcrest.Matcher;
import static android.support.test.espresso.action.Swipe.FAST;
import static com.mindbodyonline.ironhide.Infrastructure.Extensions.SwipeAction.getSwipe;
package com.mindbodyonline.ironhide.Infrastructure.IronhideViews;





/**
 * Simple element that allows to perform a swipe on the screen.
 * Allows fast/slow versions of Espresso's swipes, as well as changing the number of swipes done in
 *  one function call.
 * Use this when the main purpose of the element will be to swipe the screen
 *
 * @param <T> The model the current element will return when interacted with
 */
public class Swipeable<T extends PageObject> extends BaseView<T> {

    public static final int DEFAULT_TIMES = 1;
    public static final Swiper DEFAULT_SPEED = FAST;

    /** @see BaseView#BaseView(Class, org.hamcrest.Matcher) */
    public Swipeable(Class<T> type, Matcher<View> selector) {
        super(type, selector);
    }

    /** @see BaseView#BaseView(Class, int) */
    public Swipeable(Class<T> type, int resourceId) {
        super(type, resourceId);
    }

    /** {@inheritDoc} */
    @Override
    public <E extends PageObject> Swipeable<E> goesTo(Class<E> type) {
        return new Swipeable<>(type, getSelector());
    }

    /**
     * {@link Swipeable#swipe(
     *  android.support.test.espresso.action.Swiper,
     *  com.mindbodyonline.ironhide.Infrastructure.Extensions.SwipeAction.SwipeDirection,
     *  int)}
     * with {@link Swipeable#DEFAULT_SPEED}
     * and {@link Swipeable#DEFAULT_TIMES}
     */
// Path: lib/src/main/java/com/mindbodyonline/ironhide/Infrastructure/Extensions/SwipeAction.java
// public class SwipeAction {
// 
//     /**
//      * Initial size is the number of combination of most used swipe speeds
//      *  (from {@link android.support.test.espresso.action.Swipe}) and the number of
//      *  {@link com.mindbodyonline.ironhide.Infrastructure.Extensions.SwipeAction.SwipeDirection}s
//      */
//     private static final HashMap<Pair<Swiper, SwipeDirection>, GeneralSwipeAction> bufferedSwipeActions
//             = new HashMap<>(SwipeDirection.values().length * Swipe.values().length);
//     
// 
//     /**
//      * Gets a swipe action.
//      *
//      * @param speed the speed of the swipe
//      * @param direction the direction of the swipe
//      * @return  the swipe action requested
//      */
//     public static GeneralSwipeAction getSwipe(Swiper speed, SwipeDirection direction) {
//         Pair<Swiper, SwipeDirection> key = new Pair<>(speed, direction);
// 
//         if (!bufferedSwipeActions.containsKey(key))
//             bufferedSwipeActions.put(key, generateSwipe(speed, direction));
// 
//         return bufferedSwipeActions.get(key);
//     }
// 
//     /**
//      * Creates a new swipe action.
//      *
//      * @param speed the speed of the swipe
//      * @param direction the direction of the swipe
//      * @return  the swipe action requested
//      */
//     private static GeneralSwipeAction generateSwipe(Swiper speed, SwipeDirection direction) {
//         return new GeneralSwipeAction(speed, direction.start, direction.end, Press.FINGER);
//     }
// 
//     /**
//      * An enum to associate directions with start and end locations on a screen.
//      */
//     public enum SwipeDirection {
//         UP      (BOTTOM_CENTER, TOP_CENTER),
//         DOWN    (TOP_CENTER, BOTTOM_CENTER),
//         LEFT    (CENTER_RIGHT, CENTER_LEFT),
//         RIGHT   (CENTER_LEFT, CENTER_RIGHT);
// 
//         public final CoordinatesProvider start, end;
// 
//         private SwipeDirection(CoordinatesProvider start, CoordinatesProvider end) {
//             this.start = start;
//             this.end = end;
//         }
//     }
// }
// 
// Path: lib/src/main/java/com/mindbodyonline/ironhide/PageObjects/PageObject.java
// public class PageObject {
// 
//     public static final int DEFAULT_PAUSE_TIME = 2000;
// 
//     /**
//      * Pause the test run for {@link PageObject#DEFAULT_PAUSE_TIME} milliseconds
//      * @return A generic of the passed in type
//      */
//     public <T extends PageObject> T pause(Class<T> type) {
//         return pause(type, DEFAULT_PAUSE_TIME);
//     }
// 
//     /**
//      * Pause the test run for a given amount of time(in milliseconds).
//      * @param timeInMillis Time, in milliseconds, to pause for.
//      * @return A generic of the passed in type.                     
//      */
//     public <T extends PageObject> T pause(Class<T> type, int timeInMillis) {
//         try {
//             Thread.sleep(timeInMillis);
//             return type.newInstance();
//         } catch (InstantiationException | IllegalAccessException | InterruptedException e) {
//             e.printStackTrace();
//         }
//         return null;
//     }
// }
// 
// Path: lib/src/main/java/com/mindbodyonline/ironhide/Infrastructure/Extensions/SwipeAction.java
// public static GeneralSwipeAction getSwipe(Swiper speed, SwipeDirection direction) {
//     Pair<Swiper, SwipeDirection> key = new Pair<>(speed, direction);
// 
//     if (!bufferedSwipeActions.containsKey(key))
//         bufferedSwipeActions.put(key, generateSwipe(speed, direction));
// 
//     return bufferedSwipeActions.get(key);
// }


// Path: lib/src/main/java/com/mindbodyonline/ironhide/Infrastructure/IronhideViews/Swipeable.java
import android.support.test.espresso.Root;
import android.support.test.espresso.ViewAction;
import android.support.test.espresso.action.Swiper;
import android.view.View;
import com.mindbodyonline.ironhide.Infrastructure.Extensions.SwipeAction;
import com.mindbodyonline.ironhide.PageObjects.PageObject;
import org.hamcrest.Matcher;
import static android.support.test.espresso.action.Swipe.FAST;
import static com.mindbodyonline.ironhide.Infrastructure.Extensions.SwipeAction.getSwipe;

package com.mindbodyonline.ironhide.Infrastructure.IronhideViews;





/**
 * Simple element that allows to perform a swipe on the screen.
 * Allows fast/slow versions of Espresso's swipes, as well as changing the number of swipes done in
 *  one function call.
 * Use this when the main purpose of the element will be to swipe the screen
 *
 * @param <T> The model the current element will return when interacted with
 */
public class Swipeable<T extends PageObject> extends BaseView<T> {

    public static final int DEFAULT_TIMES = 1;
    public static final Swiper DEFAULT_SPEED = FAST;

    /** @see BaseView#BaseView(Class, org.hamcrest.Matcher) */
    public Swipeable(Class<T> type, Matcher<View> selector) {
        super(type, selector);
    }

    /** @see BaseView#BaseView(Class, int) */
    public Swipeable(Class<T> type, int resourceId) {
        super(type, resourceId);
    }

    /** {@inheritDoc} */
    @Override
    public <E extends PageObject> Swipeable<E> goesTo(Class<E> type) {
        return new Swipeable<>(type, getSelector());
    }

    /**
     * {@link Swipeable#swipe(
     *  android.support.test.espresso.action.Swiper,
     *  com.mindbodyonline.ironhide.Infrastructure.Extensions.SwipeAction.SwipeDirection,
     *  int)}
     * with {@link Swipeable#DEFAULT_SPEED}
     * and {@link Swipeable#DEFAULT_TIMES}
     */
    public T swipe(SwipeAction.SwipeDirection direction) {