package nz.bradcampbell.paperparcel;

import android.os.Parcelable;

import java.lang.reflect.Field;
import java.util.Map;

public final class PaperParcels {
  static final Map<Class, Delegator> FROM_ORIGINAL;
  static final Map<Class, Delegator> FROM_PARCELABLE;

  static {
    //noinspection TryWithIdenticalCatches
    try {
      Class clazz = Class.forName("nz.bradcampbell.paperparcel.PaperParcelMapping");
      FROM_ORIGINAL = getFieldValue(clazz, "FROM_ORIGINAL");
      FROM_PARCELABLE = getFieldValue(clazz, "FROM_PARCELABLE");
    } catch (ClassNotFoundException e) {
      throw new RuntimeException(e);
    } catch (NoSuchFieldException e) {
      throw new RuntimeException(e);
    } catch (IllegalAccessException e) {
      throw new RuntimeException(e);
    }
  }

  public static <ORIG, PARCELABLE extends Parcelable> PARCELABLE wrap(ORIG originalObj) {
    Class<?> type = originalObj.getClass();
    //noinspection unchecked
    Delegator<ORIG, PARCELABLE> delegator = FROM_ORIGINAL.get(type);
    return delegator.wrap(originalObj);
  }

  public static <ORIG, PARCELABLE extends Parcelable> ORIG unwrap(PARCELABLE parcelableObj) {
    Class<?> type = parcelableObj.getClass();
    //noinspection unchecked
    Delegator<ORIG, PARCELABLE> delegator = FROM_PARCELABLE.get(type);
    return delegator.unwrap(parcelableObj);
  }

  interface Delegator<ORIG, PARCELABLE extends Parcelable> {
    ORIG unwrap(PARCELABLE parcelableObj);

    PARCELABLE wrap(ORIG originalObj);
  }

  private static Map<Class, Delegator> getFieldValue(Class clazz, String fieldName)
      throws NoSuchFieldException, IllegalAccessException {
    Field field = clazz.getDeclaredField(fieldName);
    field.setAccessible(true);
    //noinspection unchecked
    return (Map<Class, Delegator>) field.get(null);
  }
}

@@ -117,16 +117,140 @@
 l.Map;%0A%0A
+/**%0A * Central mechanism for %7B@link #wrap(Object)%7Ding/%7B@link #unwrap(Parcelable)%7Dping arbitrary%0A * PaperParcel objects.%0A */%0A
 public f
@@ -896,24 +896,122 @@
 %0A    %7D%0A  %7D%0A%0A
+  // TODO make the generated FooParcel classes implement an interface so we can be more typesafe?%0A
   public sta
@@ -1275,16 +1275,114 @@
 );%0A  %7D%0A%0A
+  // TODO make the generated FooParcel classes implement an interface so we can be more typesafe?%0A
   public

Add javadoc, TODOs for type-safety improvements