package com.googlecode.gentyref;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

/**
 * Wrapper around {@link Type}.
 * 
 * You can use this to create instances of Type for a type known at compile time.
 * 
 * For example, to get the Type that represents List&lt;String&gt;:
 * <code>Type listOfString = new TypeToken&lt;List&lt;String&gt;&gt;(){}.getType();</code>
 * 
 * @author Wouter Coekaerts <wouter@coekaerts.be>
 *
 * @param <T> The type represented by this TypeToken.
 */
public abstract class TypeToken<T> {
	private final Type type;

	/**
	 * Constructs a type token.
	 */
	protected TypeToken() {
		this.type = extractType();
	}

//	private TypeToken(Type type) {
//		this.type = type;
//	}

	public Type getType() {
		return type;
	}

	private Type extractType() {
		Type t = getClass().getGenericSuperclass();
		if (!(t instanceof ParameterizedType)) {
			throw new RuntimeException("Invalid TypeToken; must specify type parameters");
		}
		ParameterizedType pt = (ParameterizedType) t;
		if (pt.getRawType() != TypeToken.class) {
			throw new RuntimeException("Invalid TypeToken; must directly extend TypeToken");
		}
		return pt.getActualTypeArguments()[0];
	}

//	public static TypeToken<?> get(Type type) {
//		return new SimpleTypeToken<Object>(type);
//	}
//
//	private static class SimpleTypeToken<T> extends TypeToken<T> {
//		public SimpleTypeToken(Type type) {
//			super(type);
//		}
//	}
}

@@ -222,15 +222,18 @@
 pile
+%0A *
  time.%0A
-
  * %0A
@@ -447,16 +447,17 @@
 s.be%3E%0A *
+ 
 %0A * @par
@@ -462,16 +462,30 @@
 aram %3CT%3E
+%0A *           
  The typ
@@ -682,18 +682,16 @@
 ();%0A%09%7D%0A%0A
-//
 %09private
@@ -714,18 +714,16 @@
 type) %7B%0A
-//
 %09%09this.t
@@ -734,18 +734,16 @@
 = type;%0A
-//
 %09%7D%0A%0A%09pub
@@ -1212,18 +1212,84 @@
 0%5D;%0A%09%7D%0A%0A
-//
+%09/**%0A%09 * Gets type token for the given %7B@code Class%7D instance.%0A%09 */%0A
 %09public 
@@ -1294,16 +1294,20 @@
 c static
+ %3CT%3E
  TypeTok
@@ -1313,15 +1313,174 @@
 ken%3C
-?
+T
 %3E get(
+Class%3CT%3E type) %7B%0A%09%09return new SimpleTypeToken%3CT%3E(type);%0A%09%7D%0A%0A%09/**%0A%09 * Gets type token for the given %7B@code Type%7D instance.%0A%09 */%0A%09public static TypeToken%3C?%3E get(
 Type
@@ -1488,18 +1488,16 @@
 type) %7B%0A
-//
 %09%09return
@@ -1536,18 +1536,12 @@
 e);%0A
-//
 %09%7D%0A
-//%0A//
+%0A
 %09pri
@@ -1600,18 +1600,16 @@
 en%3CT%3E %7B%0A
-//
 %09%09public
@@ -1638,18 +1638,16 @@
 type) %7B%0A
-//
 %09%09%09super
@@ -1658,16 +1658,209 @@
 e);%0A
-//%09%09%7D%0A//
+%09%09%7D%0A%09%7D%0A%0A%09@Override%0A%09public boolean equals(Object obj) %7B%0A%09%09return (obj instanceof TypeToken) && type.equals(((TypeToken%3C?%3E) obj).type);%0A%09%7D%0A%0A%09@Override%0A%09public int hashCode() %7B%0A%09%09return type.hashCode();%0A
 %09%7D%0A%7D

add static get methods (like in gson), and equals and hashcode