diff --git a/annotations/jdi/com/sun/jdi/annotations.xml b/annotations/jdi/com/sun/jdi/annotations.xml
new file mode 100644
index 00000000000..baac6359e80
--- /dev/null
+++ b/annotations/jdi/com/sun/jdi/annotations.xml
@@ -0,0 +1,20 @@
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
\ No newline at end of file
diff --git a/src/org/jetbrains/eval4j/jdi/jdiEval.kt b/src/org/jetbrains/eval4j/jdi/jdiEval.kt
new file mode 100644
index 00000000000..73a39dcb563
--- /dev/null
+++ b/src/org/jetbrains/eval4j/jdi/jdiEval.kt
@@ -0,0 +1,113 @@
+package org.jetbrains.eval4j.jdi
+
+import org.jetbrains.eval4j.*
+import org.objectweb.asm.Type
+import com.sun.jdi
+
+val CLASS = Type.getType(javaClass>())
+
+class JDIEval(
+ private val vm: jdi.VirtualMachine,
+ private val classLoader: jdi.ClassLoaderReference,
+ private val thread: jdi.ThreadReference
+) : Eval {
+ override fun loadClass(classType: Type): Value {
+ return invokeStaticMethod(
+ MethodDescription(
+ CLASS.getInternalName(),
+ "forName",
+ "(Ljava/lang/String;Ljava/lang/ClassLoader;)Ljava/lang/Class;",
+ true
+ ),
+ listOf(classLoader.asValue())
+ )
+ }
+
+ override fun loadString(str: String): Value = vm.mirrorOf(str)!!.asValue()
+
+ override fun newInstance(classType: Type): Value {
+ return NewObjectValue(classType)
+ }
+
+ override fun isInstanceOf(value: Value, targetType: Type): Boolean {
+ assert(targetType.getSort() == Type.OBJECT, "Can't check isInstanceOf() for non-object type $targetType")
+
+ val _class = loadClass(targetType)
+ return invokeMethod(
+ _class,
+ MethodDescription(
+ CLASS.getInternalName(),
+ "isInstance",
+ "(Ljava/lang/Object;)Z",
+ false
+ ),
+ listOf(value)).boolean
+ }
+
+ override fun newArray(arrayType: Type, size: Int): Value {
+ throw UnsupportedOperationException()
+ }
+ override fun newMultiDimensionalArray(arrayType: Type, dimensionSizes: List): Value {
+ throw UnsupportedOperationException()
+ }
+ override fun getArrayLength(array: Value): Value {
+ throw UnsupportedOperationException()
+ }
+ override fun getArrayElement(array: Value, index: Value): Value {
+ throw UnsupportedOperationException()
+ }
+ override fun setArrayElement(array: Value, index: Value, newValue: Value) {
+ throw UnsupportedOperationException()
+ }
+
+ private fun findField(fieldDesc: FieldDescription): jdi.Field {
+ val _class = loadClass(fieldDesc.ownerType).jdiClass!!.reflectedType()
+ val field = _class.fieldByName(fieldDesc.name)
+ if (field == null) {
+ throwException(NoSuchFieldError("Field not found: $fieldDesc"))
+ }
+ return field
+ }
+
+ private fun findStaticField(fieldDesc: FieldDescription): jdi.Field {
+ val field = findField(fieldDesc)
+ if (!field.isStatic()) {
+ throwException(NoSuchFieldError("Field is not static: $fieldDesc"))
+ }
+ return field
+ }
+
+ override fun getStaticField(fieldDesc: FieldDescription): Value {
+ val field = findStaticField(fieldDesc)
+ return field.declaringType().getValue(field).asValue()
+ }
+
+ override fun setStaticField(fieldDesc: FieldDescription, newValue: Value) {
+ val field = findStaticField(fieldDesc)
+
+ if (field.isFinal()) {
+ throwException(NoSuchFieldError("Can't modify a final field: $field"))
+ }
+
+ val _class = field.declaringType()
+ if (_class !is jdi.ClassType) {
+ throwException(NoSuchFieldError("Can't a field in a non-class: $field"))
+ }
+
+ _class.setValue(field, newValue.asJdiValue(vm))
+ }
+
+ override fun invokeStaticMethod(methodDesc: MethodDescription, arguments: List): Value {
+ throw UnsupportedOperationException()
+ }
+
+ override fun getField(instance: Value, fieldDesc: FieldDescription): Value {
+ throw UnsupportedOperationException()
+ }
+ override fun setField(instance: Value, fieldDesc: FieldDescription, newValue: Value) {
+ throw UnsupportedOperationException()
+ }
+ override fun invokeMethod(instance: Value, methodDesc: MethodDescription, arguments: List, invokespecial: Boolean): Value {
+ throw UnsupportedOperationException()
+ }
+}
\ No newline at end of file