// Path: lib-core/src/main/java/com/nhaarman/listviewanimations/util/AdapterViewUtil.java
// public class AdapterViewUtil {
// 
//     private AdapterViewUtil() {
//     }
// 
//     /**
//      * Returns the position within the adapter's dataset for the view, where view is an adapter item or a descendant of an adapter item.
//      * Unlike {@link AdapterView#getPositionForView(android.view.View)}, returned position will reflect the position of the item given view is representing,
//      * by subtracting the header views count.
//      *
//      * @param listViewWrapper the IListViewWrapper wrapping the ListView containing the view.
//      * @param view            an adapter item or a descendant of an adapter item. This must be visible in given AdapterView at the time of the call.
//      *
//      * @return the position of the item in the AdapterView represented by given view, or {@link AdapterView#INVALID_POSITION} if the view does not
//      * correspond to a list item (or it is not visible).
//      */
//     public static int getPositionForView(@NonNull final ListViewWrapper listViewWrapper, @NonNull final View view) {
//         return listViewWrapper.getPositionForView(view) - listViewWrapper.getHeaderViewsCount();
//     }
// 
//     /**
//      * Returns the position within the adapter's dataset for the view, where view is an adapter item or a descendant of an adapter item.
//      * Unlike {@link AdapterView#getPositionForView(android.view.View)}, returned position will reflect the position of the item given view is representing,
//      * by subtracting the header views count.
//      *
//      * @param absListView the ListView containing the view.
//      * @param view        an adapter item or a descendant of an adapter item. This must be visible in given AdapterView at the time of the call.
//      *
//      * @return the position of the item in the AdapterView represented by given view, or {@link AdapterView#INVALID_POSITION} if the view does not
//      * correspond to a list item (or it is not visible).
//      */
//     public static int getPositionForView(@NonNull final AbsListView absListView, @NonNull final View view) {
//         int position = absListView.getPositionForView(view);
//         if (absListView instanceof ListView) {
//             position -= ((ListView) absListView).getHeaderViewsCount();
//         }
//         return position;
//     }
// 
//     /**
//      * Returns the {@link View} that represents the item for given position.
//      *
//      * @param listViewWrapper the {@link ListViewWrapper} wrapping the ListView that should be examined
//      * @param position        the position for which the {@code View} should be returned.
//      *
//      * @return the {@code View}, or {@code null} if the position is not currently visible.
//      */
//     @Nullable
//     public static View getViewForPosition(@NonNull final ListViewWrapper listViewWrapper, final int position) {
//         int childCount = listViewWrapper.getChildCount();
//         View downView = null;
//         for (int i = 0; i < childCount && downView == null; i++) {
//             View child = listViewWrapper.getChildAt(i);
//             if (child != null && getPositionForView(listViewWrapper, child) == position) {
//                 downView = child;
//             }
//         }
//         return downView;
//     }
// 
//     /**
//      * Returns the {@link View} that represents the item for given position.
//      *
//      * @param absListView the ListView that should be examined
//      * @param position    the position for which the {@code View} should be returned.
//      *
//      * @return the {@code View}, or {@code null} if the position is not currently visible.
//      */
//     @Nullable
//     public static View getViewForPosition(@NonNull final AbsListView absListView, final int position) {
//         int childCount = absListView.getChildCount();
//         View downView = null;
//         for (int i = 0; i < childCount && downView == null; i++) {
//             View child = absListView.getChildAt(i);
//             if (child != null && getPositionForView(absListView, child) == position) {
//                 downView = child;
//             }
//         }
//         return downView;
//     }
// }
// 
// Path: lib-core/src/main/java/com/nhaarman/listviewanimations/util/ListViewWrapper.java
// public interface ListViewWrapper {
// 
//     @NonNull
//     ViewGroup getListView();
// 
//     @Nullable
//     View getChildAt(int index);
// 
//     int getFirstVisiblePosition();
// 
//     int getLastVisiblePosition();
// 
//     int getCount();
// 
//     int getChildCount();
// 
//     int getHeaderViewsCount();
// 
//     int getPositionForView(@NonNull View view);
// 
//     @Nullable
//     ListAdapter getAdapter();
// 
//     void smoothScrollBy(int distance, int duration);
// }


import java.util.List;
import java.util.Map;
import android.support.annotation.NonNull;
import android.view.View;
import android.view.ViewGroup;
import com.nhaarman.listviewanimations.itemmanipulation.swipedismiss.SwipeDismissTouchListener;
import com.nhaarman.listviewanimations.util.AdapterViewUtil;
import com.nhaarman.listviewanimations.util.ListViewWrapper;
import com.nineoldandroids.animation.Animator;
import com.nineoldandroids.animation.AnimatorListenerAdapter;
import com.nineoldandroids.animation.AnimatorSet;
import com.nineoldandroids.animation.ObjectAnimator;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
            restoreViewPresentations(mDismissedViews);
            notifyCallback(mDismissedPositions);

            Collection<Integer> newUndoPositions = Util.processDeletions(mUndoPositions, mDismissedPositions);
            mUndoPositions.clear();
            mUndoPositions.addAll(newUndoPositions);

            mDismissedViews.clear();
            mDismissedPositions.clear();
        }
    }

    /**
     * Restores the height of given {@code View}.
     * Also calls its super implementation.
     */
    @Override
    protected void restoreViewPresentation(@NonNull final View view) {
        super.restoreViewPresentation(view);
        ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
        layoutParams.height = 0;
        view.setLayoutParams(layoutParams);
    }

    /**
     * Performs the undo animation and restores the original state for given {@link android.view.View}.
     *
     * @param view the parent {@code View} which contains both primary and undo {@code View}s.
     */
    public void undo(@NonNull final View view) {
// Path: lib-core/src/main/java/com/nhaarman/listviewanimations/util/AdapterViewUtil.java
// public class AdapterViewUtil {
// 
//     private AdapterViewUtil() {
//     }
// 
//     /**
//      * Returns the position within the adapter's dataset for the view, where view is an adapter item or a descendant of an adapter item.
//      * Unlike {@link AdapterView#getPositionForView(android.view.View)}, returned position will reflect the position of the item given view is representing,
//      * by subtracting the header views count.
//      *
//      * @param listViewWrapper the IListViewWrapper wrapping the ListView containing the view.
//      * @param view            an adapter item or a descendant of an adapter item. This must be visible in given AdapterView at the time of the call.
//      *
//      * @return the position of the item in the AdapterView represented by given view, or {@link AdapterView#INVALID_POSITION} if the view does not
//      * correspond to a list item (or it is not visible).
//      */
//     public static int getPositionForView(@NonNull final ListViewWrapper listViewWrapper, @NonNull final View view) {
//         return listViewWrapper.getPositionForView(view) - listViewWrapper.getHeaderViewsCount();
//     }
// 
//     /**
//      * Returns the position within the adapter's dataset for the view, where view is an adapter item or a descendant of an adapter item.
//      * Unlike {@link AdapterView#getPositionForView(android.view.View)}, returned position will reflect the position of the item given view is representing,
//      * by subtracting the header views count.
//      *
//      * @param absListView the ListView containing the view.
//      * @param view        an adapter item or a descendant of an adapter item. This must be visible in given AdapterView at the time of the call.
//      *
//      * @return the position of the item in the AdapterView represented by given view, or {@link AdapterView#INVALID_POSITION} if the view does not
//      * correspond to a list item (or it is not visible).
//      */
//     public static int getPositionForView(@NonNull final AbsListView absListView, @NonNull final View view) {
//         int position = absListView.getPositionForView(view);
//         if (absListView instanceof ListView) {
//             position -= ((ListView) absListView).getHeaderViewsCount();
//         }
//         return position;
//     }
// 
//     /**
//      * Returns the {@link View} that represents the item for given position.
//      *
//      * @param listViewWrapper the {@link ListViewWrapper} wrapping the ListView that should be examined
//      * @param position        the position for which the {@code View} should be returned.
//      *
//      * @return the {@code View}, or {@code null} if the position is not currently visible.
//      */
//     @Nullable
//     public static View getViewForPosition(@NonNull final ListViewWrapper listViewWrapper, final int position) {
//         int childCount = listViewWrapper.getChildCount();
//         View downView = null;
//         for (int i = 0; i < childCount && downView == null; i++) {
//             View child = listViewWrapper.getChildAt(i);
//             if (child != null && getPositionForView(listViewWrapper, child) == position) {
//                 downView = child;
//             }
//         }
//         return downView;
//     }
// 
//     /**
//      * Returns the {@link View} that represents the item for given position.
//      *
//      * @param absListView the ListView that should be examined
//      * @param position    the position for which the {@code View} should be returned.
//      *
//      * @return the {@code View}, or {@code null} if the position is not currently visible.
//      */
//     @Nullable
//     public static View getViewForPosition(@NonNull final AbsListView absListView, final int position) {
//         int childCount = absListView.getChildCount();
//         View downView = null;
//         for (int i = 0; i < childCount && downView == null; i++) {
//             View child = absListView.getChildAt(i);
//             if (child != null && getPositionForView(absListView, child) == position) {
//                 downView = child;
//             }
//         }
//         return downView;
//     }
// }
// 
// Path: lib-core/src/main/java/com/nhaarman/listviewanimations/util/ListViewWrapper.java
// public interface ListViewWrapper {
// 
//     @NonNull
//     ViewGroup getListView();
// 
//     @Nullable
//     View getChildAt(int index);
// 
//     int getFirstVisiblePosition();
// 
//     int getLastVisiblePosition();
// 
//     int getCount();
// 
//     int getChildCount();
// 
//     int getHeaderViewsCount();
// 
//     int getPositionForView(@NonNull View view);
// 
//     @Nullable
//     ListAdapter getAdapter();
// 
//     void smoothScrollBy(int distance, int duration);
// }


// Path: lib-manipulation/src/main/java/com/nhaarman/listviewanimations/itemmanipulation/swipedismiss/undo/SwipeUndoTouchListener.java
import java.util.List;
import java.util.Map;
import android.support.annotation.NonNull;
import android.view.View;
import android.view.ViewGroup;
import com.nhaarman.listviewanimations.itemmanipulation.swipedismiss.SwipeDismissTouchListener;
import com.nhaarman.listviewanimations.util.AdapterViewUtil;
import com.nhaarman.listviewanimations.util.ListViewWrapper;
import com.nineoldandroids.animation.Animator;
import com.nineoldandroids.animation.AnimatorListenerAdapter;
import com.nineoldandroids.animation.AnimatorSet;
import com.nineoldandroids.animation.ObjectAnimator;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;

            restoreViewPresentations(mDismissedViews);
            notifyCallback(mDismissedPositions);

            Collection<Integer> newUndoPositions = Util.processDeletions(mUndoPositions, mDismissedPositions);
            mUndoPositions.clear();
            mUndoPositions.addAll(newUndoPositions);

            mDismissedViews.clear();
            mDismissedPositions.clear();
        }
    }

    /**
     * Restores the height of given {@code View}.
     * Also calls its super implementation.
     */
    @Override
    protected void restoreViewPresentation(@NonNull final View view) {
        super.restoreViewPresentation(view);
        ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
        layoutParams.height = 0;
        view.setLayoutParams(layoutParams);
    }

    /**
     * Performs the undo animation and restores the original state for given {@link android.view.View}.
     *
     * @param view the parent {@code View} which contains both primary and undo {@code View}s.
     */
    public void undo(@NonNull final View view) {
        int position = AdapterViewUtil.getPositionForView(getListViewWrapper(), view);