package org.minimallycorrect.javatransformer.api;

import lombok.Data;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.val;

import java.util.*;

@Data
@RequiredArgsConstructor(staticName = "of")
public class Annotation {
	@NonNull
	public final Type type;
	@NonNull
	public final Map<String, Object> values;

	public static Annotation of(Type t, Object value) {
		val map = new HashMap<String, Object>();
		map.put("value", value);
		return of(t, map);
	}

	public static Annotation of(Type t) {
		return of(t, Collections.emptyMap());
	}
}

@@ -58,20 +58,17 @@
  lombok.
-Data
+*
 ;%0Aimport
@@ -72,79 +72,65 @@
 ort 
-lombok.NonNull;%0Aimport lombok.RequiredArgsConstructor;%0Aimport lombok.va
+org.minimallycorrect.javatransformer.internal.util.JVMUti
 l;%0A%0A
@@ -263,32 +263,86 @@
 type;%0A%09@NonNull%0A
+%09@Getter(AccessLevel.NONE)%0A%09@Setter(AccessLevel.NONE)%0A
 %09public final Ma
@@ -555,16 +555,16 @@
 pe t) %7B%0A
-
 %09%09return
@@ -597,11 +597,1261 @@
 p());%0A%09%7D
+%0A%0A%09@SuppressWarnings(%22unchecked%22)%0A%09public %3CT%3E T get(String key, Class%3CT%3E clazz) %7B%0A%09%09val value = values.get(key);%0A%09%09if (value == null)%0A%09%09%09return null;%0A%09%09if (clazz.isAssignableFrom(value.getClass()))%0A%09%09%09return (T) value;%0A%09%09if (clazz.isEnum()) %7B%0A%09%09%09if (!(value instanceof String%5B%5D))%0A%09%09%09%09throw new IllegalArgumentException(%22value for %22 + key + %22 is not a String%5B%5D so can't be mapped to enum. Actual type %22 + value.getClass().getName() + %22 value %22 + value);%0A%09%09%09val array = ((String%5B%5D) value);%0A%09%09%09val type = new Type(array%5B0%5D);%0A%09%09%09if (!type.getClassName().endsWith(clazz.getName()))%0A%09%09%09%09throw new IllegalArgumentException(%22value for %22 + key + %22 is of enum type %22 + type + %22 which does not match expected type %22 + clazz.getName() + %22 actual value %22 + Arrays.toString(array));%0A%09%09%09return (T) JVMUtil.searchEnum((Class%3C? extends Enum%3C?%3E%3E) clazz, key);%0A%09%09%7D%0A%09%09throw new UnsupportedOperationException(%22Can't convert enum value of type %22 + value.getClass().getName() + %22 value %22 + value + %22 to %22 + clazz.getName());%0A%09%7D%0A%0A%09public void set(String key, Object value) %7B%0A%09%09if (value != null) %7B%0A%09%09%09val clazz = value.getClass();%0A%09%09%09if (clazz.isEnum())%0A%09%09%09%09value = new String%5B%5D %7B Type.of(clazz.getName()).descriptor, ((Enum) value).name()%7D;%0A%09%09%7D%0A%09%09values.put(key, value);%0A%09%7D
 %0A%7D%0A

Add type-safe methods for working with Annotation values