// Path: library/src/main/java/com/google/android/material/motion/MotionObserver.java
// public abstract class MotionObserver<T> extends Observer<T> {
// 
//   @Override
//   public abstract void next(T value);
// 
//   public abstract void build(MotionBuilder<T> builder, T... values);
// 
//   /**
//    * A simple observer for when you only want to implement {@link #next(Object)}.
//    */
//   public static abstract class SimpleMotionObserver<T> extends MotionObserver<T> {
//     @Override
//     public void build(MotionBuilder<T> builder, T[] values) {
//     }
//   }
// }
// 
// Path: library/src/main/java/com/google/android/material/motion/Operation.java
// public abstract class Operation<T, U> {
// 
//   public void preConnect(MotionObserver<U> observer) {
//   }
// 
//   /**
//    * Transforms the incoming value before passing it to the observer, or blocks the value.
//    *
//    * @param value The incoming value.
//    */
//   public abstract void next(MotionObserver<U> observer, T value);
// 
//   public void postConnect(MotionObserver<U> observer) {
//   }
// 
//   public void preDisconnect(MotionObserver<U> observer) {
//   }
// 
//   public void postDisconnect(MotionObserver<U> observer) {
//   }
// }


import android.os.Handler;
import android.os.Looper;
import android.support.annotation.VisibleForTesting;
import android.support.v4.util.SimpleArrayMap;
import com.google.android.material.motion.MotionObserver;
import com.google.android.material.motion.Operation;
import java.util.ArrayDeque;
import java.util.Deque;
package com.google.android.material.motion.operators;




public class DelayBy {

  @VisibleForTesting
  DelayBy() {
    throw new UnsupportedOperationException();
  }

  public static <T> Operation<T, T> delayBy(final long delayMillis) {
    return new Operation<T, T>() {

      private final Handler handler = new Handler(Looper.getMainLooper());
      private SimpleArrayMap<MotionObserver<T>, Deque<Runnable>> runnables = new SimpleArrayMap<>();

      @Override
      public void preConnect(MotionObserver<T> observer) {
        if (!runnables.containsKey(observer)) {
          runnables.put(observer, new ArrayDeque<>());
        }
      }

      @Override
      public void next(final MotionObserver<T> observer, final T value) {
// Path: library/src/main/java/com/google/android/material/motion/MotionObserver.java
// public abstract class MotionObserver<T> extends Observer<T> {
// 
//   @Override
//   public abstract void next(T value);
// 
//   public abstract void build(MotionBuilder<T> builder, T... values);
// 
//   /**
//    * A simple observer for when you only want to implement {@link #next(Object)}.
//    */
//   public static abstract class SimpleMotionObserver<T> extends MotionObserver<T> {
//     @Override
//     public void build(MotionBuilder<T> builder, T[] values) {
//     }
//   }
// }
// 
// Path: library/src/main/java/com/google/android/material/motion/Operation.java
// public abstract class Operation<T, U> {
// 
//   public void preConnect(MotionObserver<U> observer) {
//   }
// 
//   /**
//    * Transforms the incoming value before passing it to the observer, or blocks the value.
//    *
//    * @param value The incoming value.
//    */
//   public abstract void next(MotionObserver<U> observer, T value);
// 
//   public void postConnect(MotionObserver<U> observer) {
//   }
// 
//   public void preDisconnect(MotionObserver<U> observer) {
//   }
// 
//   public void postDisconnect(MotionObserver<U> observer) {
//   }
// }


// Path: library/src/main/java/com/google/android/material/motion/operators/DelayBy.java
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.VisibleForTesting;
import android.support.v4.util.SimpleArrayMap;
import com.google.android.material.motion.MotionObserver;
import com.google.android.material.motion.Operation;
import java.util.ArrayDeque;
import java.util.Deque;

package com.google.android.material.motion.operators;




public class DelayBy {

  @VisibleForTesting
  DelayBy() {
    throw new UnsupportedOperationException();
  }

  public static <T> Operation<T, T> delayBy(final long delayMillis) {
    return new Operation<T, T>() {

      private final Handler handler = new Handler(Looper.getMainLooper());
      private SimpleArrayMap<MotionObserver<T>, Deque<Runnable>> runnables = new SimpleArrayMap<>();

      @Override
      public void preConnect(MotionObserver<T> observer) {
        if (!runnables.containsKey(observer)) {
          runnables.put(observer, new ArrayDeque<>());
        }
      }

      @Override
      public void next(final MotionObserver<T> observer, final T value) {
        final Runnable runnable = new Runnable() {