package org.ccci.gto.android.common.util;

import android.annotation.TargetApi;
import android.os.AsyncTask;
import android.os.Build;
import android.support.annotation.NonNull;

import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class AsyncTaskCompat {
    private static final Compat COMPAT;
    static {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
            COMPAT = new FroyoCompat();
        } else {
            COMPAT = new HoneycombCompat();
        }
    }

    public static void execute(@NonNull final Runnable task) {
        COMPAT.execute(task);
    }

    @NonNull
    public static Executor SERIAL_EXECUTOR() {
        return COMPAT.SERIAL_EXECUTOR();
    }

    interface Compat {
        void execute(@NonNull Runnable task);

        @NonNull
        Executor SERIAL_EXECUTOR();
    }

    static class FroyoCompat implements Compat {
        private static Executor EXECUTOR;

        @NonNull
        @TargetApi(Build.VERSION_CODES.GINGERBREAD)
        private static synchronized Executor getExecutor() {
            if (EXECUTOR == null) {
                EXECUTOR = Executors.newFixedThreadPool(1);
                if (EXECUTOR instanceof ThreadPoolExecutor) {
                    ((ThreadPoolExecutor) EXECUTOR).setKeepAliveTime(30, TimeUnit.SECONDS);
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
                        ((ThreadPoolExecutor) EXECUTOR).allowCoreThreadTimeOut(true);
                    } else {
                        ((ThreadPoolExecutor) EXECUTOR).setCorePoolSize(0);
                    }
                }
            }

            return EXECUTOR;
        }

        @Override
        public void execute(@NonNull final Runnable task) {
            getExecutor().execute(task);
        }

        @NonNull
        @Override
        public Executor SERIAL_EXECUTOR() {
            return getExecutor();
        }
    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    static class HoneycombCompat extends FroyoCompat {
        @Override
        public void execute(@NonNull Runnable task) {
            AsyncTask.execute(task);
        }

        @NonNull
        @Override
        public Executor SERIAL_EXECUTOR() {
            return AsyncTask.SERIAL_EXECUTOR;
        }
    }
}

@@ -628,188 +628,157 @@
 tic 
-void execute(@NonNull final Runnable task) %7B%0A        COMPAT.execute(task);%0A    %7D%0A%0A    @NonNull%0A    public static Executor SERIAL_EXECUTOR() %7B%0A        return COMPAT.SERIAL_EXECUTOR(
+final Executor SERIAL_EXECUTOR = COMPAT.serialExecutor();%0A%0A    public static void execute(@NonNull final Runnable task) %7B%0A        COMPAT.execute(task
 );%0A 
@@ -887,31 +887,30 @@
 xecutor 
-SERIAL_EXECUTOR
+serialExecutor
 ();%0A    
@@ -977,23 +977,16 @@
 private 
-static 
 Executor
@@ -986,24 +986,25 @@
 xecutor 
-EXECUTOR
+mExecutor
 ;%0A%0A     
@@ -1083,23 +1083,16 @@
 private 
-static 
 synchron
@@ -1137,24 +1137,25 @@
     if (
-EXECUTOR
+mExecutor
  == null
@@ -1174,24 +1174,25 @@
         
-EXECUTOR
+mExecutor
  = Execu
@@ -1239,24 +1239,25 @@
     if (
-EXECUTOR
+mExecutor
  instanc
@@ -1320,32 +1320,33 @@
 olExecutor) 
-EXECUTOR
+mExecutor
 ).setKeepAli
@@ -1505,24 +1505,25 @@
 ecutor) 
-EXECUTOR
+mExecutor
 ).allowC
@@ -1621,24 +1621,25 @@
 ecutor) 
-EXECUTOR
+mExecutor
 ).setCor
@@ -1726,24 +1726,25 @@
  return 
-EXECUTOR
+mExecutor
 ;%0A      
@@ -1933,39 +1933,38 @@
 ic Executor 
-SERIAL_EXECUTOR
+serialExecutor
 () %7B%0A       
@@ -2287,31 +2287,30 @@
 xecutor 
-SERIAL_EXECUTOR
+serialExecutor
 () %7B%0A   

make SERIAL_EXECUTOR a constant