package com.github.mttkay.memento;

import android.app.Activity;
import android.os.Build;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.util.Log;

public class Memento {

    private static final String LOG_TAG = Memento.class.getSimpleName();

    public static void retain(Activity activity) {
        final String fragmentTag = getMementoFragmentTag(activity);
        log("Obtaining " + fragmentTag);

        if (activity instanceof FragmentActivity) {
            retainSupportV4((FragmentActivity) activity, fragmentTag);
        } else if (Build.VERSION.SDK_INT >= 11) {
            retainNative(activity, fragmentTag);
        } else {
            throw new RuntimeException("For API levels < 10, Memento requires the support-v4 package");
        }
    }

    private static void retainNative(Activity activity, String fragmentTag) {
        android.app.FragmentManager fragmentManager = activity.getFragmentManager();
        MementoMethods memento = (MementoMethods) fragmentManager.findFragmentByTag(fragmentTag);

        if (memento == null) {
            memento = buildMemento(activity);
            fragmentManager.beginTransaction().add((android.app.Fragment) memento, fragmentTag).commit();
        } else {
            restoreMemento(activity, memento);
        }
    }

    private static void retainSupportV4(FragmentActivity activity, String fragmentTag) {
        FragmentManager fragmentManager = activity.getSupportFragmentManager();
        MementoMethods memento = (MementoMethods) fragmentManager.findFragmentByTag(fragmentTag);

        if (memento == null) {
            memento = buildMemento(activity);
            fragmentManager.beginTransaction().add((Fragment) memento, fragmentTag).commit();
        } else {
            restoreMemento(activity, memento);
        }
    }

    private static MementoMethods buildMemento(Activity activity) {
        log("No memento found; storing...");
        MementoMethods memento = instantiateMementoFragment(activity);
        ((MementoCallbacks) activity).onLaunch();
        memento.retain(activity);
        return memento;
    }

    private static void restoreMemento(Activity activity, MementoMethods memento) {
        log("Found memento; restoring...");
        memento.restore(activity);
    }

    private static MementoMethods instantiateMementoFragment(Activity activity) {
        final String fragmentClassName = getMementoClassName(activity);
        try {
            final Class<?> fragmentClass = activity.getClassLoader().loadClass(fragmentClassName);
            return (MementoMethods) fragmentClass.newInstance();
        } catch (ClassNotFoundException e) {
            throw new IllegalStateException("Could not load memento: " + fragmentClassName, e);
        } catch (InstantiationException e) {
            throw new IllegalStateException("Could not create memento: " + fragmentClassName, e);
        } catch (IllegalAccessException e) {
            throw new IllegalStateException("Could not access memento: " + fragmentClassName, e);
        }
    }

    private static String getMementoClassName(Activity hostActivity) {
        return hostActivity.getComponentName().getClassName() + "$Memento";
    }

    private static String getMementoFragmentTag(Activity hostActivity) {
        // for simplicity, just use the Memento fragment's class name
        return getMementoClassName(hostActivity);
    }

    private static void log(String message) {
        if (Log.isLoggable(LOG_TAG, Log.DEBUG)) {
            Log.d(LOG_TAG, message);
        }
    }
}

@@ -338,24 +338,398 @@
 pleName();%0A%0A
+    private static final boolean USES_SUPPORT_FRAGMENTS;%0A%0A    static %7B%0A        boolean supportFragmentsAvailable = false;%0A        try %7B%0A            Class.forName(%22android.support.v4.app.FragmentActivity%22);%0A            supportFragmentsAvailable = true;%0A        %7D catch (ClassNotFoundException e) %7B%0A        %7D%0A        USES_SUPPORT_FRAGMENTS = supportFragmentsAvailable;%0A    %7D%0A%0A
     public s
@@ -889,16 +889,42 @@
     if (
+USES_SUPPORT_FRAGMENTS && 
 activity
@@ -1074,10 +1074,37 @@
  %3E= 
-11
+Build.VERSION_CODES.HONEYCOMB
 ) %7B%0A
@@ -1231,9 +1231,9 @@
  %3C 1
-0
+1
 , Me
@@ -1269,16 +1269,100 @@
  package
+ and %22 +%0A                    %22the target Activity must inherit from FragmentActivity
 %22);%0A    
@@ -1444,32 +1444,79 @@
  fragmentTag) %7B%0A
+        log(%22Entering native fragments mode%22);%0A
         android.
@@ -2028,32 +2028,80 @@
  fragmentTag) %7B%0A
+        log(%22Entering support fragments mode%22);%0A
         Fragment

Fix broken native fragment support