@SuppressWarnings("unchecked")
	// use runtime checks to guarantee that 'T' is what it is
	private <T> ObjectConstructor<T> newDefaultImplementationConstructor(Type type, Class<? super T> rawType) {
		if (Collection.class.isAssignableFrom(rawType)) {
			if (SortedSet.class.isAssignableFrom(rawType)) {
				return new ObjectConstructor<T>() {
					public T construct() {
						return (T) new TreeSet<Object>();
					}
				};
			} else if (Set.class.isAssignableFrom(rawType)) {
				return new ObjectConstructor<T>() {
					public T construct() {
						return (T) new LinkedHashSet<Object>();
					}
				};
			} else if (Queue.class.isAssignableFrom(rawType)) {
				return new ObjectConstructor<T>() {
					public T construct() {
						return (T) new LinkedList<Object>();
					}
				};
			} else {
				return new ObjectConstructor<T>() {
					public T construct() {
						return (T) new ArrayList<Object>();
					}
				};
			}
		}

		if (Map.class.isAssignableFrom(rawType)) {
			if (SortedMap.class.isAssignableFrom(rawType)) {
				return new ObjectConstructor<T>() {
					public T construct() {
						return (T) new TreeMap<Object, Object>();
					}
				};
			} else if (type instanceof ParameterizedType
					&& !(String.class.isAssignableFrom(TypeToken.get(((ParameterizedType) type).getActualTypeArguments()[0])
							.getRawType()))) {
				return new ObjectConstructor<T>() {
					public T construct() {
						return (T) new LinkedHashMap<Object, Object>();
					}
				};
			} else {
				return new ObjectConstructor<T>() {
					public T construct() {
						return (T) new LinkedTreeMap<String, Object>();
					}
				};
			}
		}

		return null;
	}