gt:         new AsyncTask<Void, Object, Object>() {
context: package com.orgzly.android.ui.fragments;
  
  import android.app.Activity;
  import android.app.AlertDialog;
  import android.app.ProgressDialog;
  import android.content.BroadcastReceiver;
  import android.content.ComponentName;
  import android.content.Context;
  import android.content.Intent;
  import android.content.IntentFilter;
  import android.content.ServiceConnection;
  import android.content.res.Resources;
  import android.net.Uri;
  import android.os.AsyncTask;
  import android.os.Bundle;
  import android.os.IBinder;
  import android.support.v4.app.Fragment;
  import android.support.v4.content.LocalBroadcastManager;
  import android.text.format.DateUtils;
  import android.util.Log;
  import android.view.LayoutInflater;
  import android.view.View;
  import android.view.ViewGroup;
  import android.view.animation.Animation;
  import android.view.animation.AnimationUtils;
  import android.widget.ProgressBar;
  import android.widget.TextView;
  
  import com.orgzly.BuildConfig;
  import com.orgzly.R;
  import com.orgzly.android.Book;
  import com.orgzly.android.BookAction;
  import com.orgzly.android.BookName;
  import com.orgzly.android.Broadcasts;
  import com.orgzly.android.Filter;
  import com.orgzly.android.Note;
  import com.orgzly.android.NotesBatch;
  import com.orgzly.android.Shelf;
  import com.orgzly.android.prefs.AppPreferences;
  import com.orgzly.android.provider.clients.BooksClient;
  import com.orgzly.android.repos.Repo;
  import com.orgzly.android.repos.Rook;
  import com.orgzly.android.sync.SyncService;
  import com.orgzly.android.sync.SyncStatus;
  import com.orgzly.android.ui.CommonActivity;
  import com.orgzly.android.ui.NotePlace;
  import com.orgzly.android.ui.Place;
  import com.orgzly.android.util.AppPermissions;
  import com.orgzly.android.util.LogUtils;
  import com.orgzly.android.util.UriUtils;
  import com.orgzly.org.datetime.OrgDateTime;
  
  import java.io.File;
  import java.io.IOException;
  import java.io.InputStream;
  import java.util.Map;
  import java.util.Set;
  import java.util.TreeSet;
  
  
  /**
   * Retained fragment for sync button. FIXME: Cleanup
   *
   * Misused over time and now includes most async tasks. Move them and don't use a single listener
   * (check {@link com.orgzly.android.ui.ShareActivity}, it has to implement tons of methods with no reason)
   */
  public class SyncFragment extends Fragment {
      private static final String TAG = SyncFragment.class.getName();
  
      /** Name used for {@link android.app.FragmentManager}. */
      public static final String FRAGMENT_TAG = SyncFragment.class.getName();
  
  
      private boolean isServiceBound = false;
  
      /** Activity which has this fragment attached. Used as a target for hooks. */
      private SyncFragmentListener mListener;
  
      private Shelf mShelf;
  
      /** Progress bar and button text. */
      private SyncButton mSyncButton;
  
      private BroadcastReceiver syncServiceReceiver = new BroadcastReceiver() {
          @Override
          public void onReceive(Context context, Intent intent) {
              SyncStatus status = SyncStatus.fromIntent(intent);
  
              if (BuildConfig.LOG_DEBUG) LogUtils.d(TAG, intent, status);
  
              /* Update sync button based on sync status. */
              mSyncButton.update(status);
  
              switch (status.type) {
                  case FAILED:
                      if (mListener != null) {
                          mListener.onSyncFinished(status.message);
                      }
                      break;
  
                  case NO_STORAGE_PERMISSION:
                      Activity activity = getActivity();
                      if (activity != null) {
                          AppPermissions.isGrantedOrRequest((CommonActivity) activity, AppPermissions.FOR_SYNC_START);
                      }
                      break;
  
                  case CANCELED:
                      if (mListener != null) {
                          /* No error message when sync is canceled by the user. */
                          mListener.onSyncFinished(null);
                      }
                      break;
              }
          }
      };
  
  
      public static SyncFragment getInstance() {
          return new SyncFragment();
      }
  
      /**
       * Mandatory empty constructor for the fragment manager to instantiate the
       * fragment (e.g. upon screen orientation changes).
       */
      public SyncFragment() {
          if (BuildConfig.LOG_DEBUG) LogUtils.d(TAG);
      }
  
      /**
       * Hold a reference to the parent Activity so we can report the
       * task's current progress and results. The Android framework
       * will pass us a reference to the newly created Activity after
       * each configuration change.
       */
      @Override
      public void onAttach(Context context) {
          if (BuildConfig.LOG_DEBUG) LogUtils.d(TAG, getActivity());
          super.onAttach(context);
  
          /* This makes sure that the container activity has implemented
           * the callback interface. If not, it throws an exception
           */
          try {
              mListener = (SyncFragmentListener) getActivity();
          } catch (ClassCastException e) {
              throw new ClassCastException(getActivity().toString() + " must implement " + SyncFragmentListener.class);
          }
  
          mShelf = new Shelf(context.getApplicationContext());
      }
  
      /**
       * This method will only be called once when the retained
       * Fragment is first created.
       */
      @Override
      public void onCreate(Bundle savedInstanceState) {
          if (BuildConfig.LOG_DEBUG) LogUtils.d(TAG, savedInstanceState);
          super.onCreate(savedInstanceState);
  
          // Retain this fragment across configuration changes.
          setRetainInstance(true);
  
          LocalBroadcastManager.getInstance(getContext())
                  .registerReceiver(syncServiceReceiver, new IntentFilter(Broadcasts.ACTION_SYNC_STATUS));
      }
  
      @Override
      public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
          if (BuildConfig.LOG_DEBUG) LogUtils.d(TAG, inflater, container, savedInstanceState);
  
          View view = inflater.inflate(R.layout.fragment_sync, container, false);
  
          /* Retained on configuration change. */
          mSyncButton = new SyncButton(view, mSyncButton);
  
          return view;
      }
  
      @Override
      public void onStart() {
          super.onStart();
  
          /*
           * Bind to sync service to request and receive the sync status.
           * We're doing this after button is initialized.
           */
          bindToSyncService();
      }
  
      @Override
      public void onStop() {
          super.onStop();
      }
  
      @Override
      public void onDestroy() {
          if (BuildConfig.LOG_DEBUG) LogUtils.d(TAG);
          super.onDestroy();
  
          LocalBroadcastManager.getInstance(getContext()).unregisterReceiver(syncServiceReceiver);
      }
  
      /**
       * Set the callback to null so we don't accidentally leak the Activity instance.
       */
      @Override
      public void onDetach() {
          if (BuildConfig.LOG_DEBUG) LogUtils.d(TAG);
          super.onDetach();
          mListener = null;
  
      }
  
      /**
       * Load book from the Uri.
       */
      public void importBookFromUri(
              final String bookName,
              final BookName.Format format,
              final Uri uri) {
  
          new AsyncTask<Void , Object, Object>() {
              @Override
              protected Object doInBackground(Void ... params) { /* Executing on a different thread. */
                  try {
                      Book book;
                      InputStream inputStream = getActivity().getContentResolver().openInputStream(uri);
                      try {
                          book = mShelf.loadBookFromStream(bookName, format, inputStream);
                      } finally {
                          inputStream.close();
                      }
  
                      return book;
  
                  } catch (IOException e) {
                      e.printStackTrace();
                      return e;
                  }
              }
  
              @Override
              protected void onPostExecute(Object result) {
                  if (mListener != null) {
                      if (result instanceof Book) {
                          Book book = (Book) result;
                          mShelf.setBookStatus(book, null, new BookAction(BookAction.Type.INFO, getString(R.string.imported)));
                          mListener.onBookLoaded((Book) result);
                      } else {
                          mListener.onBookLoadFailed((IOException) result);
                      }
                  }
              }
          }.execute();
      }
  
      /**
       * Load book from resource.
       *
       * FIXME: Only supports Org format (hardcoded below)
       */
      public void loadBook(final String name, final Resources resources, final int resourceId) {
          if (BuildConfig.LOG_DEBUG) LogUtils.d(TAG, name, resources, resourceId);
  
  