// Called when creating.
  @Override
  protected final void onCreate(Bundle savedInstanceState) {
    // start tracking
    trackInstance(this);

    // call super
    super.onCreate(savedInstanceState);

    // setup instance state
    Intent intent = this.getIntent();
    String sharedGalleryId =
        (intent != null ? intent.getStringExtra(EXTRA_SHARED_GALLERY_ID) : null);
    InstanceStateFragment stateFragment =
        (InstanceStateFragment)
            this.getFragmentManager().findFragmentByTag(InstanceStateFragment.TAG);
    m_Gallery = Gallery.fromId(sharedGalleryId);
    if (m_Gallery == null) {
      if (stateFragment != null) {
        Log.w(TAG, "onCreate() - Use existent Gallery : " + stateFragment.gallery.getId());
        m_Gallery = stateFragment.gallery;
        m_ActivityResultHandles = stateFragment.activityResultHandles;
      } else {
        Log.w(TAG, "onCreate() - Create new Gallery");
        m_Gallery = GalleryApplication.current().createGallery();
        m_ActivityResultHandles = new SparseArray<>();
      }
    } else {
      Log.w(TAG, "onCreate() - Use shared Gallery : " + m_Gallery.getId());
      m_ActivityResultHandles = new SparseArray<>();
      m_IsSharedGallery = true;
    }

    // attach to gallery
    m_GalleryAttachHandle = m_Gallery.attachActivity(this);
    if (!Handle.isValid(m_GalleryAttachHandle)) {
      Log.e(TAG, "onCreate() - Fail to attach to Gallery");
      this.finish();
      return;
    }
    m_Gallery.addCallback(Gallery.PROP_IS_NAVIGATION_BAR_VISIBLE, m_NavBarVisibilityCallback);
    m_Gallery.addCallback(Gallery.PROP_IS_STATUS_BAR_VISIBLE, m_StatusBarVisibilityCallback);

    // initialize screen size
    this.updateScreenSize();

    // create
    this.onCreate(savedInstanceState, stateFragment != null ? stateFragment.extras : null);
  }
  // Save instance state.
  @Override
  protected final void onSaveInstanceState(Bundle outState) {
    // get instance state fragment
    InstanceStateFragment stateFragment =
        (InstanceStateFragment)
            this.getFragmentManager().findFragmentByTag(InstanceStateFragment.TAG);
    if (stateFragment == null) {
      stateFragment = new InstanceStateFragment();
      this.getFragmentManager()
          .beginTransaction()
          .add(stateFragment, InstanceStateFragment.TAG)
          .commit();
    }

    // save instance state
    Log.w(TAG, "onSaveInstanceState() - Keep Gallery instance : " + m_Gallery.getId());
    stateFragment.gallery = m_Gallery;
    stateFragment.activityResultHandles = m_ActivityResultHandles;
    this.onSaveInstanceState(outState, stateFragment.extras);

    // call super
    super.onSaveInstanceState(outState);

    // update state
    m_IsInstanceStateSaved = true;
  }
  // Check alive instances.
  private static void checkInstances(long delayMillis) {
    // check immediately
    Handler handler = GalleryApplication.current().getHandler();
    handler.removeCallbacks(m_CheckInstancesRunnable);
    if (delayMillis <= 0) {
      for (int i = m_TrackingInstances.size() - 1; i >= 0; --i) {
        Object instance = m_TrackingInstances.get(i).get();
        if (instance == null) m_TrackingInstances.remove(i);
      }
      Log.w(
          "GalleryActivity", "checkInstances() - Alive instances : " + m_TrackingInstances.size());
      return;
    }

    // check later
    handler.postDelayed(m_CheckInstancesRunnable, delayMillis);
  }
  // Called when destroying.
  @Override
  protected void onDestroy() {
    // detach from gallery
    m_Gallery.removeCallback(Gallery.PROP_IS_NAVIGATION_BAR_VISIBLE, m_NavBarVisibilityCallback);
    m_Gallery.removeCallback(Gallery.PROP_IS_STATUS_BAR_VISIBLE, m_StatusBarVisibilityCallback);
    m_GalleryAttachHandle = Handle.close(m_GalleryAttachHandle);

    // release gallery
    if (!m_IsInstanceStateSaved && !m_IsSharedGallery) {
      Log.w(TAG, "onDestroy() - Release Gallery");
      m_Gallery.release();
    }

    // release references
    m_ActivityResultHandles = null;

    // call super
    super.onDestroy();

    // check instances
    checkInstances(DURATION_CHECK_INSTANCES_DELAY);
  }