gt:         if (mActive != null) {
context: /*
   * Copyright (C) 2011 The Android Open Source Project
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package android.support.v4.app;
  
  import android.content.Context;
  import android.content.res.Configuration;
  import android.os.Bundle;
  import android.os.Handler;
  import android.os.Looper;
  import android.os.Parcel;
  import android.os.Parcelable;
  import android.support.v4.util.DebugUtils;
  import android.support.v4.util.LogWriter;
  import android.util.Log;
  import android.util.SparseArray;
  import android.view.animation.AccelerateInterpolator;
  import android.view.animation.AlphaAnimation;
  import android.view.animation.Animation;
  import android.view.animation.AnimationSet;
  import android.view.animation.AnimationUtils;
  import android.view.animation.DecelerateInterpolator;
  import android.view.animation.Interpolator;
  import android.view.animation.ScaleAnimation;
  import android.view.animation.Animation.AnimationListener;
  import android.view.Menu;
  import android.view.MenuInflater;
  import android.view.MenuItem;
  import android.view.View;
  import android.view.ViewGroup;
  
  import java.io.FileDescriptor;
  import java.io.PrintWriter;
  import java.util.ArrayList;
  import java.util.Arrays;
  
  /**
   * Static library support version of the framework's {@link android.app.FragmentManager}.
   * Used to write apps that run on platforms prior to Android 3.0.  When running
   * on Android 3.0 or above, this implementation is still used; it does not try
   * to switch to the framework's implementation.  See the framework SDK
   * documentation for a class overview.
   * 
   * <p>Your activity must derive from {@link FragmentActivity} to use this.
   */
  public abstract class FragmentManager {
      /**
       * Representation of an entry on the fragment back stack, as created
       * with {@link FragmentTransaction#addToBackStack(String)
       * FragmentTransaction.addToBackStack()}.  Entries can later be
       * retrieved with {@link FragmentManager#getBackStackEntryAt(int)
       * FragmentManager.getBackStackEntry()}.
       *
       * <p>Note that you should never hold on to a BackStackEntry object;
       * the identifier as returned by {@link #getId} is the only thing that
       * will be persisted across activity instances.
       */
      public interface BackStackEntry {
          /**
           * Return the unique identifier for the entry.  This is the only
           * representation of the entry that will persist across activity
           * instances.
           */
          public int getId();
  
          /**
           * Get the name that was supplied to
           * {@link FragmentTransaction#addToBackStack(String)
           * FragmentTransaction.addToBackStack(String)} when creating this entry.
           */
          public String getName();
  
          /**
           * Return the full bread crumb title resource identifier for the entry,
           * or 0 if it does not have one.
           */
          public int getBreadCrumbTitleRes();
  
          /**
           * Return the short bread crumb title resource identifier for the entry,
           * or 0 if it does not have one.
           */
          public int getBreadCrumbShortTitleRes();
  
          /**
           * Return the full bread crumb title for the entry, or null if it
           * does not have one.
           */
          public CharSequence getBreadCrumbTitle();
  
          /**
           * Return the short bread crumb title for the entry, or null if it
           * does not have one.
           */
          public CharSequence getBreadCrumbShortTitle();
      }
  
      /**
       * Interface to watch for changes to the back stack.
       */
      public interface OnBackStackChangedListener {
          /**
           * Called whenever the contents of the back stack change.
           */
          public void onBackStackChanged();
      }
  
      /**
       * Start a series of edit operations on the Fragments associated with
       * this FragmentManager.
       * 
       * <p>Note: A fragment transaction can only be created/committed prior
       * to an activity saving its state.  If you try to commit a transaction
       * after {@link FragmentActivity#onSaveInstanceState FragmentActivity.onSaveInstanceState()}
       * (and prior to a following {@link FragmentActivity#onStart FragmentActivity.onStart}
       * or {@link FragmentActivity#onResume FragmentActivity.onResume()}, you will get an error.
       * This is because the framework takes care of saving your current fragments
       * in the state, and if changes are made after the state is saved then they
       * will be lost.</p>
       */
      public abstract FragmentTransaction beginTransaction();
  
      /** @hide -- remove once prebuilts are in. */
      @Deprecated
      public FragmentTransaction openTransaction() {
          return beginTransaction();
      }
      
      /**
       * After a {@link FragmentTransaction} is committed with
       * {@link FragmentTransaction#commit FragmentTransaction.commit()}, it
       * is scheduled to be executed asynchronously on the process's main thread.
       * If you want to immediately executing any such pending operations, you
       * can call this function (only from the main thread) to do so.  Note that
       * all callbacks and other related behavior will be done from within this
       * call, so be careful about where this is called from.
       *
       * @return Returns true if there were any pending transactions to be
       * executed.
       */
      public abstract boolean executePendingTransactions();
  
      /**
       * Finds a fragment that was identified by the given id either when inflated
       * from XML or as the container ID when added in a transaction.  This first
       * searches through fragments that are currently added to the manager's
       * activity; if no such fragment is found, then all fragments currently
       * on the back stack associated with this ID are searched.
       * @return The fragment if found or null otherwise.
       */
      public abstract Fragment findFragmentById(int id);
  
      /**
       * Finds a fragment that was identified by the given tag either when inflated
       * from XML or as supplied when added in a transaction.  This first
       * searches through fragments that are currently added to the manager's
       * activity; if no such fragment is found, then all fragments currently
       * on the back stack are searched.
       * @return The fragment if found or null otherwise.
       */
      public abstract Fragment findFragmentByTag(String tag);
  
      /**
       * Flag for {@link #popBackStack(String, int)}
       * and {@link #popBackStack(int, int)}: If set, and the name or ID of
       * a back stack entry has been supplied, then all matching entries will
       * be consumed until one that doesn't match is found or the bottom of
       * the stack is reached.  Otherwise, all entries up to but not including that entry
       * will be removed.
       */
      public static final int POP_BACK_STACK_INCLUSIVE = 1<<0;
  
      /**
       * Pop the top state off the back stack.  Returns true if there was one
       * to pop, else false.  This function is asynchronous -- it enqueues the
       * request to pop, but the action will not be performed until the application
       * returns to its event loop.
       */
      public abstract void popBackStack();
  
      /**
       * Like {@link #popBackStack()}, but performs the operation immediately
       * inside of the call.  This is like calling {@link #executePendingTransactions()}
       * afterwards.
       * @return Returns true if there was something popped, else false.
       */
      public abstract boolean popBackStackImmediate();
  
      /**
       * Pop the last fragment transition from the manager's fragment
       * back stack.  If there is nothing to pop, false is returned.
       * This function is asynchronous -- it enqueues the
       * request to pop, but the action will not be performed until the application
       * returns to its event loop.
       * 
       * @param name If non-null, this is the name of a previous back state
       * to look for; if found, all states up to that state will be popped.  The
       * {@link #POP_BACK_STACK_INCLUSIVE} flag can be used to control whether
       * the named state itself is popped. If null, only the top state is popped.
       * @param flags Either 0 or {@link #POP_BACK_STACK_INCLUSIVE}.
       */
      public abstract void popBackStack(String name, int flags);
  
      /**
       * Like {@link #popBackStack(String, int)}, but performs the operation immediately
       * inside of the call.  This is like calling {@link #executePendingTransactions()}
       * afterwards.
       * @return Returns true if there was something popped, else false.
       */
      public abstract boolean popBackStackImmediate(String name, int flags);
  
      /**
       * Pop all back stack states up to the one with the given identifier.
       * This function is asynchronous -- it enqueues the
       * request to pop, but the action will not be performed until the application
       * returns to its event loop.
       * 
       * @param id Identifier of the stated to be popped. If no identifier exists,
       * false is returned.
       * The identifier is the number returned by
       * {@link FragmentTransaction#commit() FragmentTransaction.commit()}.  The
       * {@link #POP_BACK_STACK_INCLUSIVE} flag can be used to control whether
       * the named state itself is popped.
       * @param flags Either 0 or {@link #POP_BACK_STACK_INCLUSIVE}.
       */
      public abstract void popBackStack(int id, int flags);
  
      /**
       * Like {@link #popBackStack(int, int)}, but performs the operation immediately
       * inside of the call.  This is like calling {@link #executePendingTransactions()}
       * afterwards.
       * @return Returns true if there was something popped, else false.
       */
      public abstract boolean popBackStackImmediate(int id, int flags);
  
      /**
       * Return the number of entries currently in the back stack.
       */
      public abstract int getBackStackEntryCount();
  
      /**
       * Return the BackStackEntry at index <var>index</var> in the back stack;
       * entries start index 0 being the bottom of the stack.
       */
      public abstract BackStackEntry getBackStackEntryAt(int index);
  
      /**
       * Add a new listener for changes to the fragment back stack.
       */
      public abstract void addOnBackStackChangedListener(OnBackStackChangedListener listener);
  
      /**
       * Remove a listener that was previously added with
       * {@link #addOnBackStackChangedListener(OnBackStackChangedListener)}.
       */
      public abstract void removeOnBackStackChangedListener(OnBackStackChangedListener listener);
  
      /**
       * Put a reference to a fragment in a Bundle.  This Bundle can be
       * persisted as saved state, and when later restoring
       * {@link #getFragment(Bundle, String)} will return the current
       * instance of the same fragment.
       *
       * @param bundle The bundle in which to put the fragment reference.
       * @param key The name of the entry in the bundle.
       * @param fragment The Fragment whose reference is to be stored.
       */
      public abstract void putFragment(Bundle bundle, String key, Fragment fragment);
  
      /**
       * Retrieve the current Fragment instance for a reference previously
       * placed with {@link #putFragment(Bundle, String, Fragment)}.
       *
       * @param bundle The bundle from which to retrieve the fragment reference.
       * @param key The name of the entry in the bundle.
       * @return Returns the current Fragment instance that is associated with
       * the given reference.
       */
      public abstract Fragment getFragment(Bundle bundle, String key);
  
      /**
       * Save the current instance state of the given Fragment.  This can be
       * used later when creating a new instance of the Fragment and adding
       * it to the fragment manager, to have it create itself to match the
       * current state returned here.  Note that there are limits on how
       * this can be used:
       *
       * <ul>
       * <li>The Fragment must currently be attached to the FragmentManager.
       * <li>A new Fragment created using this saved state must be the same class
       * type as the Fragment it was created from.
       * <li>The saved state can not contain dependencies on other fragments --
       * that is it can't use {@link #putFragment(Bundle, String, Fragment)} to
       * store a fragment reference because that reference may not be valid when
       * this saved state is later used.  Likewise the Fragment's target and
       * result code are not included in this state.
       * </ul>
       *
       * @param f The Fragment whose state is to be saved.
       * @return The generated state.  This will be null if there was no
       * interesting state created by the fragment.
       */
      public abstract Fragment.SavedState saveFragmentInstanceState(Fragment f);
  
      /**
       * Print the FragmentManager's state into the given stream.
       *
       * @param prefix Text to print at the front of each line.
       * @param fd The raw file descriptor that the dump is being sent to.
       * @param writer A PrintWriter to which the dump is to be set.
       * @param args Additional arguments to the dump request.
       */
      public abstract void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args);
  
      /**
       * Control whether the framework's internal fragment manager debugging
       * logs are turned on.  If enabled, you will see output in logcat as
       * the framework performs fragment operations.
       */
      public static void enableDebugLogging(boolean enabled) {
          FragmentManagerImpl.DEBUG = enabled;
      }
  }
  
  final class FragmentManagerState implements Parcelable {
      FragmentState[] mActive;
      int[] mAdded;
      BackStackState[] mBackStack;
      
      public FragmentManagerState() {
      }
      
      public FragmentManagerState(Parcel in) {
          mActive = in.createTypedArray(FragmentState.CREATOR);
          mAdded = in.createIntArray();
          mBackStack = in.createTypedArray(BackStackState.CREATOR);
      }
      
      public int describeContents() {
          return 0;
      }
  
      public void writeToParcel(Parcel dest, int flags) {
          dest.writeTypedArray(mActive, flags);
          dest.writeIntArray(mAdded);
          dest.writeTypedArray(mBackStack, flags);
      }
      
      public static final Parcelable.Creator<FragmentManagerState> CREATOR
              = new Parcelable.Creator<FragmentManagerState>() {
          public FragmentManagerState createFromParcel(Parcel in) {
              return new FragmentManagerState(in);
          }
          
          public FragmentManagerState[] newArray(int size) {
              return new FragmentManagerState[size];
          }
      };
  }
  
  /**
   * Container for fragments associated with an activity.
   */
  final class FragmentManagerImpl extends FragmentManager {
      static boolean DEBUG = false;
      static final String TAG = "FragmentManager";
      
      static final boolean HONEYCOMB = android.os.Build.VERSION.SDK_INT >= 11;
  
      static final String TARGET_REQUEST_CODE_STATE_TAG = "android:target_req_state";
      static final String TARGET_STATE_TAG = "android:target_state";
      static final String VIEW_STATE_TAG = "android:view_state";
      static final String USER_VISIBLE_HINT_TAG = "android:user_visible_hint";
  
      ArrayList<Runnable> mPendingActions;
      Runnable[] mTmpActions;
      boolean mExecutingActions;
      
      ArrayList<Fragment> mActive;
      ArrayList<Fragment> mAdded;
      ArrayList<Integer> mAvailIndices;
      ArrayList<BackStackRecord> mBackStack;
      ArrayList<Fragment> mCreatedMenus;
      
      // Must be accessed while locked.
      ArrayList<BackStackRecord> mBackStackIndices;
      ArrayList<Integer> mAvailBackStackIndices;
  
      ArrayList<OnBackStackChangedListener> mBackStackChangeListeners;
  
      int mCurState = Fragment.INITIALIZING;
      FragmentActivity mActivity;
      
      boolean mNeedMenuInvalidate;
      boolean mStateSaved;
      boolean mDestroyed;
      String mNoTransactionsBecause;
      boolean mHavePendingDeferredStart;
      
      // Temporary vars for state save and restore.
      Bundle mStateBundle = null;
      SparseArray<Parcelable> mStateArray = null;
      
      Runnable mExecCommit = new Runnable() {
          @Override
          public void run() {
              execPendingActions();
          }
      };
  
      @Override
      public FragmentTransaction beginTransaction() {
          return new BackStackRecord(this);
      }
  
      @Override
      public boolean executePendingTransactions() {
          return execPendingActions();
      }
  
      @Override
      public void popBackStack() {
          enqueueAction(new Runnable() {
              @Override public void run() {
                  popBackStackState(mActivity.mHandler, null, -1, 0);
              }
          }, false);
      }
  
      @Override
      public boolean popBackStackImmediate() {
          checkStateLoss();
          executePendingTransactions();
          return popBackStackState(mActivity.mHandler, null, -1, 0);
      }
  
      @Override
      public void popBackStack(final String name, final int flags) {
          enqueueAction(new Runnable() {
              @Override public void run() {
                  popBackStackState(mActivity.mHandler, name, -1, flags);
              }
          }, false);
      }
  
      @Override
      public boolean popBackStackImmediate(String name, int flags) {
          checkStateLoss();
          executePendingTransactions();
          return popBackStackState(mActivity.mHandler, name, -1, flags);
      }
  
      @Override
      public void popBackStack(final int id, final int flags) {
          if (id < 0) {
              throw new IllegalArgumentException("Bad id: " + id);
          }
          enqueueAction(new Runnable() {
              @Override public void run() {
                  popBackStackState(mActivity.mHandler, null, id, flags);
              }
          }, false);
      }
  
      @Override
      public boolean popBackStackImmediate(int id, int flags) {
          checkStateLoss();
          executePendingTransactions();
          if (id < 0) {
              throw new IllegalArgumentException("Bad id: " + id);
          }
          return popBackStackState(mActivity.mHandler, null, id, flags);
      }
  
      @Override
      public int getBackStackEntryCount() {
          return mBackStack != null ? mBackStack.size() : 0;
      }
  
      @Override
      public BackStackEntry getBackStackEntryAt(int index) {
          return mBackStack.get(index);
      }
  
      @Override
      public void addOnBackStackChangedListener(OnBackStackChangedListener listener) {
          if (mBackStackChangeListeners == null) {
              mBackStackChangeListeners = new ArrayList<OnBackStackChangedListener>();
          }
          mBackStackChangeListeners.add(listener);
      }
  
      @Override
      public void removeOnBackStackChangedListener(OnBackStackChangedListener listener) {
          if (mBackStackChangeListeners != null) {
              mBackStackChangeListeners.remove(listener);
          }
      }
  
      @Override
      public void putFragment(Bundle bundle, String key, Fragment fragment) {
          if (fragment.mIndex < 0) {
              throw new IllegalStateException("Fragment " + fragment
                      + " is not currently in the FragmentManager");
          }
          bundle.putInt(key, fragment.mIndex);
      }
  
      @Override
      public Fragment getFragment(Bundle bundle, String key) {
          int index = bundle.getInt(key, -1);
          if (index == -1) {
              return null;
          }
          if (index >= mActive.size()) {
              throw new IllegalStateException("Fragement no longer exists for key "
                      + key + ": index " + index);
          }
          Fragment f = mActive.get(index);
          if (f == null) {
              throw new IllegalStateException("Fragement no longer exists for key "
                      + key + ": index " + index);
          }
          return f;
      }
  
      @Override
      public Fragment.SavedState saveFragmentInstanceState(Fragment fragment) {
          if (fragment.mIndex < 0) {
              throw new IllegalStateException("Fragment " + fragment
                      + " is not currently in the FragmentManager");
          }
          if (fragment.mState > Fragment.INITIALIZING) {
              Bundle result = saveFragmentBasicState(fragment);
              return result != null ? new Fragment.SavedState(result) : null;
          }
          return null;
      }
  
      @Override
      public String toString() {
          StringBuilder sb = new StringBuilder(128);
          sb.append("FragmentManager{");
          sb.append(Integer.toHexString(System.identityHashCode(this)));
          sb.append(" in ");
          DebugUtils.buildShortClassTag(mActivity, sb);
          sb.append("}}");
          return sb.toString();
      }
  
      @Override
      public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
          String innerPrefix = prefix + "    ";
  
          int N;
  