package com.novoda.downloadmanager;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.os.SystemClock;
import android.support.annotation.Nullable;
import android.util.Log;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class LiteDownloadMigrationService extends Service {

    private static final String TAG = "MigrationService";
    private Migrator v1ToV2Migrator;
    private ExecutorService executor;
    private IBinder binder;
    private Migrator.Callback migrationCallback;
    private String updateMessage;

    private static boolean isBound;

    public static boolean isBound() {
        return isBound;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        super.onStartCommand(intent, flags, startId);

        Log.d(TAG, "onStartCommand");

        if (v1ToV2Migrator != null && !v1ToV2Migrator.isRunning()) {
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    Log.d(TAG, "Begin Migration");
                    v1ToV2Migrator.migrate();
                }
            });
        }

        return START_STICKY;
    }

    @Override
    public void onCreate() {
        Log.d(TAG, "onCreate");
        executor = Executors.newSingleThreadExecutor();
        binder = new MigrationDownloadServiceBinder();
        v1ToV2Migrator = MigrationFactory.createVersionOneToVersionTwoMigrator(
                getApplicationContext(),
                getDatabasePath("downloads.db"),
                migrationCallback()
        );

        super.onCreate();
    }

    private Migrator.Callback migrationCallback() {
        return new Migrator.Callback() {
            @Override
            public void onUpdate(String message) {
                updateMessage = message;
                if (migrationCallback != null) {
                    migrationCallback.onUpdate(message);
                }
            }
        };
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        isBound = true;
        return binder;
    }

    @Override
    public void onTaskRemoved(Intent rootIntent) {
        Log.d(TAG, "onTaskRemoved");
        rescheduleMigration();
        Log.d(TAG, "Rescheduling");
        super.onTaskRemoved(rootIntent);
    }

    private void rescheduleMigration() {
        Intent intent = new Intent(getApplicationContext(), LiteDownloadMigrationService.class);
        PendingIntent pendingIntent = PendingIntent.getService(this, 1, intent, PendingIntent.FLAG_ONE_SHOT);
        AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        if (alarmManager == null) {
            Log.w(TAG, "Could not retrieve AlarmManager for rescheduling.");
            return;
        }
        alarmManager.set(AlarmManager.RTC_WAKEUP, SystemClock.elapsedRealtime() + 5000, pendingIntent);
    }

    @Override
    public boolean onUnbind(Intent intent) {
        Log.d(TAG, "onUnbind");
        migrationCallback = null;
        Log.d(TAG, "Stopping service");
        isBound = false;
        return super.onUnbind(intent);
    }

    @Override
    public void onDestroy() {
        Log.d(TAG, "onDestroy");
        executor.shutdown();
        super.onDestroy();
    }

    class MigrationDownloadServiceBinder extends Binder {

        MigrationDownloadServiceBinder withCallback(Migrator.Callback migrationCallback) {
            LiteDownloadMigrationService.this.migrationCallback = migrationCallback;
            return this;
        }

        void bind() {
            LiteDownloadMigrationService.this.migrationCallback.onUpdate(LiteDownloadMigrationService.this.updateMessage);
        }

    }

}

@@ -562,33 +562,42 @@
 ate 
-Migrator v1ToV2Migra
+static ExecutorService execu
 tor;%0A
+%0A
     
@@ -604,37 +604,36 @@
 private 
-ExecutorService execu
+Migrator v1ToV2Migra
 tor;%0A   
@@ -986,17 +986,16 @@
 artId);%0A
-%0A
         
@@ -1029,81 +1029,8 @@
 );%0A%0A
-        if (v1ToV2Migrator != null && !v1ToV2Migrator.isRunning()) %7B%0A    
     
@@ -1071,36 +1071,32 @@
 ) %7B%0A            
-    
 @Override%0A      
@@ -1081,36 +1081,32 @@
       @Override%0A
-    
             publ
@@ -1133,28 +1133,24 @@
             
-    
 Log.d(TAG, %22
@@ -1164,28 +1164,24 @@
 igration%22);%0A
-    
             
@@ -1214,36 +1214,32 @@
 ();%0A            
-    
 %7D%0A            %7D)
@@ -1236,25 +1236,11 @@
     
- 
-   
 %7D);
-%0A        %7D
 %0A%0A  
@@ -1344,24 +1344,60 @@
 onCreate%22);%0A
+        if (executor == null) %7B%0A    
         exec
@@ -1436,24 +1436,35 @@
 Executor();%0A
+        %7D%0A%0A
         bind

Use a single instance of executor for Service.