Revert^4 "Allow structural redefinition on non-final classes."

This reverts commit 664999a12d6fc8a8ef5c0519b12ec1e8a51bb085.

Fixed issues with GC and quickened instructions in parent CLs.

Reason for revert: Fixed issues with GC CHECK fail and device SEGVs.

Test: ./test.py --host
Test: ./test.py --target
Bug: 134162467
Bug: 144168550
Change-Id: Ibacddaf45beb72184f97d53d5d048bd442578658
diff --git a/test/1983-structural-redefinition-failures/expected.txt b/test/1983-structural-redefinition-failures/expected.txt
index 40a0914..222aac4 100644
--- a/test/1983-structural-redefinition-failures/expected.txt
+++ b/test/1983-structural-redefinition-failures/expected.txt
@@ -24,13 +24,13 @@
 Is Structurally modifiable class java.lang.invoke.VarHandle false
 Is Structurally modifiable class java.lang.invoke.FieldVarHandle false
 Checking non-mirror'd classes
-Is Structurally modifiable class java.util.ArrayList false
+Is Structurally modifiable class java.util.ArrayList true
 Is Structurally modifiable class java.util.Objects true
 Is Structurally modifiable class java.util.Arrays true
 Is Structurally modifiable class [Ljava.lang.Object; false
 Is Structurally modifiable class java.lang.Integer true
-Is Structurally modifiable class java.lang.Number false
+Is Structurally modifiable class java.lang.Number true
 Is Structurally modifiable class art.Test1983$NoVirtuals true
-Is Structurally modifiable class art.Test1983$WithVirtuals false
-Is Structurally modifiable class art.Test1983$SubWithVirtuals false
+Is Structurally modifiable class art.Test1983$WithVirtuals true
+Is Structurally modifiable class art.Test1983$SubWithVirtuals true
 Is Structurally modifiable class java.lang.invoke.MethodHandles true
diff --git a/test/1993-fallback-non-structural/expected.txt b/test/1993-fallback-non-structural/expected.txt
index 7e2cdf4..f523e70 100644
--- a/test/1993-fallback-non-structural/expected.txt
+++ b/test/1993-fallback-non-structural/expected.txt
@@ -1,3 +1,3 @@
-Can structurally Redefine: false
+Can structurally Redefine: true
 hello
 Goodbye
diff --git a/test/1993-fallback-non-structural/src/art/Test1993.java b/test/1993-fallback-non-structural/src/art/Test1993.java
index f442099..e2a8f6e 100644
--- a/test/1993-fallback-non-structural/src/art/Test1993.java
+++ b/test/1993-fallback-non-structural/src/art/Test1993.java
@@ -17,6 +17,7 @@
 package art;
 
 import java.util.Base64;
+import java.lang.reflect.*;
 public class Test1993 {
 
   static class Transform {
@@ -61,17 +62,25 @@
     "AAAASAEAAAMgAAACAAAAgAEAAAEQAAABAAAAjAEAAAIgAAAVAAAAkgEAAAQgAAACAAAALAMAAAAg" +
     "AAABAAAAOwMAAAMQAAACAAAATAMAAAYgAAABAAAAXAMAAAAQAAABAAAAbAMAAA==");
 
-  public static void run() {
+  public static void run() throws Exception {
     Redefinition.setTestConfiguration(Redefinition.Config.COMMON_REDEFINE);
     doTest(new Transform());
   }
 
-  public static void doTest(Transform t) {
-    // TODO Remove this once the class is structurally modifiable.
+  public static void doTest(Transform t) throws Exception {
     System.out.println("Can structurally Redefine: " +
       Redefinition.isStructurallyModifiable(Transform.class));
     t.sayHi();
     Redefinition.doCommonStructuralClassRedefinition(Transform.class, DEX_BYTES);
     t.sayHi();
+    // Check and make sure we didn't structurally redefine by looking for ClassExt.obsoleteClass
+    Field ext_data_field = Class.class.getDeclaredField("extData");
+    ext_data_field.setAccessible(true);
+    Object ext_data = ext_data_field.get(Transform.class);
+    Field obsolete_class_field = ext_data.getClass().getDeclaredField("obsoleteClass");
+    obsolete_class_field.setAccessible(true);
+    if (obsolete_class_field.get(ext_data) != null)  {
+      System.out.println("Expected no ClassExt.obsoleteClass but got " + obsolete_class_field.get(ext_data));
+    }
   }
 }
diff --git a/test/1999-virtual-structural/expected.txt b/test/1999-virtual-structural/expected.txt
new file mode 100644
index 0000000..335b5d7
--- /dev/null
+++ b/test/1999-virtual-structural/expected.txt
@@ -0,0 +1,4 @@
+Hi(SubTransform called 1 times)
+Hi(SubTransform called 2 times)
+Hi(SubTransform called 3 times)
+Hello (Transform called 1 times)(SubTransform called 4 times)
diff --git a/test/1999-virtual-structural/info.txt b/test/1999-virtual-structural/info.txt
new file mode 100644
index 0000000..606c984
--- /dev/null
+++ b/test/1999-virtual-structural/info.txt
@@ -0,0 +1,3 @@
+Tests basic functions in the jvmti plugin.
+
+Tests that using the structural redefinition can add new virtual methods and fields.
diff --git a/test/1999-virtual-structural/run b/test/1999-virtual-structural/run
new file mode 100755
index 0000000..03e41a5
--- /dev/null
+++ b/test/1999-virtual-structural/run
@@ -0,0 +1,17 @@
+#!/bin/bash
+#
+# Copyright 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+./default-run "$@" --jvmti --runtime-option -Xopaque-jni-ids:true
diff --git a/test/1999-virtual-structural/src/Main.java b/test/1999-virtual-structural/src/Main.java
new file mode 100644
index 0000000..86a492b
--- /dev/null
+++ b/test/1999-virtual-structural/src/Main.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+public class Main {
+  public static void main(String[] args) throws Exception {
+    art.Test1999.run();
+  }
+}
diff --git a/test/1999-virtual-structural/src/art/Redefinition.java b/test/1999-virtual-structural/src/art/Redefinition.java
new file mode 120000
index 0000000..81eaf31
--- /dev/null
+++ b/test/1999-virtual-structural/src/art/Redefinition.java
@@ -0,0 +1 @@
+../../../jvmti-common/Redefinition.java
\ No newline at end of file
diff --git a/test/1999-virtual-structural/src/art/Test1999.java b/test/1999-virtual-structural/src/art/Test1999.java
new file mode 100644
index 0000000..f6811a9
--- /dev/null
+++ b/test/1999-virtual-structural/src/art/Test1999.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package art;
+
+import java.util.Base64;
+public class Test1999 {
+
+  public static class Transform {
+    public String getGreeting() {
+      return "Hi";
+    }
+  }
+
+  public static class SubTransform extends Transform {
+    private int count = 0;
+    public void sayHi() {
+      System.out.println(getGreeting() + "(SubTransform called " + (++count) + " times)");
+    }
+  }
+
+  /**
+   * base64 encoded class/dex file for
+   * public static class Transform {
+   *   private int count;
+   *   public String getGreeting() {
+   *     return "Hello (Transform called " + incrCount() + " times)";
+   *   }
+   *   protected int incrCount() {
+   *     return ++count;
+   *   }
+   * }
+   */
+  private static final byte[] DEX_BYTES = Base64.getDecoder().decode(
+"ZGV4CjAzNQAwwbMpPdPdWkU+6UJnvqa7v4VBdcuq2vkMBQAAcAAAAHhWNBIAAAAAAAAAAEgEAAAa" +
+"AAAAcAAAAAkAAADYAAAABQAAAPwAAAABAAAAOAEAAAgAAABAAQAAAQAAAIABAABsAwAAoAEAADoC" +
+"AABDAgAASwIAAGUCAABoAgAAawIAAG8CAABzAgAAjQIAAJ0CAADBAgAA4QIAAPUCAAAJAwAAJAMA" +
+"ADMDAAA+AwAAQQMAAE4DAABWAwAAXQMAAGoDAAB1AwAAewMAAIUDAACMAwAAAwAAAAcAAAAIAAAA" +
+"CQAAAAoAAAALAAAADAAAAA0AAAAQAAAAAwAAAAAAAAAAAAAABAAAAAYAAAAAAAAABQAAAAcAAAAs" +
+"AgAABgAAAAcAAAA0AgAAEAAAAAgAAAAAAAAAAQAAABMAAAABAAQAAQAAAAEAAQAUAAAAAQAAABUA" +
+"AAAFAAQAAQAAAAcABAABAAAABwACABIAAAAHAAMAEgAAAAcAAQAXAAAAAQAAAAEAAAAFAAAAAAAA" +
+"AA4AAAA4BAAAEwQAAAAAAAACAAEAAAAAACgCAAAHAAAAUhAAANgAAAFZEAAADwAAAAQAAQACAAAA" +
+"JAIAABsAAABuEAIAAwAKACIBBwBwEAQAAQAaAgIAbiAGACEAbiAFAAEAGgAAAG4gBgABAG4QBwAB" +
+"AAwAEQAAAAEAAQABAAAAIAIAAAQAAABwEAMAAAAOAAMADgAGAA4ACQAOAAEAAAAAAAAAAQAAAAYA" +
+"ByB0aW1lcykABjxpbml0PgAYSGVsbG8gKFRyYW5zZm9ybSBjYWxsZWQgAAFJAAFMAAJMSQACTEwA" +
+"GExhcnQvVGVzdDE5OTkkVHJhbnNmb3JtOwAOTGFydC9UZXN0MTk5OTsAIkxkYWx2aWsvYW5ub3Rh" +
+"dGlvbi9FbmNsb3NpbmdDbGFzczsAHkxkYWx2aWsvYW5ub3RhdGlvbi9Jbm5lckNsYXNzOwASTGph" +
+"dmEvbGFuZy9PYmplY3Q7ABJMamF2YS9sYW5nL1N0cmluZzsAGUxqYXZhL2xhbmcvU3RyaW5nQnVp" +
+"bGRlcjsADVRlc3QxOTk5LmphdmEACVRyYW5zZm9ybQABVgALYWNjZXNzRmxhZ3MABmFwcGVuZAAF" +
+"Y291bnQAC2dldEdyZWV0aW5nAAlpbmNyQ291bnQABG5hbWUACHRvU3RyaW5nAAV2YWx1ZQB2fn5E" +
+"OHsiY29tcGlsYXRpb24tbW9kZSI6ImRlYnVnIiwibWluLWFwaSI6MSwic2hhLTEiOiI2MGRhNGQ2" +
+"N2IzODFjNDI0Njc3NTdjNDlmYjZlNTU3NTZkODhhMmYzIiwidmVyc2lvbiI6IjEuNy4xMi1kZXYi" +
+"fQACAwEYGAICBAIRBAkWFw8AAQECAAIAgYAEiAQBAcADAQSgAwAAAAAAAgAAAAQEAAAKBAAALAQA" +
+"AAAAAAAAAAAAAAAAABAAAAAAAAAAAQAAAAAAAAABAAAAGgAAAHAAAAACAAAACQAAANgAAAADAAAA" +
+"BQAAAPwAAAAEAAAAAQAAADgBAAAFAAAACAAAAEABAAAGAAAAAQAAAIABAAABIAAAAwAAAKABAAAD" +
+"IAAAAwAAACACAAABEAAAAgAAACwCAAACIAAAGgAAADoCAAAEIAAAAgAAAAQEAAAAIAAAAQAAABME" +
+"AAADEAAAAgAAACgEAAAGIAAAAQAAADgEAAAAEAAAAQAAAEgEAAA=");
+
+
+  public static void run() {
+    Redefinition.setTestConfiguration(Redefinition.Config.COMMON_REDEFINE);
+    doTest(new SubTransform());
+  }
+
+  public static void doTest(SubTransform t) {
+    t.sayHi();
+    t.sayHi();
+    t.sayHi();
+    Redefinition.doCommonStructuralClassRedefinition(Transform.class, DEX_BYTES);
+    t.sayHi();
+  }
+}
diff --git a/test/2000-virtual-list-structural/AbstractCollection.patch b/test/2000-virtual-list-structural/AbstractCollection.patch
new file mode 100644
index 0000000..7507c7d
--- /dev/null
+++ b/test/2000-virtual-list-structural/AbstractCollection.patch
@@ -0,0 +1,16 @@
+--- ../../../libcore/ojluni/src/main/java/java/util/AbstractCollection.java	2019-05-31 10:36:26.634361294 -0700
++++ src-ex/java/util/AbstractCollection.java	2019-11-18 13:04:48.253575013 -0800
+@@ -63,7 +63,13 @@
+      * Sole constructor.  (For invocation by subclass constructors, typically
+      * implicit.)
+      */
++    public static volatile int TOTAL_COUNT;
++    public int cnt;
++
+     protected AbstractCollection() {
++      synchronized (Collection.class) {
++        cnt = ++TOTAL_COUNT;
++      }
+     }
+ 
+     // Query Operations
diff --git a/test/2000-virtual-list-structural/build b/test/2000-virtual-list-structural/build
new file mode 100755
index 0000000..87d6acc
--- /dev/null
+++ b/test/2000-virtual-list-structural/build
@@ -0,0 +1,31 @@
+#!/bin/bash
+#
+# Copyright 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Stop on failure.
+set -e
+
+# Deref the symlink.
+mv src-ex/java/util/AbstractCollection.java src-ex/java/util/AbstractCollection.bak
+cp src-ex/java/util/AbstractCollection.bak src-ex/java/util/AbstractCollection.java
+
+# Patch the copied version.
+patch src-ex/java/util/AbstractCollection.java AbstractCollection.patch
+
+DESUGAR=false ./default-build "$@"
+
+# restore the symlink
+rm src-ex/java/util/AbstractCollection.java
+mv src-ex/java/util/AbstractCollection.bak src-ex/java/util/AbstractCollection.java
diff --git a/test/2000-virtual-list-structural/expected.txt b/test/2000-virtual-list-structural/expected.txt
new file mode 100644
index 0000000..9d3e1b6
--- /dev/null
+++ b/test/2000-virtual-list-structural/expected.txt
@@ -0,0 +1,5 @@
+List is: [a, b, c, d]
+List is: [1, 2, 3, 4]
+List is: [1, 2, 3, 4, xyz: 0, xyz: 1, xyz: 2, xyz: 3, xyz: 4, xyz: 5, xyz: 6, xyz: 7, xyz: 8, xyz: 9, xyz: 10, xyz: 11, xyz: 12, xyz: 13, xyz: 14, xyz: 15, xyz: 16, xyz: 17, xyz: 18, xyz: 19, xyz: 20, xyz: 21, xyz: 22, xyz: 23, xyz: 24, xyz: 25, xyz: 26, xyz: 27, xyz: 28, xyz: 29, xyz: 30, xyz: 31, xyz: 32, xyz: 33, xyz: 34, xyz: 35, xyz: 36, xyz: 37, xyz: 38, xyz: 39, xyz: 40, xyz: 41, xyz: 42, xyz: 43, xyz: 44, xyz: 45, xyz: 46, xyz: 47, xyz: 48, xyz: 49, xyz: 50, xyz: 51, xyz: 52, xyz: 53, xyz: 54, xyz: 55, xyz: 56, xyz: 57, xyz: 58, xyz: 59, xyz: 60, xyz: 61, xyz: 62, xyz: 63, xyz: 64, xyz: 65, xyz: 66, xyz: 67, xyz: 68, xyz: 69, xyz: 70, xyz: 71, xyz: 72, xyz: 73, xyz: 74, xyz: 75, xyz: 76, xyz: 77, xyz: 78, xyz: 79, xyz: 80, xyz: 81, xyz: 82, xyz: 83, xyz: 84, xyz: 85, xyz: 86, xyz: 87, xyz: 88, xyz: 89, xyz: 90, xyz: 91, xyz: 92, xyz: 93, xyz: 94, xyz: 95, xyz: 96, xyz: 97, xyz: 98, xyz: 99, xyz: 100, xyz: 101, xyz: 102, xyz: 103, xyz: 104, xyz: 105, xyz: 106, xyz: 107, xyz: 108, xyz: 109, xyz: 110, xyz: 111, xyz: 112, xyz: 113, xyz: 114, xyz: 115, xyz: 116, xyz: 117, xyz: 118, xyz: 119, xyz: 120, xyz: 121, xyz: 122, xyz: 123, xyz: 124, xyz: 125, xyz: 126, xyz: 127, xyz: 128, xyz: 129, xyz: 130, xyz: 131, xyz: 132, xyz: 133, xyz: 134, xyz: 135, xyz: 136, xyz: 137, xyz: 138, xyz: 139, xyz: 140, xyz: 141, xyz: 142, xyz: 143, xyz: 144, xyz: 145, xyz: 146, xyz: 147, xyz: 148, xyz: 149, xyz: 150, xyz: 151, xyz: 152, xyz: 153, xyz: 154, xyz: 155, xyz: 156, xyz: 157, xyz: 158, xyz: 159, xyz: 160, xyz: 161, xyz: 162, xyz: 163, xyz: 164, xyz: 165, xyz: 166, xyz: 167, xyz: 168, xyz: 169, xyz: 170, xyz: 171, xyz: 172, xyz: 173, xyz: 174, xyz: 175, xyz: 176, xyz: 177, xyz: 178, xyz: 179, xyz: 180, xyz: 181, xyz: 182, xyz: 183, xyz: 184, xyz: 185, xyz: 186, xyz: 187, xyz: 188, xyz: 189, xyz: 190, xyz: 191, xyz: 192, xyz: 193, xyz: 194, xyz: 195, xyz: 196, xyz: 197, xyz: 198, xyz: 199, xyz: 200, xyz: 201, xyz: 202, xyz: 203, xyz: 204, xyz: 205, xyz: 206, xyz: 207, xyz: 208, xyz: 209, xyz: 210, xyz: 211, xyz: 212, xyz: 213, xyz: 214, xyz: 215, xyz: 216, xyz: 217, xyz: 218, xyz: 219, xyz: 220, xyz: 221, xyz: 222, xyz: 223, xyz: 224, xyz: 225, xyz: 226, xyz: 227, xyz: 228, xyz: 229, xyz: 230, xyz: 231, xyz: 232, xyz: 233, xyz: 234, xyz: 235, xyz: 236, xyz: 237, xyz: 238, xyz: 239, xyz: 240, xyz: 241, xyz: 242, xyz: 243, xyz: 244, xyz: 245, xyz: 246, xyz: 247, xyz: 248, xyz: 249, xyz: 250, xyz: 251, xyz: 252, xyz: 253, xyz: 254, xyz: 255, xyz: 256, xyz: 257, xyz: 258, xyz: 259, xyz: 260, xyz: 261, xyz: 262, xyz: 263, xyz: 264, xyz: 265, xyz: 266, xyz: 267, xyz: 268, xyz: 269, xyz: 270, xyz: 271, xyz: 272, xyz: 273, xyz: 274, xyz: 275, xyz: 276, xyz: 277, xyz: 278, xyz: 279, xyz: 280, xyz: 281, xyz: 282, xyz: 283, xyz: 284, xyz: 285, xyz: 286, xyz: 287, xyz: 288, xyz: 289, xyz: 290, xyz: 291, xyz: 292, xyz: 293, xyz: 294, xyz: 295, xyz: 296, xyz: 297, xyz: 298, xyz: 299, xyz: 300, xyz: 301, xyz: 302, xyz: 303, xyz: 304, xyz: 305, xyz: 306, xyz: 307, xyz: 308, xyz: 309, xyz: 310, xyz: 311, xyz: 312, xyz: 313, xyz: 314, xyz: 315, xyz: 316, xyz: 317, xyz: 318, xyz: 319, xyz: 320, xyz: 321, xyz: 322, xyz: 323, xyz: 324, xyz: 325, xyz: 326, xyz: 327, xyz: 328, xyz: 329, xyz: 330, xyz: 331, xyz: 332, xyz: 333, xyz: 334, xyz: 335, xyz: 336, xyz: 337, xyz: 338, xyz: 339, xyz: 340, xyz: 341, xyz: 342, xyz: 343, xyz: 344, xyz: 345, xyz: 346, xyz: 347, xyz: 348, xyz: 349, xyz: 350, xyz: 351, xyz: 352, xyz: 353, xyz: 354, xyz: 355, xyz: 356, xyz: 357, xyz: 358, xyz: 359, xyz: 360, xyz: 361, xyz: 362, xyz: 363, xyz: 364, xyz: 365, xyz: 366, xyz: 367, xyz: 368, xyz: 369, xyz: 370, xyz: 371, xyz: 372, xyz: 373, xyz: 374, xyz: 375, xyz: 376, xyz: 377, xyz: 378, xyz: 379, xyz: 380, xyz: 381, xyz: 382, xyz: 383, xyz: 384, xyz: 385, xyz: 386, xyz: 387, xyz: 388, xyz: 389, xyz: 390, xyz: 391, xyz: 392, xyz: 393, xyz: 394, xyz: 395, xyz: 396, xyz: 397, xyz: 398, xyz: 399, xyz: 400, xyz: 401, xyz: 402, xyz: 403, xyz: 404, xyz: 405, xyz: 406, xyz: 407, xyz: 408, xyz: 409, xyz: 410, xyz: 411, xyz: 412, xyz: 413, xyz: 414, xyz: 415, xyz: 416, xyz: 417, xyz: 418, xyz: 419, xyz: 420, xyz: 421, xyz: 422, xyz: 423, xyz: 424, xyz: 425, xyz: 426, xyz: 427, xyz: 428, xyz: 429, xyz: 430, xyz: 431, xyz: 432, xyz: 433, xyz: 434, xyz: 435, xyz: 436, xyz: 437, xyz: 438, xyz: 439, xyz: 440, xyz: 441, xyz: 442, xyz: 443, xyz: 444, xyz: 445, xyz: 446, xyz: 447, xyz: 448, xyz: 449, xyz: 450, xyz: 451, xyz: 452, xyz: 453, xyz: 454, xyz: 455, xyz: 456, xyz: 457, xyz: 458, xyz: 459, xyz: 460, xyz: 461, xyz: 462, xyz: 463, xyz: 464, xyz: 465, xyz: 466, xyz: 467, xyz: 468, xyz: 469, xyz: 470, xyz: 471, xyz: 472, xyz: 473, xyz: 474, xyz: 475, xyz: 476, xyz: 477, xyz: 478, xyz: 479, xyz: 480, xyz: 481, xyz: 482, xyz: 483, xyz: 484, xyz: 485, xyz: 486, xyz: 487, xyz: 488, xyz: 489, xyz: 490, xyz: 491, xyz: 492, xyz: 493, xyz: 494, xyz: 495, xyz: 496, xyz: 497, xyz: 498, xyz: 499, xyz: 500, xyz: 501, xyz: 502, xyz: 503, xyz: 504, xyz: 505, xyz: 506, xyz: 507, xyz: 508, xyz: 509, xyz: 510, xyz: 511, xyz: 512, xyz: 513, xyz: 514, xyz: 515, xyz: 516, xyz: 517, xyz: 518, xyz: 519, xyz: 520, xyz: 521, xyz: 522, xyz: 523, xyz: 524, xyz: 525, xyz: 526, xyz: 527, xyz: 528, xyz: 529, xyz: 530, xyz: 531, xyz: 532, xyz: 533, xyz: 534, xyz: 535, xyz: 536, xyz: 537, xyz: 538, xyz: 539, xyz: 540, xyz: 541, xyz: 542, xyz: 543, xyz: 544, xyz: 545, xyz: 546, xyz: 547, xyz: 548, xyz: 549, xyz: 550, xyz: 551, xyz: 552, xyz: 553, xyz: 554, xyz: 555, xyz: 556, xyz: 557, xyz: 558, xyz: 559, xyz: 560, xyz: 561, xyz: 562, xyz: 563, xyz: 564, xyz: 565, xyz: 566, xyz: 567, xyz: 568, xyz: 569, xyz: 570, xyz: 571, xyz: 572, xyz: 573, xyz: 574, xyz: 575, xyz: 576, xyz: 577, xyz: 578, xyz: 579, xyz: 580, xyz: 581, xyz: 582, xyz: 583, xyz: 584, xyz: 585, xyz: 586, xyz: 587, xyz: 588, xyz: 589, xyz: 590, xyz: 591, xyz: 592, xyz: 593, xyz: 594, xyz: 595, xyz: 596, xyz: 597, xyz: 598, xyz: 599, xyz: 600, xyz: 601, xyz: 602, xyz: 603, xyz: 604, xyz: 605, xyz: 606, xyz: 607, xyz: 608, xyz: 609, xyz: 610, xyz: 611, xyz: 612, xyz: 613, xyz: 614, xyz: 615, xyz: 616, xyz: 617, xyz: 618, xyz: 619, xyz: 620, xyz: 621, xyz: 622, xyz: 623, xyz: 624, xyz: 625, xyz: 626, xyz: 627, xyz: 628, xyz: 629, xyz: 630, xyz: 631, xyz: 632, xyz: 633, xyz: 634, xyz: 635, xyz: 636, xyz: 637, xyz: 638, xyz: 639, xyz: 640, xyz: 641, xyz: 642, xyz: 643, xyz: 644, xyz: 645, xyz: 646, xyz: 647, xyz: 648, xyz: 649, xyz: 650, xyz: 651, xyz: 652, xyz: 653, xyz: 654, xyz: 655, xyz: 656, xyz: 657, xyz: 658, xyz: 659, xyz: 660, xyz: 661, xyz: 662, xyz: 663, xyz: 664, xyz: 665, xyz: 666, xyz: 667, xyz: 668, xyz: 669, xyz: 670, xyz: 671, xyz: 672, xyz: 673, xyz: 674, xyz: 675, xyz: 676, xyz: 677, xyz: 678, xyz: 679, xyz: 680, xyz: 681, xyz: 682, xyz: 683, xyz: 684, xyz: 685, xyz: 686, xyz: 687, xyz: 688, xyz: 689, xyz: 690, xyz: 691, xyz: 692, xyz: 693, xyz: 694, xyz: 695, xyz: 696, xyz: 697, xyz: 698, xyz: 699, xyz: 700, xyz: 701, xyz: 702, xyz: 703, xyz: 704, xyz: 705, xyz: 706, xyz: 707, xyz: 708, xyz: 709, xyz: 710, xyz: 711, xyz: 712, xyz: 713, xyz: 714, xyz: 715, xyz: 716, xyz: 717, xyz: 718, xyz: 719, xyz: 720, xyz: 721, xyz: 722, xyz: 723, xyz: 724, xyz: 725, xyz: 726, xyz: 727, xyz: 728, xyz: 729, xyz: 730, xyz: 731, xyz: 732, xyz: 733, xyz: 734, xyz: 735, xyz: 736, xyz: 737, xyz: 738, xyz: 739, xyz: 740, xyz: 741, xyz: 742, xyz: 743, xyz: 744, xyz: 745, xyz: 746, xyz: 747, xyz: 748, xyz: 749, xyz: 750, xyz: 751, xyz: 752, xyz: 753, xyz: 754, xyz: 755, xyz: 756, xyz: 757, xyz: 758, xyz: 759, xyz: 760, xyz: 761, xyz: 762, xyz: 763, xyz: 764, xyz: 765, xyz: 766, xyz: 767, xyz: 768, xyz: 769, xyz: 770, xyz: 771, xyz: 772, xyz: 773, xyz: 774, xyz: 775, xyz: 776, xyz: 777, xyz: 778, xyz: 779, xyz: 780, xyz: 781, xyz: 782, xyz: 783, xyz: 784, xyz: 785, xyz: 786, xyz: 787, xyz: 788, xyz: 789, xyz: 790, xyz: 791, xyz: 792, xyz: 793, xyz: 794, xyz: 795, xyz: 796, xyz: 797, xyz: 798, xyz: 799, xyz: 800, xyz: 801, xyz: 802, xyz: 803, xyz: 804, xyz: 805, xyz: 806, xyz: 807, xyz: 808, xyz: 809, xyz: 810, xyz: 811, xyz: 812, xyz: 813, xyz: 814, xyz: 815, xyz: 816, xyz: 817, xyz: 818, xyz: 819, xyz: 820, xyz: 821, xyz: 822, xyz: 823, xyz: 824, xyz: 825, xyz: 826, xyz: 827, xyz: 828, xyz: 829, xyz: 830, xyz: 831, xyz: 832, xyz: 833, xyz: 834, xyz: 835, xyz: 836, xyz: 837, xyz: 838, xyz: 839, xyz: 840, xyz: 841, xyz: 842, xyz: 843, xyz: 844, xyz: 845, xyz: 846, xyz: 847, xyz: 848, xyz: 849, xyz: 850, xyz: 851, xyz: 852, xyz: 853, xyz: 854, xyz: 855, xyz: 856, xyz: 857, xyz: 858, xyz: 859, xyz: 860, xyz: 861, xyz: 862, xyz: 863, xyz: 864, xyz: 865, xyz: 866, xyz: 867, xyz: 868, xyz: 869, xyz: 870, xyz: 871, xyz: 872, xyz: 873, xyz: 874, xyz: 875, xyz: 876, xyz: 877, xyz: 878, xyz: 879, xyz: 880, xyz: 881, xyz: 882, xyz: 883, xyz: 884, xyz: 885, xyz: 886, xyz: 887, xyz: 888, xyz: 889, xyz: 890, xyz: 891, xyz: 892, xyz: 893, xyz: 894, xyz: 895, xyz: 896, xyz: 897, xyz: 898, xyz: 899, xyz: 900, xyz: 901, xyz: 902, xyz: 903, xyz: 904, xyz: 905, xyz: 906, xyz: 907, xyz: 908, xyz: 909, xyz: 910, xyz: 911, xyz: 912, xyz: 913, xyz: 914, xyz: 915, xyz: 916, xyz: 917, xyz: 918, xyz: 919, xyz: 920, xyz: 921, xyz: 922, xyz: 923, xyz: 924, xyz: 925, xyz: 926, xyz: 927, xyz: 928, xyz: 929, xyz: 930, xyz: 931, xyz: 932, xyz: 933, xyz: 934, xyz: 935, xyz: 936, xyz: 937, xyz: 938, xyz: 939, xyz: 940, xyz: 941, xyz: 942, xyz: 943, xyz: 944, xyz: 945, xyz: 946, xyz: 947, xyz: 948, xyz: 949, xyz: 950, xyz: 951, xyz: 952, xyz: 953, xyz: 954, xyz: 955, xyz: 956, xyz: 957, xyz: 958, xyz: 959, xyz: 960, xyz: 961, xyz: 962, xyz: 963, xyz: 964, xyz: 965, xyz: 966, xyz: 967, xyz: 968, xyz: 969, xyz: 970, xyz: 971, xyz: 972, xyz: 973, xyz: 974, xyz: 975, xyz: 976, xyz: 977, xyz: 978, xyz: 979, xyz: 980, xyz: 981, xyz: 982, xyz: 983, xyz: 984, xyz: 985, xyz: 986, xyz: 987, xyz: 988, xyz: 989, xyz: 990, xyz: 991, xyz: 992, xyz: 993, xyz: 994, xyz: 995, xyz: 996, xyz: 997, xyz: 998, xyz: 999]
+List is: [1, 2, 3, 4]
+List is: [a, b, c, d]
diff --git a/test/2000-virtual-list-structural/info.txt b/test/2000-virtual-list-structural/info.txt
new file mode 100644
index 0000000..606c984
--- /dev/null
+++ b/test/2000-virtual-list-structural/info.txt
@@ -0,0 +1,3 @@
+Tests basic functions in the jvmti plugin.
+
+Tests that using the structural redefinition can add new virtual methods and fields.
diff --git a/test/2000-virtual-list-structural/run b/test/2000-virtual-list-structural/run
new file mode 100755
index 0000000..03e41a5
--- /dev/null
+++ b/test/2000-virtual-list-structural/run
@@ -0,0 +1,17 @@
+#!/bin/bash
+#
+# Copyright 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+./default-run "$@" --jvmti --runtime-option -Xopaque-jni-ids:true
diff --git a/test/2000-virtual-list-structural/src-ex/java/util/AbstractCollection.java b/test/2000-virtual-list-structural/src-ex/java/util/AbstractCollection.java
new file mode 120000
index 0000000..a30fbdc
--- /dev/null
+++ b/test/2000-virtual-list-structural/src-ex/java/util/AbstractCollection.java
@@ -0,0 +1 @@
+../../../../../../libcore/ojluni/src/main/java/java/util/AbstractCollection.java
\ No newline at end of file
diff --git a/test/2000-virtual-list-structural/src/Main.java b/test/2000-virtual-list-structural/src/Main.java
new file mode 100644
index 0000000..b2a42c2
--- /dev/null
+++ b/test/2000-virtual-list-structural/src/Main.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import art.*;
+import java.util.*;
+import java.lang.invoke.*;
+import java.io.*;
+import java.util.zip.*;
+
+public class Main {
+  public static final String TEST_NAME = "2000-virtual-list-structural";
+  public static final boolean PRINT_COUNT = false;
+  public static MethodHandles.Lookup lookup = MethodHandles.publicLookup();
+  public static MethodHandle getcnt;
+  public static MethodHandle get_total_cnt;
+  public static void GetHandles() throws Throwable {
+    getcnt = lookup.findGetter(AbstractCollection.class, "cnt", Integer.TYPE);
+    get_total_cnt = lookup.findStaticGetter(AbstractCollection.class, "TOTAL_COUNT", Integer.TYPE);
+  }
+
+  public static byte[] GetDexBytes() throws Throwable {
+    String jar_loc = System.getenv("DEX_LOCATION") + "/" + TEST_NAME + "-ex.jar";
+    try (ZipFile zip = new ZipFile(new File(jar_loc))) {
+      ZipEntry entry = zip.getEntry("classes.dex");
+      try (InputStream is = zip.getInputStream(entry)) {
+        byte[] res = new byte[(int)entry.getSize()];
+        is.read(res);
+        return res;
+      }
+    }
+  }
+  public static void PrintListAndData(AbstractCollection<String> c) throws Throwable {
+    if (PRINT_COUNT) {
+      System.out.println("List is: " + c + " count = " + getcnt.invoke(c) + " TOTAL_COUNT = " + get_total_cnt.invoke());
+    } else {
+      System.out.println("List is: " + c);
+    }
+  }
+  public static void main(String[] args) throws Throwable {
+    AbstractCollection<String> l1 = (AbstractCollection<String>)Arrays.asList("a", "b", "c", "d");
+    AbstractCollection<String> l2 = new ArrayList<>();
+    l2.add("1");
+    l2.add("2");
+    l2.add("3");
+    l2.add("4");
+    Redefinition.doCommonStructuralClassRedefinition(AbstractCollection.class, GetDexBytes());
+    GetHandles();
+    AbstractCollection<String> l3 = new HashSet<>(l2);
+    AbstractCollection<String> l4 = new LinkedList<>(l1);
+    PrintListAndData(l1);
+    PrintListAndData(l2);
+    for (int i = 0; i < 1000; i++) {
+      l2.add("xyz: " + i);
+    }
+    PrintListAndData(l2);
+    PrintListAndData(l3);
+    PrintListAndData(l4);
+    CheckLE(getcnt.invoke(l1), get_total_cnt.invoke());
+    CheckLE(getcnt.invoke(l2), get_total_cnt.invoke());
+    CheckLE(getcnt.invoke(l3), get_total_cnt.invoke());
+    CheckLE(getcnt.invoke(l4), get_total_cnt.invoke());
+    CheckEQ(getcnt.invoke(l1), 0);
+    CheckLE(getcnt.invoke(l2), 0);
+    CheckLE(getcnt.invoke(l1), getcnt.invoke(l2));
+    CheckLE(getcnt.invoke(l1), getcnt.invoke(l3));
+    CheckLE(getcnt.invoke(l1), getcnt.invoke(l4));
+    CheckLE(getcnt.invoke(l2), getcnt.invoke(l3));
+    CheckLE(getcnt.invoke(l2), getcnt.invoke(l4));
+    CheckLE(getcnt.invoke(l3), getcnt.invoke(l4));
+  }
+  public static void CheckEQ(Object a, int b) {
+    CheckEQ(((Integer)a).intValue(), b);
+  }
+  public static void CheckLE(Object a, Object b) {
+    CheckLE(((Integer)a).intValue(), ((Integer)b).intValue());
+  }
+  public static void CheckEQ(int a, int b) {
+    if (a != b) {
+      throw new Error(a + " is not equal to " + b);
+    }
+  }
+  public static void CheckLE(int a, int b) {
+    if (!(a <= b)) {
+      throw new Error(a + " is not less than or equal to " + b);
+    }
+  }
+}
diff --git a/test/2000-virtual-list-structural/src/art/Redefinition.java b/test/2000-virtual-list-structural/src/art/Redefinition.java
new file mode 120000
index 0000000..81eaf31
--- /dev/null
+++ b/test/2000-virtual-list-structural/src/art/Redefinition.java
@@ -0,0 +1 @@
+../../../jvmti-common/Redefinition.java
\ No newline at end of file
diff --git a/test/2001-virtual-structural-multithread/expected.txt b/test/2001-virtual-structural-multithread/expected.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/2001-virtual-structural-multithread/expected.txt
diff --git a/test/2001-virtual-structural-multithread/info.txt b/test/2001-virtual-structural-multithread/info.txt
new file mode 100644
index 0000000..3e5291d
--- /dev/null
+++ b/test/2001-virtual-structural-multithread/info.txt
@@ -0,0 +1,4 @@
+Tests structural redefinition with multiple threads.
+
+Tests that using the structural redefinition while concurrently loading and using a subtype of
+the class being redefined doesn't cause any unexpected problems.
diff --git a/test/2001-virtual-structural-multithread/run b/test/2001-virtual-structural-multithread/run
new file mode 100755
index 0000000..03e41a5
--- /dev/null
+++ b/test/2001-virtual-structural-multithread/run
@@ -0,0 +1,17 @@
+#!/bin/bash
+#
+# Copyright 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+./default-run "$@" --jvmti --runtime-option -Xopaque-jni-ids:true
diff --git a/test/2001-virtual-structural-multithread/src-art/Main.java b/test/2001-virtual-structural-multithread/src-art/Main.java
new file mode 100644
index 0000000..618cdcd
--- /dev/null
+++ b/test/2001-virtual-structural-multithread/src-art/Main.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+public class Main {
+  public static void main(String[] args) throws Exception {
+    art.Test2001.run();
+  }
+}
diff --git a/test/2001-virtual-structural-multithread/src-art/art/Redefinition.java b/test/2001-virtual-structural-multithread/src-art/art/Redefinition.java
new file mode 120000
index 0000000..81eaf31
--- /dev/null
+++ b/test/2001-virtual-structural-multithread/src-art/art/Redefinition.java
@@ -0,0 +1 @@
+../../../jvmti-common/Redefinition.java
\ No newline at end of file
diff --git a/test/2001-virtual-structural-multithread/src-art/art/Test2001.java b/test/2001-virtual-structural-multithread/src-art/art/Test2001.java
new file mode 100644
index 0000000..e6ee0ce
--- /dev/null
+++ b/test/2001-virtual-structural-multithread/src-art/art/Test2001.java
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package art;
+
+import dalvik.system.InMemoryDexClassLoader;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Base64;
+import java.util.concurrent.CountDownLatch;
+import java.util.function.Supplier;
+
+public class Test2001 {
+  private static final int NUM_THREADS = 20;
+
+  public static class Transform {
+    public String greetingEnglish;
+
+    public Transform() {
+      this.greetingEnglish = "Hello";
+    }
+
+    public String sayHi() {
+      return greetingEnglish + " from " + Thread.currentThread().getName();
+    }
+  }
+
+  /**
+   * base64 encoded class/dex file for
+   * public static class Transform {
+   *   public String greetingEnglish;
+   *   public String greetingFrench;
+   *   public String greetingDanish;
+   *   public String greetingJapanese;
+   *
+   *   public Transform() {
+   *     this.greetingEnglish = "Hello World";
+   *     this.greetingFrench = "Bonjour le Monde";
+   *     this.greetingDanish = "Hej Verden";
+   *     this.greetingJapanese = "こんにちは世界";
+   *   }
+   *   public String sayHi() {
+   *     return sayHiEnglish() + ", " + sayHiFrench() + ", " + sayHiDanish() + ", " + sayHiJapanese() + " from " + Thread.currentThread().getName();
+   *   }
+   *   public String sayHiEnglish() {
+   *     return greetingEnglish;
+   *   }
+   *   public String sayHiDanish() {
+   *     return greetingDanish;
+   *   }
+   *   public String sayHiJapanese() {
+   *     return greetingJapanese;
+   *   }
+   *   public String sayHiFrench() {
+   *     return greetingFrench;
+   *   }
+   * }
+   */
+  private static final byte[] DEX_BYTES =
+      Base64.getDecoder()
+          .decode(
+              "ZGV4CjAzNQCnKPY06VRa4aM/zFW0MYLmRxT/NtXxD/H4BgAAcAAAAHhWNBIAAAAAAAAAADQGAAAl"
+                  + "AAAAcAAAAAkAAAAEAQAABAAAACgBAAAEAAAAWAEAAAwAAAB4AQAAAQAAANgBAAAABQAA+AEAAEoD"
+                  + "AABSAwAAVgMAAF4DAABwAwAAfAMAAIkDAACMAwAAkAMAAKoDAAC6AwAA3gMAAP4DAAASBAAAJgQA"
+                  + "AEEEAABVBAAAZAQAAG8EAAByBAAAfwQAAIcEAACWBAAAnwQAAK8EAADABAAA0AQAAOIEAADoBAAA"
+                  + "7wQAAPwEAAAKBQAAFwUAACYFAAAwBQAANwUAAMUFAAAIAAAACQAAAAoAAAALAAAADAAAAA0AAAAO"
+                  + "AAAADwAAABIAAAAGAAAABQAAAAAAAAAHAAAABgAAAEQDAAAGAAAABwAAAAAAAAASAAAACAAAAAAA"
+                  + "AAAAAAUAFwAAAAAABQAYAAAAAAAFABkAAAAAAAUAGgAAAAAAAwACAAAAAAAAABwAAAAAAAAAHQAA"
+                  + "AAAAAAAeAAAAAAAAAB8AAAAAAAAAIAAAAAQAAwACAAAABgADAAIAAAAGAAEAFAAAAAYAAAAhAAAA"
+                  + "BwACABUAAAAHAAAAFgAAAAAAAAABAAAABAAAAAAAAAAQAAAAJAYAAOsFAAAAAAAABwABAAIAAAAt"
+                  + "AwAAQQAAAG4QAwAGAAwAbhAEAAYADAFuEAIABgAMAm4QBQAGAAwDcQAKAAAADARuEAsABAAMBCIF"
+                  + "BgBwEAcABQBuIAgABQAaAAEAbiAIAAUAbiAIABUAbiAIAAUAbiAIACUAbiAIAAUAbiAIADUAGgAA"
+                  + "AG4gCAAFAG4gCABFAG4QCQAFAAwAEQAAAAIAAQAAAAAAMQMAAAMAAABUEAAAEQAAAAIAAQAAAAAA"
+                  + "NQMAAAMAAABUEAEAEQAAAAIAAQAAAAAAOQMAAAMAAABUEAIAEQAAAAIAAQAAAAAAPQMAAAMAAABU"
+                  + "EAMAEQAAAAIAAQABAAAAJAMAABQAAABwEAYAAQAaAAUAWxABABoAAwBbEAIAGgAEAFsQAAAaACQA"
+                  + "WxADAA4ACwAOPEtLS0sAEgAOABgADgAVAA4AHgAOABsADgAAAAABAAAABQAGIGZyb20gAAIsIAAG"
+                  + "PGluaXQ+ABBCb25qb3VyIGxlIE1vbmRlAApIZWogVmVyZGVuAAtIZWxsbyBXb3JsZAABTAACTEwA"
+                  + "GExhcnQvVGVzdDIwMDEkVHJhbnNmb3JtOwAOTGFydC9UZXN0MjAwMTsAIkxkYWx2aWsvYW5ub3Rh"
+                  + "dGlvbi9FbmNsb3NpbmdDbGFzczsAHkxkYWx2aWsvYW5ub3RhdGlvbi9Jbm5lckNsYXNzOwASTGph"
+                  + "dmEvbGFuZy9PYmplY3Q7ABJMamF2YS9sYW5nL1N0cmluZzsAGUxqYXZhL2xhbmcvU3RyaW5nQnVp"
+                  + "bGRlcjsAEkxqYXZhL2xhbmcvVGhyZWFkOwANVGVzdDIwMDEuamF2YQAJVHJhbnNmb3JtAAFWAAth"
+                  + "Y2Nlc3NGbGFncwAGYXBwZW5kAA1jdXJyZW50VGhyZWFkAAdnZXROYW1lAA5ncmVldGluZ0Rhbmlz"
+                  + "aAAPZ3JlZXRpbmdFbmdsaXNoAA5ncmVldGluZ0ZyZW5jaAAQZ3JlZXRpbmdKYXBhbmVzZQAEbmFt"
+                  + "ZQAFc2F5SGkAC3NheUhpRGFuaXNoAAxzYXlIaUVuZ2xpc2gAC3NheUhpRnJlbmNoAA1zYXlIaUph"
+                  + "cGFuZXNlAAh0b1N0cmluZwAFdmFsdWUAiwF+fkQ4eyJjb21waWxhdGlvbi1tb2RlIjoiZGVidWci"
+                  + "LCJoYXMtY2hlY2tzdW1zIjpmYWxzZSwibWluLWFwaSI6MSwic2hhLTEiOiJmNjJiOGNlNmEwNTkw"
+                  + "MDU0ZWYzNGExYWVkZTcwYjQ2NjY4ZThiNDlmIiwidmVyc2lvbiI6IjIuMC4xLWRldiJ9AAfjgZPj"
+                  + "gpPjgavjgaHjga/kuJbnlYwAAgIBIhgBAgMCEwQJGxcRAAQBBQABAQEBAQEBAIGABOwFAQH4AwEB"
+                  + "jAUBAaQFAQG8BQEB1AUAAAAAAAAAAgAAANwFAADiBQAAGAYAAAAAAAAAAAAAAAAAABAAAAAAAAAA"
+                  + "AQAAAAAAAAABAAAAJQAAAHAAAAACAAAACQAAAAQBAAADAAAABAAAACgBAAAEAAAABAAAAFgBAAAF"
+                  + "AAAADAAAAHgBAAAGAAAAAQAAANgBAAABIAAABgAAAPgBAAADIAAABgAAACQDAAABEAAAAQAAAEQD"
+                  + "AAACIAAAJQAAAEoDAAAEIAAAAgAAANwFAAAAIAAAAQAAAOsFAAADEAAAAgAAABQGAAAGIAAAAQAA"
+                  + "ACQGAAAAEAAAAQAAADQGAAA=");
+
+  /*
+   * base64 encoded class/dex file for
+    package art;
+    import java.util.function.Supplier;
+    public class SubTransform extends art.Test2001.Transform implements Supplier<String> {
+      public SubTransform() {
+        super();
+      }
+      public String get() {
+        return "from SUBCLASS: " + super.sayHi();
+      }
+    }
+   */
+  private static final byte[] SUB_DEX_BYTES =
+      Base64.getDecoder()
+          .decode(
+              "ZGV4CjAzNQBawzkIDf9khFw00md41U4vIqRuhqBTjM+0BAAAcAAAAHhWNBIAAAAAAAAAAPwDAAAV"
+                  + "AAAAcAAAAAgAAADEAAAABAAAAOQAAAAAAAAAAAAAAAgAAAAUAQAAAQAAAFQBAABAAwAAdAEAAAIC"
+                  + "AAAKAgAADgIAABECAAAVAgAAKQIAAEMCAABiAgAAdgIAAIoCAAClAgAAxAIAAOMCAAD2AgAA+QIA"
+                  + "AAEDAAASAwAAFwMAAB4DAAAoAwAALwMAAAQAAAAFAAAABgAAAAcAAAAIAAAACQAAAAoAAAANAAAA"
+                  + "AgAAAAMAAAAAAAAAAgAAAAQAAAAAAAAAAwAAAAUAAAD8AQAADQAAAAcAAAAAAAAAAAADAAAAAAAA"
+                  + "AAAAEAAAAAAAAQAQAAAAAQADAAAAAAABAAEAEQAAAAUAAwAAAAAABQACAA4AAAAFAAEAEgAAAAAA"
+                  + "AAABAAAAAQAAAPQBAAAMAAAA7AMAAMsDAAAAAAAAAgABAAEAAADpAQAABQAAAG4QAgABAAwAEQAA"
+                  + "AAQAAQACAAAA7QEAABYAAABvEAQAAwAMACIBBQBwEAUAAQAaAg8AbiAGACEAbiAGAAEAbhAHAAEA"
+                  + "DAARAAEAAQABAAAA5AEAAAQAAABwEAMAAAAOAAYADjwABAAOAAkADgAAAAABAAAABgAAAAEAAAAE"
+                  + "AAY8aW5pdD4AAj47AAFMAAJMTAASTGFydC9TdWJUcmFuc2Zvcm07ABhMYXJ0L1Rlc3QyMDAxJFRy"
+                  + "YW5zZm9ybTsAHUxkYWx2aWsvYW5ub3RhdGlvbi9TaWduYXR1cmU7ABJMamF2YS9sYW5nL09iamVj"
+                  + "dDsAEkxqYXZhL2xhbmcvU3RyaW5nOwAZTGphdmEvbGFuZy9TdHJpbmdCdWlsZGVyOwAdTGphdmEv"
+                  + "dXRpbC9mdW5jdGlvbi9TdXBwbGllcjsAHUxqYXZhL3V0aWwvZnVuY3Rpb24vU3VwcGxpZXI8ABFT"
+                  + "dWJUcmFuc2Zvcm0uamF2YQABVgAGYXBwZW5kAA9mcm9tIFNVQkNMQVNTOiAAA2dldAAFc2F5SGkA"
+                  + "CHRvU3RyaW5nAAV2YWx1ZQCLAX5+RDh7ImNvbXBpbGF0aW9uLW1vZGUiOiJkZWJ1ZyIsImhhcy1j"
+                  + "aGVja3N1bXMiOmZhbHNlLCJtaW4tYXBpIjoxLCJzaGEtMSI6ImY2MmI4Y2U2YTA1OTAwNTRlZjM0"
+                  + "YTFhZWRlNzBiNDY2NjhlOGI0OWYiLCJ2ZXJzaW9uIjoiMi4wLjEtZGV2In0AAgIBExwEFwUXCxcI"
+                  + "FwEAAAECAIGABMwDAcEg9AIBAZADAAAAAAAAAQAAAL0DAADkAwAAAAAAAAAAAAAAAAAADwAAAAAA"
+                  + "AAABAAAAAAAAAAEAAAAVAAAAcAAAAAIAAAAIAAAAxAAAAAMAAAAEAAAA5AAAAAUAAAAIAAAAFAEA"
+                  + "AAYAAAABAAAAVAEAAAEgAAADAAAAdAEAAAMgAAADAAAA5AEAAAEQAAACAAAA9AEAAAIgAAAVAAAA"
+                  + "AgIAAAQgAAABAAAAvQMAAAAgAAABAAAAywMAAAMQAAACAAAA4AMAAAYgAAABAAAA7AMAAAAQAAAB"
+                  + "AAAA/AMAAA==");
+
+  public static void run() throws Exception {
+    Redefinition.setTestConfiguration(Redefinition.Config.COMMON_REDEFINE);
+    doTest();
+  }
+
+  public static Supplier<String> mkTransform() {
+    try {
+      return (Supplier<String>)
+          (new InMemoryDexClassLoader(
+                  ByteBuffer.wrap(SUB_DEX_BYTES), Test2001.class.getClassLoader())
+              .loadClass("art.SubTransform")
+              .newInstance());
+    } catch (Exception e) {
+      return () -> {
+        return e.toString();
+      };
+    }
+  }
+
+  public static final class MyThread extends Thread {
+    public MyThread(CountDownLatch delay, int id) {
+      super("Thread: " + id);
+      this.thr_id = id;
+      this.results = new ArrayList<>(1000);
+      this.finish = false;
+      this.delay = delay;
+    }
+
+    public void run() {
+      delay.countDown();
+      while (!finish) {
+        Supplier<String> t = mkTransform();
+        results.add(t.get());
+      }
+    }
+
+    public void finish() throws Exception {
+      finish = true;
+      this.join();
+    }
+
+    public void Check() throws Exception {
+      for (String s : results) {
+        if (!s.equals("from SUBCLASS: Hello from " + getName())
+            && !s.equals("from SUBCLASS: Hello, null, null, null from " + getName())
+            && !s.equals(
+                "from SUBCLASS: Hello World, Bonjour le Monde, Hej Verden, こんにちは世界 from "
+                    + getName())) {
+          System.out.println("FAIL " + thr_id + ": Unexpected result: " + s);
+        }
+      }
+    }
+
+    public ArrayList<String> results;
+    public volatile boolean finish;
+    public int thr_id;
+    public CountDownLatch delay;
+  }
+
+  public static MyThread[] startThreads(int num_threads) throws Exception {
+    CountDownLatch cdl = new CountDownLatch(num_threads);
+    MyThread[] res = new MyThread[num_threads];
+    for (int i = 0; i < num_threads; i++) {
+      res[i] = new MyThread(cdl, i);
+      res[i].start();
+    }
+    cdl.await();
+    return res;
+  }
+
+  public static void finishThreads(MyThread[] thrs) throws Exception {
+    for (MyThread t : thrs) {
+      t.finish();
+    }
+    for (MyThread t : thrs) {
+      t.Check();
+    }
+  }
+
+  public static void doTest() throws Exception {
+    MyThread[] threads = startThreads(NUM_THREADS);
+    Redefinition.doCommonStructuralClassRedefinition(Transform.class, DEX_BYTES);
+    finishThreads(threads);
+  }
+}
diff --git a/test/2001-virtual-structural-multithread/src/Main.java b/test/2001-virtual-structural-multithread/src/Main.java
new file mode 100644
index 0000000..89b8557
--- /dev/null
+++ b/test/2001-virtual-structural-multithread/src/Main.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+public class Main {
+  public static void main(String[] args) throws Exception {
+    System.out.println("FAIL: Test is only for art!");
+  }
+}
diff --git a/test/2002-virtual-structural-initializing/expected.txt b/test/2002-virtual-structural-initializing/expected.txt
new file mode 100644
index 0000000..c1c8a70
--- /dev/null
+++ b/test/2002-virtual-structural-initializing/expected.txt
@@ -0,0 +1 @@
+Initialized Static Hello
diff --git a/test/2002-virtual-structural-initializing/info.txt b/test/2002-virtual-structural-initializing/info.txt
new file mode 100644
index 0000000..3e5291d
--- /dev/null
+++ b/test/2002-virtual-structural-initializing/info.txt
@@ -0,0 +1,4 @@
+Tests structural redefinition with multiple threads.
+
+Tests that using the structural redefinition while concurrently loading and using a subtype of
+the class being redefined doesn't cause any unexpected problems.
diff --git a/test/2002-virtual-structural-initializing/run b/test/2002-virtual-structural-initializing/run
new file mode 100755
index 0000000..03e41a5
--- /dev/null
+++ b/test/2002-virtual-structural-initializing/run
@@ -0,0 +1,17 @@
+#!/bin/bash
+#
+# Copyright 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+./default-run "$@" --jvmti --runtime-option -Xopaque-jni-ids:true
diff --git a/test/2002-virtual-structural-initializing/src-art/Main.java b/test/2002-virtual-structural-initializing/src-art/Main.java
new file mode 100644
index 0000000..a0aab42
--- /dev/null
+++ b/test/2002-virtual-structural-initializing/src-art/Main.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+public class Main {
+  public static void main(String[] args) throws Exception {
+    art.Test2002.run();
+  }
+}
diff --git a/test/2002-virtual-structural-initializing/src-art/art/Redefinition.java b/test/2002-virtual-structural-initializing/src-art/art/Redefinition.java
new file mode 120000
index 0000000..81eaf31
--- /dev/null
+++ b/test/2002-virtual-structural-initializing/src-art/art/Redefinition.java
@@ -0,0 +1 @@
+../../../jvmti-common/Redefinition.java
\ No newline at end of file
diff --git a/test/2002-virtual-structural-initializing/src-art/art/Test2002.java b/test/2002-virtual-structural-initializing/src-art/art/Test2002.java
new file mode 100644
index 0000000..f91e3f7
--- /dev/null
+++ b/test/2002-virtual-structural-initializing/src-art/art/Test2002.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package art;
+
+import dalvik.system.InMemoryDexClassLoader;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Base64;
+import java.util.concurrent.CountDownLatch;
+import java.util.function.Supplier;
+
+public class Test2002 {
+  public static final CountDownLatch start_latch = new CountDownLatch(1);
+  public static final CountDownLatch finish_latch = new CountDownLatch(1);
+  public static class Transform {
+    public Transform() { }
+
+    public String sayHi() {
+      return "Hi";
+    }
+  }
+
+  /**
+   * base64 encoded class/dex file for
+   * public static class Transform {
+   *   public String greeting;
+   *
+   *   public Transform() {
+   *     greeting = "Hello";
+   *   }
+   *   public String sayHi() {
+   *     return greeting;
+   *   }
+   * }
+   */
+  private static final byte[] DEX_BYTES =
+      Base64.getDecoder()
+          .decode(
+"ZGV4CjAzNQBlpDFxr5PhCBfCyN+GZYuYQvSqtTEESU3oAwAAcAAAAHhWNBIAAAAAAAAAADADAAAS" +
+"AAAAcAAAAAcAAAC4AAAAAgAAANQAAAABAAAA7AAAAAMAAAD0AAAAAQAAAAwBAAC8AgAALAEAAHAB" +
+"AAB4AQAAfwEAAIIBAACcAQAArAEAANABAADwAQAABAIAABgCAAAnAgAAMgIAADUCAABCAgAATAIA" +
+"AFICAABZAgAAYAIAAAMAAAAEAAAABQAAAAYAAAAHAAAACAAAAAsAAAACAAAABQAAAAAAAAALAAAA" +
+"BgAAAAAAAAAAAAUADQAAAAAAAQAAAAAAAAAAAA8AAAAEAAEAAAAAAAAAAAABAAAABAAAAAAAAAAJ" +
+"AAAAIAMAAP0CAAAAAAAAAgABAAAAAABqAQAAAwAAAFQQAAARAAAAAgABAAEAAABkAQAACAAAAHAQ" +
+"AgABABoAAQBbEAAADgAGAA48SwAKAA4AAAAGPGluaXQ+AAVIZWxsbwABTAAYTGFydC9UZXN0MjAw" +
+"MiRUcmFuc2Zvcm07AA5MYXJ0L1Rlc3QyMDAyOwAiTGRhbHZpay9hbm5vdGF0aW9uL0VuY2xvc2lu" +
+"Z0NsYXNzOwAeTGRhbHZpay9hbm5vdGF0aW9uL0lubmVyQ2xhc3M7ABJMamF2YS9sYW5nL09iamVj" +
+"dDsAEkxqYXZhL2xhbmcvU3RyaW5nOwANVGVzdDIwMDIuamF2YQAJVHJhbnNmb3JtAAFWAAthY2Nl" +
+"c3NGbGFncwAIZ3JlZXRpbmcABG5hbWUABXNheUhpAAV2YWx1ZQCLAX5+RDh7ImNvbXBpbGF0aW9u" +
+"LW1vZGUiOiJkZWJ1ZyIsImhhcy1jaGVja3N1bXMiOmZhbHNlLCJtaW4tYXBpIjoxLCJzaGEtMSI6" +
+"ImY2MmI4Y2U2YTA1OTAwNTRlZjM0YTFhZWRlNzBiNDY2NjhlOGI0OWYiLCJ2ZXJzaW9uIjoiMi4w" +
+"LjEtZGV2In0AAgIBEBgBAgMCDAQJDhcKAAEBAQABAIGABMQCAQGsAgAAAAAAAAACAAAA7gIAAPQC" +
+"AAAUAwAAAAAAAAAAAAAAAAAADwAAAAAAAAABAAAAAAAAAAEAAAASAAAAcAAAAAIAAAAHAAAAuAAA" +
+"AAMAAAACAAAA1AAAAAQAAAABAAAA7AAAAAUAAAADAAAA9AAAAAYAAAABAAAADAEAAAEgAAACAAAA" +
+"LAEAAAMgAAACAAAAZAEAAAIgAAASAAAAcAEAAAQgAAACAAAA7gIAAAAgAAABAAAA/QIAAAMQAAAC" +
+"AAAAEAMAAAYgAAABAAAAIAMAAAAQAAABAAAAMAMAAA==");
+
+  /*
+   * base64 encoded class/dex file for
+    package art;
+    import java.util.function.Supplier;
+    import java.util.concurrent.CountDownLatch;
+
+    public class SubTransform extends art.Test2002.Transform implements Supplier<String> {
+      public static final String staticId;
+      static {
+        String res = null;
+        try {
+          Test2002.start_latch.countDown();
+          Test2002.finish_latch.await();
+          res = "Initialized Static";
+        } catch (Exception e) {
+          res = e.toString();
+        }
+        staticId = res;
+      }
+      public SubTransform() {
+        super();
+      }
+      public String get() {
+        return SubTransform.staticId + " " + sayHi();
+      }
+    }
+   */
+  private static final byte[] SUB_DEX_BYTES =
+      Base64.getDecoder()
+          .decode(
+"ZGV4CjAzNQB0BhXQtGTKXAGE/UzeevPgeNK7UrQJRJkoBgAAcAAAAHhWNBIAAAAAAAAAAGQFAAAf" +
+"AAAAcAAAAAsAAADsAAAABAAAABgBAAADAAAASAEAAAwAAABgAQAAAQAAAMABAABIBAAA4AEAAM4C" +
+"AADRAgAA2wIAAOMCAADnAgAA+wIAAP4CAAACAwAAFgMAADADAABAAwAAXwMAAHYDAACKAwAAngMA" +
+"ALkDAADgAwAA/wMAAB4EAAAxBAAANAQAADwEAABDBAAATgQAAFwEAABhBAAAaAQAAHUEAAB/BAAA" +
+"iQQAAJAEAAAHAAAACAAAAAkAAAAKAAAACwAAAAwAAAANAAAADgAAAA8AAAAQAAAAEwAAAAUAAAAF" +
+"AAAAAAAAAAUAAAAGAAAAAAAAAAYAAAAHAAAAyAIAABMAAAAKAAAAAAAAAAAABgAbAAAAAgAIABcA" +
+"AAACAAgAGgAAAAAAAwABAAAAAAADAAIAAAAAAAAAGAAAAAAAAQAYAAAAAAABABkAAAABAAMAAgAA" +
+"AAQAAQAcAAAABwADAAIAAAAHAAIAFAAAAAcAAQAcAAAACAADABUAAAAIAAMAFgAAAAAAAAABAAAA" +
+"AQAAAMACAAASAAAAVAUAACwFAAAAAAAAAgABAAEAAAC1AgAABQAAAG4QAwABAAwAEQAAAAQAAQAC" +
+"AAAAuQIAABsAAABiAAAAbhAEAAMADAEiAgcAcBAHAAIAbiAIAAIAGgAAAG4gCAACAG4gCAASAG4Q" +
+"CQACAAwAEQAAAAEAAAABAAEApAIAABYAAAAAAGIAAgBuEAsAAABiAAEAbhAKAAAAGgAEACgGDQBu" +
+"EAYAAAAMAGkAAAAOAAEAAAAMAAEAAQEEDgEAAQABAAAAsAIAAAQAAABwEAUAAAAOAAgADh9aWi8b" +
+"HkwtABMADjwABQAOABYADgAAAAABAAAACQAAAAEAAAAGAAEgAAg8Y2xpbml0PgAGPGluaXQ+AAI+" +
+"OwASSW5pdGlhbGl6ZWQgU3RhdGljAAFMAAJMTAASTGFydC9TdWJUcmFuc2Zvcm07ABhMYXJ0L1Rl" +
+"c3QyMDAyJFRyYW5zZm9ybTsADkxhcnQvVGVzdDIwMDI7AB1MZGFsdmlrL2Fubm90YXRpb24vU2ln" +
+"bmF0dXJlOwAVTGphdmEvbGFuZy9FeGNlcHRpb247ABJMamF2YS9sYW5nL09iamVjdDsAEkxqYXZh" +
+"L2xhbmcvU3RyaW5nOwAZTGphdmEvbGFuZy9TdHJpbmdCdWlsZGVyOwAlTGphdmEvdXRpbC9jb25j" +
+"dXJyZW50L0NvdW50RG93bkxhdGNoOwAdTGphdmEvdXRpbC9mdW5jdGlvbi9TdXBwbGllcjsAHUxq" +
+"YXZhL3V0aWwvZnVuY3Rpb24vU3VwcGxpZXI8ABFTdWJUcmFuc2Zvcm0uamF2YQABVgAGYXBwZW5k" +
+"AAVhd2FpdAAJY291bnREb3duAAxmaW5pc2hfbGF0Y2gAA2dldAAFc2F5SGkAC3N0YXJ0X2xhdGNo" +
+"AAhzdGF0aWNJZAAIdG9TdHJpbmcABXZhbHVlAIsBfn5EOHsiY29tcGlsYXRpb24tbW9kZSI6ImRl" +
+"YnVnIiwiaGFzLWNoZWNrc3VtcyI6ZmFsc2UsIm1pbi1hcGkiOjEsInNoYS0xIjoiZjYyYjhjZTZh" +
+"MDU5MDA1NGVmMzRhMWFlZGU3MGI0NjY2OGU4YjQ5ZiIsInZlcnNpb24iOiIyLjAuMS1kZXYifQAC" +
+"AwEdHAQXCBcRFw0XAwEAAgIAGQCIgATEBAGBgASMBQLBIOADAQH8AwAAAAAAAQAAAB4FAABMBQAA" +
+"AAAAAAAAAAAAAAAAEAAAAAAAAAABAAAAAAAAAAEAAAAfAAAAcAAAAAIAAAALAAAA7AAAAAMAAAAE" +
+"AAAAGAEAAAQAAAADAAAASAEAAAUAAAAMAAAAYAEAAAYAAAABAAAAwAEAAAEgAAAEAAAA4AEAAAMg" +
+"AAAEAAAApAIAAAEQAAACAAAAwAIAAAIgAAAfAAAAzgIAAAQgAAABAAAAHgUAAAAgAAABAAAALAUA" +
+"AAMQAAACAAAASAUAAAYgAAABAAAAVAUAAAAQAAABAAAAZAUAAA==");
+
+  public static void run() throws Exception {
+    Redefinition.setTestConfiguration(Redefinition.Config.COMMON_REDEFINE);
+    doTest();
+  }
+
+  public static Supplier<String> mkTransform() {
+    try {
+      return (Supplier<String>)
+          (new InMemoryDexClassLoader(
+                  ByteBuffer.wrap(SUB_DEX_BYTES), Test2002.class.getClassLoader())
+              .loadClass("art.SubTransform")
+              .newInstance());
+    } catch (Exception e) {
+      return () -> {
+        return e.toString();
+      };
+    }
+  }
+
+  public static void doTest() throws Exception {
+    Thread t = new Thread(() -> {
+      Supplier<String> s = mkTransform();
+      System.out.println(s.get());
+    });
+    t.start();
+    start_latch.await();
+    Redefinition.doCommonStructuralClassRedefinition(Transform.class, DEX_BYTES);
+    finish_latch.countDown();
+    t.join();
+  }
+}
diff --git a/test/2002-virtual-structural-initializing/src/Main.java b/test/2002-virtual-structural-initializing/src/Main.java
new file mode 100644
index 0000000..89b8557
--- /dev/null
+++ b/test/2002-virtual-structural-initializing/src/Main.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+public class Main {
+  public static void main(String[] args) throws Exception {
+    System.out.println("FAIL: Test is only for art!");
+  }
+}
diff --git a/test/knownfailures.json b/test/knownfailures.json
index 8840de5..c5115e9 100644
--- a/test/knownfailures.json
+++ b/test/knownfailures.json
@@ -1150,7 +1150,11 @@
                   "1995-final-virtual-structural-multithread",
                   "1996-final-override-virtual-structural",
                   "1997-structural-shadow-method",
-                  "1998-structural-shadow-field"
+                  "1998-structural-shadow-field",
+                  "1999-virtual-structural",
+                  "2000-virtual-list-structural",
+                  "2001-virtual-structural-multithread",
+                  "2002-virtual-structural-initializing"
                 ],
         "variant": "jvm",
         "description": ["Doesn't run on RI."]