Centralize all the jvmti common test classes
am: 23ca8fbcb2

Change-Id: I90d7400caf8a3dda054672b5f8e76f95db87fb79
diff --git a/test/1900-track-alloc/src/art/Main.java b/test/1900-track-alloc/src/art/Main.java
deleted file mode 100644
index aa5498b..0000000
--- a/test/1900-track-alloc/src/art/Main.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-// Binder class so the agent's C code has something that can be bound and exposed to tests.
-// In a package to separate cleanly and work around CTS reference issues (though this class
-// should be replaced in the CTS version).
-public class Main {
-  // Load the given class with the given classloader, and bind all native methods to corresponding
-  // C methods in the agent. Will abort if any of the steps fail.
-  public static native void bindAgentJNI(String className, ClassLoader classLoader);
-  // Same as above, giving the class directly.
-  public static native void bindAgentJNIForClass(Class<?> klass);
-
-  // Common infrastructure.
-  public static native void setTag(Object o, long tag);
-  public static native long getTag(Object o);
-}
diff --git a/test/1900-track-alloc/src/art/Main.java b/test/1900-track-alloc/src/art/Main.java
new file mode 120000
index 0000000..84ae4ac
--- /dev/null
+++ b/test/1900-track-alloc/src/art/Main.java
@@ -0,0 +1 @@
+../../../jvmti-common/Main.java
\ No newline at end of file
diff --git a/test/1902-suspend/src/art/Suspension.java b/test/1902-suspend/src/art/Suspension.java
new file mode 120000
index 0000000..bcef96f
--- /dev/null
+++ b/test/1902-suspend/src/art/Suspension.java
@@ -0,0 +1 @@
+../../../jvmti-common/Suspension.java
\ No newline at end of file
diff --git a/test/1903-suspend-self/src/art/Suspension.java b/test/1903-suspend-self/src/art/Suspension.java
deleted file mode 100644
index 16e62cc..0000000
--- a/test/1903-suspend-self/src/art/Suspension.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-public class Suspension {
-  // Suspends a thread using jvmti.
-  public native static void suspend(Thread thr);
-
-  // Resumes a thread using jvmti.
-  public native static void resume(Thread thr);
-
-  public native static boolean isSuspended(Thread thr);
-
-  public native static int[] suspendList(Thread... threads);
-  public native static int[] resumeList(Thread... threads);
-}
diff --git a/test/1903-suspend-self/src/art/Suspension.java b/test/1903-suspend-self/src/art/Suspension.java
new file mode 120000
index 0000000..bcef96f
--- /dev/null
+++ b/test/1903-suspend-self/src/art/Suspension.java
@@ -0,0 +1 @@
+../../../jvmti-common/Suspension.java
\ No newline at end of file
diff --git a/test/1904-double-suspend/src/art/Suspension.java b/test/1904-double-suspend/src/art/Suspension.java
deleted file mode 100644
index 16e62cc..0000000
--- a/test/1904-double-suspend/src/art/Suspension.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-public class Suspension {
-  // Suspends a thread using jvmti.
-  public native static void suspend(Thread thr);
-
-  // Resumes a thread using jvmti.
-  public native static void resume(Thread thr);
-
-  public native static boolean isSuspended(Thread thr);
-
-  public native static int[] suspendList(Thread... threads);
-  public native static int[] resumeList(Thread... threads);
-}
diff --git a/test/1904-double-suspend/src/art/Suspension.java b/test/1904-double-suspend/src/art/Suspension.java
new file mode 120000
index 0000000..bcef96f
--- /dev/null
+++ b/test/1904-double-suspend/src/art/Suspension.java
@@ -0,0 +1 @@
+../../../jvmti-common/Suspension.java
\ No newline at end of file
diff --git a/test/1905-suspend-native/src/art/Suspension.java b/test/1905-suspend-native/src/art/Suspension.java
deleted file mode 100644
index 16e62cc..0000000
--- a/test/1905-suspend-native/src/art/Suspension.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-public class Suspension {
-  // Suspends a thread using jvmti.
-  public native static void suspend(Thread thr);
-
-  // Resumes a thread using jvmti.
-  public native static void resume(Thread thr);
-
-  public native static boolean isSuspended(Thread thr);
-
-  public native static int[] suspendList(Thread... threads);
-  public native static int[] resumeList(Thread... threads);
-}
diff --git a/test/1905-suspend-native/src/art/Suspension.java b/test/1905-suspend-native/src/art/Suspension.java
new file mode 120000
index 0000000..bcef96f
--- /dev/null
+++ b/test/1905-suspend-native/src/art/Suspension.java
@@ -0,0 +1 @@
+../../../jvmti-common/Suspension.java
\ No newline at end of file
diff --git a/test/1906-suspend-list-me-first/src/art/Suspension.java b/test/1906-suspend-list-me-first/src/art/Suspension.java
deleted file mode 100644
index 16e62cc..0000000
--- a/test/1906-suspend-list-me-first/src/art/Suspension.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-public class Suspension {
-  // Suspends a thread using jvmti.
-  public native static void suspend(Thread thr);
-
-  // Resumes a thread using jvmti.
-  public native static void resume(Thread thr);
-
-  public native static boolean isSuspended(Thread thr);
-
-  public native static int[] suspendList(Thread... threads);
-  public native static int[] resumeList(Thread... threads);
-}
diff --git a/test/1906-suspend-list-me-first/src/art/Suspension.java b/test/1906-suspend-list-me-first/src/art/Suspension.java
new file mode 120000
index 0000000..bcef96f
--- /dev/null
+++ b/test/1906-suspend-list-me-first/src/art/Suspension.java
@@ -0,0 +1 @@
+../../../jvmti-common/Suspension.java
\ No newline at end of file
diff --git a/test/1907-suspend-list-self-twice/src/art/Suspension.java b/test/1907-suspend-list-self-twice/src/art/Suspension.java
deleted file mode 100644
index 16e62cc..0000000
--- a/test/1907-suspend-list-self-twice/src/art/Suspension.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-public class Suspension {
-  // Suspends a thread using jvmti.
-  public native static void suspend(Thread thr);
-
-  // Resumes a thread using jvmti.
-  public native static void resume(Thread thr);
-
-  public native static boolean isSuspended(Thread thr);
-
-  public native static int[] suspendList(Thread... threads);
-  public native static int[] resumeList(Thread... threads);
-}
diff --git a/test/1907-suspend-list-self-twice/src/art/Suspension.java b/test/1907-suspend-list-self-twice/src/art/Suspension.java
new file mode 120000
index 0000000..bcef96f
--- /dev/null
+++ b/test/1907-suspend-list-self-twice/src/art/Suspension.java
@@ -0,0 +1 @@
+../../../jvmti-common/Suspension.java
\ No newline at end of file
diff --git a/test/1908-suspend-native-resume-self/src/art/Suspension.java b/test/1908-suspend-native-resume-self/src/art/Suspension.java
deleted file mode 100644
index 16e62cc..0000000
--- a/test/1908-suspend-native-resume-self/src/art/Suspension.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-public class Suspension {
-  // Suspends a thread using jvmti.
-  public native static void suspend(Thread thr);
-
-  // Resumes a thread using jvmti.
-  public native static void resume(Thread thr);
-
-  public native static boolean isSuspended(Thread thr);
-
-  public native static int[] suspendList(Thread... threads);
-  public native static int[] resumeList(Thread... threads);
-}
diff --git a/test/1908-suspend-native-resume-self/src/art/Suspension.java b/test/1908-suspend-native-resume-self/src/art/Suspension.java
new file mode 120000
index 0000000..bcef96f
--- /dev/null
+++ b/test/1908-suspend-native-resume-self/src/art/Suspension.java
@@ -0,0 +1 @@
+../../../jvmti-common/Suspension.java
\ No newline at end of file
diff --git a/test/1909-per-agent-tls/src/art/Main.java b/test/1909-per-agent-tls/src/art/Main.java
deleted file mode 100644
index aa5498b..0000000
--- a/test/1909-per-agent-tls/src/art/Main.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-// Binder class so the agent's C code has something that can be bound and exposed to tests.
-// In a package to separate cleanly and work around CTS reference issues (though this class
-// should be replaced in the CTS version).
-public class Main {
-  // Load the given class with the given classloader, and bind all native methods to corresponding
-  // C methods in the agent. Will abort if any of the steps fail.
-  public static native void bindAgentJNI(String className, ClassLoader classLoader);
-  // Same as above, giving the class directly.
-  public static native void bindAgentJNIForClass(Class<?> klass);
-
-  // Common infrastructure.
-  public static native void setTag(Object o, long tag);
-  public static native long getTag(Object o);
-}
diff --git a/test/1909-per-agent-tls/src/art/Main.java b/test/1909-per-agent-tls/src/art/Main.java
new file mode 120000
index 0000000..84ae4ac
--- /dev/null
+++ b/test/1909-per-agent-tls/src/art/Main.java
@@ -0,0 +1 @@
+../../../jvmti-common/Main.java
\ No newline at end of file
diff --git a/test/1910-transform-with-default/src/art/Redefinition.java b/test/1910-transform-with-default/src/art/Redefinition.java
deleted file mode 100644
index 56d2938..0000000
--- a/test/1910-transform-with-default/src/art/Redefinition.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.util.ArrayList;
-// Common Redefinition functions. Placed here for use by CTS
-public class Redefinition {
-  public static final class CommonClassDefinition {
-    public final Class<?> target;
-    public final byte[] class_file_bytes;
-    public final byte[] dex_file_bytes;
-
-    public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
-      this.target = target;
-      this.class_file_bytes = class_file_bytes;
-      this.dex_file_bytes = dex_file_bytes;
-    }
-  }
-
-  // A set of possible test configurations. Test should set this if they need to.
-  // This must be kept in sync with the defines in ti-agent/common_helper.cc
-  public static enum Config {
-    COMMON_REDEFINE(0),
-    COMMON_RETRANSFORM(1),
-    COMMON_TRANSFORM(2);
-
-    private final int val;
-    private Config(int val) {
-      this.val = val;
-    }
-  }
-
-  public static void setTestConfiguration(Config type) {
-    nativeSetTestConfiguration(type.val);
-  }
-
-  private static native void nativeSetTestConfiguration(int type);
-
-  // Transforms the class
-  public static native void doCommonClassRedefinition(Class<?> target,
-                                                      byte[] classfile,
-                                                      byte[] dexfile);
-
-  public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
-    ArrayList<Class<?>> classes = new ArrayList<>();
-    ArrayList<byte[]> class_files = new ArrayList<>();
-    ArrayList<byte[]> dex_files = new ArrayList<>();
-
-    for (CommonClassDefinition d : defs) {
-      classes.add(d.target);
-      class_files.add(d.class_file_bytes);
-      dex_files.add(d.dex_file_bytes);
-    }
-    doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
-                                   class_files.toArray(new byte[0][]),
-                                   dex_files.toArray(new byte[0][]));
-  }
-
-  public static void addMultiTransformationResults(CommonClassDefinition... defs) {
-    for (CommonClassDefinition d : defs) {
-      addCommonTransformationResult(d.target.getCanonicalName(),
-                                    d.class_file_bytes,
-                                    d.dex_file_bytes);
-    }
-  }
-
-  public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
-                                                           byte[][] classfiles,
-                                                           byte[][] dexfiles);
-  public static native void doCommonClassRetransformation(Class<?>... target);
-  public static native void setPopRetransformations(boolean pop);
-  public static native void popTransformationFor(String name);
-  public static native void enableCommonRetransformation(boolean enable);
-  public static native void addCommonTransformationResult(String target_name,
-                                                          byte[] class_bytes,
-                                                          byte[] dex_bytes);
-}
diff --git a/test/1910-transform-with-default/src/art/Redefinition.java b/test/1910-transform-with-default/src/art/Redefinition.java
new file mode 120000
index 0000000..81eaf31
--- /dev/null
+++ b/test/1910-transform-with-default/src/art/Redefinition.java
@@ -0,0 +1 @@
+../../../jvmti-common/Redefinition.java
\ No newline at end of file
diff --git a/test/1911-get-local-var-table/src/art/Breakpoint.java b/test/1911-get-local-var-table/src/art/Breakpoint.java
deleted file mode 100644
index bbb89f7..0000000
--- a/test/1911-get-local-var-table/src/art/Breakpoint.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Executable;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.Objects;
-
-public class Breakpoint {
-  public static class Manager {
-    public static class BP {
-      public final Executable method;
-      public final long location;
-
-      public BP(Executable method) {
-        this(method, getStartLocation(method));
-      }
-
-      public BP(Executable method, long location) {
-        this.method = method;
-        this.location = location;
-      }
-
-      @Override
-      public boolean equals(Object other) {
-        return (other instanceof BP) &&
-            method.equals(((BP)other).method) &&
-            location == ((BP)other).location;
-      }
-
-      @Override
-      public String toString() {
-        return method.toString() + " @ " + getLine();
-      }
-
-      @Override
-      public int hashCode() {
-        return Objects.hash(method, location);
-      }
-
-      public int getLine() {
-        try {
-          LineNumber[] lines = getLineNumberTable(method);
-          int best = -1;
-          for (LineNumber l : lines) {
-            if (l.location > location) {
-              break;
-            } else {
-              best = l.line;
-            }
-          }
-          return best;
-        } catch (Exception e) {
-          return -1;
-        }
-      }
-    }
-
-    private Set<BP> breaks = new HashSet<>();
-
-    public void setBreakpoints(BP... bs) {
-      for (BP b : bs) {
-        if (breaks.add(b)) {
-          Breakpoint.setBreakpoint(b.method, b.location);
-        }
-      }
-    }
-    public void setBreakpoint(Executable method, long location) {
-      setBreakpoints(new BP(method, location));
-    }
-
-    public void clearBreakpoints(BP... bs) {
-      for (BP b : bs) {
-        if (breaks.remove(b)) {
-          Breakpoint.clearBreakpoint(b.method, b.location);
-        }
-      }
-    }
-    public void clearBreakpoint(Executable method, long location) {
-      clearBreakpoints(new BP(method, location));
-    }
-
-    public void clearAllBreakpoints() {
-      clearBreakpoints(breaks.toArray(new BP[0]));
-    }
-  }
-
-  public static void startBreakpointWatch(Class<?> methodClass,
-                                          Executable breakpointReached,
-                                          Thread thr) {
-    startBreakpointWatch(methodClass, breakpointReached, false, thr);
-  }
-
-  /**
-   * Enables the trapping of breakpoint events.
-   *
-   * If allowRecursive == true then breakpoints will be sent even if one is currently being handled.
-   */
-  public static native void startBreakpointWatch(Class<?> methodClass,
-                                                 Executable breakpointReached,
-                                                 boolean allowRecursive,
-                                                 Thread thr);
-  public static native void stopBreakpointWatch(Thread thr);
-
-  public static final class LineNumber implements Comparable<LineNumber> {
-    public final long location;
-    public final int line;
-
-    private LineNumber(long loc, int line) {
-      this.location = loc;
-      this.line = line;
-    }
-
-    public boolean equals(Object other) {
-      return other instanceof LineNumber && ((LineNumber)other).line == line &&
-          ((LineNumber)other).location == location;
-    }
-
-    public int compareTo(LineNumber other) {
-      int v = Integer.valueOf(line).compareTo(Integer.valueOf(other.line));
-      if (v != 0) {
-        return v;
-      } else {
-        return Long.valueOf(location).compareTo(Long.valueOf(other.location));
-      }
-    }
-  }
-
-  public static native void setBreakpoint(Executable m, long loc);
-  public static void setBreakpoint(Executable m, LineNumber l) {
-    setBreakpoint(m, l.location);
-  }
-
-  public static native void clearBreakpoint(Executable m, long loc);
-  public static void clearBreakpoint(Executable m, LineNumber l) {
-    clearBreakpoint(m, l.location);
-  }
-
-  private static native Object[] getLineNumberTableNative(Executable m);
-  public static LineNumber[] getLineNumberTable(Executable m) {
-    Object[] nativeTable = getLineNumberTableNative(m);
-    long[] location = (long[])(nativeTable[0]);
-    int[] lines = (int[])(nativeTable[1]);
-    if (lines.length != location.length) {
-      throw new Error("Lines and locations have different lengths!");
-    }
-    LineNumber[] out = new LineNumber[lines.length];
-    for (int i = 0; i < lines.length; i++) {
-      out[i] = new LineNumber(location[i], lines[i]);
-    }
-    return out;
-  }
-
-  public static native long getStartLocation(Executable m);
-
-  public static int locationToLine(Executable m, long location) {
-    try {
-      Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
-      int best = -1;
-      for (Breakpoint.LineNumber l : lines) {
-        if (l.location > location) {
-          break;
-        } else {
-          best = l.line;
-        }
-      }
-      return best;
-    } catch (Exception e) {
-      return -1;
-    }
-  }
-
-  public static long lineToLocation(Executable m, int line) throws Exception {
-    try {
-      Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
-      for (Breakpoint.LineNumber l : lines) {
-        if (l.line == line) {
-          return l.location;
-        }
-      }
-      throw new Exception("Unable to find line " + line + " in " + m);
-    } catch (Exception e) {
-      throw new Exception("Unable to get line number info for " + m, e);
-    }
-  }
-}
-
diff --git a/test/1911-get-local-var-table/src/art/Breakpoint.java b/test/1911-get-local-var-table/src/art/Breakpoint.java
new file mode 120000
index 0000000..3673916
--- /dev/null
+++ b/test/1911-get-local-var-table/src/art/Breakpoint.java
@@ -0,0 +1 @@
+../../../jvmti-common/Breakpoint.java
\ No newline at end of file
diff --git a/test/1911-get-local-var-table/src/art/Locals.java b/test/1911-get-local-var-table/src/art/Locals.java
deleted file mode 100644
index 22e21be..0000000
--- a/test/1911-get-local-var-table/src/art/Locals.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Executable;
-import java.util.Objects;
-
-public class Locals {
-  public static native void EnableLocalVariableAccess();
-
-  public static class VariableDescription {
-    public final long start_location;
-    public final int length;
-    public final String name;
-    public final String signature;
-    public final String generic_signature;
-    public final int slot;
-
-    public VariableDescription(
-        long start, int length, String name, String sig, String gen_sig, int slot) {
-      this.start_location = start;
-      this.length = length;
-      this.name = name;
-      this.signature = sig;
-      this.generic_signature = gen_sig;
-      this.slot = slot;
-    }
-
-    @Override
-    public String toString() {
-      return String.format(
-          "VariableDescription { " +
-            "Sig: '%s', Name: '%s', Gen_sig: '%s', slot: %d, start: %d, len: %d" +
-          "}",
-          this.signature,
-          this.name,
-          this.generic_signature,
-          this.slot,
-          this.start_location,
-          this.length);
-    }
-    public boolean equals(Object other) {
-      if (!(other instanceof VariableDescription)) {
-        return false;
-      } else {
-        VariableDescription v = (VariableDescription)other;
-        return Objects.equals(v.signature, signature) &&
-            Objects.equals(v.name, name) &&
-            Objects.equals(v.generic_signature, generic_signature) &&
-            v.slot == slot &&
-            v.start_location == start_location &&
-            v.length == length;
-      }
-    }
-    public int hashCode() {
-      return Objects.hash(this.signature, this.name, this.generic_signature, this.slot,
-          this.start_location, this.length);
-    }
-  }
-
-  public static native VariableDescription[] GetLocalVariableTable(Executable e);
-
-  public static VariableDescription GetVariableAtLine(
-      Executable e, String name, String sig, int line) throws Exception {
-    return GetVariableAtLocation(e, name, sig, Breakpoint.lineToLocation(e, line));
-  }
-
-  public static VariableDescription GetVariableAtLocation(
-      Executable e, String name, String sig, long loc) {
-    VariableDescription[] vars = GetLocalVariableTable(e);
-    for (VariableDescription var : vars) {
-      if (var.start_location <= loc &&
-          var.length + var.start_location > loc &&
-          var.name.equals(name) &&
-          var.signature.equals(sig)) {
-        return var;
-      }
-    }
-    throw new Error(
-        "Unable to find variable " + name + " (sig: " + sig + ") in " + e + " at loc " + loc);
-  }
-
-  public static native int GetLocalVariableInt(Thread thr, int depth, int slot);
-  public static native long GetLocalVariableLong(Thread thr, int depth, int slot);
-  public static native float GetLocalVariableFloat(Thread thr, int depth, int slot);
-  public static native double GetLocalVariableDouble(Thread thr, int depth, int slot);
-  public static native Object GetLocalVariableObject(Thread thr, int depth, int slot);
-  public static native Object GetLocalInstance(Thread thr, int depth);
-
-  public static void SetLocalVariableInt(Thread thr, int depth, int slot, Object val) {
-    SetLocalVariableInt(thr, depth, slot, ((Number)val).intValue());
-  }
-  public static void SetLocalVariableLong(Thread thr, int depth, int slot, Object val) {
-    SetLocalVariableLong(thr, depth, slot, ((Number)val).longValue());
-  }
-  public static void SetLocalVariableFloat(Thread thr, int depth, int slot, Object val) {
-    SetLocalVariableFloat(thr, depth, slot, ((Number)val).floatValue());
-  }
-  public static void SetLocalVariableDouble(Thread thr, int depth, int slot, Object val) {
-    SetLocalVariableDouble(thr, depth, slot, ((Number)val).doubleValue());
-  }
-  public static native void SetLocalVariableInt(Thread thr, int depth, int slot, int val);
-  public static native void SetLocalVariableLong(Thread thr, int depth, int slot, long val);
-  public static native void SetLocalVariableFloat(Thread thr, int depth, int slot, float val);
-  public static native void SetLocalVariableDouble(Thread thr, int depth, int slot, double val);
-  public static native void SetLocalVariableObject(Thread thr, int depth, int slot, Object val);
-}
diff --git a/test/1911-get-local-var-table/src/art/Locals.java b/test/1911-get-local-var-table/src/art/Locals.java
new file mode 120000
index 0000000..2998386
--- /dev/null
+++ b/test/1911-get-local-var-table/src/art/Locals.java
@@ -0,0 +1 @@
+../../../jvmti-common/Locals.java
\ No newline at end of file
diff --git a/test/1911-get-local-var-table/src/art/Suspension.java b/test/1911-get-local-var-table/src/art/Suspension.java
deleted file mode 100644
index 16e62cc..0000000
--- a/test/1911-get-local-var-table/src/art/Suspension.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-public class Suspension {
-  // Suspends a thread using jvmti.
-  public native static void suspend(Thread thr);
-
-  // Resumes a thread using jvmti.
-  public native static void resume(Thread thr);
-
-  public native static boolean isSuspended(Thread thr);
-
-  public native static int[] suspendList(Thread... threads);
-  public native static int[] resumeList(Thread... threads);
-}
diff --git a/test/1911-get-local-var-table/src/art/Suspension.java b/test/1911-get-local-var-table/src/art/Suspension.java
new file mode 120000
index 0000000..bcef96f
--- /dev/null
+++ b/test/1911-get-local-var-table/src/art/Suspension.java
@@ -0,0 +1 @@
+../../../jvmti-common/Suspension.java
\ No newline at end of file
diff --git a/test/1912-get-set-local-primitive/src/art/Breakpoint.java b/test/1912-get-set-local-primitive/src/art/Breakpoint.java
deleted file mode 100644
index bbb89f7..0000000
--- a/test/1912-get-set-local-primitive/src/art/Breakpoint.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Executable;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.Objects;
-
-public class Breakpoint {
-  public static class Manager {
-    public static class BP {
-      public final Executable method;
-      public final long location;
-
-      public BP(Executable method) {
-        this(method, getStartLocation(method));
-      }
-
-      public BP(Executable method, long location) {
-        this.method = method;
-        this.location = location;
-      }
-
-      @Override
-      public boolean equals(Object other) {
-        return (other instanceof BP) &&
-            method.equals(((BP)other).method) &&
-            location == ((BP)other).location;
-      }
-
-      @Override
-      public String toString() {
-        return method.toString() + " @ " + getLine();
-      }
-
-      @Override
-      public int hashCode() {
-        return Objects.hash(method, location);
-      }
-
-      public int getLine() {
-        try {
-          LineNumber[] lines = getLineNumberTable(method);
-          int best = -1;
-          for (LineNumber l : lines) {
-            if (l.location > location) {
-              break;
-            } else {
-              best = l.line;
-            }
-          }
-          return best;
-        } catch (Exception e) {
-          return -1;
-        }
-      }
-    }
-
-    private Set<BP> breaks = new HashSet<>();
-
-    public void setBreakpoints(BP... bs) {
-      for (BP b : bs) {
-        if (breaks.add(b)) {
-          Breakpoint.setBreakpoint(b.method, b.location);
-        }
-      }
-    }
-    public void setBreakpoint(Executable method, long location) {
-      setBreakpoints(new BP(method, location));
-    }
-
-    public void clearBreakpoints(BP... bs) {
-      for (BP b : bs) {
-        if (breaks.remove(b)) {
-          Breakpoint.clearBreakpoint(b.method, b.location);
-        }
-      }
-    }
-    public void clearBreakpoint(Executable method, long location) {
-      clearBreakpoints(new BP(method, location));
-    }
-
-    public void clearAllBreakpoints() {
-      clearBreakpoints(breaks.toArray(new BP[0]));
-    }
-  }
-
-  public static void startBreakpointWatch(Class<?> methodClass,
-                                          Executable breakpointReached,
-                                          Thread thr) {
-    startBreakpointWatch(methodClass, breakpointReached, false, thr);
-  }
-
-  /**
-   * Enables the trapping of breakpoint events.
-   *
-   * If allowRecursive == true then breakpoints will be sent even if one is currently being handled.
-   */
-  public static native void startBreakpointWatch(Class<?> methodClass,
-                                                 Executable breakpointReached,
-                                                 boolean allowRecursive,
-                                                 Thread thr);
-  public static native void stopBreakpointWatch(Thread thr);
-
-  public static final class LineNumber implements Comparable<LineNumber> {
-    public final long location;
-    public final int line;
-
-    private LineNumber(long loc, int line) {
-      this.location = loc;
-      this.line = line;
-    }
-
-    public boolean equals(Object other) {
-      return other instanceof LineNumber && ((LineNumber)other).line == line &&
-          ((LineNumber)other).location == location;
-    }
-
-    public int compareTo(LineNumber other) {
-      int v = Integer.valueOf(line).compareTo(Integer.valueOf(other.line));
-      if (v != 0) {
-        return v;
-      } else {
-        return Long.valueOf(location).compareTo(Long.valueOf(other.location));
-      }
-    }
-  }
-
-  public static native void setBreakpoint(Executable m, long loc);
-  public static void setBreakpoint(Executable m, LineNumber l) {
-    setBreakpoint(m, l.location);
-  }
-
-  public static native void clearBreakpoint(Executable m, long loc);
-  public static void clearBreakpoint(Executable m, LineNumber l) {
-    clearBreakpoint(m, l.location);
-  }
-
-  private static native Object[] getLineNumberTableNative(Executable m);
-  public static LineNumber[] getLineNumberTable(Executable m) {
-    Object[] nativeTable = getLineNumberTableNative(m);
-    long[] location = (long[])(nativeTable[0]);
-    int[] lines = (int[])(nativeTable[1]);
-    if (lines.length != location.length) {
-      throw new Error("Lines and locations have different lengths!");
-    }
-    LineNumber[] out = new LineNumber[lines.length];
-    for (int i = 0; i < lines.length; i++) {
-      out[i] = new LineNumber(location[i], lines[i]);
-    }
-    return out;
-  }
-
-  public static native long getStartLocation(Executable m);
-
-  public static int locationToLine(Executable m, long location) {
-    try {
-      Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
-      int best = -1;
-      for (Breakpoint.LineNumber l : lines) {
-        if (l.location > location) {
-          break;
-        } else {
-          best = l.line;
-        }
-      }
-      return best;
-    } catch (Exception e) {
-      return -1;
-    }
-  }
-
-  public static long lineToLocation(Executable m, int line) throws Exception {
-    try {
-      Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
-      for (Breakpoint.LineNumber l : lines) {
-        if (l.line == line) {
-          return l.location;
-        }
-      }
-      throw new Exception("Unable to find line " + line + " in " + m);
-    } catch (Exception e) {
-      throw new Exception("Unable to get line number info for " + m, e);
-    }
-  }
-}
-
diff --git a/test/1912-get-set-local-primitive/src/art/Breakpoint.java b/test/1912-get-set-local-primitive/src/art/Breakpoint.java
new file mode 120000
index 0000000..3673916
--- /dev/null
+++ b/test/1912-get-set-local-primitive/src/art/Breakpoint.java
@@ -0,0 +1 @@
+../../../jvmti-common/Breakpoint.java
\ No newline at end of file
diff --git a/test/1912-get-set-local-primitive/src/art/Locals.java b/test/1912-get-set-local-primitive/src/art/Locals.java
deleted file mode 100644
index 22e21be..0000000
--- a/test/1912-get-set-local-primitive/src/art/Locals.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Executable;
-import java.util.Objects;
-
-public class Locals {
-  public static native void EnableLocalVariableAccess();
-
-  public static class VariableDescription {
-    public final long start_location;
-    public final int length;
-    public final String name;
-    public final String signature;
-    public final String generic_signature;
-    public final int slot;
-
-    public VariableDescription(
-        long start, int length, String name, String sig, String gen_sig, int slot) {
-      this.start_location = start;
-      this.length = length;
-      this.name = name;
-      this.signature = sig;
-      this.generic_signature = gen_sig;
-      this.slot = slot;
-    }
-
-    @Override
-    public String toString() {
-      return String.format(
-          "VariableDescription { " +
-            "Sig: '%s', Name: '%s', Gen_sig: '%s', slot: %d, start: %d, len: %d" +
-          "}",
-          this.signature,
-          this.name,
-          this.generic_signature,
-          this.slot,
-          this.start_location,
-          this.length);
-    }
-    public boolean equals(Object other) {
-      if (!(other instanceof VariableDescription)) {
-        return false;
-      } else {
-        VariableDescription v = (VariableDescription)other;
-        return Objects.equals(v.signature, signature) &&
-            Objects.equals(v.name, name) &&
-            Objects.equals(v.generic_signature, generic_signature) &&
-            v.slot == slot &&
-            v.start_location == start_location &&
-            v.length == length;
-      }
-    }
-    public int hashCode() {
-      return Objects.hash(this.signature, this.name, this.generic_signature, this.slot,
-          this.start_location, this.length);
-    }
-  }
-
-  public static native VariableDescription[] GetLocalVariableTable(Executable e);
-
-  public static VariableDescription GetVariableAtLine(
-      Executable e, String name, String sig, int line) throws Exception {
-    return GetVariableAtLocation(e, name, sig, Breakpoint.lineToLocation(e, line));
-  }
-
-  public static VariableDescription GetVariableAtLocation(
-      Executable e, String name, String sig, long loc) {
-    VariableDescription[] vars = GetLocalVariableTable(e);
-    for (VariableDescription var : vars) {
-      if (var.start_location <= loc &&
-          var.length + var.start_location > loc &&
-          var.name.equals(name) &&
-          var.signature.equals(sig)) {
-        return var;
-      }
-    }
-    throw new Error(
-        "Unable to find variable " + name + " (sig: " + sig + ") in " + e + " at loc " + loc);
-  }
-
-  public static native int GetLocalVariableInt(Thread thr, int depth, int slot);
-  public static native long GetLocalVariableLong(Thread thr, int depth, int slot);
-  public static native float GetLocalVariableFloat(Thread thr, int depth, int slot);
-  public static native double GetLocalVariableDouble(Thread thr, int depth, int slot);
-  public static native Object GetLocalVariableObject(Thread thr, int depth, int slot);
-  public static native Object GetLocalInstance(Thread thr, int depth);
-
-  public static void SetLocalVariableInt(Thread thr, int depth, int slot, Object val) {
-    SetLocalVariableInt(thr, depth, slot, ((Number)val).intValue());
-  }
-  public static void SetLocalVariableLong(Thread thr, int depth, int slot, Object val) {
-    SetLocalVariableLong(thr, depth, slot, ((Number)val).longValue());
-  }
-  public static void SetLocalVariableFloat(Thread thr, int depth, int slot, Object val) {
-    SetLocalVariableFloat(thr, depth, slot, ((Number)val).floatValue());
-  }
-  public static void SetLocalVariableDouble(Thread thr, int depth, int slot, Object val) {
-    SetLocalVariableDouble(thr, depth, slot, ((Number)val).doubleValue());
-  }
-  public static native void SetLocalVariableInt(Thread thr, int depth, int slot, int val);
-  public static native void SetLocalVariableLong(Thread thr, int depth, int slot, long val);
-  public static native void SetLocalVariableFloat(Thread thr, int depth, int slot, float val);
-  public static native void SetLocalVariableDouble(Thread thr, int depth, int slot, double val);
-  public static native void SetLocalVariableObject(Thread thr, int depth, int slot, Object val);
-}
diff --git a/test/1912-get-set-local-primitive/src/art/Locals.java b/test/1912-get-set-local-primitive/src/art/Locals.java
new file mode 120000
index 0000000..2998386
--- /dev/null
+++ b/test/1912-get-set-local-primitive/src/art/Locals.java
@@ -0,0 +1 @@
+../../../jvmti-common/Locals.java
\ No newline at end of file
diff --git a/test/1912-get-set-local-primitive/src/art/StackTrace.java b/test/1912-get-set-local-primitive/src/art/StackTrace.java
deleted file mode 100644
index 2ea2f20..0000000
--- a/test/1912-get-set-local-primitive/src/art/StackTrace.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Executable;
-
-public class StackTrace {
-  public static class StackFrameData {
-    public final Thread thr;
-    public final Executable method;
-    public final long current_location;
-    public final int depth;
-
-    public StackFrameData(Thread thr, Executable e, long loc, int depth) {
-      this.thr = thr;
-      this.method = e;
-      this.current_location = loc;
-      this.depth = depth;
-    }
-    @Override
-    public String toString() {
-      return String.format(
-          "StackFrameData { thr: '%s', method: '%s', loc: %d, depth: %d }",
-          this.thr,
-          this.method,
-          this.current_location,
-          this.depth);
-    }
-  }
-
-  public static native int GetStackDepth(Thread thr);
-
-  private static native StackFrameData[] nativeGetStackTrace(Thread thr);
-
-  public static StackFrameData[] GetStackTrace(Thread thr) {
-    // The RI seems to give inconsistent (and sometimes nonsensical) results if the thread is not
-    // suspended. The spec says that not being suspended is fine but since we want this to be
-    // consistent we will suspend for the RI.
-    boolean suspend_thread =
-        !System.getProperty("java.vm.name").equals("Dalvik") &&
-        !thr.equals(Thread.currentThread()) &&
-        !Suspension.isSuspended(thr);
-    if (suspend_thread) {
-      Suspension.suspend(thr);
-    }
-    StackFrameData[] out = nativeGetStackTrace(thr);
-    if (suspend_thread) {
-      Suspension.resume(thr);
-    }
-    return out;
-  }
-}
-
diff --git a/test/1912-get-set-local-primitive/src/art/StackTrace.java b/test/1912-get-set-local-primitive/src/art/StackTrace.java
new file mode 120000
index 0000000..e1a08aa
--- /dev/null
+++ b/test/1912-get-set-local-primitive/src/art/StackTrace.java
@@ -0,0 +1 @@
+../../../jvmti-common/StackTrace.java
\ No newline at end of file
diff --git a/test/1912-get-set-local-primitive/src/art/Suspension.java b/test/1912-get-set-local-primitive/src/art/Suspension.java
deleted file mode 100644
index 16e62cc..0000000
--- a/test/1912-get-set-local-primitive/src/art/Suspension.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-public class Suspension {
-  // Suspends a thread using jvmti.
-  public native static void suspend(Thread thr);
-
-  // Resumes a thread using jvmti.
-  public native static void resume(Thread thr);
-
-  public native static boolean isSuspended(Thread thr);
-
-  public native static int[] suspendList(Thread... threads);
-  public native static int[] resumeList(Thread... threads);
-}
diff --git a/test/1912-get-set-local-primitive/src/art/Suspension.java b/test/1912-get-set-local-primitive/src/art/Suspension.java
new file mode 120000
index 0000000..bcef96f
--- /dev/null
+++ b/test/1912-get-set-local-primitive/src/art/Suspension.java
@@ -0,0 +1 @@
+../../../jvmti-common/Suspension.java
\ No newline at end of file
diff --git a/test/1913-get-set-local-objects/src/art/Breakpoint.java b/test/1913-get-set-local-objects/src/art/Breakpoint.java
deleted file mode 100644
index bbb89f7..0000000
--- a/test/1913-get-set-local-objects/src/art/Breakpoint.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Executable;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.Objects;
-
-public class Breakpoint {
-  public static class Manager {
-    public static class BP {
-      public final Executable method;
-      public final long location;
-
-      public BP(Executable method) {
-        this(method, getStartLocation(method));
-      }
-
-      public BP(Executable method, long location) {
-        this.method = method;
-        this.location = location;
-      }
-
-      @Override
-      public boolean equals(Object other) {
-        return (other instanceof BP) &&
-            method.equals(((BP)other).method) &&
-            location == ((BP)other).location;
-      }
-
-      @Override
-      public String toString() {
-        return method.toString() + " @ " + getLine();
-      }
-
-      @Override
-      public int hashCode() {
-        return Objects.hash(method, location);
-      }
-
-      public int getLine() {
-        try {
-          LineNumber[] lines = getLineNumberTable(method);
-          int best = -1;
-          for (LineNumber l : lines) {
-            if (l.location > location) {
-              break;
-            } else {
-              best = l.line;
-            }
-          }
-          return best;
-        } catch (Exception e) {
-          return -1;
-        }
-      }
-    }
-
-    private Set<BP> breaks = new HashSet<>();
-
-    public void setBreakpoints(BP... bs) {
-      for (BP b : bs) {
-        if (breaks.add(b)) {
-          Breakpoint.setBreakpoint(b.method, b.location);
-        }
-      }
-    }
-    public void setBreakpoint(Executable method, long location) {
-      setBreakpoints(new BP(method, location));
-    }
-
-    public void clearBreakpoints(BP... bs) {
-      for (BP b : bs) {
-        if (breaks.remove(b)) {
-          Breakpoint.clearBreakpoint(b.method, b.location);
-        }
-      }
-    }
-    public void clearBreakpoint(Executable method, long location) {
-      clearBreakpoints(new BP(method, location));
-    }
-
-    public void clearAllBreakpoints() {
-      clearBreakpoints(breaks.toArray(new BP[0]));
-    }
-  }
-
-  public static void startBreakpointWatch(Class<?> methodClass,
-                                          Executable breakpointReached,
-                                          Thread thr) {
-    startBreakpointWatch(methodClass, breakpointReached, false, thr);
-  }
-
-  /**
-   * Enables the trapping of breakpoint events.
-   *
-   * If allowRecursive == true then breakpoints will be sent even if one is currently being handled.
-   */
-  public static native void startBreakpointWatch(Class<?> methodClass,
-                                                 Executable breakpointReached,
-                                                 boolean allowRecursive,
-                                                 Thread thr);
-  public static native void stopBreakpointWatch(Thread thr);
-
-  public static final class LineNumber implements Comparable<LineNumber> {
-    public final long location;
-    public final int line;
-
-    private LineNumber(long loc, int line) {
-      this.location = loc;
-      this.line = line;
-    }
-
-    public boolean equals(Object other) {
-      return other instanceof LineNumber && ((LineNumber)other).line == line &&
-          ((LineNumber)other).location == location;
-    }
-
-    public int compareTo(LineNumber other) {
-      int v = Integer.valueOf(line).compareTo(Integer.valueOf(other.line));
-      if (v != 0) {
-        return v;
-      } else {
-        return Long.valueOf(location).compareTo(Long.valueOf(other.location));
-      }
-    }
-  }
-
-  public static native void setBreakpoint(Executable m, long loc);
-  public static void setBreakpoint(Executable m, LineNumber l) {
-    setBreakpoint(m, l.location);
-  }
-
-  public static native void clearBreakpoint(Executable m, long loc);
-  public static void clearBreakpoint(Executable m, LineNumber l) {
-    clearBreakpoint(m, l.location);
-  }
-
-  private static native Object[] getLineNumberTableNative(Executable m);
-  public static LineNumber[] getLineNumberTable(Executable m) {
-    Object[] nativeTable = getLineNumberTableNative(m);
-    long[] location = (long[])(nativeTable[0]);
-    int[] lines = (int[])(nativeTable[1]);
-    if (lines.length != location.length) {
-      throw new Error("Lines and locations have different lengths!");
-    }
-    LineNumber[] out = new LineNumber[lines.length];
-    for (int i = 0; i < lines.length; i++) {
-      out[i] = new LineNumber(location[i], lines[i]);
-    }
-    return out;
-  }
-
-  public static native long getStartLocation(Executable m);
-
-  public static int locationToLine(Executable m, long location) {
-    try {
-      Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
-      int best = -1;
-      for (Breakpoint.LineNumber l : lines) {
-        if (l.location > location) {
-          break;
-        } else {
-          best = l.line;
-        }
-      }
-      return best;
-    } catch (Exception e) {
-      return -1;
-    }
-  }
-
-  public static long lineToLocation(Executable m, int line) throws Exception {
-    try {
-      Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
-      for (Breakpoint.LineNumber l : lines) {
-        if (l.line == line) {
-          return l.location;
-        }
-      }
-      throw new Exception("Unable to find line " + line + " in " + m);
-    } catch (Exception e) {
-      throw new Exception("Unable to get line number info for " + m, e);
-    }
-  }
-}
-
diff --git a/test/1913-get-set-local-objects/src/art/Breakpoint.java b/test/1913-get-set-local-objects/src/art/Breakpoint.java
new file mode 120000
index 0000000..3673916
--- /dev/null
+++ b/test/1913-get-set-local-objects/src/art/Breakpoint.java
@@ -0,0 +1 @@
+../../../jvmti-common/Breakpoint.java
\ No newline at end of file
diff --git a/test/1913-get-set-local-objects/src/art/Locals.java b/test/1913-get-set-local-objects/src/art/Locals.java
deleted file mode 100644
index 22e21be..0000000
--- a/test/1913-get-set-local-objects/src/art/Locals.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Executable;
-import java.util.Objects;
-
-public class Locals {
-  public static native void EnableLocalVariableAccess();
-
-  public static class VariableDescription {
-    public final long start_location;
-    public final int length;
-    public final String name;
-    public final String signature;
-    public final String generic_signature;
-    public final int slot;
-
-    public VariableDescription(
-        long start, int length, String name, String sig, String gen_sig, int slot) {
-      this.start_location = start;
-      this.length = length;
-      this.name = name;
-      this.signature = sig;
-      this.generic_signature = gen_sig;
-      this.slot = slot;
-    }
-
-    @Override
-    public String toString() {
-      return String.format(
-          "VariableDescription { " +
-            "Sig: '%s', Name: '%s', Gen_sig: '%s', slot: %d, start: %d, len: %d" +
-          "}",
-          this.signature,
-          this.name,
-          this.generic_signature,
-          this.slot,
-          this.start_location,
-          this.length);
-    }
-    public boolean equals(Object other) {
-      if (!(other instanceof VariableDescription)) {
-        return false;
-      } else {
-        VariableDescription v = (VariableDescription)other;
-        return Objects.equals(v.signature, signature) &&
-            Objects.equals(v.name, name) &&
-            Objects.equals(v.generic_signature, generic_signature) &&
-            v.slot == slot &&
-            v.start_location == start_location &&
-            v.length == length;
-      }
-    }
-    public int hashCode() {
-      return Objects.hash(this.signature, this.name, this.generic_signature, this.slot,
-          this.start_location, this.length);
-    }
-  }
-
-  public static native VariableDescription[] GetLocalVariableTable(Executable e);
-
-  public static VariableDescription GetVariableAtLine(
-      Executable e, String name, String sig, int line) throws Exception {
-    return GetVariableAtLocation(e, name, sig, Breakpoint.lineToLocation(e, line));
-  }
-
-  public static VariableDescription GetVariableAtLocation(
-      Executable e, String name, String sig, long loc) {
-    VariableDescription[] vars = GetLocalVariableTable(e);
-    for (VariableDescription var : vars) {
-      if (var.start_location <= loc &&
-          var.length + var.start_location > loc &&
-          var.name.equals(name) &&
-          var.signature.equals(sig)) {
-        return var;
-      }
-    }
-    throw new Error(
-        "Unable to find variable " + name + " (sig: " + sig + ") in " + e + " at loc " + loc);
-  }
-
-  public static native int GetLocalVariableInt(Thread thr, int depth, int slot);
-  public static native long GetLocalVariableLong(Thread thr, int depth, int slot);
-  public static native float GetLocalVariableFloat(Thread thr, int depth, int slot);
-  public static native double GetLocalVariableDouble(Thread thr, int depth, int slot);
-  public static native Object GetLocalVariableObject(Thread thr, int depth, int slot);
-  public static native Object GetLocalInstance(Thread thr, int depth);
-
-  public static void SetLocalVariableInt(Thread thr, int depth, int slot, Object val) {
-    SetLocalVariableInt(thr, depth, slot, ((Number)val).intValue());
-  }
-  public static void SetLocalVariableLong(Thread thr, int depth, int slot, Object val) {
-    SetLocalVariableLong(thr, depth, slot, ((Number)val).longValue());
-  }
-  public static void SetLocalVariableFloat(Thread thr, int depth, int slot, Object val) {
-    SetLocalVariableFloat(thr, depth, slot, ((Number)val).floatValue());
-  }
-  public static void SetLocalVariableDouble(Thread thr, int depth, int slot, Object val) {
-    SetLocalVariableDouble(thr, depth, slot, ((Number)val).doubleValue());
-  }
-  public static native void SetLocalVariableInt(Thread thr, int depth, int slot, int val);
-  public static native void SetLocalVariableLong(Thread thr, int depth, int slot, long val);
-  public static native void SetLocalVariableFloat(Thread thr, int depth, int slot, float val);
-  public static native void SetLocalVariableDouble(Thread thr, int depth, int slot, double val);
-  public static native void SetLocalVariableObject(Thread thr, int depth, int slot, Object val);
-}
diff --git a/test/1913-get-set-local-objects/src/art/Locals.java b/test/1913-get-set-local-objects/src/art/Locals.java
new file mode 120000
index 0000000..2998386
--- /dev/null
+++ b/test/1913-get-set-local-objects/src/art/Locals.java
@@ -0,0 +1 @@
+../../../jvmti-common/Locals.java
\ No newline at end of file
diff --git a/test/1913-get-set-local-objects/src/art/StackTrace.java b/test/1913-get-set-local-objects/src/art/StackTrace.java
deleted file mode 100644
index 2ea2f20..0000000
--- a/test/1913-get-set-local-objects/src/art/StackTrace.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Executable;
-
-public class StackTrace {
-  public static class StackFrameData {
-    public final Thread thr;
-    public final Executable method;
-    public final long current_location;
-    public final int depth;
-
-    public StackFrameData(Thread thr, Executable e, long loc, int depth) {
-      this.thr = thr;
-      this.method = e;
-      this.current_location = loc;
-      this.depth = depth;
-    }
-    @Override
-    public String toString() {
-      return String.format(
-          "StackFrameData { thr: '%s', method: '%s', loc: %d, depth: %d }",
-          this.thr,
-          this.method,
-          this.current_location,
-          this.depth);
-    }
-  }
-
-  public static native int GetStackDepth(Thread thr);
-
-  private static native StackFrameData[] nativeGetStackTrace(Thread thr);
-
-  public static StackFrameData[] GetStackTrace(Thread thr) {
-    // The RI seems to give inconsistent (and sometimes nonsensical) results if the thread is not
-    // suspended. The spec says that not being suspended is fine but since we want this to be
-    // consistent we will suspend for the RI.
-    boolean suspend_thread =
-        !System.getProperty("java.vm.name").equals("Dalvik") &&
-        !thr.equals(Thread.currentThread()) &&
-        !Suspension.isSuspended(thr);
-    if (suspend_thread) {
-      Suspension.suspend(thr);
-    }
-    StackFrameData[] out = nativeGetStackTrace(thr);
-    if (suspend_thread) {
-      Suspension.resume(thr);
-    }
-    return out;
-  }
-}
-
diff --git a/test/1913-get-set-local-objects/src/art/StackTrace.java b/test/1913-get-set-local-objects/src/art/StackTrace.java
new file mode 120000
index 0000000..e1a08aa
--- /dev/null
+++ b/test/1913-get-set-local-objects/src/art/StackTrace.java
@@ -0,0 +1 @@
+../../../jvmti-common/StackTrace.java
\ No newline at end of file
diff --git a/test/1913-get-set-local-objects/src/art/Suspension.java b/test/1913-get-set-local-objects/src/art/Suspension.java
deleted file mode 100644
index 16e62cc..0000000
--- a/test/1913-get-set-local-objects/src/art/Suspension.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-public class Suspension {
-  // Suspends a thread using jvmti.
-  public native static void suspend(Thread thr);
-
-  // Resumes a thread using jvmti.
-  public native static void resume(Thread thr);
-
-  public native static boolean isSuspended(Thread thr);
-
-  public native static int[] suspendList(Thread... threads);
-  public native static int[] resumeList(Thread... threads);
-}
diff --git a/test/1913-get-set-local-objects/src/art/Suspension.java b/test/1913-get-set-local-objects/src/art/Suspension.java
new file mode 120000
index 0000000..bcef96f
--- /dev/null
+++ b/test/1913-get-set-local-objects/src/art/Suspension.java
@@ -0,0 +1 @@
+../../../jvmti-common/Suspension.java
\ No newline at end of file
diff --git a/test/1914-get-local-instance/src/art/Breakpoint.java b/test/1914-get-local-instance/src/art/Breakpoint.java
deleted file mode 100644
index bbb89f7..0000000
--- a/test/1914-get-local-instance/src/art/Breakpoint.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Executable;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.Objects;
-
-public class Breakpoint {
-  public static class Manager {
-    public static class BP {
-      public final Executable method;
-      public final long location;
-
-      public BP(Executable method) {
-        this(method, getStartLocation(method));
-      }
-
-      public BP(Executable method, long location) {
-        this.method = method;
-        this.location = location;
-      }
-
-      @Override
-      public boolean equals(Object other) {
-        return (other instanceof BP) &&
-            method.equals(((BP)other).method) &&
-            location == ((BP)other).location;
-      }
-
-      @Override
-      public String toString() {
-        return method.toString() + " @ " + getLine();
-      }
-
-      @Override
-      public int hashCode() {
-        return Objects.hash(method, location);
-      }
-
-      public int getLine() {
-        try {
-          LineNumber[] lines = getLineNumberTable(method);
-          int best = -1;
-          for (LineNumber l : lines) {
-            if (l.location > location) {
-              break;
-            } else {
-              best = l.line;
-            }
-          }
-          return best;
-        } catch (Exception e) {
-          return -1;
-        }
-      }
-    }
-
-    private Set<BP> breaks = new HashSet<>();
-
-    public void setBreakpoints(BP... bs) {
-      for (BP b : bs) {
-        if (breaks.add(b)) {
-          Breakpoint.setBreakpoint(b.method, b.location);
-        }
-      }
-    }
-    public void setBreakpoint(Executable method, long location) {
-      setBreakpoints(new BP(method, location));
-    }
-
-    public void clearBreakpoints(BP... bs) {
-      for (BP b : bs) {
-        if (breaks.remove(b)) {
-          Breakpoint.clearBreakpoint(b.method, b.location);
-        }
-      }
-    }
-    public void clearBreakpoint(Executable method, long location) {
-      clearBreakpoints(new BP(method, location));
-    }
-
-    public void clearAllBreakpoints() {
-      clearBreakpoints(breaks.toArray(new BP[0]));
-    }
-  }
-
-  public static void startBreakpointWatch(Class<?> methodClass,
-                                          Executable breakpointReached,
-                                          Thread thr) {
-    startBreakpointWatch(methodClass, breakpointReached, false, thr);
-  }
-
-  /**
-   * Enables the trapping of breakpoint events.
-   *
-   * If allowRecursive == true then breakpoints will be sent even if one is currently being handled.
-   */
-  public static native void startBreakpointWatch(Class<?> methodClass,
-                                                 Executable breakpointReached,
-                                                 boolean allowRecursive,
-                                                 Thread thr);
-  public static native void stopBreakpointWatch(Thread thr);
-
-  public static final class LineNumber implements Comparable<LineNumber> {
-    public final long location;
-    public final int line;
-
-    private LineNumber(long loc, int line) {
-      this.location = loc;
-      this.line = line;
-    }
-
-    public boolean equals(Object other) {
-      return other instanceof LineNumber && ((LineNumber)other).line == line &&
-          ((LineNumber)other).location == location;
-    }
-
-    public int compareTo(LineNumber other) {
-      int v = Integer.valueOf(line).compareTo(Integer.valueOf(other.line));
-      if (v != 0) {
-        return v;
-      } else {
-        return Long.valueOf(location).compareTo(Long.valueOf(other.location));
-      }
-    }
-  }
-
-  public static native void setBreakpoint(Executable m, long loc);
-  public static void setBreakpoint(Executable m, LineNumber l) {
-    setBreakpoint(m, l.location);
-  }
-
-  public static native void clearBreakpoint(Executable m, long loc);
-  public static void clearBreakpoint(Executable m, LineNumber l) {
-    clearBreakpoint(m, l.location);
-  }
-
-  private static native Object[] getLineNumberTableNative(Executable m);
-  public static LineNumber[] getLineNumberTable(Executable m) {
-    Object[] nativeTable = getLineNumberTableNative(m);
-    long[] location = (long[])(nativeTable[0]);
-    int[] lines = (int[])(nativeTable[1]);
-    if (lines.length != location.length) {
-      throw new Error("Lines and locations have different lengths!");
-    }
-    LineNumber[] out = new LineNumber[lines.length];
-    for (int i = 0; i < lines.length; i++) {
-      out[i] = new LineNumber(location[i], lines[i]);
-    }
-    return out;
-  }
-
-  public static native long getStartLocation(Executable m);
-
-  public static int locationToLine(Executable m, long location) {
-    try {
-      Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
-      int best = -1;
-      for (Breakpoint.LineNumber l : lines) {
-        if (l.location > location) {
-          break;
-        } else {
-          best = l.line;
-        }
-      }
-      return best;
-    } catch (Exception e) {
-      return -1;
-    }
-  }
-
-  public static long lineToLocation(Executable m, int line) throws Exception {
-    try {
-      Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
-      for (Breakpoint.LineNumber l : lines) {
-        if (l.line == line) {
-          return l.location;
-        }
-      }
-      throw new Exception("Unable to find line " + line + " in " + m);
-    } catch (Exception e) {
-      throw new Exception("Unable to get line number info for " + m, e);
-    }
-  }
-}
-
diff --git a/test/1914-get-local-instance/src/art/Breakpoint.java b/test/1914-get-local-instance/src/art/Breakpoint.java
new file mode 120000
index 0000000..3673916
--- /dev/null
+++ b/test/1914-get-local-instance/src/art/Breakpoint.java
@@ -0,0 +1 @@
+../../../jvmti-common/Breakpoint.java
\ No newline at end of file
diff --git a/test/1914-get-local-instance/src/art/Locals.java b/test/1914-get-local-instance/src/art/Locals.java
deleted file mode 100644
index 22e21be..0000000
--- a/test/1914-get-local-instance/src/art/Locals.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Executable;
-import java.util.Objects;
-
-public class Locals {
-  public static native void EnableLocalVariableAccess();
-
-  public static class VariableDescription {
-    public final long start_location;
-    public final int length;
-    public final String name;
-    public final String signature;
-    public final String generic_signature;
-    public final int slot;
-
-    public VariableDescription(
-        long start, int length, String name, String sig, String gen_sig, int slot) {
-      this.start_location = start;
-      this.length = length;
-      this.name = name;
-      this.signature = sig;
-      this.generic_signature = gen_sig;
-      this.slot = slot;
-    }
-
-    @Override
-    public String toString() {
-      return String.format(
-          "VariableDescription { " +
-            "Sig: '%s', Name: '%s', Gen_sig: '%s', slot: %d, start: %d, len: %d" +
-          "}",
-          this.signature,
-          this.name,
-          this.generic_signature,
-          this.slot,
-          this.start_location,
-          this.length);
-    }
-    public boolean equals(Object other) {
-      if (!(other instanceof VariableDescription)) {
-        return false;
-      } else {
-        VariableDescription v = (VariableDescription)other;
-        return Objects.equals(v.signature, signature) &&
-            Objects.equals(v.name, name) &&
-            Objects.equals(v.generic_signature, generic_signature) &&
-            v.slot == slot &&
-            v.start_location == start_location &&
-            v.length == length;
-      }
-    }
-    public int hashCode() {
-      return Objects.hash(this.signature, this.name, this.generic_signature, this.slot,
-          this.start_location, this.length);
-    }
-  }
-
-  public static native VariableDescription[] GetLocalVariableTable(Executable e);
-
-  public static VariableDescription GetVariableAtLine(
-      Executable e, String name, String sig, int line) throws Exception {
-    return GetVariableAtLocation(e, name, sig, Breakpoint.lineToLocation(e, line));
-  }
-
-  public static VariableDescription GetVariableAtLocation(
-      Executable e, String name, String sig, long loc) {
-    VariableDescription[] vars = GetLocalVariableTable(e);
-    for (VariableDescription var : vars) {
-      if (var.start_location <= loc &&
-          var.length + var.start_location > loc &&
-          var.name.equals(name) &&
-          var.signature.equals(sig)) {
-        return var;
-      }
-    }
-    throw new Error(
-        "Unable to find variable " + name + " (sig: " + sig + ") in " + e + " at loc " + loc);
-  }
-
-  public static native int GetLocalVariableInt(Thread thr, int depth, int slot);
-  public static native long GetLocalVariableLong(Thread thr, int depth, int slot);
-  public static native float GetLocalVariableFloat(Thread thr, int depth, int slot);
-  public static native double GetLocalVariableDouble(Thread thr, int depth, int slot);
-  public static native Object GetLocalVariableObject(Thread thr, int depth, int slot);
-  public static native Object GetLocalInstance(Thread thr, int depth);
-
-  public static void SetLocalVariableInt(Thread thr, int depth, int slot, Object val) {
-    SetLocalVariableInt(thr, depth, slot, ((Number)val).intValue());
-  }
-  public static void SetLocalVariableLong(Thread thr, int depth, int slot, Object val) {
-    SetLocalVariableLong(thr, depth, slot, ((Number)val).longValue());
-  }
-  public static void SetLocalVariableFloat(Thread thr, int depth, int slot, Object val) {
-    SetLocalVariableFloat(thr, depth, slot, ((Number)val).floatValue());
-  }
-  public static void SetLocalVariableDouble(Thread thr, int depth, int slot, Object val) {
-    SetLocalVariableDouble(thr, depth, slot, ((Number)val).doubleValue());
-  }
-  public static native void SetLocalVariableInt(Thread thr, int depth, int slot, int val);
-  public static native void SetLocalVariableLong(Thread thr, int depth, int slot, long val);
-  public static native void SetLocalVariableFloat(Thread thr, int depth, int slot, float val);
-  public static native void SetLocalVariableDouble(Thread thr, int depth, int slot, double val);
-  public static native void SetLocalVariableObject(Thread thr, int depth, int slot, Object val);
-}
diff --git a/test/1914-get-local-instance/src/art/Locals.java b/test/1914-get-local-instance/src/art/Locals.java
new file mode 120000
index 0000000..2998386
--- /dev/null
+++ b/test/1914-get-local-instance/src/art/Locals.java
@@ -0,0 +1 @@
+../../../jvmti-common/Locals.java
\ No newline at end of file
diff --git a/test/1914-get-local-instance/src/art/StackTrace.java b/test/1914-get-local-instance/src/art/StackTrace.java
deleted file mode 100644
index 2ea2f20..0000000
--- a/test/1914-get-local-instance/src/art/StackTrace.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Executable;
-
-public class StackTrace {
-  public static class StackFrameData {
-    public final Thread thr;
-    public final Executable method;
-    public final long current_location;
-    public final int depth;
-
-    public StackFrameData(Thread thr, Executable e, long loc, int depth) {
-      this.thr = thr;
-      this.method = e;
-      this.current_location = loc;
-      this.depth = depth;
-    }
-    @Override
-    public String toString() {
-      return String.format(
-          "StackFrameData { thr: '%s', method: '%s', loc: %d, depth: %d }",
-          this.thr,
-          this.method,
-          this.current_location,
-          this.depth);
-    }
-  }
-
-  public static native int GetStackDepth(Thread thr);
-
-  private static native StackFrameData[] nativeGetStackTrace(Thread thr);
-
-  public static StackFrameData[] GetStackTrace(Thread thr) {
-    // The RI seems to give inconsistent (and sometimes nonsensical) results if the thread is not
-    // suspended. The spec says that not being suspended is fine but since we want this to be
-    // consistent we will suspend for the RI.
-    boolean suspend_thread =
-        !System.getProperty("java.vm.name").equals("Dalvik") &&
-        !thr.equals(Thread.currentThread()) &&
-        !Suspension.isSuspended(thr);
-    if (suspend_thread) {
-      Suspension.suspend(thr);
-    }
-    StackFrameData[] out = nativeGetStackTrace(thr);
-    if (suspend_thread) {
-      Suspension.resume(thr);
-    }
-    return out;
-  }
-}
-
diff --git a/test/1914-get-local-instance/src/art/StackTrace.java b/test/1914-get-local-instance/src/art/StackTrace.java
new file mode 120000
index 0000000..e1a08aa
--- /dev/null
+++ b/test/1914-get-local-instance/src/art/StackTrace.java
@@ -0,0 +1 @@
+../../../jvmti-common/StackTrace.java
\ No newline at end of file
diff --git a/test/1914-get-local-instance/src/art/Suspension.java b/test/1914-get-local-instance/src/art/Suspension.java
deleted file mode 100644
index 16e62cc..0000000
--- a/test/1914-get-local-instance/src/art/Suspension.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-public class Suspension {
-  // Suspends a thread using jvmti.
-  public native static void suspend(Thread thr);
-
-  // Resumes a thread using jvmti.
-  public native static void resume(Thread thr);
-
-  public native static boolean isSuspended(Thread thr);
-
-  public native static int[] suspendList(Thread... threads);
-  public native static int[] resumeList(Thread... threads);
-}
diff --git a/test/1914-get-local-instance/src/art/Suspension.java b/test/1914-get-local-instance/src/art/Suspension.java
new file mode 120000
index 0000000..bcef96f
--- /dev/null
+++ b/test/1914-get-local-instance/src/art/Suspension.java
@@ -0,0 +1 @@
+../../../jvmti-common/Suspension.java
\ No newline at end of file
diff --git a/test/1915-get-set-local-current-thread/src/art/Breakpoint.java b/test/1915-get-set-local-current-thread/src/art/Breakpoint.java
deleted file mode 100644
index bbb89f7..0000000
--- a/test/1915-get-set-local-current-thread/src/art/Breakpoint.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Executable;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.Objects;
-
-public class Breakpoint {
-  public static class Manager {
-    public static class BP {
-      public final Executable method;
-      public final long location;
-
-      public BP(Executable method) {
-        this(method, getStartLocation(method));
-      }
-
-      public BP(Executable method, long location) {
-        this.method = method;
-        this.location = location;
-      }
-
-      @Override
-      public boolean equals(Object other) {
-        return (other instanceof BP) &&
-            method.equals(((BP)other).method) &&
-            location == ((BP)other).location;
-      }
-
-      @Override
-      public String toString() {
-        return method.toString() + " @ " + getLine();
-      }
-
-      @Override
-      public int hashCode() {
-        return Objects.hash(method, location);
-      }
-
-      public int getLine() {
-        try {
-          LineNumber[] lines = getLineNumberTable(method);
-          int best = -1;
-          for (LineNumber l : lines) {
-            if (l.location > location) {
-              break;
-            } else {
-              best = l.line;
-            }
-          }
-          return best;
-        } catch (Exception e) {
-          return -1;
-        }
-      }
-    }
-
-    private Set<BP> breaks = new HashSet<>();
-
-    public void setBreakpoints(BP... bs) {
-      for (BP b : bs) {
-        if (breaks.add(b)) {
-          Breakpoint.setBreakpoint(b.method, b.location);
-        }
-      }
-    }
-    public void setBreakpoint(Executable method, long location) {
-      setBreakpoints(new BP(method, location));
-    }
-
-    public void clearBreakpoints(BP... bs) {
-      for (BP b : bs) {
-        if (breaks.remove(b)) {
-          Breakpoint.clearBreakpoint(b.method, b.location);
-        }
-      }
-    }
-    public void clearBreakpoint(Executable method, long location) {
-      clearBreakpoints(new BP(method, location));
-    }
-
-    public void clearAllBreakpoints() {
-      clearBreakpoints(breaks.toArray(new BP[0]));
-    }
-  }
-
-  public static void startBreakpointWatch(Class<?> methodClass,
-                                          Executable breakpointReached,
-                                          Thread thr) {
-    startBreakpointWatch(methodClass, breakpointReached, false, thr);
-  }
-
-  /**
-   * Enables the trapping of breakpoint events.
-   *
-   * If allowRecursive == true then breakpoints will be sent even if one is currently being handled.
-   */
-  public static native void startBreakpointWatch(Class<?> methodClass,
-                                                 Executable breakpointReached,
-                                                 boolean allowRecursive,
-                                                 Thread thr);
-  public static native void stopBreakpointWatch(Thread thr);
-
-  public static final class LineNumber implements Comparable<LineNumber> {
-    public final long location;
-    public final int line;
-
-    private LineNumber(long loc, int line) {
-      this.location = loc;
-      this.line = line;
-    }
-
-    public boolean equals(Object other) {
-      return other instanceof LineNumber && ((LineNumber)other).line == line &&
-          ((LineNumber)other).location == location;
-    }
-
-    public int compareTo(LineNumber other) {
-      int v = Integer.valueOf(line).compareTo(Integer.valueOf(other.line));
-      if (v != 0) {
-        return v;
-      } else {
-        return Long.valueOf(location).compareTo(Long.valueOf(other.location));
-      }
-    }
-  }
-
-  public static native void setBreakpoint(Executable m, long loc);
-  public static void setBreakpoint(Executable m, LineNumber l) {
-    setBreakpoint(m, l.location);
-  }
-
-  public static native void clearBreakpoint(Executable m, long loc);
-  public static void clearBreakpoint(Executable m, LineNumber l) {
-    clearBreakpoint(m, l.location);
-  }
-
-  private static native Object[] getLineNumberTableNative(Executable m);
-  public static LineNumber[] getLineNumberTable(Executable m) {
-    Object[] nativeTable = getLineNumberTableNative(m);
-    long[] location = (long[])(nativeTable[0]);
-    int[] lines = (int[])(nativeTable[1]);
-    if (lines.length != location.length) {
-      throw new Error("Lines and locations have different lengths!");
-    }
-    LineNumber[] out = new LineNumber[lines.length];
-    for (int i = 0; i < lines.length; i++) {
-      out[i] = new LineNumber(location[i], lines[i]);
-    }
-    return out;
-  }
-
-  public static native long getStartLocation(Executable m);
-
-  public static int locationToLine(Executable m, long location) {
-    try {
-      Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
-      int best = -1;
-      for (Breakpoint.LineNumber l : lines) {
-        if (l.location > location) {
-          break;
-        } else {
-          best = l.line;
-        }
-      }
-      return best;
-    } catch (Exception e) {
-      return -1;
-    }
-  }
-
-  public static long lineToLocation(Executable m, int line) throws Exception {
-    try {
-      Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
-      for (Breakpoint.LineNumber l : lines) {
-        if (l.line == line) {
-          return l.location;
-        }
-      }
-      throw new Exception("Unable to find line " + line + " in " + m);
-    } catch (Exception e) {
-      throw new Exception("Unable to get line number info for " + m, e);
-    }
-  }
-}
-
diff --git a/test/1915-get-set-local-current-thread/src/art/Breakpoint.java b/test/1915-get-set-local-current-thread/src/art/Breakpoint.java
new file mode 120000
index 0000000..3673916
--- /dev/null
+++ b/test/1915-get-set-local-current-thread/src/art/Breakpoint.java
@@ -0,0 +1 @@
+../../../jvmti-common/Breakpoint.java
\ No newline at end of file
diff --git a/test/1915-get-set-local-current-thread/src/art/Locals.java b/test/1915-get-set-local-current-thread/src/art/Locals.java
deleted file mode 100644
index 22e21be..0000000
--- a/test/1915-get-set-local-current-thread/src/art/Locals.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Executable;
-import java.util.Objects;
-
-public class Locals {
-  public static native void EnableLocalVariableAccess();
-
-  public static class VariableDescription {
-    public final long start_location;
-    public final int length;
-    public final String name;
-    public final String signature;
-    public final String generic_signature;
-    public final int slot;
-
-    public VariableDescription(
-        long start, int length, String name, String sig, String gen_sig, int slot) {
-      this.start_location = start;
-      this.length = length;
-      this.name = name;
-      this.signature = sig;
-      this.generic_signature = gen_sig;
-      this.slot = slot;
-    }
-
-    @Override
-    public String toString() {
-      return String.format(
-          "VariableDescription { " +
-            "Sig: '%s', Name: '%s', Gen_sig: '%s', slot: %d, start: %d, len: %d" +
-          "}",
-          this.signature,
-          this.name,
-          this.generic_signature,
-          this.slot,
-          this.start_location,
-          this.length);
-    }
-    public boolean equals(Object other) {
-      if (!(other instanceof VariableDescription)) {
-        return false;
-      } else {
-        VariableDescription v = (VariableDescription)other;
-        return Objects.equals(v.signature, signature) &&
-            Objects.equals(v.name, name) &&
-            Objects.equals(v.generic_signature, generic_signature) &&
-            v.slot == slot &&
-            v.start_location == start_location &&
-            v.length == length;
-      }
-    }
-    public int hashCode() {
-      return Objects.hash(this.signature, this.name, this.generic_signature, this.slot,
-          this.start_location, this.length);
-    }
-  }
-
-  public static native VariableDescription[] GetLocalVariableTable(Executable e);
-
-  public static VariableDescription GetVariableAtLine(
-      Executable e, String name, String sig, int line) throws Exception {
-    return GetVariableAtLocation(e, name, sig, Breakpoint.lineToLocation(e, line));
-  }
-
-  public static VariableDescription GetVariableAtLocation(
-      Executable e, String name, String sig, long loc) {
-    VariableDescription[] vars = GetLocalVariableTable(e);
-    for (VariableDescription var : vars) {
-      if (var.start_location <= loc &&
-          var.length + var.start_location > loc &&
-          var.name.equals(name) &&
-          var.signature.equals(sig)) {
-        return var;
-      }
-    }
-    throw new Error(
-        "Unable to find variable " + name + " (sig: " + sig + ") in " + e + " at loc " + loc);
-  }
-
-  public static native int GetLocalVariableInt(Thread thr, int depth, int slot);
-  public static native long GetLocalVariableLong(Thread thr, int depth, int slot);
-  public static native float GetLocalVariableFloat(Thread thr, int depth, int slot);
-  public static native double GetLocalVariableDouble(Thread thr, int depth, int slot);
-  public static native Object GetLocalVariableObject(Thread thr, int depth, int slot);
-  public static native Object GetLocalInstance(Thread thr, int depth);
-
-  public static void SetLocalVariableInt(Thread thr, int depth, int slot, Object val) {
-    SetLocalVariableInt(thr, depth, slot, ((Number)val).intValue());
-  }
-  public static void SetLocalVariableLong(Thread thr, int depth, int slot, Object val) {
-    SetLocalVariableLong(thr, depth, slot, ((Number)val).longValue());
-  }
-  public static void SetLocalVariableFloat(Thread thr, int depth, int slot, Object val) {
-    SetLocalVariableFloat(thr, depth, slot, ((Number)val).floatValue());
-  }
-  public static void SetLocalVariableDouble(Thread thr, int depth, int slot, Object val) {
-    SetLocalVariableDouble(thr, depth, slot, ((Number)val).doubleValue());
-  }
-  public static native void SetLocalVariableInt(Thread thr, int depth, int slot, int val);
-  public static native void SetLocalVariableLong(Thread thr, int depth, int slot, long val);
-  public static native void SetLocalVariableFloat(Thread thr, int depth, int slot, float val);
-  public static native void SetLocalVariableDouble(Thread thr, int depth, int slot, double val);
-  public static native void SetLocalVariableObject(Thread thr, int depth, int slot, Object val);
-}
diff --git a/test/1915-get-set-local-current-thread/src/art/Locals.java b/test/1915-get-set-local-current-thread/src/art/Locals.java
new file mode 120000
index 0000000..2998386
--- /dev/null
+++ b/test/1915-get-set-local-current-thread/src/art/Locals.java
@@ -0,0 +1 @@
+../../../jvmti-common/Locals.java
\ No newline at end of file
diff --git a/test/1915-get-set-local-current-thread/src/art/StackTrace.java b/test/1915-get-set-local-current-thread/src/art/StackTrace.java
deleted file mode 100644
index 2ea2f20..0000000
--- a/test/1915-get-set-local-current-thread/src/art/StackTrace.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Executable;
-
-public class StackTrace {
-  public static class StackFrameData {
-    public final Thread thr;
-    public final Executable method;
-    public final long current_location;
-    public final int depth;
-
-    public StackFrameData(Thread thr, Executable e, long loc, int depth) {
-      this.thr = thr;
-      this.method = e;
-      this.current_location = loc;
-      this.depth = depth;
-    }
-    @Override
-    public String toString() {
-      return String.format(
-          "StackFrameData { thr: '%s', method: '%s', loc: %d, depth: %d }",
-          this.thr,
-          this.method,
-          this.current_location,
-          this.depth);
-    }
-  }
-
-  public static native int GetStackDepth(Thread thr);
-
-  private static native StackFrameData[] nativeGetStackTrace(Thread thr);
-
-  public static StackFrameData[] GetStackTrace(Thread thr) {
-    // The RI seems to give inconsistent (and sometimes nonsensical) results if the thread is not
-    // suspended. The spec says that not being suspended is fine but since we want this to be
-    // consistent we will suspend for the RI.
-    boolean suspend_thread =
-        !System.getProperty("java.vm.name").equals("Dalvik") &&
-        !thr.equals(Thread.currentThread()) &&
-        !Suspension.isSuspended(thr);
-    if (suspend_thread) {
-      Suspension.suspend(thr);
-    }
-    StackFrameData[] out = nativeGetStackTrace(thr);
-    if (suspend_thread) {
-      Suspension.resume(thr);
-    }
-    return out;
-  }
-}
-
diff --git a/test/1915-get-set-local-current-thread/src/art/StackTrace.java b/test/1915-get-set-local-current-thread/src/art/StackTrace.java
new file mode 120000
index 0000000..e1a08aa
--- /dev/null
+++ b/test/1915-get-set-local-current-thread/src/art/StackTrace.java
@@ -0,0 +1 @@
+../../../jvmti-common/StackTrace.java
\ No newline at end of file
diff --git a/test/1915-get-set-local-current-thread/src/art/Suspension.java b/test/1915-get-set-local-current-thread/src/art/Suspension.java
deleted file mode 100644
index 16e62cc..0000000
--- a/test/1915-get-set-local-current-thread/src/art/Suspension.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-public class Suspension {
-  // Suspends a thread using jvmti.
-  public native static void suspend(Thread thr);
-
-  // Resumes a thread using jvmti.
-  public native static void resume(Thread thr);
-
-  public native static boolean isSuspended(Thread thr);
-
-  public native static int[] suspendList(Thread... threads);
-  public native static int[] resumeList(Thread... threads);
-}
diff --git a/test/1915-get-set-local-current-thread/src/art/Suspension.java b/test/1915-get-set-local-current-thread/src/art/Suspension.java
new file mode 120000
index 0000000..bcef96f
--- /dev/null
+++ b/test/1915-get-set-local-current-thread/src/art/Suspension.java
@@ -0,0 +1 @@
+../../../jvmti-common/Suspension.java
\ No newline at end of file
diff --git a/test/1916-get-set-current-frame/src/art/Breakpoint.java b/test/1916-get-set-current-frame/src/art/Breakpoint.java
deleted file mode 100644
index bbb89f7..0000000
--- a/test/1916-get-set-current-frame/src/art/Breakpoint.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Executable;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.Objects;
-
-public class Breakpoint {
-  public static class Manager {
-    public static class BP {
-      public final Executable method;
-      public final long location;
-
-      public BP(Executable method) {
-        this(method, getStartLocation(method));
-      }
-
-      public BP(Executable method, long location) {
-        this.method = method;
-        this.location = location;
-      }
-
-      @Override
-      public boolean equals(Object other) {
-        return (other instanceof BP) &&
-            method.equals(((BP)other).method) &&
-            location == ((BP)other).location;
-      }
-
-      @Override
-      public String toString() {
-        return method.toString() + " @ " + getLine();
-      }
-
-      @Override
-      public int hashCode() {
-        return Objects.hash(method, location);
-      }
-
-      public int getLine() {
-        try {
-          LineNumber[] lines = getLineNumberTable(method);
-          int best = -1;
-          for (LineNumber l : lines) {
-            if (l.location > location) {
-              break;
-            } else {
-              best = l.line;
-            }
-          }
-          return best;
-        } catch (Exception e) {
-          return -1;
-        }
-      }
-    }
-
-    private Set<BP> breaks = new HashSet<>();
-
-    public void setBreakpoints(BP... bs) {
-      for (BP b : bs) {
-        if (breaks.add(b)) {
-          Breakpoint.setBreakpoint(b.method, b.location);
-        }
-      }
-    }
-    public void setBreakpoint(Executable method, long location) {
-      setBreakpoints(new BP(method, location));
-    }
-
-    public void clearBreakpoints(BP... bs) {
-      for (BP b : bs) {
-        if (breaks.remove(b)) {
-          Breakpoint.clearBreakpoint(b.method, b.location);
-        }
-      }
-    }
-    public void clearBreakpoint(Executable method, long location) {
-      clearBreakpoints(new BP(method, location));
-    }
-
-    public void clearAllBreakpoints() {
-      clearBreakpoints(breaks.toArray(new BP[0]));
-    }
-  }
-
-  public static void startBreakpointWatch(Class<?> methodClass,
-                                          Executable breakpointReached,
-                                          Thread thr) {
-    startBreakpointWatch(methodClass, breakpointReached, false, thr);
-  }
-
-  /**
-   * Enables the trapping of breakpoint events.
-   *
-   * If allowRecursive == true then breakpoints will be sent even if one is currently being handled.
-   */
-  public static native void startBreakpointWatch(Class<?> methodClass,
-                                                 Executable breakpointReached,
-                                                 boolean allowRecursive,
-                                                 Thread thr);
-  public static native void stopBreakpointWatch(Thread thr);
-
-  public static final class LineNumber implements Comparable<LineNumber> {
-    public final long location;
-    public final int line;
-
-    private LineNumber(long loc, int line) {
-      this.location = loc;
-      this.line = line;
-    }
-
-    public boolean equals(Object other) {
-      return other instanceof LineNumber && ((LineNumber)other).line == line &&
-          ((LineNumber)other).location == location;
-    }
-
-    public int compareTo(LineNumber other) {
-      int v = Integer.valueOf(line).compareTo(Integer.valueOf(other.line));
-      if (v != 0) {
-        return v;
-      } else {
-        return Long.valueOf(location).compareTo(Long.valueOf(other.location));
-      }
-    }
-  }
-
-  public static native void setBreakpoint(Executable m, long loc);
-  public static void setBreakpoint(Executable m, LineNumber l) {
-    setBreakpoint(m, l.location);
-  }
-
-  public static native void clearBreakpoint(Executable m, long loc);
-  public static void clearBreakpoint(Executable m, LineNumber l) {
-    clearBreakpoint(m, l.location);
-  }
-
-  private static native Object[] getLineNumberTableNative(Executable m);
-  public static LineNumber[] getLineNumberTable(Executable m) {
-    Object[] nativeTable = getLineNumberTableNative(m);
-    long[] location = (long[])(nativeTable[0]);
-    int[] lines = (int[])(nativeTable[1]);
-    if (lines.length != location.length) {
-      throw new Error("Lines and locations have different lengths!");
-    }
-    LineNumber[] out = new LineNumber[lines.length];
-    for (int i = 0; i < lines.length; i++) {
-      out[i] = new LineNumber(location[i], lines[i]);
-    }
-    return out;
-  }
-
-  public static native long getStartLocation(Executable m);
-
-  public static int locationToLine(Executable m, long location) {
-    try {
-      Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
-      int best = -1;
-      for (Breakpoint.LineNumber l : lines) {
-        if (l.location > location) {
-          break;
-        } else {
-          best = l.line;
-        }
-      }
-      return best;
-    } catch (Exception e) {
-      return -1;
-    }
-  }
-
-  public static long lineToLocation(Executable m, int line) throws Exception {
-    try {
-      Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
-      for (Breakpoint.LineNumber l : lines) {
-        if (l.line == line) {
-          return l.location;
-        }
-      }
-      throw new Exception("Unable to find line " + line + " in " + m);
-    } catch (Exception e) {
-      throw new Exception("Unable to get line number info for " + m, e);
-    }
-  }
-}
-
diff --git a/test/1916-get-set-current-frame/src/art/Breakpoint.java b/test/1916-get-set-current-frame/src/art/Breakpoint.java
new file mode 120000
index 0000000..3673916
--- /dev/null
+++ b/test/1916-get-set-current-frame/src/art/Breakpoint.java
@@ -0,0 +1 @@
+../../../jvmti-common/Breakpoint.java
\ No newline at end of file
diff --git a/test/1916-get-set-current-frame/src/art/Locals.java b/test/1916-get-set-current-frame/src/art/Locals.java
deleted file mode 100644
index 22e21be..0000000
--- a/test/1916-get-set-current-frame/src/art/Locals.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Executable;
-import java.util.Objects;
-
-public class Locals {
-  public static native void EnableLocalVariableAccess();
-
-  public static class VariableDescription {
-    public final long start_location;
-    public final int length;
-    public final String name;
-    public final String signature;
-    public final String generic_signature;
-    public final int slot;
-
-    public VariableDescription(
-        long start, int length, String name, String sig, String gen_sig, int slot) {
-      this.start_location = start;
-      this.length = length;
-      this.name = name;
-      this.signature = sig;
-      this.generic_signature = gen_sig;
-      this.slot = slot;
-    }
-
-    @Override
-    public String toString() {
-      return String.format(
-          "VariableDescription { " +
-            "Sig: '%s', Name: '%s', Gen_sig: '%s', slot: %d, start: %d, len: %d" +
-          "}",
-          this.signature,
-          this.name,
-          this.generic_signature,
-          this.slot,
-          this.start_location,
-          this.length);
-    }
-    public boolean equals(Object other) {
-      if (!(other instanceof VariableDescription)) {
-        return false;
-      } else {
-        VariableDescription v = (VariableDescription)other;
-        return Objects.equals(v.signature, signature) &&
-            Objects.equals(v.name, name) &&
-            Objects.equals(v.generic_signature, generic_signature) &&
-            v.slot == slot &&
-            v.start_location == start_location &&
-            v.length == length;
-      }
-    }
-    public int hashCode() {
-      return Objects.hash(this.signature, this.name, this.generic_signature, this.slot,
-          this.start_location, this.length);
-    }
-  }
-
-  public static native VariableDescription[] GetLocalVariableTable(Executable e);
-
-  public static VariableDescription GetVariableAtLine(
-      Executable e, String name, String sig, int line) throws Exception {
-    return GetVariableAtLocation(e, name, sig, Breakpoint.lineToLocation(e, line));
-  }
-
-  public static VariableDescription GetVariableAtLocation(
-      Executable e, String name, String sig, long loc) {
-    VariableDescription[] vars = GetLocalVariableTable(e);
-    for (VariableDescription var : vars) {
-      if (var.start_location <= loc &&
-          var.length + var.start_location > loc &&
-          var.name.equals(name) &&
-          var.signature.equals(sig)) {
-        return var;
-      }
-    }
-    throw new Error(
-        "Unable to find variable " + name + " (sig: " + sig + ") in " + e + " at loc " + loc);
-  }
-
-  public static native int GetLocalVariableInt(Thread thr, int depth, int slot);
-  public static native long GetLocalVariableLong(Thread thr, int depth, int slot);
-  public static native float GetLocalVariableFloat(Thread thr, int depth, int slot);
-  public static native double GetLocalVariableDouble(Thread thr, int depth, int slot);
-  public static native Object GetLocalVariableObject(Thread thr, int depth, int slot);
-  public static native Object GetLocalInstance(Thread thr, int depth);
-
-  public static void SetLocalVariableInt(Thread thr, int depth, int slot, Object val) {
-    SetLocalVariableInt(thr, depth, slot, ((Number)val).intValue());
-  }
-  public static void SetLocalVariableLong(Thread thr, int depth, int slot, Object val) {
-    SetLocalVariableLong(thr, depth, slot, ((Number)val).longValue());
-  }
-  public static void SetLocalVariableFloat(Thread thr, int depth, int slot, Object val) {
-    SetLocalVariableFloat(thr, depth, slot, ((Number)val).floatValue());
-  }
-  public static void SetLocalVariableDouble(Thread thr, int depth, int slot, Object val) {
-    SetLocalVariableDouble(thr, depth, slot, ((Number)val).doubleValue());
-  }
-  public static native void SetLocalVariableInt(Thread thr, int depth, int slot, int val);
-  public static native void SetLocalVariableLong(Thread thr, int depth, int slot, long val);
-  public static native void SetLocalVariableFloat(Thread thr, int depth, int slot, float val);
-  public static native void SetLocalVariableDouble(Thread thr, int depth, int slot, double val);
-  public static native void SetLocalVariableObject(Thread thr, int depth, int slot, Object val);
-}
diff --git a/test/1916-get-set-current-frame/src/art/Locals.java b/test/1916-get-set-current-frame/src/art/Locals.java
new file mode 120000
index 0000000..2998386
--- /dev/null
+++ b/test/1916-get-set-current-frame/src/art/Locals.java
@@ -0,0 +1 @@
+../../../jvmti-common/Locals.java
\ No newline at end of file
diff --git a/test/1916-get-set-current-frame/src/art/StackTrace.java b/test/1916-get-set-current-frame/src/art/StackTrace.java
deleted file mode 100644
index 2ea2f20..0000000
--- a/test/1916-get-set-current-frame/src/art/StackTrace.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Executable;
-
-public class StackTrace {
-  public static class StackFrameData {
-    public final Thread thr;
-    public final Executable method;
-    public final long current_location;
-    public final int depth;
-
-    public StackFrameData(Thread thr, Executable e, long loc, int depth) {
-      this.thr = thr;
-      this.method = e;
-      this.current_location = loc;
-      this.depth = depth;
-    }
-    @Override
-    public String toString() {
-      return String.format(
-          "StackFrameData { thr: '%s', method: '%s', loc: %d, depth: %d }",
-          this.thr,
-          this.method,
-          this.current_location,
-          this.depth);
-    }
-  }
-
-  public static native int GetStackDepth(Thread thr);
-
-  private static native StackFrameData[] nativeGetStackTrace(Thread thr);
-
-  public static StackFrameData[] GetStackTrace(Thread thr) {
-    // The RI seems to give inconsistent (and sometimes nonsensical) results if the thread is not
-    // suspended. The spec says that not being suspended is fine but since we want this to be
-    // consistent we will suspend for the RI.
-    boolean suspend_thread =
-        !System.getProperty("java.vm.name").equals("Dalvik") &&
-        !thr.equals(Thread.currentThread()) &&
-        !Suspension.isSuspended(thr);
-    if (suspend_thread) {
-      Suspension.suspend(thr);
-    }
-    StackFrameData[] out = nativeGetStackTrace(thr);
-    if (suspend_thread) {
-      Suspension.resume(thr);
-    }
-    return out;
-  }
-}
-
diff --git a/test/1916-get-set-current-frame/src/art/StackTrace.java b/test/1916-get-set-current-frame/src/art/StackTrace.java
new file mode 120000
index 0000000..e1a08aa
--- /dev/null
+++ b/test/1916-get-set-current-frame/src/art/StackTrace.java
@@ -0,0 +1 @@
+../../../jvmti-common/StackTrace.java
\ No newline at end of file
diff --git a/test/1916-get-set-current-frame/src/art/Suspension.java b/test/1916-get-set-current-frame/src/art/Suspension.java
deleted file mode 100644
index 16e62cc..0000000
--- a/test/1916-get-set-current-frame/src/art/Suspension.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-public class Suspension {
-  // Suspends a thread using jvmti.
-  public native static void suspend(Thread thr);
-
-  // Resumes a thread using jvmti.
-  public native static void resume(Thread thr);
-
-  public native static boolean isSuspended(Thread thr);
-
-  public native static int[] suspendList(Thread... threads);
-  public native static int[] resumeList(Thread... threads);
-}
diff --git a/test/1916-get-set-current-frame/src/art/Suspension.java b/test/1916-get-set-current-frame/src/art/Suspension.java
new file mode 120000
index 0000000..bcef96f
--- /dev/null
+++ b/test/1916-get-set-current-frame/src/art/Suspension.java
@@ -0,0 +1 @@
+../../../jvmti-common/Suspension.java
\ No newline at end of file
diff --git a/test/1917-get-stack-frame/src/art/Breakpoint.java b/test/1917-get-stack-frame/src/art/Breakpoint.java
deleted file mode 100644
index bbb89f7..0000000
--- a/test/1917-get-stack-frame/src/art/Breakpoint.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Executable;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.Objects;
-
-public class Breakpoint {
-  public static class Manager {
-    public static class BP {
-      public final Executable method;
-      public final long location;
-
-      public BP(Executable method) {
-        this(method, getStartLocation(method));
-      }
-
-      public BP(Executable method, long location) {
-        this.method = method;
-        this.location = location;
-      }
-
-      @Override
-      public boolean equals(Object other) {
-        return (other instanceof BP) &&
-            method.equals(((BP)other).method) &&
-            location == ((BP)other).location;
-      }
-
-      @Override
-      public String toString() {
-        return method.toString() + " @ " + getLine();
-      }
-
-      @Override
-      public int hashCode() {
-        return Objects.hash(method, location);
-      }
-
-      public int getLine() {
-        try {
-          LineNumber[] lines = getLineNumberTable(method);
-          int best = -1;
-          for (LineNumber l : lines) {
-            if (l.location > location) {
-              break;
-            } else {
-              best = l.line;
-            }
-          }
-          return best;
-        } catch (Exception e) {
-          return -1;
-        }
-      }
-    }
-
-    private Set<BP> breaks = new HashSet<>();
-
-    public void setBreakpoints(BP... bs) {
-      for (BP b : bs) {
-        if (breaks.add(b)) {
-          Breakpoint.setBreakpoint(b.method, b.location);
-        }
-      }
-    }
-    public void setBreakpoint(Executable method, long location) {
-      setBreakpoints(new BP(method, location));
-    }
-
-    public void clearBreakpoints(BP... bs) {
-      for (BP b : bs) {
-        if (breaks.remove(b)) {
-          Breakpoint.clearBreakpoint(b.method, b.location);
-        }
-      }
-    }
-    public void clearBreakpoint(Executable method, long location) {
-      clearBreakpoints(new BP(method, location));
-    }
-
-    public void clearAllBreakpoints() {
-      clearBreakpoints(breaks.toArray(new BP[0]));
-    }
-  }
-
-  public static void startBreakpointWatch(Class<?> methodClass,
-                                          Executable breakpointReached,
-                                          Thread thr) {
-    startBreakpointWatch(methodClass, breakpointReached, false, thr);
-  }
-
-  /**
-   * Enables the trapping of breakpoint events.
-   *
-   * If allowRecursive == true then breakpoints will be sent even if one is currently being handled.
-   */
-  public static native void startBreakpointWatch(Class<?> methodClass,
-                                                 Executable breakpointReached,
-                                                 boolean allowRecursive,
-                                                 Thread thr);
-  public static native void stopBreakpointWatch(Thread thr);
-
-  public static final class LineNumber implements Comparable<LineNumber> {
-    public final long location;
-    public final int line;
-
-    private LineNumber(long loc, int line) {
-      this.location = loc;
-      this.line = line;
-    }
-
-    public boolean equals(Object other) {
-      return other instanceof LineNumber && ((LineNumber)other).line == line &&
-          ((LineNumber)other).location == location;
-    }
-
-    public int compareTo(LineNumber other) {
-      int v = Integer.valueOf(line).compareTo(Integer.valueOf(other.line));
-      if (v != 0) {
-        return v;
-      } else {
-        return Long.valueOf(location).compareTo(Long.valueOf(other.location));
-      }
-    }
-  }
-
-  public static native void setBreakpoint(Executable m, long loc);
-  public static void setBreakpoint(Executable m, LineNumber l) {
-    setBreakpoint(m, l.location);
-  }
-
-  public static native void clearBreakpoint(Executable m, long loc);
-  public static void clearBreakpoint(Executable m, LineNumber l) {
-    clearBreakpoint(m, l.location);
-  }
-
-  private static native Object[] getLineNumberTableNative(Executable m);
-  public static LineNumber[] getLineNumberTable(Executable m) {
-    Object[] nativeTable = getLineNumberTableNative(m);
-    long[] location = (long[])(nativeTable[0]);
-    int[] lines = (int[])(nativeTable[1]);
-    if (lines.length != location.length) {
-      throw new Error("Lines and locations have different lengths!");
-    }
-    LineNumber[] out = new LineNumber[lines.length];
-    for (int i = 0; i < lines.length; i++) {
-      out[i] = new LineNumber(location[i], lines[i]);
-    }
-    return out;
-  }
-
-  public static native long getStartLocation(Executable m);
-
-  public static int locationToLine(Executable m, long location) {
-    try {
-      Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
-      int best = -1;
-      for (Breakpoint.LineNumber l : lines) {
-        if (l.location > location) {
-          break;
-        } else {
-          best = l.line;
-        }
-      }
-      return best;
-    } catch (Exception e) {
-      return -1;
-    }
-  }
-
-  public static long lineToLocation(Executable m, int line) throws Exception {
-    try {
-      Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
-      for (Breakpoint.LineNumber l : lines) {
-        if (l.line == line) {
-          return l.location;
-        }
-      }
-      throw new Exception("Unable to find line " + line + " in " + m);
-    } catch (Exception e) {
-      throw new Exception("Unable to get line number info for " + m, e);
-    }
-  }
-}
-
diff --git a/test/1917-get-stack-frame/src/art/Breakpoint.java b/test/1917-get-stack-frame/src/art/Breakpoint.java
new file mode 120000
index 0000000..3673916
--- /dev/null
+++ b/test/1917-get-stack-frame/src/art/Breakpoint.java
@@ -0,0 +1 @@
+../../../jvmti-common/Breakpoint.java
\ No newline at end of file
diff --git a/test/1917-get-stack-frame/src/art/StackTrace.java b/test/1917-get-stack-frame/src/art/StackTrace.java
deleted file mode 100644
index 2ea2f20..0000000
--- a/test/1917-get-stack-frame/src/art/StackTrace.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Executable;
-
-public class StackTrace {
-  public static class StackFrameData {
-    public final Thread thr;
-    public final Executable method;
-    public final long current_location;
-    public final int depth;
-
-    public StackFrameData(Thread thr, Executable e, long loc, int depth) {
-      this.thr = thr;
-      this.method = e;
-      this.current_location = loc;
-      this.depth = depth;
-    }
-    @Override
-    public String toString() {
-      return String.format(
-          "StackFrameData { thr: '%s', method: '%s', loc: %d, depth: %d }",
-          this.thr,
-          this.method,
-          this.current_location,
-          this.depth);
-    }
-  }
-
-  public static native int GetStackDepth(Thread thr);
-
-  private static native StackFrameData[] nativeGetStackTrace(Thread thr);
-
-  public static StackFrameData[] GetStackTrace(Thread thr) {
-    // The RI seems to give inconsistent (and sometimes nonsensical) results if the thread is not
-    // suspended. The spec says that not being suspended is fine but since we want this to be
-    // consistent we will suspend for the RI.
-    boolean suspend_thread =
-        !System.getProperty("java.vm.name").equals("Dalvik") &&
-        !thr.equals(Thread.currentThread()) &&
-        !Suspension.isSuspended(thr);
-    if (suspend_thread) {
-      Suspension.suspend(thr);
-    }
-    StackFrameData[] out = nativeGetStackTrace(thr);
-    if (suspend_thread) {
-      Suspension.resume(thr);
-    }
-    return out;
-  }
-}
-
diff --git a/test/1917-get-stack-frame/src/art/StackTrace.java b/test/1917-get-stack-frame/src/art/StackTrace.java
new file mode 120000
index 0000000..e1a08aa
--- /dev/null
+++ b/test/1917-get-stack-frame/src/art/StackTrace.java
@@ -0,0 +1 @@
+../../../jvmti-common/StackTrace.java
\ No newline at end of file
diff --git a/test/1917-get-stack-frame/src/art/Suspension.java b/test/1917-get-stack-frame/src/art/Suspension.java
deleted file mode 100644
index 16e62cc..0000000
--- a/test/1917-get-stack-frame/src/art/Suspension.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-public class Suspension {
-  // Suspends a thread using jvmti.
-  public native static void suspend(Thread thr);
-
-  // Resumes a thread using jvmti.
-  public native static void resume(Thread thr);
-
-  public native static boolean isSuspended(Thread thr);
-
-  public native static int[] suspendList(Thread... threads);
-  public native static int[] resumeList(Thread... threads);
-}
diff --git a/test/1917-get-stack-frame/src/art/Suspension.java b/test/1917-get-stack-frame/src/art/Suspension.java
new file mode 120000
index 0000000..bcef96f
--- /dev/null
+++ b/test/1917-get-stack-frame/src/art/Suspension.java
@@ -0,0 +1 @@
+../../../jvmti-common/Suspension.java
\ No newline at end of file
diff --git a/test/1919-vminit-thread-start-timing/src/art/Main.java b/test/1919-vminit-thread-start-timing/src/art/Main.java
deleted file mode 100644
index 8b01920..0000000
--- a/test/1919-vminit-thread-start-timing/src/art/Main.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-// Binder class so the agent's C code has something that can be bound and exposed to tests.
-// In a package to separate cleanly and work around CTS reference issues (though this class
-// should be replaced in the CTS version).
-public class Main {
-  // Load the given class with the given classloader, and bind all native methods to corresponding
-  // C methods in the agent. Will abort if any of the steps fail.
-  public static native void bindAgentJNI(String className, ClassLoader classLoader);
-  // Same as above, giving the class directly.
-  public static native void bindAgentJNIForClass(Class<?> klass);
-}
diff --git a/test/1919-vminit-thread-start-timing/src/art/Main.java b/test/1919-vminit-thread-start-timing/src/art/Main.java
new file mode 120000
index 0000000..84ae4ac
--- /dev/null
+++ b/test/1919-vminit-thread-start-timing/src/art/Main.java
@@ -0,0 +1 @@
+../../../jvmti-common/Main.java
\ No newline at end of file
diff --git a/test/1920-suspend-native-monitor/src/art/Suspension.java b/test/1920-suspend-native-monitor/src/art/Suspension.java
deleted file mode 100644
index 16e62cc..0000000
--- a/test/1920-suspend-native-monitor/src/art/Suspension.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-public class Suspension {
-  // Suspends a thread using jvmti.
-  public native static void suspend(Thread thr);
-
-  // Resumes a thread using jvmti.
-  public native static void resume(Thread thr);
-
-  public native static boolean isSuspended(Thread thr);
-
-  public native static int[] suspendList(Thread... threads);
-  public native static int[] resumeList(Thread... threads);
-}
diff --git a/test/1920-suspend-native-monitor/src/art/Suspension.java b/test/1920-suspend-native-monitor/src/art/Suspension.java
new file mode 120000
index 0000000..bcef96f
--- /dev/null
+++ b/test/1920-suspend-native-monitor/src/art/Suspension.java
@@ -0,0 +1 @@
+../../../jvmti-common/Suspension.java
\ No newline at end of file
diff --git a/test/1921-suspend-native-recursive-monitor/src/art/Suspension.java b/test/1921-suspend-native-recursive-monitor/src/art/Suspension.java
deleted file mode 100644
index 16e62cc..0000000
--- a/test/1921-suspend-native-recursive-monitor/src/art/Suspension.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-public class Suspension {
-  // Suspends a thread using jvmti.
-  public native static void suspend(Thread thr);
-
-  // Resumes a thread using jvmti.
-  public native static void resume(Thread thr);
-
-  public native static boolean isSuspended(Thread thr);
-
-  public native static int[] suspendList(Thread... threads);
-  public native static int[] resumeList(Thread... threads);
-}
diff --git a/test/1921-suspend-native-recursive-monitor/src/art/Suspension.java b/test/1921-suspend-native-recursive-monitor/src/art/Suspension.java
new file mode 120000
index 0000000..bcef96f
--- /dev/null
+++ b/test/1921-suspend-native-recursive-monitor/src/art/Suspension.java
@@ -0,0 +1 @@
+../../../jvmti-common/Suspension.java
\ No newline at end of file
diff --git a/test/1922-owned-monitors-info/src/art/Suspension.java b/test/1922-owned-monitors-info/src/art/Suspension.java
deleted file mode 100644
index 16e62cc..0000000
--- a/test/1922-owned-monitors-info/src/art/Suspension.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-public class Suspension {
-  // Suspends a thread using jvmti.
-  public native static void suspend(Thread thr);
-
-  // Resumes a thread using jvmti.
-  public native static void resume(Thread thr);
-
-  public native static boolean isSuspended(Thread thr);
-
-  public native static int[] suspendList(Thread... threads);
-  public native static int[] resumeList(Thread... threads);
-}
diff --git a/test/1922-owned-monitors-info/src/art/Suspension.java b/test/1922-owned-monitors-info/src/art/Suspension.java
new file mode 120000
index 0000000..bcef96f
--- /dev/null
+++ b/test/1922-owned-monitors-info/src/art/Suspension.java
@@ -0,0 +1 @@
+../../../jvmti-common/Suspension.java
\ No newline at end of file
diff --git a/test/1923-frame-pop/src/art/Breakpoint.java b/test/1923-frame-pop/src/art/Breakpoint.java
new file mode 120000
index 0000000..3673916
--- /dev/null
+++ b/test/1923-frame-pop/src/art/Breakpoint.java
@@ -0,0 +1 @@
+../../../jvmti-common/Breakpoint.java
\ No newline at end of file
diff --git a/test/1923-frame-pop/src/art/FramePop.java b/test/1923-frame-pop/src/art/FramePop.java
new file mode 120000
index 0000000..3e573af
--- /dev/null
+++ b/test/1923-frame-pop/src/art/FramePop.java
@@ -0,0 +1 @@
+../../../jvmti-common/FramePop.java
\ No newline at end of file
diff --git a/test/1923-frame-pop/src/art/Locals.java b/test/1923-frame-pop/src/art/Locals.java
new file mode 120000
index 0000000..2998386
--- /dev/null
+++ b/test/1923-frame-pop/src/art/Locals.java
@@ -0,0 +1 @@
+../../../jvmti-common/Locals.java
\ No newline at end of file
diff --git a/test/1923-frame-pop/src/art/StackTrace.java b/test/1923-frame-pop/src/art/StackTrace.java
new file mode 120000
index 0000000..e1a08aa
--- /dev/null
+++ b/test/1923-frame-pop/src/art/StackTrace.java
@@ -0,0 +1 @@
+../../../jvmti-common/StackTrace.java
\ No newline at end of file
diff --git a/test/1923-frame-pop/src/art/Suspension.java b/test/1923-frame-pop/src/art/Suspension.java
deleted file mode 100644
index 16e62cc..0000000
--- a/test/1923-frame-pop/src/art/Suspension.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-public class Suspension {
-  // Suspends a thread using jvmti.
-  public native static void suspend(Thread thr);
-
-  // Resumes a thread using jvmti.
-  public native static void resume(Thread thr);
-
-  public native static boolean isSuspended(Thread thr);
-
-  public native static int[] suspendList(Thread... threads);
-  public native static int[] resumeList(Thread... threads);
-}
diff --git a/test/1923-frame-pop/src/art/Suspension.java b/test/1923-frame-pop/src/art/Suspension.java
new file mode 120000
index 0000000..bcef96f
--- /dev/null
+++ b/test/1923-frame-pop/src/art/Suspension.java
@@ -0,0 +1 @@
+../../../jvmti-common/Suspension.java
\ No newline at end of file
diff --git a/test/1923-frame-pop/src/art/Trace.java b/test/1923-frame-pop/src/art/Trace.java
new file mode 120000
index 0000000..5d9b44b
--- /dev/null
+++ b/test/1923-frame-pop/src/art/Trace.java
@@ -0,0 +1 @@
+../../../jvmti-common/Trace.java
\ No newline at end of file
diff --git a/test/1924-frame-pop-toggle/src/art/Breakpoint.java b/test/1924-frame-pop-toggle/src/art/Breakpoint.java
deleted file mode 100644
index bbb89f7..0000000
--- a/test/1924-frame-pop-toggle/src/art/Breakpoint.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Executable;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.Objects;
-
-public class Breakpoint {
-  public static class Manager {
-    public static class BP {
-      public final Executable method;
-      public final long location;
-
-      public BP(Executable method) {
-        this(method, getStartLocation(method));
-      }
-
-      public BP(Executable method, long location) {
-        this.method = method;
-        this.location = location;
-      }
-
-      @Override
-      public boolean equals(Object other) {
-        return (other instanceof BP) &&
-            method.equals(((BP)other).method) &&
-            location == ((BP)other).location;
-      }
-
-      @Override
-      public String toString() {
-        return method.toString() + " @ " + getLine();
-      }
-
-      @Override
-      public int hashCode() {
-        return Objects.hash(method, location);
-      }
-
-      public int getLine() {
-        try {
-          LineNumber[] lines = getLineNumberTable(method);
-          int best = -1;
-          for (LineNumber l : lines) {
-            if (l.location > location) {
-              break;
-            } else {
-              best = l.line;
-            }
-          }
-          return best;
-        } catch (Exception e) {
-          return -1;
-        }
-      }
-    }
-
-    private Set<BP> breaks = new HashSet<>();
-
-    public void setBreakpoints(BP... bs) {
-      for (BP b : bs) {
-        if (breaks.add(b)) {
-          Breakpoint.setBreakpoint(b.method, b.location);
-        }
-      }
-    }
-    public void setBreakpoint(Executable method, long location) {
-      setBreakpoints(new BP(method, location));
-    }
-
-    public void clearBreakpoints(BP... bs) {
-      for (BP b : bs) {
-        if (breaks.remove(b)) {
-          Breakpoint.clearBreakpoint(b.method, b.location);
-        }
-      }
-    }
-    public void clearBreakpoint(Executable method, long location) {
-      clearBreakpoints(new BP(method, location));
-    }
-
-    public void clearAllBreakpoints() {
-      clearBreakpoints(breaks.toArray(new BP[0]));
-    }
-  }
-
-  public static void startBreakpointWatch(Class<?> methodClass,
-                                          Executable breakpointReached,
-                                          Thread thr) {
-    startBreakpointWatch(methodClass, breakpointReached, false, thr);
-  }
-
-  /**
-   * Enables the trapping of breakpoint events.
-   *
-   * If allowRecursive == true then breakpoints will be sent even if one is currently being handled.
-   */
-  public static native void startBreakpointWatch(Class<?> methodClass,
-                                                 Executable breakpointReached,
-                                                 boolean allowRecursive,
-                                                 Thread thr);
-  public static native void stopBreakpointWatch(Thread thr);
-
-  public static final class LineNumber implements Comparable<LineNumber> {
-    public final long location;
-    public final int line;
-
-    private LineNumber(long loc, int line) {
-      this.location = loc;
-      this.line = line;
-    }
-
-    public boolean equals(Object other) {
-      return other instanceof LineNumber && ((LineNumber)other).line == line &&
-          ((LineNumber)other).location == location;
-    }
-
-    public int compareTo(LineNumber other) {
-      int v = Integer.valueOf(line).compareTo(Integer.valueOf(other.line));
-      if (v != 0) {
-        return v;
-      } else {
-        return Long.valueOf(location).compareTo(Long.valueOf(other.location));
-      }
-    }
-  }
-
-  public static native void setBreakpoint(Executable m, long loc);
-  public static void setBreakpoint(Executable m, LineNumber l) {
-    setBreakpoint(m, l.location);
-  }
-
-  public static native void clearBreakpoint(Executable m, long loc);
-  public static void clearBreakpoint(Executable m, LineNumber l) {
-    clearBreakpoint(m, l.location);
-  }
-
-  private static native Object[] getLineNumberTableNative(Executable m);
-  public static LineNumber[] getLineNumberTable(Executable m) {
-    Object[] nativeTable = getLineNumberTableNative(m);
-    long[] location = (long[])(nativeTable[0]);
-    int[] lines = (int[])(nativeTable[1]);
-    if (lines.length != location.length) {
-      throw new Error("Lines and locations have different lengths!");
-    }
-    LineNumber[] out = new LineNumber[lines.length];
-    for (int i = 0; i < lines.length; i++) {
-      out[i] = new LineNumber(location[i], lines[i]);
-    }
-    return out;
-  }
-
-  public static native long getStartLocation(Executable m);
-
-  public static int locationToLine(Executable m, long location) {
-    try {
-      Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
-      int best = -1;
-      for (Breakpoint.LineNumber l : lines) {
-        if (l.location > location) {
-          break;
-        } else {
-          best = l.line;
-        }
-      }
-      return best;
-    } catch (Exception e) {
-      return -1;
-    }
-  }
-
-  public static long lineToLocation(Executable m, int line) throws Exception {
-    try {
-      Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
-      for (Breakpoint.LineNumber l : lines) {
-        if (l.line == line) {
-          return l.location;
-        }
-      }
-      throw new Exception("Unable to find line " + line + " in " + m);
-    } catch (Exception e) {
-      throw new Exception("Unable to get line number info for " + m, e);
-    }
-  }
-}
-
diff --git a/test/1924-frame-pop-toggle/src/art/Breakpoint.java b/test/1924-frame-pop-toggle/src/art/Breakpoint.java
new file mode 120000
index 0000000..3673916
--- /dev/null
+++ b/test/1924-frame-pop-toggle/src/art/Breakpoint.java
@@ -0,0 +1 @@
+../../../jvmti-common/Breakpoint.java
\ No newline at end of file
diff --git a/test/1924-frame-pop-toggle/src/art/FramePop.java b/test/1924-frame-pop-toggle/src/art/FramePop.java
deleted file mode 100644
index 86bf226..0000000
--- a/test/1924-frame-pop-toggle/src/art/FramePop.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Method;
-
-public class FramePop {
-  public static native void enableFramePopEvent(Class klass, Method method, Thread thr)
-      throws Exception;
-  public static native void notifyFramePop(Thread target, int depth) throws Exception;
-}
diff --git a/test/1924-frame-pop-toggle/src/art/FramePop.java b/test/1924-frame-pop-toggle/src/art/FramePop.java
new file mode 120000
index 0000000..3e573af
--- /dev/null
+++ b/test/1924-frame-pop-toggle/src/art/FramePop.java
@@ -0,0 +1 @@
+../../../jvmti-common/FramePop.java
\ No newline at end of file
diff --git a/test/1924-frame-pop-toggle/src/art/Locals.java b/test/1924-frame-pop-toggle/src/art/Locals.java
deleted file mode 100644
index 22e21be..0000000
--- a/test/1924-frame-pop-toggle/src/art/Locals.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Executable;
-import java.util.Objects;
-
-public class Locals {
-  public static native void EnableLocalVariableAccess();
-
-  public static class VariableDescription {
-    public final long start_location;
-    public final int length;
-    public final String name;
-    public final String signature;
-    public final String generic_signature;
-    public final int slot;
-
-    public VariableDescription(
-        long start, int length, String name, String sig, String gen_sig, int slot) {
-      this.start_location = start;
-      this.length = length;
-      this.name = name;
-      this.signature = sig;
-      this.generic_signature = gen_sig;
-      this.slot = slot;
-    }
-
-    @Override
-    public String toString() {
-      return String.format(
-          "VariableDescription { " +
-            "Sig: '%s', Name: '%s', Gen_sig: '%s', slot: %d, start: %d, len: %d" +
-          "}",
-          this.signature,
-          this.name,
-          this.generic_signature,
-          this.slot,
-          this.start_location,
-          this.length);
-    }
-    public boolean equals(Object other) {
-      if (!(other instanceof VariableDescription)) {
-        return false;
-      } else {
-        VariableDescription v = (VariableDescription)other;
-        return Objects.equals(v.signature, signature) &&
-            Objects.equals(v.name, name) &&
-            Objects.equals(v.generic_signature, generic_signature) &&
-            v.slot == slot &&
-            v.start_location == start_location &&
-            v.length == length;
-      }
-    }
-    public int hashCode() {
-      return Objects.hash(this.signature, this.name, this.generic_signature, this.slot,
-          this.start_location, this.length);
-    }
-  }
-
-  public static native VariableDescription[] GetLocalVariableTable(Executable e);
-
-  public static VariableDescription GetVariableAtLine(
-      Executable e, String name, String sig, int line) throws Exception {
-    return GetVariableAtLocation(e, name, sig, Breakpoint.lineToLocation(e, line));
-  }
-
-  public static VariableDescription GetVariableAtLocation(
-      Executable e, String name, String sig, long loc) {
-    VariableDescription[] vars = GetLocalVariableTable(e);
-    for (VariableDescription var : vars) {
-      if (var.start_location <= loc &&
-          var.length + var.start_location > loc &&
-          var.name.equals(name) &&
-          var.signature.equals(sig)) {
-        return var;
-      }
-    }
-    throw new Error(
-        "Unable to find variable " + name + " (sig: " + sig + ") in " + e + " at loc " + loc);
-  }
-
-  public static native int GetLocalVariableInt(Thread thr, int depth, int slot);
-  public static native long GetLocalVariableLong(Thread thr, int depth, int slot);
-  public static native float GetLocalVariableFloat(Thread thr, int depth, int slot);
-  public static native double GetLocalVariableDouble(Thread thr, int depth, int slot);
-  public static native Object GetLocalVariableObject(Thread thr, int depth, int slot);
-  public static native Object GetLocalInstance(Thread thr, int depth);
-
-  public static void SetLocalVariableInt(Thread thr, int depth, int slot, Object val) {
-    SetLocalVariableInt(thr, depth, slot, ((Number)val).intValue());
-  }
-  public static void SetLocalVariableLong(Thread thr, int depth, int slot, Object val) {
-    SetLocalVariableLong(thr, depth, slot, ((Number)val).longValue());
-  }
-  public static void SetLocalVariableFloat(Thread thr, int depth, int slot, Object val) {
-    SetLocalVariableFloat(thr, depth, slot, ((Number)val).floatValue());
-  }
-  public static void SetLocalVariableDouble(Thread thr, int depth, int slot, Object val) {
-    SetLocalVariableDouble(thr, depth, slot, ((Number)val).doubleValue());
-  }
-  public static native void SetLocalVariableInt(Thread thr, int depth, int slot, int val);
-  public static native void SetLocalVariableLong(Thread thr, int depth, int slot, long val);
-  public static native void SetLocalVariableFloat(Thread thr, int depth, int slot, float val);
-  public static native void SetLocalVariableDouble(Thread thr, int depth, int slot, double val);
-  public static native void SetLocalVariableObject(Thread thr, int depth, int slot, Object val);
-}
diff --git a/test/1924-frame-pop-toggle/src/art/Locals.java b/test/1924-frame-pop-toggle/src/art/Locals.java
new file mode 120000
index 0000000..2998386
--- /dev/null
+++ b/test/1924-frame-pop-toggle/src/art/Locals.java
@@ -0,0 +1 @@
+../../../jvmti-common/Locals.java
\ No newline at end of file
diff --git a/test/1924-frame-pop-toggle/src/art/StackTrace.java b/test/1924-frame-pop-toggle/src/art/StackTrace.java
deleted file mode 100644
index 2ea2f20..0000000
--- a/test/1924-frame-pop-toggle/src/art/StackTrace.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Executable;
-
-public class StackTrace {
-  public static class StackFrameData {
-    public final Thread thr;
-    public final Executable method;
-    public final long current_location;
-    public final int depth;
-
-    public StackFrameData(Thread thr, Executable e, long loc, int depth) {
-      this.thr = thr;
-      this.method = e;
-      this.current_location = loc;
-      this.depth = depth;
-    }
-    @Override
-    public String toString() {
-      return String.format(
-          "StackFrameData { thr: '%s', method: '%s', loc: %d, depth: %d }",
-          this.thr,
-          this.method,
-          this.current_location,
-          this.depth);
-    }
-  }
-
-  public static native int GetStackDepth(Thread thr);
-
-  private static native StackFrameData[] nativeGetStackTrace(Thread thr);
-
-  public static StackFrameData[] GetStackTrace(Thread thr) {
-    // The RI seems to give inconsistent (and sometimes nonsensical) results if the thread is not
-    // suspended. The spec says that not being suspended is fine but since we want this to be
-    // consistent we will suspend for the RI.
-    boolean suspend_thread =
-        !System.getProperty("java.vm.name").equals("Dalvik") &&
-        !thr.equals(Thread.currentThread()) &&
-        !Suspension.isSuspended(thr);
-    if (suspend_thread) {
-      Suspension.suspend(thr);
-    }
-    StackFrameData[] out = nativeGetStackTrace(thr);
-    if (suspend_thread) {
-      Suspension.resume(thr);
-    }
-    return out;
-  }
-}
-
diff --git a/test/1924-frame-pop-toggle/src/art/StackTrace.java b/test/1924-frame-pop-toggle/src/art/StackTrace.java
new file mode 120000
index 0000000..e1a08aa
--- /dev/null
+++ b/test/1924-frame-pop-toggle/src/art/StackTrace.java
@@ -0,0 +1 @@
+../../../jvmti-common/StackTrace.java
\ No newline at end of file
diff --git a/test/1924-frame-pop-toggle/src/art/Suspension.java b/test/1924-frame-pop-toggle/src/art/Suspension.java
deleted file mode 100644
index 16e62cc..0000000
--- a/test/1924-frame-pop-toggle/src/art/Suspension.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-public class Suspension {
-  // Suspends a thread using jvmti.
-  public native static void suspend(Thread thr);
-
-  // Resumes a thread using jvmti.
-  public native static void resume(Thread thr);
-
-  public native static boolean isSuspended(Thread thr);
-
-  public native static int[] suspendList(Thread... threads);
-  public native static int[] resumeList(Thread... threads);
-}
diff --git a/test/1924-frame-pop-toggle/src/art/Suspension.java b/test/1924-frame-pop-toggle/src/art/Suspension.java
new file mode 120000
index 0000000..bcef96f
--- /dev/null
+++ b/test/1924-frame-pop-toggle/src/art/Suspension.java
@@ -0,0 +1 @@
+../../../jvmti-common/Suspension.java
\ No newline at end of file
diff --git a/test/1924-frame-pop-toggle/src/art/Trace.java b/test/1924-frame-pop-toggle/src/art/Trace.java
deleted file mode 100644
index 8999bb1..0000000
--- a/test/1924-frame-pop-toggle/src/art/Trace.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-
-public class Trace {
-  public static native void enableTracing(Class<?> methodClass,
-                                          Method entryMethod,
-                                          Method exitMethod,
-                                          Method fieldAccess,
-                                          Method fieldModify,
-                                          Method singleStep,
-                                          Thread thr);
-  public static native void disableTracing(Thread thr);
-
-  public static void enableFieldTracing(Class<?> methodClass,
-                                        Method fieldAccess,
-                                        Method fieldModify,
-                                        Thread thr) {
-    enableTracing(methodClass, null, null, fieldAccess, fieldModify, null, thr);
-  }
-
-  public static void enableMethodTracing(Class<?> methodClass,
-                                         Method entryMethod,
-                                         Method exitMethod,
-                                         Thread thr) {
-    enableTracing(methodClass, entryMethod, exitMethod, null, null, null, thr);
-  }
-
-  public static void enableSingleStepTracing(Class<?> methodClass,
-                                             Method singleStep,
-                                             Thread thr) {
-    enableTracing(methodClass, null, null, null, null, singleStep, thr);
-  }
-
-  public static native void watchFieldAccess(Field f);
-  public static native void watchFieldModification(Field f);
-  public static native void watchAllFieldAccesses();
-  public static native void watchAllFieldModifications();
-
-  // the names, arguments, and even line numbers of these functions are embedded in the tests so we
-  // need to add to the bottom and not modify old ones to maintain compat.
-  public static native void enableTracing2(Class<?> methodClass,
-                                           Method entryMethod,
-                                           Method exitMethod,
-                                           Method fieldAccess,
-                                           Method fieldModify,
-                                           Method singleStep,
-                                           Method ThreadStart,
-                                           Method ThreadEnd,
-                                           Thread thr);
-}
diff --git a/test/1924-frame-pop-toggle/src/art/Trace.java b/test/1924-frame-pop-toggle/src/art/Trace.java
new file mode 120000
index 0000000..5d9b44b
--- /dev/null
+++ b/test/1924-frame-pop-toggle/src/art/Trace.java
@@ -0,0 +1 @@
+../../../jvmti-common/Trace.java
\ No newline at end of file
diff --git a/test/1925-self-frame-pop/src/art/Breakpoint.java b/test/1925-self-frame-pop/src/art/Breakpoint.java
deleted file mode 100644
index bbb89f7..0000000
--- a/test/1925-self-frame-pop/src/art/Breakpoint.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Executable;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.Objects;
-
-public class Breakpoint {
-  public static class Manager {
-    public static class BP {
-      public final Executable method;
-      public final long location;
-
-      public BP(Executable method) {
-        this(method, getStartLocation(method));
-      }
-
-      public BP(Executable method, long location) {
-        this.method = method;
-        this.location = location;
-      }
-
-      @Override
-      public boolean equals(Object other) {
-        return (other instanceof BP) &&
-            method.equals(((BP)other).method) &&
-            location == ((BP)other).location;
-      }
-
-      @Override
-      public String toString() {
-        return method.toString() + " @ " + getLine();
-      }
-
-      @Override
-      public int hashCode() {
-        return Objects.hash(method, location);
-      }
-
-      public int getLine() {
-        try {
-          LineNumber[] lines = getLineNumberTable(method);
-          int best = -1;
-          for (LineNumber l : lines) {
-            if (l.location > location) {
-              break;
-            } else {
-              best = l.line;
-            }
-          }
-          return best;
-        } catch (Exception e) {
-          return -1;
-        }
-      }
-    }
-
-    private Set<BP> breaks = new HashSet<>();
-
-    public void setBreakpoints(BP... bs) {
-      for (BP b : bs) {
-        if (breaks.add(b)) {
-          Breakpoint.setBreakpoint(b.method, b.location);
-        }
-      }
-    }
-    public void setBreakpoint(Executable method, long location) {
-      setBreakpoints(new BP(method, location));
-    }
-
-    public void clearBreakpoints(BP... bs) {
-      for (BP b : bs) {
-        if (breaks.remove(b)) {
-          Breakpoint.clearBreakpoint(b.method, b.location);
-        }
-      }
-    }
-    public void clearBreakpoint(Executable method, long location) {
-      clearBreakpoints(new BP(method, location));
-    }
-
-    public void clearAllBreakpoints() {
-      clearBreakpoints(breaks.toArray(new BP[0]));
-    }
-  }
-
-  public static void startBreakpointWatch(Class<?> methodClass,
-                                          Executable breakpointReached,
-                                          Thread thr) {
-    startBreakpointWatch(methodClass, breakpointReached, false, thr);
-  }
-
-  /**
-   * Enables the trapping of breakpoint events.
-   *
-   * If allowRecursive == true then breakpoints will be sent even if one is currently being handled.
-   */
-  public static native void startBreakpointWatch(Class<?> methodClass,
-                                                 Executable breakpointReached,
-                                                 boolean allowRecursive,
-                                                 Thread thr);
-  public static native void stopBreakpointWatch(Thread thr);
-
-  public static final class LineNumber implements Comparable<LineNumber> {
-    public final long location;
-    public final int line;
-
-    private LineNumber(long loc, int line) {
-      this.location = loc;
-      this.line = line;
-    }
-
-    public boolean equals(Object other) {
-      return other instanceof LineNumber && ((LineNumber)other).line == line &&
-          ((LineNumber)other).location == location;
-    }
-
-    public int compareTo(LineNumber other) {
-      int v = Integer.valueOf(line).compareTo(Integer.valueOf(other.line));
-      if (v != 0) {
-        return v;
-      } else {
-        return Long.valueOf(location).compareTo(Long.valueOf(other.location));
-      }
-    }
-  }
-
-  public static native void setBreakpoint(Executable m, long loc);
-  public static void setBreakpoint(Executable m, LineNumber l) {
-    setBreakpoint(m, l.location);
-  }
-
-  public static native void clearBreakpoint(Executable m, long loc);
-  public static void clearBreakpoint(Executable m, LineNumber l) {
-    clearBreakpoint(m, l.location);
-  }
-
-  private static native Object[] getLineNumberTableNative(Executable m);
-  public static LineNumber[] getLineNumberTable(Executable m) {
-    Object[] nativeTable = getLineNumberTableNative(m);
-    long[] location = (long[])(nativeTable[0]);
-    int[] lines = (int[])(nativeTable[1]);
-    if (lines.length != location.length) {
-      throw new Error("Lines and locations have different lengths!");
-    }
-    LineNumber[] out = new LineNumber[lines.length];
-    for (int i = 0; i < lines.length; i++) {
-      out[i] = new LineNumber(location[i], lines[i]);
-    }
-    return out;
-  }
-
-  public static native long getStartLocation(Executable m);
-
-  public static int locationToLine(Executable m, long location) {
-    try {
-      Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
-      int best = -1;
-      for (Breakpoint.LineNumber l : lines) {
-        if (l.location > location) {
-          break;
-        } else {
-          best = l.line;
-        }
-      }
-      return best;
-    } catch (Exception e) {
-      return -1;
-    }
-  }
-
-  public static long lineToLocation(Executable m, int line) throws Exception {
-    try {
-      Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
-      for (Breakpoint.LineNumber l : lines) {
-        if (l.line == line) {
-          return l.location;
-        }
-      }
-      throw new Exception("Unable to find line " + line + " in " + m);
-    } catch (Exception e) {
-      throw new Exception("Unable to get line number info for " + m, e);
-    }
-  }
-}
-
diff --git a/test/1925-self-frame-pop/src/art/Breakpoint.java b/test/1925-self-frame-pop/src/art/Breakpoint.java
new file mode 120000
index 0000000..3673916
--- /dev/null
+++ b/test/1925-self-frame-pop/src/art/Breakpoint.java
@@ -0,0 +1 @@
+../../../jvmti-common/Breakpoint.java
\ No newline at end of file
diff --git a/test/1925-self-frame-pop/src/art/FramePop.java b/test/1925-self-frame-pop/src/art/FramePop.java
deleted file mode 100644
index 86bf226..0000000
--- a/test/1925-self-frame-pop/src/art/FramePop.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Method;
-
-public class FramePop {
-  public static native void enableFramePopEvent(Class klass, Method method, Thread thr)
-      throws Exception;
-  public static native void notifyFramePop(Thread target, int depth) throws Exception;
-}
diff --git a/test/1925-self-frame-pop/src/art/FramePop.java b/test/1925-self-frame-pop/src/art/FramePop.java
new file mode 120000
index 0000000..3e573af
--- /dev/null
+++ b/test/1925-self-frame-pop/src/art/FramePop.java
@@ -0,0 +1 @@
+../../../jvmti-common/FramePop.java
\ No newline at end of file
diff --git a/test/1925-self-frame-pop/src/art/Locals.java b/test/1925-self-frame-pop/src/art/Locals.java
deleted file mode 100644
index 22e21be..0000000
--- a/test/1925-self-frame-pop/src/art/Locals.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Executable;
-import java.util.Objects;
-
-public class Locals {
-  public static native void EnableLocalVariableAccess();
-
-  public static class VariableDescription {
-    public final long start_location;
-    public final int length;
-    public final String name;
-    public final String signature;
-    public final String generic_signature;
-    public final int slot;
-
-    public VariableDescription(
-        long start, int length, String name, String sig, String gen_sig, int slot) {
-      this.start_location = start;
-      this.length = length;
-      this.name = name;
-      this.signature = sig;
-      this.generic_signature = gen_sig;
-      this.slot = slot;
-    }
-
-    @Override
-    public String toString() {
-      return String.format(
-          "VariableDescription { " +
-            "Sig: '%s', Name: '%s', Gen_sig: '%s', slot: %d, start: %d, len: %d" +
-          "}",
-          this.signature,
-          this.name,
-          this.generic_signature,
-          this.slot,
-          this.start_location,
-          this.length);
-    }
-    public boolean equals(Object other) {
-      if (!(other instanceof VariableDescription)) {
-        return false;
-      } else {
-        VariableDescription v = (VariableDescription)other;
-        return Objects.equals(v.signature, signature) &&
-            Objects.equals(v.name, name) &&
-            Objects.equals(v.generic_signature, generic_signature) &&
-            v.slot == slot &&
-            v.start_location == start_location &&
-            v.length == length;
-      }
-    }
-    public int hashCode() {
-      return Objects.hash(this.signature, this.name, this.generic_signature, this.slot,
-          this.start_location, this.length);
-    }
-  }
-
-  public static native VariableDescription[] GetLocalVariableTable(Executable e);
-
-  public static VariableDescription GetVariableAtLine(
-      Executable e, String name, String sig, int line) throws Exception {
-    return GetVariableAtLocation(e, name, sig, Breakpoint.lineToLocation(e, line));
-  }
-
-  public static VariableDescription GetVariableAtLocation(
-      Executable e, String name, String sig, long loc) {
-    VariableDescription[] vars = GetLocalVariableTable(e);
-    for (VariableDescription var : vars) {
-      if (var.start_location <= loc &&
-          var.length + var.start_location > loc &&
-          var.name.equals(name) &&
-          var.signature.equals(sig)) {
-        return var;
-      }
-    }
-    throw new Error(
-        "Unable to find variable " + name + " (sig: " + sig + ") in " + e + " at loc " + loc);
-  }
-
-  public static native int GetLocalVariableInt(Thread thr, int depth, int slot);
-  public static native long GetLocalVariableLong(Thread thr, int depth, int slot);
-  public static native float GetLocalVariableFloat(Thread thr, int depth, int slot);
-  public static native double GetLocalVariableDouble(Thread thr, int depth, int slot);
-  public static native Object GetLocalVariableObject(Thread thr, int depth, int slot);
-  public static native Object GetLocalInstance(Thread thr, int depth);
-
-  public static void SetLocalVariableInt(Thread thr, int depth, int slot, Object val) {
-    SetLocalVariableInt(thr, depth, slot, ((Number)val).intValue());
-  }
-  public static void SetLocalVariableLong(Thread thr, int depth, int slot, Object val) {
-    SetLocalVariableLong(thr, depth, slot, ((Number)val).longValue());
-  }
-  public static void SetLocalVariableFloat(Thread thr, int depth, int slot, Object val) {
-    SetLocalVariableFloat(thr, depth, slot, ((Number)val).floatValue());
-  }
-  public static void SetLocalVariableDouble(Thread thr, int depth, int slot, Object val) {
-    SetLocalVariableDouble(thr, depth, slot, ((Number)val).doubleValue());
-  }
-  public static native void SetLocalVariableInt(Thread thr, int depth, int slot, int val);
-  public static native void SetLocalVariableLong(Thread thr, int depth, int slot, long val);
-  public static native void SetLocalVariableFloat(Thread thr, int depth, int slot, float val);
-  public static native void SetLocalVariableDouble(Thread thr, int depth, int slot, double val);
-  public static native void SetLocalVariableObject(Thread thr, int depth, int slot, Object val);
-}
diff --git a/test/1925-self-frame-pop/src/art/Locals.java b/test/1925-self-frame-pop/src/art/Locals.java
new file mode 120000
index 0000000..2998386
--- /dev/null
+++ b/test/1925-self-frame-pop/src/art/Locals.java
@@ -0,0 +1 @@
+../../../jvmti-common/Locals.java
\ No newline at end of file
diff --git a/test/1925-self-frame-pop/src/art/StackTrace.java b/test/1925-self-frame-pop/src/art/StackTrace.java
deleted file mode 100644
index 2ea2f20..0000000
--- a/test/1925-self-frame-pop/src/art/StackTrace.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Executable;
-
-public class StackTrace {
-  public static class StackFrameData {
-    public final Thread thr;
-    public final Executable method;
-    public final long current_location;
-    public final int depth;
-
-    public StackFrameData(Thread thr, Executable e, long loc, int depth) {
-      this.thr = thr;
-      this.method = e;
-      this.current_location = loc;
-      this.depth = depth;
-    }
-    @Override
-    public String toString() {
-      return String.format(
-          "StackFrameData { thr: '%s', method: '%s', loc: %d, depth: %d }",
-          this.thr,
-          this.method,
-          this.current_location,
-          this.depth);
-    }
-  }
-
-  public static native int GetStackDepth(Thread thr);
-
-  private static native StackFrameData[] nativeGetStackTrace(Thread thr);
-
-  public static StackFrameData[] GetStackTrace(Thread thr) {
-    // The RI seems to give inconsistent (and sometimes nonsensical) results if the thread is not
-    // suspended. The spec says that not being suspended is fine but since we want this to be
-    // consistent we will suspend for the RI.
-    boolean suspend_thread =
-        !System.getProperty("java.vm.name").equals("Dalvik") &&
-        !thr.equals(Thread.currentThread()) &&
-        !Suspension.isSuspended(thr);
-    if (suspend_thread) {
-      Suspension.suspend(thr);
-    }
-    StackFrameData[] out = nativeGetStackTrace(thr);
-    if (suspend_thread) {
-      Suspension.resume(thr);
-    }
-    return out;
-  }
-}
-
diff --git a/test/1925-self-frame-pop/src/art/StackTrace.java b/test/1925-self-frame-pop/src/art/StackTrace.java
new file mode 120000
index 0000000..e1a08aa
--- /dev/null
+++ b/test/1925-self-frame-pop/src/art/StackTrace.java
@@ -0,0 +1 @@
+../../../jvmti-common/StackTrace.java
\ No newline at end of file
diff --git a/test/1925-self-frame-pop/src/art/Suspension.java b/test/1925-self-frame-pop/src/art/Suspension.java
deleted file mode 100644
index 16e62cc..0000000
--- a/test/1925-self-frame-pop/src/art/Suspension.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-public class Suspension {
-  // Suspends a thread using jvmti.
-  public native static void suspend(Thread thr);
-
-  // Resumes a thread using jvmti.
-  public native static void resume(Thread thr);
-
-  public native static boolean isSuspended(Thread thr);
-
-  public native static int[] suspendList(Thread... threads);
-  public native static int[] resumeList(Thread... threads);
-}
diff --git a/test/1925-self-frame-pop/src/art/Suspension.java b/test/1925-self-frame-pop/src/art/Suspension.java
new file mode 120000
index 0000000..bcef96f
--- /dev/null
+++ b/test/1925-self-frame-pop/src/art/Suspension.java
@@ -0,0 +1 @@
+../../../jvmti-common/Suspension.java
\ No newline at end of file
diff --git a/test/1925-self-frame-pop/src/art/Trace.java b/test/1925-self-frame-pop/src/art/Trace.java
deleted file mode 100644
index 8999bb1..0000000
--- a/test/1925-self-frame-pop/src/art/Trace.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-
-public class Trace {
-  public static native void enableTracing(Class<?> methodClass,
-                                          Method entryMethod,
-                                          Method exitMethod,
-                                          Method fieldAccess,
-                                          Method fieldModify,
-                                          Method singleStep,
-                                          Thread thr);
-  public static native void disableTracing(Thread thr);
-
-  public static void enableFieldTracing(Class<?> methodClass,
-                                        Method fieldAccess,
-                                        Method fieldModify,
-                                        Thread thr) {
-    enableTracing(methodClass, null, null, fieldAccess, fieldModify, null, thr);
-  }
-
-  public static void enableMethodTracing(Class<?> methodClass,
-                                         Method entryMethod,
-                                         Method exitMethod,
-                                         Thread thr) {
-    enableTracing(methodClass, entryMethod, exitMethod, null, null, null, thr);
-  }
-
-  public static void enableSingleStepTracing(Class<?> methodClass,
-                                             Method singleStep,
-                                             Thread thr) {
-    enableTracing(methodClass, null, null, null, null, singleStep, thr);
-  }
-
-  public static native void watchFieldAccess(Field f);
-  public static native void watchFieldModification(Field f);
-  public static native void watchAllFieldAccesses();
-  public static native void watchAllFieldModifications();
-
-  // the names, arguments, and even line numbers of these functions are embedded in the tests so we
-  // need to add to the bottom and not modify old ones to maintain compat.
-  public static native void enableTracing2(Class<?> methodClass,
-                                           Method entryMethod,
-                                           Method exitMethod,
-                                           Method fieldAccess,
-                                           Method fieldModify,
-                                           Method singleStep,
-                                           Method ThreadStart,
-                                           Method ThreadEnd,
-                                           Thread thr);
-}
diff --git a/test/1925-self-frame-pop/src/art/Trace.java b/test/1925-self-frame-pop/src/art/Trace.java
new file mode 120000
index 0000000..5d9b44b
--- /dev/null
+++ b/test/1925-self-frame-pop/src/art/Trace.java
@@ -0,0 +1 @@
+../../../jvmti-common/Trace.java
\ No newline at end of file
diff --git a/test/1926-missed-frame-pop/src/art/Breakpoint.java b/test/1926-missed-frame-pop/src/art/Breakpoint.java
deleted file mode 100644
index bbb89f7..0000000
--- a/test/1926-missed-frame-pop/src/art/Breakpoint.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Executable;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.Objects;
-
-public class Breakpoint {
-  public static class Manager {
-    public static class BP {
-      public final Executable method;
-      public final long location;
-
-      public BP(Executable method) {
-        this(method, getStartLocation(method));
-      }
-
-      public BP(Executable method, long location) {
-        this.method = method;
-        this.location = location;
-      }
-
-      @Override
-      public boolean equals(Object other) {
-        return (other instanceof BP) &&
-            method.equals(((BP)other).method) &&
-            location == ((BP)other).location;
-      }
-
-      @Override
-      public String toString() {
-        return method.toString() + " @ " + getLine();
-      }
-
-      @Override
-      public int hashCode() {
-        return Objects.hash(method, location);
-      }
-
-      public int getLine() {
-        try {
-          LineNumber[] lines = getLineNumberTable(method);
-          int best = -1;
-          for (LineNumber l : lines) {
-            if (l.location > location) {
-              break;
-            } else {
-              best = l.line;
-            }
-          }
-          return best;
-        } catch (Exception e) {
-          return -1;
-        }
-      }
-    }
-
-    private Set<BP> breaks = new HashSet<>();
-
-    public void setBreakpoints(BP... bs) {
-      for (BP b : bs) {
-        if (breaks.add(b)) {
-          Breakpoint.setBreakpoint(b.method, b.location);
-        }
-      }
-    }
-    public void setBreakpoint(Executable method, long location) {
-      setBreakpoints(new BP(method, location));
-    }
-
-    public void clearBreakpoints(BP... bs) {
-      for (BP b : bs) {
-        if (breaks.remove(b)) {
-          Breakpoint.clearBreakpoint(b.method, b.location);
-        }
-      }
-    }
-    public void clearBreakpoint(Executable method, long location) {
-      clearBreakpoints(new BP(method, location));
-    }
-
-    public void clearAllBreakpoints() {
-      clearBreakpoints(breaks.toArray(new BP[0]));
-    }
-  }
-
-  public static void startBreakpointWatch(Class<?> methodClass,
-                                          Executable breakpointReached,
-                                          Thread thr) {
-    startBreakpointWatch(methodClass, breakpointReached, false, thr);
-  }
-
-  /**
-   * Enables the trapping of breakpoint events.
-   *
-   * If allowRecursive == true then breakpoints will be sent even if one is currently being handled.
-   */
-  public static native void startBreakpointWatch(Class<?> methodClass,
-                                                 Executable breakpointReached,
-                                                 boolean allowRecursive,
-                                                 Thread thr);
-  public static native void stopBreakpointWatch(Thread thr);
-
-  public static final class LineNumber implements Comparable<LineNumber> {
-    public final long location;
-    public final int line;
-
-    private LineNumber(long loc, int line) {
-      this.location = loc;
-      this.line = line;
-    }
-
-    public boolean equals(Object other) {
-      return other instanceof LineNumber && ((LineNumber)other).line == line &&
-          ((LineNumber)other).location == location;
-    }
-
-    public int compareTo(LineNumber other) {
-      int v = Integer.valueOf(line).compareTo(Integer.valueOf(other.line));
-      if (v != 0) {
-        return v;
-      } else {
-        return Long.valueOf(location).compareTo(Long.valueOf(other.location));
-      }
-    }
-  }
-
-  public static native void setBreakpoint(Executable m, long loc);
-  public static void setBreakpoint(Executable m, LineNumber l) {
-    setBreakpoint(m, l.location);
-  }
-
-  public static native void clearBreakpoint(Executable m, long loc);
-  public static void clearBreakpoint(Executable m, LineNumber l) {
-    clearBreakpoint(m, l.location);
-  }
-
-  private static native Object[] getLineNumberTableNative(Executable m);
-  public static LineNumber[] getLineNumberTable(Executable m) {
-    Object[] nativeTable = getLineNumberTableNative(m);
-    long[] location = (long[])(nativeTable[0]);
-    int[] lines = (int[])(nativeTable[1]);
-    if (lines.length != location.length) {
-      throw new Error("Lines and locations have different lengths!");
-    }
-    LineNumber[] out = new LineNumber[lines.length];
-    for (int i = 0; i < lines.length; i++) {
-      out[i] = new LineNumber(location[i], lines[i]);
-    }
-    return out;
-  }
-
-  public static native long getStartLocation(Executable m);
-
-  public static int locationToLine(Executable m, long location) {
-    try {
-      Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
-      int best = -1;
-      for (Breakpoint.LineNumber l : lines) {
-        if (l.location > location) {
-          break;
-        } else {
-          best = l.line;
-        }
-      }
-      return best;
-    } catch (Exception e) {
-      return -1;
-    }
-  }
-
-  public static long lineToLocation(Executable m, int line) throws Exception {
-    try {
-      Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
-      for (Breakpoint.LineNumber l : lines) {
-        if (l.line == line) {
-          return l.location;
-        }
-      }
-      throw new Exception("Unable to find line " + line + " in " + m);
-    } catch (Exception e) {
-      throw new Exception("Unable to get line number info for " + m, e);
-    }
-  }
-}
-
diff --git a/test/1926-missed-frame-pop/src/art/Breakpoint.java b/test/1926-missed-frame-pop/src/art/Breakpoint.java
new file mode 120000
index 0000000..3673916
--- /dev/null
+++ b/test/1926-missed-frame-pop/src/art/Breakpoint.java
@@ -0,0 +1 @@
+../../../jvmti-common/Breakpoint.java
\ No newline at end of file
diff --git a/test/1926-missed-frame-pop/src/art/FramePop.java b/test/1926-missed-frame-pop/src/art/FramePop.java
deleted file mode 100644
index 86bf226..0000000
--- a/test/1926-missed-frame-pop/src/art/FramePop.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Method;
-
-public class FramePop {
-  public static native void enableFramePopEvent(Class klass, Method method, Thread thr)
-      throws Exception;
-  public static native void notifyFramePop(Thread target, int depth) throws Exception;
-}
diff --git a/test/1926-missed-frame-pop/src/art/FramePop.java b/test/1926-missed-frame-pop/src/art/FramePop.java
new file mode 120000
index 0000000..3e573af
--- /dev/null
+++ b/test/1926-missed-frame-pop/src/art/FramePop.java
@@ -0,0 +1 @@
+../../../jvmti-common/FramePop.java
\ No newline at end of file
diff --git a/test/1926-missed-frame-pop/src/art/Locals.java b/test/1926-missed-frame-pop/src/art/Locals.java
deleted file mode 100644
index 22e21be..0000000
--- a/test/1926-missed-frame-pop/src/art/Locals.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Executable;
-import java.util.Objects;
-
-public class Locals {
-  public static native void EnableLocalVariableAccess();
-
-  public static class VariableDescription {
-    public final long start_location;
-    public final int length;
-    public final String name;
-    public final String signature;
-    public final String generic_signature;
-    public final int slot;
-
-    public VariableDescription(
-        long start, int length, String name, String sig, String gen_sig, int slot) {
-      this.start_location = start;
-      this.length = length;
-      this.name = name;
-      this.signature = sig;
-      this.generic_signature = gen_sig;
-      this.slot = slot;
-    }
-
-    @Override
-    public String toString() {
-      return String.format(
-          "VariableDescription { " +
-            "Sig: '%s', Name: '%s', Gen_sig: '%s', slot: %d, start: %d, len: %d" +
-          "}",
-          this.signature,
-          this.name,
-          this.generic_signature,
-          this.slot,
-          this.start_location,
-          this.length);
-    }
-    public boolean equals(Object other) {
-      if (!(other instanceof VariableDescription)) {
-        return false;
-      } else {
-        VariableDescription v = (VariableDescription)other;
-        return Objects.equals(v.signature, signature) &&
-            Objects.equals(v.name, name) &&
-            Objects.equals(v.generic_signature, generic_signature) &&
-            v.slot == slot &&
-            v.start_location == start_location &&
-            v.length == length;
-      }
-    }
-    public int hashCode() {
-      return Objects.hash(this.signature, this.name, this.generic_signature, this.slot,
-          this.start_location, this.length);
-    }
-  }
-
-  public static native VariableDescription[] GetLocalVariableTable(Executable e);
-
-  public static VariableDescription GetVariableAtLine(
-      Executable e, String name, String sig, int line) throws Exception {
-    return GetVariableAtLocation(e, name, sig, Breakpoint.lineToLocation(e, line));
-  }
-
-  public static VariableDescription GetVariableAtLocation(
-      Executable e, String name, String sig, long loc) {
-    VariableDescription[] vars = GetLocalVariableTable(e);
-    for (VariableDescription var : vars) {
-      if (var.start_location <= loc &&
-          var.length + var.start_location > loc &&
-          var.name.equals(name) &&
-          var.signature.equals(sig)) {
-        return var;
-      }
-    }
-    throw new Error(
-        "Unable to find variable " + name + " (sig: " + sig + ") in " + e + " at loc " + loc);
-  }
-
-  public static native int GetLocalVariableInt(Thread thr, int depth, int slot);
-  public static native long GetLocalVariableLong(Thread thr, int depth, int slot);
-  public static native float GetLocalVariableFloat(Thread thr, int depth, int slot);
-  public static native double GetLocalVariableDouble(Thread thr, int depth, int slot);
-  public static native Object GetLocalVariableObject(Thread thr, int depth, int slot);
-  public static native Object GetLocalInstance(Thread thr, int depth);
-
-  public static void SetLocalVariableInt(Thread thr, int depth, int slot, Object val) {
-    SetLocalVariableInt(thr, depth, slot, ((Number)val).intValue());
-  }
-  public static void SetLocalVariableLong(Thread thr, int depth, int slot, Object val) {
-    SetLocalVariableLong(thr, depth, slot, ((Number)val).longValue());
-  }
-  public static void SetLocalVariableFloat(Thread thr, int depth, int slot, Object val) {
-    SetLocalVariableFloat(thr, depth, slot, ((Number)val).floatValue());
-  }
-  public static void SetLocalVariableDouble(Thread thr, int depth, int slot, Object val) {
-    SetLocalVariableDouble(thr, depth, slot, ((Number)val).doubleValue());
-  }
-  public static native void SetLocalVariableInt(Thread thr, int depth, int slot, int val);
-  public static native void SetLocalVariableLong(Thread thr, int depth, int slot, long val);
-  public static native void SetLocalVariableFloat(Thread thr, int depth, int slot, float val);
-  public static native void SetLocalVariableDouble(Thread thr, int depth, int slot, double val);
-  public static native void SetLocalVariableObject(Thread thr, int depth, int slot, Object val);
-}
diff --git a/test/1926-missed-frame-pop/src/art/Locals.java b/test/1926-missed-frame-pop/src/art/Locals.java
new file mode 120000
index 0000000..2998386
--- /dev/null
+++ b/test/1926-missed-frame-pop/src/art/Locals.java
@@ -0,0 +1 @@
+../../../jvmti-common/Locals.java
\ No newline at end of file
diff --git a/test/1926-missed-frame-pop/src/art/StackTrace.java b/test/1926-missed-frame-pop/src/art/StackTrace.java
deleted file mode 100644
index 2ea2f20..0000000
--- a/test/1926-missed-frame-pop/src/art/StackTrace.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Executable;
-
-public class StackTrace {
-  public static class StackFrameData {
-    public final Thread thr;
-    public final Executable method;
-    public final long current_location;
-    public final int depth;
-
-    public StackFrameData(Thread thr, Executable e, long loc, int depth) {
-      this.thr = thr;
-      this.method = e;
-      this.current_location = loc;
-      this.depth = depth;
-    }
-    @Override
-    public String toString() {
-      return String.format(
-          "StackFrameData { thr: '%s', method: '%s', loc: %d, depth: %d }",
-          this.thr,
-          this.method,
-          this.current_location,
-          this.depth);
-    }
-  }
-
-  public static native int GetStackDepth(Thread thr);
-
-  private static native StackFrameData[] nativeGetStackTrace(Thread thr);
-
-  public static StackFrameData[] GetStackTrace(Thread thr) {
-    // The RI seems to give inconsistent (and sometimes nonsensical) results if the thread is not
-    // suspended. The spec says that not being suspended is fine but since we want this to be
-    // consistent we will suspend for the RI.
-    boolean suspend_thread =
-        !System.getProperty("java.vm.name").equals("Dalvik") &&
-        !thr.equals(Thread.currentThread()) &&
-        !Suspension.isSuspended(thr);
-    if (suspend_thread) {
-      Suspension.suspend(thr);
-    }
-    StackFrameData[] out = nativeGetStackTrace(thr);
-    if (suspend_thread) {
-      Suspension.resume(thr);
-    }
-    return out;
-  }
-}
-
diff --git a/test/1926-missed-frame-pop/src/art/StackTrace.java b/test/1926-missed-frame-pop/src/art/StackTrace.java
new file mode 120000
index 0000000..e1a08aa
--- /dev/null
+++ b/test/1926-missed-frame-pop/src/art/StackTrace.java
@@ -0,0 +1 @@
+../../../jvmti-common/StackTrace.java
\ No newline at end of file
diff --git a/test/1926-missed-frame-pop/src/art/Suspension.java b/test/1926-missed-frame-pop/src/art/Suspension.java
deleted file mode 100644
index 16e62cc..0000000
--- a/test/1926-missed-frame-pop/src/art/Suspension.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-public class Suspension {
-  // Suspends a thread using jvmti.
-  public native static void suspend(Thread thr);
-
-  // Resumes a thread using jvmti.
-  public native static void resume(Thread thr);
-
-  public native static boolean isSuspended(Thread thr);
-
-  public native static int[] suspendList(Thread... threads);
-  public native static int[] resumeList(Thread... threads);
-}
diff --git a/test/1926-missed-frame-pop/src/art/Suspension.java b/test/1926-missed-frame-pop/src/art/Suspension.java
new file mode 120000
index 0000000..bcef96f
--- /dev/null
+++ b/test/1926-missed-frame-pop/src/art/Suspension.java
@@ -0,0 +1 @@
+../../../jvmti-common/Suspension.java
\ No newline at end of file
diff --git a/test/1926-missed-frame-pop/src/art/Trace.java b/test/1926-missed-frame-pop/src/art/Trace.java
deleted file mode 100644
index 8999bb1..0000000
--- a/test/1926-missed-frame-pop/src/art/Trace.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-
-public class Trace {
-  public static native void enableTracing(Class<?> methodClass,
-                                          Method entryMethod,
-                                          Method exitMethod,
-                                          Method fieldAccess,
-                                          Method fieldModify,
-                                          Method singleStep,
-                                          Thread thr);
-  public static native void disableTracing(Thread thr);
-
-  public static void enableFieldTracing(Class<?> methodClass,
-                                        Method fieldAccess,
-                                        Method fieldModify,
-                                        Thread thr) {
-    enableTracing(methodClass, null, null, fieldAccess, fieldModify, null, thr);
-  }
-
-  public static void enableMethodTracing(Class<?> methodClass,
-                                         Method entryMethod,
-                                         Method exitMethod,
-                                         Thread thr) {
-    enableTracing(methodClass, entryMethod, exitMethod, null, null, null, thr);
-  }
-
-  public static void enableSingleStepTracing(Class<?> methodClass,
-                                             Method singleStep,
-                                             Thread thr) {
-    enableTracing(methodClass, null, null, null, null, singleStep, thr);
-  }
-
-  public static native void watchFieldAccess(Field f);
-  public static native void watchFieldModification(Field f);
-  public static native void watchAllFieldAccesses();
-  public static native void watchAllFieldModifications();
-
-  // the names, arguments, and even line numbers of these functions are embedded in the tests so we
-  // need to add to the bottom and not modify old ones to maintain compat.
-  public static native void enableTracing2(Class<?> methodClass,
-                                           Method entryMethod,
-                                           Method exitMethod,
-                                           Method fieldAccess,
-                                           Method fieldModify,
-                                           Method singleStep,
-                                           Method ThreadStart,
-                                           Method ThreadEnd,
-                                           Thread thr);
-}
diff --git a/test/1926-missed-frame-pop/src/art/Trace.java b/test/1926-missed-frame-pop/src/art/Trace.java
new file mode 120000
index 0000000..5d9b44b
--- /dev/null
+++ b/test/1926-missed-frame-pop/src/art/Trace.java
@@ -0,0 +1 @@
+../../../jvmti-common/Trace.java
\ No newline at end of file
diff --git a/test/1927-exception-event/src/art/Breakpoint.java b/test/1927-exception-event/src/art/Breakpoint.java
deleted file mode 100644
index bbb89f7..0000000
--- a/test/1927-exception-event/src/art/Breakpoint.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Executable;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.Objects;
-
-public class Breakpoint {
-  public static class Manager {
-    public static class BP {
-      public final Executable method;
-      public final long location;
-
-      public BP(Executable method) {
-        this(method, getStartLocation(method));
-      }
-
-      public BP(Executable method, long location) {
-        this.method = method;
-        this.location = location;
-      }
-
-      @Override
-      public boolean equals(Object other) {
-        return (other instanceof BP) &&
-            method.equals(((BP)other).method) &&
-            location == ((BP)other).location;
-      }
-
-      @Override
-      public String toString() {
-        return method.toString() + " @ " + getLine();
-      }
-
-      @Override
-      public int hashCode() {
-        return Objects.hash(method, location);
-      }
-
-      public int getLine() {
-        try {
-          LineNumber[] lines = getLineNumberTable(method);
-          int best = -1;
-          for (LineNumber l : lines) {
-            if (l.location > location) {
-              break;
-            } else {
-              best = l.line;
-            }
-          }
-          return best;
-        } catch (Exception e) {
-          return -1;
-        }
-      }
-    }
-
-    private Set<BP> breaks = new HashSet<>();
-
-    public void setBreakpoints(BP... bs) {
-      for (BP b : bs) {
-        if (breaks.add(b)) {
-          Breakpoint.setBreakpoint(b.method, b.location);
-        }
-      }
-    }
-    public void setBreakpoint(Executable method, long location) {
-      setBreakpoints(new BP(method, location));
-    }
-
-    public void clearBreakpoints(BP... bs) {
-      for (BP b : bs) {
-        if (breaks.remove(b)) {
-          Breakpoint.clearBreakpoint(b.method, b.location);
-        }
-      }
-    }
-    public void clearBreakpoint(Executable method, long location) {
-      clearBreakpoints(new BP(method, location));
-    }
-
-    public void clearAllBreakpoints() {
-      clearBreakpoints(breaks.toArray(new BP[0]));
-    }
-  }
-
-  public static void startBreakpointWatch(Class<?> methodClass,
-                                          Executable breakpointReached,
-                                          Thread thr) {
-    startBreakpointWatch(methodClass, breakpointReached, false, thr);
-  }
-
-  /**
-   * Enables the trapping of breakpoint events.
-   *
-   * If allowRecursive == true then breakpoints will be sent even if one is currently being handled.
-   */
-  public static native void startBreakpointWatch(Class<?> methodClass,
-                                                 Executable breakpointReached,
-                                                 boolean allowRecursive,
-                                                 Thread thr);
-  public static native void stopBreakpointWatch(Thread thr);
-
-  public static final class LineNumber implements Comparable<LineNumber> {
-    public final long location;
-    public final int line;
-
-    private LineNumber(long loc, int line) {
-      this.location = loc;
-      this.line = line;
-    }
-
-    public boolean equals(Object other) {
-      return other instanceof LineNumber && ((LineNumber)other).line == line &&
-          ((LineNumber)other).location == location;
-    }
-
-    public int compareTo(LineNumber other) {
-      int v = Integer.valueOf(line).compareTo(Integer.valueOf(other.line));
-      if (v != 0) {
-        return v;
-      } else {
-        return Long.valueOf(location).compareTo(Long.valueOf(other.location));
-      }
-    }
-  }
-
-  public static native void setBreakpoint(Executable m, long loc);
-  public static void setBreakpoint(Executable m, LineNumber l) {
-    setBreakpoint(m, l.location);
-  }
-
-  public static native void clearBreakpoint(Executable m, long loc);
-  public static void clearBreakpoint(Executable m, LineNumber l) {
-    clearBreakpoint(m, l.location);
-  }
-
-  private static native Object[] getLineNumberTableNative(Executable m);
-  public static LineNumber[] getLineNumberTable(Executable m) {
-    Object[] nativeTable = getLineNumberTableNative(m);
-    long[] location = (long[])(nativeTable[0]);
-    int[] lines = (int[])(nativeTable[1]);
-    if (lines.length != location.length) {
-      throw new Error("Lines and locations have different lengths!");
-    }
-    LineNumber[] out = new LineNumber[lines.length];
-    for (int i = 0; i < lines.length; i++) {
-      out[i] = new LineNumber(location[i], lines[i]);
-    }
-    return out;
-  }
-
-  public static native long getStartLocation(Executable m);
-
-  public static int locationToLine(Executable m, long location) {
-    try {
-      Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
-      int best = -1;
-      for (Breakpoint.LineNumber l : lines) {
-        if (l.location > location) {
-          break;
-        } else {
-          best = l.line;
-        }
-      }
-      return best;
-    } catch (Exception e) {
-      return -1;
-    }
-  }
-
-  public static long lineToLocation(Executable m, int line) throws Exception {
-    try {
-      Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
-      for (Breakpoint.LineNumber l : lines) {
-        if (l.line == line) {
-          return l.location;
-        }
-      }
-      throw new Exception("Unable to find line " + line + " in " + m);
-    } catch (Exception e) {
-      throw new Exception("Unable to get line number info for " + m, e);
-    }
-  }
-}
-
diff --git a/test/1927-exception-event/src/art/Breakpoint.java b/test/1927-exception-event/src/art/Breakpoint.java
new file mode 120000
index 0000000..3673916
--- /dev/null
+++ b/test/1927-exception-event/src/art/Breakpoint.java
@@ -0,0 +1 @@
+../../../jvmti-common/Breakpoint.java
\ No newline at end of file
diff --git a/test/1927-exception-event/src/art/Exceptions.java b/test/1927-exception-event/src/art/Exceptions.java
new file mode 120000
index 0000000..b8450fe
--- /dev/null
+++ b/test/1927-exception-event/src/art/Exceptions.java
@@ -0,0 +1 @@
+../../../jvmti-common/Exceptions.java
\ No newline at end of file
diff --git a/test/1927-exception-event/src/art/StackTrace.java b/test/1927-exception-event/src/art/StackTrace.java
deleted file mode 100644
index 2ea2f20..0000000
--- a/test/1927-exception-event/src/art/StackTrace.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Executable;
-
-public class StackTrace {
-  public static class StackFrameData {
-    public final Thread thr;
-    public final Executable method;
-    public final long current_location;
-    public final int depth;
-
-    public StackFrameData(Thread thr, Executable e, long loc, int depth) {
-      this.thr = thr;
-      this.method = e;
-      this.current_location = loc;
-      this.depth = depth;
-    }
-    @Override
-    public String toString() {
-      return String.format(
-          "StackFrameData { thr: '%s', method: '%s', loc: %d, depth: %d }",
-          this.thr,
-          this.method,
-          this.current_location,
-          this.depth);
-    }
-  }
-
-  public static native int GetStackDepth(Thread thr);
-
-  private static native StackFrameData[] nativeGetStackTrace(Thread thr);
-
-  public static StackFrameData[] GetStackTrace(Thread thr) {
-    // The RI seems to give inconsistent (and sometimes nonsensical) results if the thread is not
-    // suspended. The spec says that not being suspended is fine but since we want this to be
-    // consistent we will suspend for the RI.
-    boolean suspend_thread =
-        !System.getProperty("java.vm.name").equals("Dalvik") &&
-        !thr.equals(Thread.currentThread()) &&
-        !Suspension.isSuspended(thr);
-    if (suspend_thread) {
-      Suspension.suspend(thr);
-    }
-    StackFrameData[] out = nativeGetStackTrace(thr);
-    if (suspend_thread) {
-      Suspension.resume(thr);
-    }
-    return out;
-  }
-}
-
diff --git a/test/1927-exception-event/src/art/StackTrace.java b/test/1927-exception-event/src/art/StackTrace.java
new file mode 120000
index 0000000..e1a08aa
--- /dev/null
+++ b/test/1927-exception-event/src/art/StackTrace.java
@@ -0,0 +1 @@
+../../../jvmti-common/StackTrace.java
\ No newline at end of file
diff --git a/test/1927-exception-event/src/art/Suspension.java b/test/1927-exception-event/src/art/Suspension.java
deleted file mode 100644
index 16e62cc..0000000
--- a/test/1927-exception-event/src/art/Suspension.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-public class Suspension {
-  // Suspends a thread using jvmti.
-  public native static void suspend(Thread thr);
-
-  // Resumes a thread using jvmti.
-  public native static void resume(Thread thr);
-
-  public native static boolean isSuspended(Thread thr);
-
-  public native static int[] suspendList(Thread... threads);
-  public native static int[] resumeList(Thread... threads);
-}
diff --git a/test/1927-exception-event/src/art/Suspension.java b/test/1927-exception-event/src/art/Suspension.java
new file mode 120000
index 0000000..bcef96f
--- /dev/null
+++ b/test/1927-exception-event/src/art/Suspension.java
@@ -0,0 +1 @@
+../../../jvmti-common/Suspension.java
\ No newline at end of file
diff --git a/test/1928-exception-event-exception/src/art/Breakpoint.java b/test/1928-exception-event-exception/src/art/Breakpoint.java
deleted file mode 100644
index bbb89f7..0000000
--- a/test/1928-exception-event-exception/src/art/Breakpoint.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Executable;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.Objects;
-
-public class Breakpoint {
-  public static class Manager {
-    public static class BP {
-      public final Executable method;
-      public final long location;
-
-      public BP(Executable method) {
-        this(method, getStartLocation(method));
-      }
-
-      public BP(Executable method, long location) {
-        this.method = method;
-        this.location = location;
-      }
-
-      @Override
-      public boolean equals(Object other) {
-        return (other instanceof BP) &&
-            method.equals(((BP)other).method) &&
-            location == ((BP)other).location;
-      }
-
-      @Override
-      public String toString() {
-        return method.toString() + " @ " + getLine();
-      }
-
-      @Override
-      public int hashCode() {
-        return Objects.hash(method, location);
-      }
-
-      public int getLine() {
-        try {
-          LineNumber[] lines = getLineNumberTable(method);
-          int best = -1;
-          for (LineNumber l : lines) {
-            if (l.location > location) {
-              break;
-            } else {
-              best = l.line;
-            }
-          }
-          return best;
-        } catch (Exception e) {
-          return -1;
-        }
-      }
-    }
-
-    private Set<BP> breaks = new HashSet<>();
-
-    public void setBreakpoints(BP... bs) {
-      for (BP b : bs) {
-        if (breaks.add(b)) {
-          Breakpoint.setBreakpoint(b.method, b.location);
-        }
-      }
-    }
-    public void setBreakpoint(Executable method, long location) {
-      setBreakpoints(new BP(method, location));
-    }
-
-    public void clearBreakpoints(BP... bs) {
-      for (BP b : bs) {
-        if (breaks.remove(b)) {
-          Breakpoint.clearBreakpoint(b.method, b.location);
-        }
-      }
-    }
-    public void clearBreakpoint(Executable method, long location) {
-      clearBreakpoints(new BP(method, location));
-    }
-
-    public void clearAllBreakpoints() {
-      clearBreakpoints(breaks.toArray(new BP[0]));
-    }
-  }
-
-  public static void startBreakpointWatch(Class<?> methodClass,
-                                          Executable breakpointReached,
-                                          Thread thr) {
-    startBreakpointWatch(methodClass, breakpointReached, false, thr);
-  }
-
-  /**
-   * Enables the trapping of breakpoint events.
-   *
-   * If allowRecursive == true then breakpoints will be sent even if one is currently being handled.
-   */
-  public static native void startBreakpointWatch(Class<?> methodClass,
-                                                 Executable breakpointReached,
-                                                 boolean allowRecursive,
-                                                 Thread thr);
-  public static native void stopBreakpointWatch(Thread thr);
-
-  public static final class LineNumber implements Comparable<LineNumber> {
-    public final long location;
-    public final int line;
-
-    private LineNumber(long loc, int line) {
-      this.location = loc;
-      this.line = line;
-    }
-
-    public boolean equals(Object other) {
-      return other instanceof LineNumber && ((LineNumber)other).line == line &&
-          ((LineNumber)other).location == location;
-    }
-
-    public int compareTo(LineNumber other) {
-      int v = Integer.valueOf(line).compareTo(Integer.valueOf(other.line));
-      if (v != 0) {
-        return v;
-      } else {
-        return Long.valueOf(location).compareTo(Long.valueOf(other.location));
-      }
-    }
-  }
-
-  public static native void setBreakpoint(Executable m, long loc);
-  public static void setBreakpoint(Executable m, LineNumber l) {
-    setBreakpoint(m, l.location);
-  }
-
-  public static native void clearBreakpoint(Executable m, long loc);
-  public static void clearBreakpoint(Executable m, LineNumber l) {
-    clearBreakpoint(m, l.location);
-  }
-
-  private static native Object[] getLineNumberTableNative(Executable m);
-  public static LineNumber[] getLineNumberTable(Executable m) {
-    Object[] nativeTable = getLineNumberTableNative(m);
-    long[] location = (long[])(nativeTable[0]);
-    int[] lines = (int[])(nativeTable[1]);
-    if (lines.length != location.length) {
-      throw new Error("Lines and locations have different lengths!");
-    }
-    LineNumber[] out = new LineNumber[lines.length];
-    for (int i = 0; i < lines.length; i++) {
-      out[i] = new LineNumber(location[i], lines[i]);
-    }
-    return out;
-  }
-
-  public static native long getStartLocation(Executable m);
-
-  public static int locationToLine(Executable m, long location) {
-    try {
-      Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
-      int best = -1;
-      for (Breakpoint.LineNumber l : lines) {
-        if (l.location > location) {
-          break;
-        } else {
-          best = l.line;
-        }
-      }
-      return best;
-    } catch (Exception e) {
-      return -1;
-    }
-  }
-
-  public static long lineToLocation(Executable m, int line) throws Exception {
-    try {
-      Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
-      for (Breakpoint.LineNumber l : lines) {
-        if (l.line == line) {
-          return l.location;
-        }
-      }
-      throw new Exception("Unable to find line " + line + " in " + m);
-    } catch (Exception e) {
-      throw new Exception("Unable to get line number info for " + m, e);
-    }
-  }
-}
-
diff --git a/test/1928-exception-event-exception/src/art/Breakpoint.java b/test/1928-exception-event-exception/src/art/Breakpoint.java
new file mode 120000
index 0000000..3673916
--- /dev/null
+++ b/test/1928-exception-event-exception/src/art/Breakpoint.java
@@ -0,0 +1 @@
+../../../jvmti-common/Breakpoint.java
\ No newline at end of file
diff --git a/test/1928-exception-event-exception/src/art/Exceptions.java b/test/1928-exception-event-exception/src/art/Exceptions.java
deleted file mode 100644
index 2c959ec..0000000
--- a/test/1928-exception-event-exception/src/art/Exceptions.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-
-public class Exceptions {
-  public static native void setupExceptionTracing(
-      Class<?> methodClass,
-      Class<?> exceptionClass,
-      Method exceptionEventMethod,
-      Method exceptionCaughtEventMethod);
-
-  public static native void enableExceptionCatchEvent(Thread thr);
-  public static native void enableExceptionEvent(Thread thr);
-  public static native void disableExceptionCatchEvent(Thread thr);
-  public static native void disableExceptionEvent(Thread thr);
-}
diff --git a/test/1928-exception-event-exception/src/art/Exceptions.java b/test/1928-exception-event-exception/src/art/Exceptions.java
new file mode 120000
index 0000000..b8450fe
--- /dev/null
+++ b/test/1928-exception-event-exception/src/art/Exceptions.java
@@ -0,0 +1 @@
+../../../jvmti-common/Exceptions.java
\ No newline at end of file
diff --git a/test/1928-exception-event-exception/src/art/StackTrace.java b/test/1928-exception-event-exception/src/art/StackTrace.java
deleted file mode 100644
index 2ea2f20..0000000
--- a/test/1928-exception-event-exception/src/art/StackTrace.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Executable;
-
-public class StackTrace {
-  public static class StackFrameData {
-    public final Thread thr;
-    public final Executable method;
-    public final long current_location;
-    public final int depth;
-
-    public StackFrameData(Thread thr, Executable e, long loc, int depth) {
-      this.thr = thr;
-      this.method = e;
-      this.current_location = loc;
-      this.depth = depth;
-    }
-    @Override
-    public String toString() {
-      return String.format(
-          "StackFrameData { thr: '%s', method: '%s', loc: %d, depth: %d }",
-          this.thr,
-          this.method,
-          this.current_location,
-          this.depth);
-    }
-  }
-
-  public static native int GetStackDepth(Thread thr);
-
-  private static native StackFrameData[] nativeGetStackTrace(Thread thr);
-
-  public static StackFrameData[] GetStackTrace(Thread thr) {
-    // The RI seems to give inconsistent (and sometimes nonsensical) results if the thread is not
-    // suspended. The spec says that not being suspended is fine but since we want this to be
-    // consistent we will suspend for the RI.
-    boolean suspend_thread =
-        !System.getProperty("java.vm.name").equals("Dalvik") &&
-        !thr.equals(Thread.currentThread()) &&
-        !Suspension.isSuspended(thr);
-    if (suspend_thread) {
-      Suspension.suspend(thr);
-    }
-    StackFrameData[] out = nativeGetStackTrace(thr);
-    if (suspend_thread) {
-      Suspension.resume(thr);
-    }
-    return out;
-  }
-}
-
diff --git a/test/1928-exception-event-exception/src/art/StackTrace.java b/test/1928-exception-event-exception/src/art/StackTrace.java
new file mode 120000
index 0000000..e1a08aa
--- /dev/null
+++ b/test/1928-exception-event-exception/src/art/StackTrace.java
@@ -0,0 +1 @@
+../../../jvmti-common/StackTrace.java
\ No newline at end of file
diff --git a/test/1928-exception-event-exception/src/art/Suspension.java b/test/1928-exception-event-exception/src/art/Suspension.java
deleted file mode 100644
index 16e62cc..0000000
--- a/test/1928-exception-event-exception/src/art/Suspension.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-public class Suspension {
-  // Suspends a thread using jvmti.
-  public native static void suspend(Thread thr);
-
-  // Resumes a thread using jvmti.
-  public native static void resume(Thread thr);
-
-  public native static boolean isSuspended(Thread thr);
-
-  public native static int[] suspendList(Thread... threads);
-  public native static int[] resumeList(Thread... threads);
-}
diff --git a/test/1928-exception-event-exception/src/art/Suspension.java b/test/1928-exception-event-exception/src/art/Suspension.java
new file mode 120000
index 0000000..bcef96f
--- /dev/null
+++ b/test/1928-exception-event-exception/src/art/Suspension.java
@@ -0,0 +1 @@
+../../../jvmti-common/Suspension.java
\ No newline at end of file
diff --git a/test/1929-exception-catch-exception/src/art/Breakpoint.java b/test/1929-exception-catch-exception/src/art/Breakpoint.java
deleted file mode 100644
index bbb89f7..0000000
--- a/test/1929-exception-catch-exception/src/art/Breakpoint.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Executable;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.Objects;
-
-public class Breakpoint {
-  public static class Manager {
-    public static class BP {
-      public final Executable method;
-      public final long location;
-
-      public BP(Executable method) {
-        this(method, getStartLocation(method));
-      }
-
-      public BP(Executable method, long location) {
-        this.method = method;
-        this.location = location;
-      }
-
-      @Override
-      public boolean equals(Object other) {
-        return (other instanceof BP) &&
-            method.equals(((BP)other).method) &&
-            location == ((BP)other).location;
-      }
-
-      @Override
-      public String toString() {
-        return method.toString() + " @ " + getLine();
-      }
-
-      @Override
-      public int hashCode() {
-        return Objects.hash(method, location);
-      }
-
-      public int getLine() {
-        try {
-          LineNumber[] lines = getLineNumberTable(method);
-          int best = -1;
-          for (LineNumber l : lines) {
-            if (l.location > location) {
-              break;
-            } else {
-              best = l.line;
-            }
-          }
-          return best;
-        } catch (Exception e) {
-          return -1;
-        }
-      }
-    }
-
-    private Set<BP> breaks = new HashSet<>();
-
-    public void setBreakpoints(BP... bs) {
-      for (BP b : bs) {
-        if (breaks.add(b)) {
-          Breakpoint.setBreakpoint(b.method, b.location);
-        }
-      }
-    }
-    public void setBreakpoint(Executable method, long location) {
-      setBreakpoints(new BP(method, location));
-    }
-
-    public void clearBreakpoints(BP... bs) {
-      for (BP b : bs) {
-        if (breaks.remove(b)) {
-          Breakpoint.clearBreakpoint(b.method, b.location);
-        }
-      }
-    }
-    public void clearBreakpoint(Executable method, long location) {
-      clearBreakpoints(new BP(method, location));
-    }
-
-    public void clearAllBreakpoints() {
-      clearBreakpoints(breaks.toArray(new BP[0]));
-    }
-  }
-
-  public static void startBreakpointWatch(Class<?> methodClass,
-                                          Executable breakpointReached,
-                                          Thread thr) {
-    startBreakpointWatch(methodClass, breakpointReached, false, thr);
-  }
-
-  /**
-   * Enables the trapping of breakpoint events.
-   *
-   * If allowRecursive == true then breakpoints will be sent even if one is currently being handled.
-   */
-  public static native void startBreakpointWatch(Class<?> methodClass,
-                                                 Executable breakpointReached,
-                                                 boolean allowRecursive,
-                                                 Thread thr);
-  public static native void stopBreakpointWatch(Thread thr);
-
-  public static final class LineNumber implements Comparable<LineNumber> {
-    public final long location;
-    public final int line;
-
-    private LineNumber(long loc, int line) {
-      this.location = loc;
-      this.line = line;
-    }
-
-    public boolean equals(Object other) {
-      return other instanceof LineNumber && ((LineNumber)other).line == line &&
-          ((LineNumber)other).location == location;
-    }
-
-    public int compareTo(LineNumber other) {
-      int v = Integer.valueOf(line).compareTo(Integer.valueOf(other.line));
-      if (v != 0) {
-        return v;
-      } else {
-        return Long.valueOf(location).compareTo(Long.valueOf(other.location));
-      }
-    }
-  }
-
-  public static native void setBreakpoint(Executable m, long loc);
-  public static void setBreakpoint(Executable m, LineNumber l) {
-    setBreakpoint(m, l.location);
-  }
-
-  public static native void clearBreakpoint(Executable m, long loc);
-  public static void clearBreakpoint(Executable m, LineNumber l) {
-    clearBreakpoint(m, l.location);
-  }
-
-  private static native Object[] getLineNumberTableNative(Executable m);
-  public static LineNumber[] getLineNumberTable(Executable m) {
-    Object[] nativeTable = getLineNumberTableNative(m);
-    long[] location = (long[])(nativeTable[0]);
-    int[] lines = (int[])(nativeTable[1]);
-    if (lines.length != location.length) {
-      throw new Error("Lines and locations have different lengths!");
-    }
-    LineNumber[] out = new LineNumber[lines.length];
-    for (int i = 0; i < lines.length; i++) {
-      out[i] = new LineNumber(location[i], lines[i]);
-    }
-    return out;
-  }
-
-  public static native long getStartLocation(Executable m);
-
-  public static int locationToLine(Executable m, long location) {
-    try {
-      Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
-      int best = -1;
-      for (Breakpoint.LineNumber l : lines) {
-        if (l.location > location) {
-          break;
-        } else {
-          best = l.line;
-        }
-      }
-      return best;
-    } catch (Exception e) {
-      return -1;
-    }
-  }
-
-  public static long lineToLocation(Executable m, int line) throws Exception {
-    try {
-      Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
-      for (Breakpoint.LineNumber l : lines) {
-        if (l.line == line) {
-          return l.location;
-        }
-      }
-      throw new Exception("Unable to find line " + line + " in " + m);
-    } catch (Exception e) {
-      throw new Exception("Unable to get line number info for " + m, e);
-    }
-  }
-}
-
diff --git a/test/1929-exception-catch-exception/src/art/Breakpoint.java b/test/1929-exception-catch-exception/src/art/Breakpoint.java
new file mode 120000
index 0000000..3673916
--- /dev/null
+++ b/test/1929-exception-catch-exception/src/art/Breakpoint.java
@@ -0,0 +1 @@
+../../../jvmti-common/Breakpoint.java
\ No newline at end of file
diff --git a/test/1929-exception-catch-exception/src/art/Exceptions.java b/test/1929-exception-catch-exception/src/art/Exceptions.java
deleted file mode 100644
index 2c959ec..0000000
--- a/test/1929-exception-catch-exception/src/art/Exceptions.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-
-public class Exceptions {
-  public static native void setupExceptionTracing(
-      Class<?> methodClass,
-      Class<?> exceptionClass,
-      Method exceptionEventMethod,
-      Method exceptionCaughtEventMethod);
-
-  public static native void enableExceptionCatchEvent(Thread thr);
-  public static native void enableExceptionEvent(Thread thr);
-  public static native void disableExceptionCatchEvent(Thread thr);
-  public static native void disableExceptionEvent(Thread thr);
-}
diff --git a/test/1929-exception-catch-exception/src/art/Exceptions.java b/test/1929-exception-catch-exception/src/art/Exceptions.java
new file mode 120000
index 0000000..b8450fe
--- /dev/null
+++ b/test/1929-exception-catch-exception/src/art/Exceptions.java
@@ -0,0 +1 @@
+../../../jvmti-common/Exceptions.java
\ No newline at end of file
diff --git a/test/1929-exception-catch-exception/src/art/StackTrace.java b/test/1929-exception-catch-exception/src/art/StackTrace.java
deleted file mode 100644
index 2ea2f20..0000000
--- a/test/1929-exception-catch-exception/src/art/StackTrace.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Executable;
-
-public class StackTrace {
-  public static class StackFrameData {
-    public final Thread thr;
-    public final Executable method;
-    public final long current_location;
-    public final int depth;
-
-    public StackFrameData(Thread thr, Executable e, long loc, int depth) {
-      this.thr = thr;
-      this.method = e;
-      this.current_location = loc;
-      this.depth = depth;
-    }
-    @Override
-    public String toString() {
-      return String.format(
-          "StackFrameData { thr: '%s', method: '%s', loc: %d, depth: %d }",
-          this.thr,
-          this.method,
-          this.current_location,
-          this.depth);
-    }
-  }
-
-  public static native int GetStackDepth(Thread thr);
-
-  private static native StackFrameData[] nativeGetStackTrace(Thread thr);
-
-  public static StackFrameData[] GetStackTrace(Thread thr) {
-    // The RI seems to give inconsistent (and sometimes nonsensical) results if the thread is not
-    // suspended. The spec says that not being suspended is fine but since we want this to be
-    // consistent we will suspend for the RI.
-    boolean suspend_thread =
-        !System.getProperty("java.vm.name").equals("Dalvik") &&
-        !thr.equals(Thread.currentThread()) &&
-        !Suspension.isSuspended(thr);
-    if (suspend_thread) {
-      Suspension.suspend(thr);
-    }
-    StackFrameData[] out = nativeGetStackTrace(thr);
-    if (suspend_thread) {
-      Suspension.resume(thr);
-    }
-    return out;
-  }
-}
-
diff --git a/test/1929-exception-catch-exception/src/art/StackTrace.java b/test/1929-exception-catch-exception/src/art/StackTrace.java
new file mode 120000
index 0000000..e1a08aa
--- /dev/null
+++ b/test/1929-exception-catch-exception/src/art/StackTrace.java
@@ -0,0 +1 @@
+../../../jvmti-common/StackTrace.java
\ No newline at end of file
diff --git a/test/1929-exception-catch-exception/src/art/Suspension.java b/test/1929-exception-catch-exception/src/art/Suspension.java
deleted file mode 100644
index 16e62cc..0000000
--- a/test/1929-exception-catch-exception/src/art/Suspension.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-public class Suspension {
-  // Suspends a thread using jvmti.
-  public native static void suspend(Thread thr);
-
-  // Resumes a thread using jvmti.
-  public native static void resume(Thread thr);
-
-  public native static boolean isSuspended(Thread thr);
-
-  public native static int[] suspendList(Thread... threads);
-  public native static int[] resumeList(Thread... threads);
-}
diff --git a/test/1929-exception-catch-exception/src/art/Suspension.java b/test/1929-exception-catch-exception/src/art/Suspension.java
new file mode 120000
index 0000000..bcef96f
--- /dev/null
+++ b/test/1929-exception-catch-exception/src/art/Suspension.java
@@ -0,0 +1 @@
+../../../jvmti-common/Suspension.java
\ No newline at end of file
diff --git a/test/1930-monitor-info/src/art/Monitors.java b/test/1930-monitor-info/src/art/Monitors.java
new file mode 120000
index 0000000..61e8367
--- /dev/null
+++ b/test/1930-monitor-info/src/art/Monitors.java
@@ -0,0 +1 @@
+../../../jvmti-common/Monitors.java
\ No newline at end of file
diff --git a/test/1930-monitor-info/src/art/Suspension.java b/test/1930-monitor-info/src/art/Suspension.java
deleted file mode 100644
index 16e62cc..0000000
--- a/test/1930-monitor-info/src/art/Suspension.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-public class Suspension {
-  // Suspends a thread using jvmti.
-  public native static void suspend(Thread thr);
-
-  // Resumes a thread using jvmti.
-  public native static void resume(Thread thr);
-
-  public native static boolean isSuspended(Thread thr);
-
-  public native static int[] suspendList(Thread... threads);
-  public native static int[] resumeList(Thread... threads);
-}
diff --git a/test/1930-monitor-info/src/art/Suspension.java b/test/1930-monitor-info/src/art/Suspension.java
new file mode 120000
index 0000000..bcef96f
--- /dev/null
+++ b/test/1930-monitor-info/src/art/Suspension.java
@@ -0,0 +1 @@
+../../../jvmti-common/Suspension.java
\ No newline at end of file
diff --git a/test/1931-monitor-events/src/art/Monitors.java b/test/1931-monitor-events/src/art/Monitors.java
deleted file mode 100644
index 7fe2b60..0000000
--- a/test/1931-monitor-events/src/art/Monitors.java
+++ /dev/null
@@ -1,344 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Method;
-import java.util.concurrent.atomic.*;
-import java.util.function.Function;
-import java.util.stream.Stream;
-import java.util.Arrays;
-import java.util.Objects;
-
-public class Monitors {
-  public native static void setupMonitorEvents(
-      Class<?> method_klass,
-      Method monitor_contended_enter_event,
-      Method monitor_contended_entered_event,
-      Method monitor_wait_event,
-      Method monitor_waited_event,
-      Class<?> lock_klass,
-      Thread thr);
-  public native static void stopMonitorEvents();
-
-  public static class NamedLock {
-    public final String name;
-    private volatile int calledNotify;
-    public NamedLock(String name) {
-      this.name = name;
-      calledNotify = 0;
-    }
-
-    public String toString() {
-      return String.format("NamedLock[%s]", name);
-    }
-
-    public final void DoWait() throws Exception {
-      final int v = calledNotify;
-      while (v == calledNotify) {
-        wait();
-      }
-    }
-
-    public final void DoWait(long t) throws Exception {
-      final int v = calledNotify;
-      final long target = System.currentTimeMillis() + (t / 2);
-      while (v == calledNotify && (t < 0 || System.currentTimeMillis() < target)) {
-        wait(t);
-      }
-    }
-
-    public final void DoNotifyAll() throws Exception {
-      calledNotify++;
-      notifyAll();
-    }
-
-    public final void DoNotify() throws Exception {
-      calledNotify++;
-      notify();
-    }
-  }
-
-  public static final class MonitorUsage {
-    public final Object monitor;
-    public final Thread owner;
-    public final int entryCount;
-    public final Thread[] waiters;
-    public final Thread[] notifyWaiters;
-
-    public MonitorUsage(
-        Object monitor,
-        Thread owner,
-        int entryCount,
-        Thread[] waiters,
-        Thread[] notifyWaiters) {
-      this.monitor = monitor;
-      this.entryCount = entryCount;
-      this.owner = owner;
-      this.waiters = waiters;
-      this.notifyWaiters = notifyWaiters;
-    }
-
-    private static String toNameList(Thread[] ts) {
-      return Arrays.toString(Arrays.stream(ts).map((Thread t) -> t.getName()).toArray());
-    }
-
-    public String toString() {
-      return String.format(
-          "MonitorUsage{ monitor: %s, owner: %s, entryCount: %d, waiters: %s, notify_waiters: %s }",
-          monitor,
-          (owner != null) ? owner.getName() : "<NULL>",
-          entryCount,
-          toNameList(waiters),
-          toNameList(notifyWaiters));
-    }
-  }
-
-  public static native MonitorUsage getObjectMonitorUsage(Object monitor);
-  public static native Object getCurrentContendedMonitor(Thread thr);
-
-  public static class TestException extends Error {
-    public TestException() { super(); }
-    public TestException(String s) { super(s); }
-    public TestException(String s, Throwable c) { super(s, c); }
-  }
-
-  public static class LockController {
-    private static enum Action { HOLD, RELEASE, NOTIFY, NOTIFY_ALL, WAIT, TIMED_WAIT }
-
-    public final NamedLock lock;
-    public final long timeout;
-    private final AtomicStampedReference<Action> action;
-    private volatile Thread runner = null;
-    private volatile boolean started = false;
-    private volatile boolean held = false;
-    private static final AtomicInteger cnt = new AtomicInteger(0);
-    private volatile Throwable exe;
-
-    public LockController(NamedLock lock) {
-      this(lock, 10 * 1000);
-    }
-    public LockController(NamedLock lock, long timeout) {
-      this.lock = lock;
-      this.timeout = timeout;
-      this.action = new AtomicStampedReference(Action.HOLD, 0);
-      this.exe = null;
-    }
-
-    public boolean IsWorkerThread(Thread thd) {
-      return Objects.equals(runner, thd);
-    }
-
-    public boolean IsLocked() {
-      checkException();
-      return held;
-    }
-
-    public void checkException() {
-      if (exe != null) {
-        throw new TestException("Exception thrown by other thread!", exe);
-      }
-    }
-
-    private void setAction(Action a) {
-      int stamp = action.getStamp();
-      // Wait for it to be HOLD before updating.
-      while (!action.compareAndSet(Action.HOLD, a, stamp, stamp + 1)) {
-        stamp = action.getStamp();
-      }
-    }
-
-    public synchronized void suspendWorker() throws Exception {
-      checkException();
-      if (runner == null) {
-        throw new TestException("We don't have any runner holding  " + lock);
-      }
-      Suspension.suspend(runner);
-    }
-
-    public Object getWorkerContendedMonitor() throws Exception {
-      checkException();
-      if (runner == null) {
-        return null;
-      }
-      return getCurrentContendedMonitor(runner);
-    }
-
-    public synchronized void DoLock() {
-      if (IsLocked()) {
-        throw new Error("lock is already acquired or being acquired.");
-      }
-      if (runner != null) {
-        throw new Error("Already have thread!");
-      }
-      runner = new Thread(() -> {
-        started = true;
-        try {
-          synchronized (lock) {
-            held = true;
-            int[] stamp_h = new int[] { -1 };
-            Action cur_action = Action.HOLD;
-            try {
-              while (true) {
-                cur_action = action.get(stamp_h);
-                int stamp = stamp_h[0];
-                if (cur_action == Action.RELEASE) {
-                  // The other thread will deal with reseting action.
-                  break;
-                }
-                try {
-                  switch (cur_action) {
-                    case HOLD:
-                      Thread.yield();
-                      break;
-                    case NOTIFY:
-                      lock.DoNotify();
-                      break;
-                    case NOTIFY_ALL:
-                      lock.DoNotifyAll();
-                      break;
-                    case TIMED_WAIT:
-                      lock.DoWait(timeout);
-                      break;
-                    case WAIT:
-                      lock.DoWait();
-                      break;
-                    default:
-                      throw new Error("Unknown action " + action);
-                  }
-                } finally {
-                  // reset action back to hold if it isn't something else.
-                  action.compareAndSet(cur_action, Action.HOLD, stamp, stamp+1);
-                }
-              }
-            } catch (Exception e) {
-              throw new TestException("Got an error while performing action " + cur_action, e);
-            }
-          }
-        } finally {
-          held = false;
-          started = false;
-        }
-      }, "Locker thread " + cnt.getAndIncrement() + " for " + lock);
-      // Make sure we can get any exceptions this throws.
-      runner.setUncaughtExceptionHandler((t, e) -> { exe = e; });
-      runner.start();
-    }
-
-    public void waitForLockToBeHeld() throws Exception {
-      while (true) {
-        if (IsLocked() && Objects.equals(runner, Monitors.getObjectMonitorUsage(lock).owner)) {
-          return;
-        }
-      }
-    }
-
-    public synchronized void waitForNotifySleep() throws Exception {
-      if (runner == null) {
-        throw new Error("No thread trying to lock!");
-      }
-      do {
-        checkException();
-      } while (!started ||
-          !Arrays.asList(Monitors.getObjectMonitorUsage(lock).notifyWaiters).contains(runner));
-    }
-
-    public synchronized void waitForContendedSleep() throws Exception {
-      if (runner == null) {
-        throw new Error("No thread trying to lock!");
-      }
-      do {
-        checkException();
-      } while (!started ||
-          runner.getState() != Thread.State.BLOCKED ||
-          !Arrays.asList(Monitors.getObjectMonitorUsage(lock).waiters).contains(runner));
-    }
-
-    public synchronized void DoNotify() {
-      if (!IsLocked()) {
-        throw new Error("Not locked");
-      }
-      setAction(Action.NOTIFY);
-    }
-
-    public synchronized void DoNotifyAll() {
-      if (!IsLocked()) {
-        throw new Error("Not locked");
-      }
-      setAction(Action.NOTIFY_ALL);
-    }
-
-    public synchronized void DoTimedWait() throws Exception {
-      if (!IsLocked()) {
-        throw new Error("Not locked");
-      }
-      setAction(Action.TIMED_WAIT);
-    }
-
-    public synchronized void DoWait() throws Exception {
-      if (!IsLocked()) {
-        throw new Error("Not locked");
-      }
-      setAction(Action.WAIT);
-    }
-
-    public synchronized void interruptWorker() throws Exception {
-      if (!IsLocked()) {
-        throw new Error("Not locked");
-      }
-      runner.interrupt();
-    }
-
-    public synchronized void waitForActionToFinish() throws Exception {
-      checkException();
-      while (action.getReference() != Action.HOLD) { checkException(); }
-    }
-
-    public synchronized void DoUnlock() throws Exception {
-      Error throwing = null;
-      if (!IsLocked()) {
-        // We might just be racing some exception that was thrown by the worker thread. Cache the
-        // exception, we will throw one from the worker before this one.
-        throwing = new Error("Not locked!");
-      }
-      setAction(Action.RELEASE);
-      Thread run = runner;
-      runner = null;
-      while (held) {}
-      run.join();
-      action.set(Action.HOLD, 0);
-      // Make sure to throw any exception that occurred since it might not have unlocked due to our
-      // request.
-      checkException();
-      DoCleanup();
-      if (throwing != null) {
-        throw throwing;
-      }
-    }
-
-    public synchronized void DoCleanup() throws Exception {
-      if (runner != null) {
-        Thread run = runner;
-        runner = null;
-        while (held) {}
-        run.join();
-      }
-      action.set(Action.HOLD, 0);
-      exe = null;
-    }
-  }
-}
-
diff --git a/test/1931-monitor-events/src/art/Monitors.java b/test/1931-monitor-events/src/art/Monitors.java
new file mode 120000
index 0000000..61e8367
--- /dev/null
+++ b/test/1931-monitor-events/src/art/Monitors.java
@@ -0,0 +1 @@
+../../../jvmti-common/Monitors.java
\ No newline at end of file
diff --git a/test/1931-monitor-events/src/art/Suspension.java b/test/1931-monitor-events/src/art/Suspension.java
deleted file mode 100644
index 16e62cc..0000000
--- a/test/1931-monitor-events/src/art/Suspension.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-public class Suspension {
-  // Suspends a thread using jvmti.
-  public native static void suspend(Thread thr);
-
-  // Resumes a thread using jvmti.
-  public native static void resume(Thread thr);
-
-  public native static boolean isSuspended(Thread thr);
-
-  public native static int[] suspendList(Thread... threads);
-  public native static int[] resumeList(Thread... threads);
-}
diff --git a/test/1931-monitor-events/src/art/Suspension.java b/test/1931-monitor-events/src/art/Suspension.java
new file mode 120000
index 0000000..bcef96f
--- /dev/null
+++ b/test/1931-monitor-events/src/art/Suspension.java
@@ -0,0 +1 @@
+../../../jvmti-common/Suspension.java
\ No newline at end of file
diff --git a/test/1932-monitor-events-misc/src/art/Monitors.java b/test/1932-monitor-events-misc/src/art/Monitors.java
deleted file mode 100644
index 7fe2b60..0000000
--- a/test/1932-monitor-events-misc/src/art/Monitors.java
+++ /dev/null
@@ -1,344 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Method;
-import java.util.concurrent.atomic.*;
-import java.util.function.Function;
-import java.util.stream.Stream;
-import java.util.Arrays;
-import java.util.Objects;
-
-public class Monitors {
-  public native static void setupMonitorEvents(
-      Class<?> method_klass,
-      Method monitor_contended_enter_event,
-      Method monitor_contended_entered_event,
-      Method monitor_wait_event,
-      Method monitor_waited_event,
-      Class<?> lock_klass,
-      Thread thr);
-  public native static void stopMonitorEvents();
-
-  public static class NamedLock {
-    public final String name;
-    private volatile int calledNotify;
-    public NamedLock(String name) {
-      this.name = name;
-      calledNotify = 0;
-    }
-
-    public String toString() {
-      return String.format("NamedLock[%s]", name);
-    }
-
-    public final void DoWait() throws Exception {
-      final int v = calledNotify;
-      while (v == calledNotify) {
-        wait();
-      }
-    }
-
-    public final void DoWait(long t) throws Exception {
-      final int v = calledNotify;
-      final long target = System.currentTimeMillis() + (t / 2);
-      while (v == calledNotify && (t < 0 || System.currentTimeMillis() < target)) {
-        wait(t);
-      }
-    }
-
-    public final void DoNotifyAll() throws Exception {
-      calledNotify++;
-      notifyAll();
-    }
-
-    public final void DoNotify() throws Exception {
-      calledNotify++;
-      notify();
-    }
-  }
-
-  public static final class MonitorUsage {
-    public final Object monitor;
-    public final Thread owner;
-    public final int entryCount;
-    public final Thread[] waiters;
-    public final Thread[] notifyWaiters;
-
-    public MonitorUsage(
-        Object monitor,
-        Thread owner,
-        int entryCount,
-        Thread[] waiters,
-        Thread[] notifyWaiters) {
-      this.monitor = monitor;
-      this.entryCount = entryCount;
-      this.owner = owner;
-      this.waiters = waiters;
-      this.notifyWaiters = notifyWaiters;
-    }
-
-    private static String toNameList(Thread[] ts) {
-      return Arrays.toString(Arrays.stream(ts).map((Thread t) -> t.getName()).toArray());
-    }
-
-    public String toString() {
-      return String.format(
-          "MonitorUsage{ monitor: %s, owner: %s, entryCount: %d, waiters: %s, notify_waiters: %s }",
-          monitor,
-          (owner != null) ? owner.getName() : "<NULL>",
-          entryCount,
-          toNameList(waiters),
-          toNameList(notifyWaiters));
-    }
-  }
-
-  public static native MonitorUsage getObjectMonitorUsage(Object monitor);
-  public static native Object getCurrentContendedMonitor(Thread thr);
-
-  public static class TestException extends Error {
-    public TestException() { super(); }
-    public TestException(String s) { super(s); }
-    public TestException(String s, Throwable c) { super(s, c); }
-  }
-
-  public static class LockController {
-    private static enum Action { HOLD, RELEASE, NOTIFY, NOTIFY_ALL, WAIT, TIMED_WAIT }
-
-    public final NamedLock lock;
-    public final long timeout;
-    private final AtomicStampedReference<Action> action;
-    private volatile Thread runner = null;
-    private volatile boolean started = false;
-    private volatile boolean held = false;
-    private static final AtomicInteger cnt = new AtomicInteger(0);
-    private volatile Throwable exe;
-
-    public LockController(NamedLock lock) {
-      this(lock, 10 * 1000);
-    }
-    public LockController(NamedLock lock, long timeout) {
-      this.lock = lock;
-      this.timeout = timeout;
-      this.action = new AtomicStampedReference(Action.HOLD, 0);
-      this.exe = null;
-    }
-
-    public boolean IsWorkerThread(Thread thd) {
-      return Objects.equals(runner, thd);
-    }
-
-    public boolean IsLocked() {
-      checkException();
-      return held;
-    }
-
-    public void checkException() {
-      if (exe != null) {
-        throw new TestException("Exception thrown by other thread!", exe);
-      }
-    }
-
-    private void setAction(Action a) {
-      int stamp = action.getStamp();
-      // Wait for it to be HOLD before updating.
-      while (!action.compareAndSet(Action.HOLD, a, stamp, stamp + 1)) {
-        stamp = action.getStamp();
-      }
-    }
-
-    public synchronized void suspendWorker() throws Exception {
-      checkException();
-      if (runner == null) {
-        throw new TestException("We don't have any runner holding  " + lock);
-      }
-      Suspension.suspend(runner);
-    }
-
-    public Object getWorkerContendedMonitor() throws Exception {
-      checkException();
-      if (runner == null) {
-        return null;
-      }
-      return getCurrentContendedMonitor(runner);
-    }
-
-    public synchronized void DoLock() {
-      if (IsLocked()) {
-        throw new Error("lock is already acquired or being acquired.");
-      }
-      if (runner != null) {
-        throw new Error("Already have thread!");
-      }
-      runner = new Thread(() -> {
-        started = true;
-        try {
-          synchronized (lock) {
-            held = true;
-            int[] stamp_h = new int[] { -1 };
-            Action cur_action = Action.HOLD;
-            try {
-              while (true) {
-                cur_action = action.get(stamp_h);
-                int stamp = stamp_h[0];
-                if (cur_action == Action.RELEASE) {
-                  // The other thread will deal with reseting action.
-                  break;
-                }
-                try {
-                  switch (cur_action) {
-                    case HOLD:
-                      Thread.yield();
-                      break;
-                    case NOTIFY:
-                      lock.DoNotify();
-                      break;
-                    case NOTIFY_ALL:
-                      lock.DoNotifyAll();
-                      break;
-                    case TIMED_WAIT:
-                      lock.DoWait(timeout);
-                      break;
-                    case WAIT:
-                      lock.DoWait();
-                      break;
-                    default:
-                      throw new Error("Unknown action " + action);
-                  }
-                } finally {
-                  // reset action back to hold if it isn't something else.
-                  action.compareAndSet(cur_action, Action.HOLD, stamp, stamp+1);
-                }
-              }
-            } catch (Exception e) {
-              throw new TestException("Got an error while performing action " + cur_action, e);
-            }
-          }
-        } finally {
-          held = false;
-          started = false;
-        }
-      }, "Locker thread " + cnt.getAndIncrement() + " for " + lock);
-      // Make sure we can get any exceptions this throws.
-      runner.setUncaughtExceptionHandler((t, e) -> { exe = e; });
-      runner.start();
-    }
-
-    public void waitForLockToBeHeld() throws Exception {
-      while (true) {
-        if (IsLocked() && Objects.equals(runner, Monitors.getObjectMonitorUsage(lock).owner)) {
-          return;
-        }
-      }
-    }
-
-    public synchronized void waitForNotifySleep() throws Exception {
-      if (runner == null) {
-        throw new Error("No thread trying to lock!");
-      }
-      do {
-        checkException();
-      } while (!started ||
-          !Arrays.asList(Monitors.getObjectMonitorUsage(lock).notifyWaiters).contains(runner));
-    }
-
-    public synchronized void waitForContendedSleep() throws Exception {
-      if (runner == null) {
-        throw new Error("No thread trying to lock!");
-      }
-      do {
-        checkException();
-      } while (!started ||
-          runner.getState() != Thread.State.BLOCKED ||
-          !Arrays.asList(Monitors.getObjectMonitorUsage(lock).waiters).contains(runner));
-    }
-
-    public synchronized void DoNotify() {
-      if (!IsLocked()) {
-        throw new Error("Not locked");
-      }
-      setAction(Action.NOTIFY);
-    }
-
-    public synchronized void DoNotifyAll() {
-      if (!IsLocked()) {
-        throw new Error("Not locked");
-      }
-      setAction(Action.NOTIFY_ALL);
-    }
-
-    public synchronized void DoTimedWait() throws Exception {
-      if (!IsLocked()) {
-        throw new Error("Not locked");
-      }
-      setAction(Action.TIMED_WAIT);
-    }
-
-    public synchronized void DoWait() throws Exception {
-      if (!IsLocked()) {
-        throw new Error("Not locked");
-      }
-      setAction(Action.WAIT);
-    }
-
-    public synchronized void interruptWorker() throws Exception {
-      if (!IsLocked()) {
-        throw new Error("Not locked");
-      }
-      runner.interrupt();
-    }
-
-    public synchronized void waitForActionToFinish() throws Exception {
-      checkException();
-      while (action.getReference() != Action.HOLD) { checkException(); }
-    }
-
-    public synchronized void DoUnlock() throws Exception {
-      Error throwing = null;
-      if (!IsLocked()) {
-        // We might just be racing some exception that was thrown by the worker thread. Cache the
-        // exception, we will throw one from the worker before this one.
-        throwing = new Error("Not locked!");
-      }
-      setAction(Action.RELEASE);
-      Thread run = runner;
-      runner = null;
-      while (held) {}
-      run.join();
-      action.set(Action.HOLD, 0);
-      // Make sure to throw any exception that occurred since it might not have unlocked due to our
-      // request.
-      checkException();
-      DoCleanup();
-      if (throwing != null) {
-        throw throwing;
-      }
-    }
-
-    public synchronized void DoCleanup() throws Exception {
-      if (runner != null) {
-        Thread run = runner;
-        runner = null;
-        while (held) {}
-        run.join();
-      }
-      action.set(Action.HOLD, 0);
-      exe = null;
-    }
-  }
-}
-
diff --git a/test/1932-monitor-events-misc/src/art/Monitors.java b/test/1932-monitor-events-misc/src/art/Monitors.java
new file mode 120000
index 0000000..61e8367
--- /dev/null
+++ b/test/1932-monitor-events-misc/src/art/Monitors.java
@@ -0,0 +1 @@
+../../../jvmti-common/Monitors.java
\ No newline at end of file
diff --git a/test/1932-monitor-events-misc/src/art/Suspension.java b/test/1932-monitor-events-misc/src/art/Suspension.java
deleted file mode 100644
index 16e62cc..0000000
--- a/test/1932-monitor-events-misc/src/art/Suspension.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-public class Suspension {
-  // Suspends a thread using jvmti.
-  public native static void suspend(Thread thr);
-
-  // Resumes a thread using jvmti.
-  public native static void resume(Thread thr);
-
-  public native static boolean isSuspended(Thread thr);
-
-  public native static int[] suspendList(Thread... threads);
-  public native static int[] resumeList(Thread... threads);
-}
diff --git a/test/1932-monitor-events-misc/src/art/Suspension.java b/test/1932-monitor-events-misc/src/art/Suspension.java
new file mode 120000
index 0000000..bcef96f
--- /dev/null
+++ b/test/1932-monitor-events-misc/src/art/Suspension.java
@@ -0,0 +1 @@
+../../../jvmti-common/Suspension.java
\ No newline at end of file
diff --git a/test/1933-monitor-current-contended/src/art/Monitors.java b/test/1933-monitor-current-contended/src/art/Monitors.java
deleted file mode 100644
index 7fe2b60..0000000
--- a/test/1933-monitor-current-contended/src/art/Monitors.java
+++ /dev/null
@@ -1,344 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Method;
-import java.util.concurrent.atomic.*;
-import java.util.function.Function;
-import java.util.stream.Stream;
-import java.util.Arrays;
-import java.util.Objects;
-
-public class Monitors {
-  public native static void setupMonitorEvents(
-      Class<?> method_klass,
-      Method monitor_contended_enter_event,
-      Method monitor_contended_entered_event,
-      Method monitor_wait_event,
-      Method monitor_waited_event,
-      Class<?> lock_klass,
-      Thread thr);
-  public native static void stopMonitorEvents();
-
-  public static class NamedLock {
-    public final String name;
-    private volatile int calledNotify;
-    public NamedLock(String name) {
-      this.name = name;
-      calledNotify = 0;
-    }
-
-    public String toString() {
-      return String.format("NamedLock[%s]", name);
-    }
-
-    public final void DoWait() throws Exception {
-      final int v = calledNotify;
-      while (v == calledNotify) {
-        wait();
-      }
-    }
-
-    public final void DoWait(long t) throws Exception {
-      final int v = calledNotify;
-      final long target = System.currentTimeMillis() + (t / 2);
-      while (v == calledNotify && (t < 0 || System.currentTimeMillis() < target)) {
-        wait(t);
-      }
-    }
-
-    public final void DoNotifyAll() throws Exception {
-      calledNotify++;
-      notifyAll();
-    }
-
-    public final void DoNotify() throws Exception {
-      calledNotify++;
-      notify();
-    }
-  }
-
-  public static final class MonitorUsage {
-    public final Object monitor;
-    public final Thread owner;
-    public final int entryCount;
-    public final Thread[] waiters;
-    public final Thread[] notifyWaiters;
-
-    public MonitorUsage(
-        Object monitor,
-        Thread owner,
-        int entryCount,
-        Thread[] waiters,
-        Thread[] notifyWaiters) {
-      this.monitor = monitor;
-      this.entryCount = entryCount;
-      this.owner = owner;
-      this.waiters = waiters;
-      this.notifyWaiters = notifyWaiters;
-    }
-
-    private static String toNameList(Thread[] ts) {
-      return Arrays.toString(Arrays.stream(ts).map((Thread t) -> t.getName()).toArray());
-    }
-
-    public String toString() {
-      return String.format(
-          "MonitorUsage{ monitor: %s, owner: %s, entryCount: %d, waiters: %s, notify_waiters: %s }",
-          monitor,
-          (owner != null) ? owner.getName() : "<NULL>",
-          entryCount,
-          toNameList(waiters),
-          toNameList(notifyWaiters));
-    }
-  }
-
-  public static native MonitorUsage getObjectMonitorUsage(Object monitor);
-  public static native Object getCurrentContendedMonitor(Thread thr);
-
-  public static class TestException extends Error {
-    public TestException() { super(); }
-    public TestException(String s) { super(s); }
-    public TestException(String s, Throwable c) { super(s, c); }
-  }
-
-  public static class LockController {
-    private static enum Action { HOLD, RELEASE, NOTIFY, NOTIFY_ALL, WAIT, TIMED_WAIT }
-
-    public final NamedLock lock;
-    public final long timeout;
-    private final AtomicStampedReference<Action> action;
-    private volatile Thread runner = null;
-    private volatile boolean started = false;
-    private volatile boolean held = false;
-    private static final AtomicInteger cnt = new AtomicInteger(0);
-    private volatile Throwable exe;
-
-    public LockController(NamedLock lock) {
-      this(lock, 10 * 1000);
-    }
-    public LockController(NamedLock lock, long timeout) {
-      this.lock = lock;
-      this.timeout = timeout;
-      this.action = new AtomicStampedReference(Action.HOLD, 0);
-      this.exe = null;
-    }
-
-    public boolean IsWorkerThread(Thread thd) {
-      return Objects.equals(runner, thd);
-    }
-
-    public boolean IsLocked() {
-      checkException();
-      return held;
-    }
-
-    public void checkException() {
-      if (exe != null) {
-        throw new TestException("Exception thrown by other thread!", exe);
-      }
-    }
-
-    private void setAction(Action a) {
-      int stamp = action.getStamp();
-      // Wait for it to be HOLD before updating.
-      while (!action.compareAndSet(Action.HOLD, a, stamp, stamp + 1)) {
-        stamp = action.getStamp();
-      }
-    }
-
-    public synchronized void suspendWorker() throws Exception {
-      checkException();
-      if (runner == null) {
-        throw new TestException("We don't have any runner holding  " + lock);
-      }
-      Suspension.suspend(runner);
-    }
-
-    public Object getWorkerContendedMonitor() throws Exception {
-      checkException();
-      if (runner == null) {
-        return null;
-      }
-      return getCurrentContendedMonitor(runner);
-    }
-
-    public synchronized void DoLock() {
-      if (IsLocked()) {
-        throw new Error("lock is already acquired or being acquired.");
-      }
-      if (runner != null) {
-        throw new Error("Already have thread!");
-      }
-      runner = new Thread(() -> {
-        started = true;
-        try {
-          synchronized (lock) {
-            held = true;
-            int[] stamp_h = new int[] { -1 };
-            Action cur_action = Action.HOLD;
-            try {
-              while (true) {
-                cur_action = action.get(stamp_h);
-                int stamp = stamp_h[0];
-                if (cur_action == Action.RELEASE) {
-                  // The other thread will deal with reseting action.
-                  break;
-                }
-                try {
-                  switch (cur_action) {
-                    case HOLD:
-                      Thread.yield();
-                      break;
-                    case NOTIFY:
-                      lock.DoNotify();
-                      break;
-                    case NOTIFY_ALL:
-                      lock.DoNotifyAll();
-                      break;
-                    case TIMED_WAIT:
-                      lock.DoWait(timeout);
-                      break;
-                    case WAIT:
-                      lock.DoWait();
-                      break;
-                    default:
-                      throw new Error("Unknown action " + action);
-                  }
-                } finally {
-                  // reset action back to hold if it isn't something else.
-                  action.compareAndSet(cur_action, Action.HOLD, stamp, stamp+1);
-                }
-              }
-            } catch (Exception e) {
-              throw new TestException("Got an error while performing action " + cur_action, e);
-            }
-          }
-        } finally {
-          held = false;
-          started = false;
-        }
-      }, "Locker thread " + cnt.getAndIncrement() + " for " + lock);
-      // Make sure we can get any exceptions this throws.
-      runner.setUncaughtExceptionHandler((t, e) -> { exe = e; });
-      runner.start();
-    }
-
-    public void waitForLockToBeHeld() throws Exception {
-      while (true) {
-        if (IsLocked() && Objects.equals(runner, Monitors.getObjectMonitorUsage(lock).owner)) {
-          return;
-        }
-      }
-    }
-
-    public synchronized void waitForNotifySleep() throws Exception {
-      if (runner == null) {
-        throw new Error("No thread trying to lock!");
-      }
-      do {
-        checkException();
-      } while (!started ||
-          !Arrays.asList(Monitors.getObjectMonitorUsage(lock).notifyWaiters).contains(runner));
-    }
-
-    public synchronized void waitForContendedSleep() throws Exception {
-      if (runner == null) {
-        throw new Error("No thread trying to lock!");
-      }
-      do {
-        checkException();
-      } while (!started ||
-          runner.getState() != Thread.State.BLOCKED ||
-          !Arrays.asList(Monitors.getObjectMonitorUsage(lock).waiters).contains(runner));
-    }
-
-    public synchronized void DoNotify() {
-      if (!IsLocked()) {
-        throw new Error("Not locked");
-      }
-      setAction(Action.NOTIFY);
-    }
-
-    public synchronized void DoNotifyAll() {
-      if (!IsLocked()) {
-        throw new Error("Not locked");
-      }
-      setAction(Action.NOTIFY_ALL);
-    }
-
-    public synchronized void DoTimedWait() throws Exception {
-      if (!IsLocked()) {
-        throw new Error("Not locked");
-      }
-      setAction(Action.TIMED_WAIT);
-    }
-
-    public synchronized void DoWait() throws Exception {
-      if (!IsLocked()) {
-        throw new Error("Not locked");
-      }
-      setAction(Action.WAIT);
-    }
-
-    public synchronized void interruptWorker() throws Exception {
-      if (!IsLocked()) {
-        throw new Error("Not locked");
-      }
-      runner.interrupt();
-    }
-
-    public synchronized void waitForActionToFinish() throws Exception {
-      checkException();
-      while (action.getReference() != Action.HOLD) { checkException(); }
-    }
-
-    public synchronized void DoUnlock() throws Exception {
-      Error throwing = null;
-      if (!IsLocked()) {
-        // We might just be racing some exception that was thrown by the worker thread. Cache the
-        // exception, we will throw one from the worker before this one.
-        throwing = new Error("Not locked!");
-      }
-      setAction(Action.RELEASE);
-      Thread run = runner;
-      runner = null;
-      while (held) {}
-      run.join();
-      action.set(Action.HOLD, 0);
-      // Make sure to throw any exception that occurred since it might not have unlocked due to our
-      // request.
-      checkException();
-      DoCleanup();
-      if (throwing != null) {
-        throw throwing;
-      }
-    }
-
-    public synchronized void DoCleanup() throws Exception {
-      if (runner != null) {
-        Thread run = runner;
-        runner = null;
-        while (held) {}
-        run.join();
-      }
-      action.set(Action.HOLD, 0);
-      exe = null;
-    }
-  }
-}
-
diff --git a/test/1933-monitor-current-contended/src/art/Monitors.java b/test/1933-monitor-current-contended/src/art/Monitors.java
new file mode 120000
index 0000000..61e8367
--- /dev/null
+++ b/test/1933-monitor-current-contended/src/art/Monitors.java
@@ -0,0 +1 @@
+../../../jvmti-common/Monitors.java
\ No newline at end of file
diff --git a/test/1933-monitor-current-contended/src/art/Suspension.java b/test/1933-monitor-current-contended/src/art/Suspension.java
deleted file mode 100644
index 16e62cc..0000000
--- a/test/1933-monitor-current-contended/src/art/Suspension.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-public class Suspension {
-  // Suspends a thread using jvmti.
-  public native static void suspend(Thread thr);
-
-  // Resumes a thread using jvmti.
-  public native static void resume(Thread thr);
-
-  public native static boolean isSuspended(Thread thr);
-
-  public native static int[] suspendList(Thread... threads);
-  public native static int[] resumeList(Thread... threads);
-}
diff --git a/test/1933-monitor-current-contended/src/art/Suspension.java b/test/1933-monitor-current-contended/src/art/Suspension.java
new file mode 120000
index 0000000..bcef96f
--- /dev/null
+++ b/test/1933-monitor-current-contended/src/art/Suspension.java
@@ -0,0 +1 @@
+../../../jvmti-common/Suspension.java
\ No newline at end of file
diff --git a/test/1934-jvmti-signal-thread/src/art/Monitors.java b/test/1934-jvmti-signal-thread/src/art/Monitors.java
deleted file mode 100644
index 7fe2b60..0000000
--- a/test/1934-jvmti-signal-thread/src/art/Monitors.java
+++ /dev/null
@@ -1,344 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Method;
-import java.util.concurrent.atomic.*;
-import java.util.function.Function;
-import java.util.stream.Stream;
-import java.util.Arrays;
-import java.util.Objects;
-
-public class Monitors {
-  public native static void setupMonitorEvents(
-      Class<?> method_klass,
-      Method monitor_contended_enter_event,
-      Method monitor_contended_entered_event,
-      Method monitor_wait_event,
-      Method monitor_waited_event,
-      Class<?> lock_klass,
-      Thread thr);
-  public native static void stopMonitorEvents();
-
-  public static class NamedLock {
-    public final String name;
-    private volatile int calledNotify;
-    public NamedLock(String name) {
-      this.name = name;
-      calledNotify = 0;
-    }
-
-    public String toString() {
-      return String.format("NamedLock[%s]", name);
-    }
-
-    public final void DoWait() throws Exception {
-      final int v = calledNotify;
-      while (v == calledNotify) {
-        wait();
-      }
-    }
-
-    public final void DoWait(long t) throws Exception {
-      final int v = calledNotify;
-      final long target = System.currentTimeMillis() + (t / 2);
-      while (v == calledNotify && (t < 0 || System.currentTimeMillis() < target)) {
-        wait(t);
-      }
-    }
-
-    public final void DoNotifyAll() throws Exception {
-      calledNotify++;
-      notifyAll();
-    }
-
-    public final void DoNotify() throws Exception {
-      calledNotify++;
-      notify();
-    }
-  }
-
-  public static final class MonitorUsage {
-    public final Object monitor;
-    public final Thread owner;
-    public final int entryCount;
-    public final Thread[] waiters;
-    public final Thread[] notifyWaiters;
-
-    public MonitorUsage(
-        Object monitor,
-        Thread owner,
-        int entryCount,
-        Thread[] waiters,
-        Thread[] notifyWaiters) {
-      this.monitor = monitor;
-      this.entryCount = entryCount;
-      this.owner = owner;
-      this.waiters = waiters;
-      this.notifyWaiters = notifyWaiters;
-    }
-
-    private static String toNameList(Thread[] ts) {
-      return Arrays.toString(Arrays.stream(ts).map((Thread t) -> t.getName()).toArray());
-    }
-
-    public String toString() {
-      return String.format(
-          "MonitorUsage{ monitor: %s, owner: %s, entryCount: %d, waiters: %s, notify_waiters: %s }",
-          monitor,
-          (owner != null) ? owner.getName() : "<NULL>",
-          entryCount,
-          toNameList(waiters),
-          toNameList(notifyWaiters));
-    }
-  }
-
-  public static native MonitorUsage getObjectMonitorUsage(Object monitor);
-  public static native Object getCurrentContendedMonitor(Thread thr);
-
-  public static class TestException extends Error {
-    public TestException() { super(); }
-    public TestException(String s) { super(s); }
-    public TestException(String s, Throwable c) { super(s, c); }
-  }
-
-  public static class LockController {
-    private static enum Action { HOLD, RELEASE, NOTIFY, NOTIFY_ALL, WAIT, TIMED_WAIT }
-
-    public final NamedLock lock;
-    public final long timeout;
-    private final AtomicStampedReference<Action> action;
-    private volatile Thread runner = null;
-    private volatile boolean started = false;
-    private volatile boolean held = false;
-    private static final AtomicInteger cnt = new AtomicInteger(0);
-    private volatile Throwable exe;
-
-    public LockController(NamedLock lock) {
-      this(lock, 10 * 1000);
-    }
-    public LockController(NamedLock lock, long timeout) {
-      this.lock = lock;
-      this.timeout = timeout;
-      this.action = new AtomicStampedReference(Action.HOLD, 0);
-      this.exe = null;
-    }
-
-    public boolean IsWorkerThread(Thread thd) {
-      return Objects.equals(runner, thd);
-    }
-
-    public boolean IsLocked() {
-      checkException();
-      return held;
-    }
-
-    public void checkException() {
-      if (exe != null) {
-        throw new TestException("Exception thrown by other thread!", exe);
-      }
-    }
-
-    private void setAction(Action a) {
-      int stamp = action.getStamp();
-      // Wait for it to be HOLD before updating.
-      while (!action.compareAndSet(Action.HOLD, a, stamp, stamp + 1)) {
-        stamp = action.getStamp();
-      }
-    }
-
-    public synchronized void suspendWorker() throws Exception {
-      checkException();
-      if (runner == null) {
-        throw new TestException("We don't have any runner holding  " + lock);
-      }
-      Suspension.suspend(runner);
-    }
-
-    public Object getWorkerContendedMonitor() throws Exception {
-      checkException();
-      if (runner == null) {
-        return null;
-      }
-      return getCurrentContendedMonitor(runner);
-    }
-
-    public synchronized void DoLock() {
-      if (IsLocked()) {
-        throw new Error("lock is already acquired or being acquired.");
-      }
-      if (runner != null) {
-        throw new Error("Already have thread!");
-      }
-      runner = new Thread(() -> {
-        started = true;
-        try {
-          synchronized (lock) {
-            held = true;
-            int[] stamp_h = new int[] { -1 };
-            Action cur_action = Action.HOLD;
-            try {
-              while (true) {
-                cur_action = action.get(stamp_h);
-                int stamp = stamp_h[0];
-                if (cur_action == Action.RELEASE) {
-                  // The other thread will deal with reseting action.
-                  break;
-                }
-                try {
-                  switch (cur_action) {
-                    case HOLD:
-                      Thread.yield();
-                      break;
-                    case NOTIFY:
-                      lock.DoNotify();
-                      break;
-                    case NOTIFY_ALL:
-                      lock.DoNotifyAll();
-                      break;
-                    case TIMED_WAIT:
-                      lock.DoWait(timeout);
-                      break;
-                    case WAIT:
-                      lock.DoWait();
-                      break;
-                    default:
-                      throw new Error("Unknown action " + action);
-                  }
-                } finally {
-                  // reset action back to hold if it isn't something else.
-                  action.compareAndSet(cur_action, Action.HOLD, stamp, stamp+1);
-                }
-              }
-            } catch (Exception e) {
-              throw new TestException("Got an error while performing action " + cur_action, e);
-            }
-          }
-        } finally {
-          held = false;
-          started = false;
-        }
-      }, "Locker thread " + cnt.getAndIncrement() + " for " + lock);
-      // Make sure we can get any exceptions this throws.
-      runner.setUncaughtExceptionHandler((t, e) -> { exe = e; });
-      runner.start();
-    }
-
-    public void waitForLockToBeHeld() throws Exception {
-      while (true) {
-        if (IsLocked() && Objects.equals(runner, Monitors.getObjectMonitorUsage(lock).owner)) {
-          return;
-        }
-      }
-    }
-
-    public synchronized void waitForNotifySleep() throws Exception {
-      if (runner == null) {
-        throw new Error("No thread trying to lock!");
-      }
-      do {
-        checkException();
-      } while (!started ||
-          !Arrays.asList(Monitors.getObjectMonitorUsage(lock).notifyWaiters).contains(runner));
-    }
-
-    public synchronized void waitForContendedSleep() throws Exception {
-      if (runner == null) {
-        throw new Error("No thread trying to lock!");
-      }
-      do {
-        checkException();
-      } while (!started ||
-          runner.getState() != Thread.State.BLOCKED ||
-          !Arrays.asList(Monitors.getObjectMonitorUsage(lock).waiters).contains(runner));
-    }
-
-    public synchronized void DoNotify() {
-      if (!IsLocked()) {
-        throw new Error("Not locked");
-      }
-      setAction(Action.NOTIFY);
-    }
-
-    public synchronized void DoNotifyAll() {
-      if (!IsLocked()) {
-        throw new Error("Not locked");
-      }
-      setAction(Action.NOTIFY_ALL);
-    }
-
-    public synchronized void DoTimedWait() throws Exception {
-      if (!IsLocked()) {
-        throw new Error("Not locked");
-      }
-      setAction(Action.TIMED_WAIT);
-    }
-
-    public synchronized void DoWait() throws Exception {
-      if (!IsLocked()) {
-        throw new Error("Not locked");
-      }
-      setAction(Action.WAIT);
-    }
-
-    public synchronized void interruptWorker() throws Exception {
-      if (!IsLocked()) {
-        throw new Error("Not locked");
-      }
-      runner.interrupt();
-    }
-
-    public synchronized void waitForActionToFinish() throws Exception {
-      checkException();
-      while (action.getReference() != Action.HOLD) { checkException(); }
-    }
-
-    public synchronized void DoUnlock() throws Exception {
-      Error throwing = null;
-      if (!IsLocked()) {
-        // We might just be racing some exception that was thrown by the worker thread. Cache the
-        // exception, we will throw one from the worker before this one.
-        throwing = new Error("Not locked!");
-      }
-      setAction(Action.RELEASE);
-      Thread run = runner;
-      runner = null;
-      while (held) {}
-      run.join();
-      action.set(Action.HOLD, 0);
-      // Make sure to throw any exception that occurred since it might not have unlocked due to our
-      // request.
-      checkException();
-      DoCleanup();
-      if (throwing != null) {
-        throw throwing;
-      }
-    }
-
-    public synchronized void DoCleanup() throws Exception {
-      if (runner != null) {
-        Thread run = runner;
-        runner = null;
-        while (held) {}
-        run.join();
-      }
-      action.set(Action.HOLD, 0);
-      exe = null;
-    }
-  }
-}
-
diff --git a/test/1934-jvmti-signal-thread/src/art/Monitors.java b/test/1934-jvmti-signal-thread/src/art/Monitors.java
new file mode 120000
index 0000000..61e8367
--- /dev/null
+++ b/test/1934-jvmti-signal-thread/src/art/Monitors.java
@@ -0,0 +1 @@
+../../../jvmti-common/Monitors.java
\ No newline at end of file
diff --git a/test/1934-jvmti-signal-thread/src/art/Suspension.java b/test/1934-jvmti-signal-thread/src/art/Suspension.java
deleted file mode 100644
index 16e62cc..0000000
--- a/test/1934-jvmti-signal-thread/src/art/Suspension.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-public class Suspension {
-  // Suspends a thread using jvmti.
-  public native static void suspend(Thread thr);
-
-  // Resumes a thread using jvmti.
-  public native static void resume(Thread thr);
-
-  public native static boolean isSuspended(Thread thr);
-
-  public native static int[] suspendList(Thread... threads);
-  public native static int[] resumeList(Thread... threads);
-}
diff --git a/test/1934-jvmti-signal-thread/src/art/Suspension.java b/test/1934-jvmti-signal-thread/src/art/Suspension.java
new file mode 120000
index 0000000..bcef96f
--- /dev/null
+++ b/test/1934-jvmti-signal-thread/src/art/Suspension.java
@@ -0,0 +1 @@
+../../../jvmti-common/Suspension.java
\ No newline at end of file
diff --git a/test/1934-jvmti-signal-thread/src/art/Threads.java b/test/1934-jvmti-signal-thread/src/art/Threads.java
new file mode 120000
index 0000000..0749743
--- /dev/null
+++ b/test/1934-jvmti-signal-thread/src/art/Threads.java
@@ -0,0 +1 @@
+../../../jvmti-common/Threads.java
\ No newline at end of file
diff --git a/test/1935-get-set-current-frame-jit/src/art/Breakpoint.java b/test/1935-get-set-current-frame-jit/src/art/Breakpoint.java
deleted file mode 100644
index bbb89f7..0000000
--- a/test/1935-get-set-current-frame-jit/src/art/Breakpoint.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Executable;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.Objects;
-
-public class Breakpoint {
-  public static class Manager {
-    public static class BP {
-      public final Executable method;
-      public final long location;
-
-      public BP(Executable method) {
-        this(method, getStartLocation(method));
-      }
-
-      public BP(Executable method, long location) {
-        this.method = method;
-        this.location = location;
-      }
-
-      @Override
-      public boolean equals(Object other) {
-        return (other instanceof BP) &&
-            method.equals(((BP)other).method) &&
-            location == ((BP)other).location;
-      }
-
-      @Override
-      public String toString() {
-        return method.toString() + " @ " + getLine();
-      }
-
-      @Override
-      public int hashCode() {
-        return Objects.hash(method, location);
-      }
-
-      public int getLine() {
-        try {
-          LineNumber[] lines = getLineNumberTable(method);
-          int best = -1;
-          for (LineNumber l : lines) {
-            if (l.location > location) {
-              break;
-            } else {
-              best = l.line;
-            }
-          }
-          return best;
-        } catch (Exception e) {
-          return -1;
-        }
-      }
-    }
-
-    private Set<BP> breaks = new HashSet<>();
-
-    public void setBreakpoints(BP... bs) {
-      for (BP b : bs) {
-        if (breaks.add(b)) {
-          Breakpoint.setBreakpoint(b.method, b.location);
-        }
-      }
-    }
-    public void setBreakpoint(Executable method, long location) {
-      setBreakpoints(new BP(method, location));
-    }
-
-    public void clearBreakpoints(BP... bs) {
-      for (BP b : bs) {
-        if (breaks.remove(b)) {
-          Breakpoint.clearBreakpoint(b.method, b.location);
-        }
-      }
-    }
-    public void clearBreakpoint(Executable method, long location) {
-      clearBreakpoints(new BP(method, location));
-    }
-
-    public void clearAllBreakpoints() {
-      clearBreakpoints(breaks.toArray(new BP[0]));
-    }
-  }
-
-  public static void startBreakpointWatch(Class<?> methodClass,
-                                          Executable breakpointReached,
-                                          Thread thr) {
-    startBreakpointWatch(methodClass, breakpointReached, false, thr);
-  }
-
-  /**
-   * Enables the trapping of breakpoint events.
-   *
-   * If allowRecursive == true then breakpoints will be sent even if one is currently being handled.
-   */
-  public static native void startBreakpointWatch(Class<?> methodClass,
-                                                 Executable breakpointReached,
-                                                 boolean allowRecursive,
-                                                 Thread thr);
-  public static native void stopBreakpointWatch(Thread thr);
-
-  public static final class LineNumber implements Comparable<LineNumber> {
-    public final long location;
-    public final int line;
-
-    private LineNumber(long loc, int line) {
-      this.location = loc;
-      this.line = line;
-    }
-
-    public boolean equals(Object other) {
-      return other instanceof LineNumber && ((LineNumber)other).line == line &&
-          ((LineNumber)other).location == location;
-    }
-
-    public int compareTo(LineNumber other) {
-      int v = Integer.valueOf(line).compareTo(Integer.valueOf(other.line));
-      if (v != 0) {
-        return v;
-      } else {
-        return Long.valueOf(location).compareTo(Long.valueOf(other.location));
-      }
-    }
-  }
-
-  public static native void setBreakpoint(Executable m, long loc);
-  public static void setBreakpoint(Executable m, LineNumber l) {
-    setBreakpoint(m, l.location);
-  }
-
-  public static native void clearBreakpoint(Executable m, long loc);
-  public static void clearBreakpoint(Executable m, LineNumber l) {
-    clearBreakpoint(m, l.location);
-  }
-
-  private static native Object[] getLineNumberTableNative(Executable m);
-  public static LineNumber[] getLineNumberTable(Executable m) {
-    Object[] nativeTable = getLineNumberTableNative(m);
-    long[] location = (long[])(nativeTable[0]);
-    int[] lines = (int[])(nativeTable[1]);
-    if (lines.length != location.length) {
-      throw new Error("Lines and locations have different lengths!");
-    }
-    LineNumber[] out = new LineNumber[lines.length];
-    for (int i = 0; i < lines.length; i++) {
-      out[i] = new LineNumber(location[i], lines[i]);
-    }
-    return out;
-  }
-
-  public static native long getStartLocation(Executable m);
-
-  public static int locationToLine(Executable m, long location) {
-    try {
-      Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
-      int best = -1;
-      for (Breakpoint.LineNumber l : lines) {
-        if (l.location > location) {
-          break;
-        } else {
-          best = l.line;
-        }
-      }
-      return best;
-    } catch (Exception e) {
-      return -1;
-    }
-  }
-
-  public static long lineToLocation(Executable m, int line) throws Exception {
-    try {
-      Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
-      for (Breakpoint.LineNumber l : lines) {
-        if (l.line == line) {
-          return l.location;
-        }
-      }
-      throw new Exception("Unable to find line " + line + " in " + m);
-    } catch (Exception e) {
-      throw new Exception("Unable to get line number info for " + m, e);
-    }
-  }
-}
-
diff --git a/test/1935-get-set-current-frame-jit/src/art/Breakpoint.java b/test/1935-get-set-current-frame-jit/src/art/Breakpoint.java
new file mode 120000
index 0000000..3673916
--- /dev/null
+++ b/test/1935-get-set-current-frame-jit/src/art/Breakpoint.java
@@ -0,0 +1 @@
+../../../jvmti-common/Breakpoint.java
\ No newline at end of file
diff --git a/test/1935-get-set-current-frame-jit/src/art/Locals.java b/test/1935-get-set-current-frame-jit/src/art/Locals.java
deleted file mode 100644
index 22e21be..0000000
--- a/test/1935-get-set-current-frame-jit/src/art/Locals.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Executable;
-import java.util.Objects;
-
-public class Locals {
-  public static native void EnableLocalVariableAccess();
-
-  public static class VariableDescription {
-    public final long start_location;
-    public final int length;
-    public final String name;
-    public final String signature;
-    public final String generic_signature;
-    public final int slot;
-
-    public VariableDescription(
-        long start, int length, String name, String sig, String gen_sig, int slot) {
-      this.start_location = start;
-      this.length = length;
-      this.name = name;
-      this.signature = sig;
-      this.generic_signature = gen_sig;
-      this.slot = slot;
-    }
-
-    @Override
-    public String toString() {
-      return String.format(
-          "VariableDescription { " +
-            "Sig: '%s', Name: '%s', Gen_sig: '%s', slot: %d, start: %d, len: %d" +
-          "}",
-          this.signature,
-          this.name,
-          this.generic_signature,
-          this.slot,
-          this.start_location,
-          this.length);
-    }
-    public boolean equals(Object other) {
-      if (!(other instanceof VariableDescription)) {
-        return false;
-      } else {
-        VariableDescription v = (VariableDescription)other;
-        return Objects.equals(v.signature, signature) &&
-            Objects.equals(v.name, name) &&
-            Objects.equals(v.generic_signature, generic_signature) &&
-            v.slot == slot &&
-            v.start_location == start_location &&
-            v.length == length;
-      }
-    }
-    public int hashCode() {
-      return Objects.hash(this.signature, this.name, this.generic_signature, this.slot,
-          this.start_location, this.length);
-    }
-  }
-
-  public static native VariableDescription[] GetLocalVariableTable(Executable e);
-
-  public static VariableDescription GetVariableAtLine(
-      Executable e, String name, String sig, int line) throws Exception {
-    return GetVariableAtLocation(e, name, sig, Breakpoint.lineToLocation(e, line));
-  }
-
-  public static VariableDescription GetVariableAtLocation(
-      Executable e, String name, String sig, long loc) {
-    VariableDescription[] vars = GetLocalVariableTable(e);
-    for (VariableDescription var : vars) {
-      if (var.start_location <= loc &&
-          var.length + var.start_location > loc &&
-          var.name.equals(name) &&
-          var.signature.equals(sig)) {
-        return var;
-      }
-    }
-    throw new Error(
-        "Unable to find variable " + name + " (sig: " + sig + ") in " + e + " at loc " + loc);
-  }
-
-  public static native int GetLocalVariableInt(Thread thr, int depth, int slot);
-  public static native long GetLocalVariableLong(Thread thr, int depth, int slot);
-  public static native float GetLocalVariableFloat(Thread thr, int depth, int slot);
-  public static native double GetLocalVariableDouble(Thread thr, int depth, int slot);
-  public static native Object GetLocalVariableObject(Thread thr, int depth, int slot);
-  public static native Object GetLocalInstance(Thread thr, int depth);
-
-  public static void SetLocalVariableInt(Thread thr, int depth, int slot, Object val) {
-    SetLocalVariableInt(thr, depth, slot, ((Number)val).intValue());
-  }
-  public static void SetLocalVariableLong(Thread thr, int depth, int slot, Object val) {
-    SetLocalVariableLong(thr, depth, slot, ((Number)val).longValue());
-  }
-  public static void SetLocalVariableFloat(Thread thr, int depth, int slot, Object val) {
-    SetLocalVariableFloat(thr, depth, slot, ((Number)val).floatValue());
-  }
-  public static void SetLocalVariableDouble(Thread thr, int depth, int slot, Object val) {
-    SetLocalVariableDouble(thr, depth, slot, ((Number)val).doubleValue());
-  }
-  public static native void SetLocalVariableInt(Thread thr, int depth, int slot, int val);
-  public static native void SetLocalVariableLong(Thread thr, int depth, int slot, long val);
-  public static native void SetLocalVariableFloat(Thread thr, int depth, int slot, float val);
-  public static native void SetLocalVariableDouble(Thread thr, int depth, int slot, double val);
-  public static native void SetLocalVariableObject(Thread thr, int depth, int slot, Object val);
-}
diff --git a/test/1935-get-set-current-frame-jit/src/art/Locals.java b/test/1935-get-set-current-frame-jit/src/art/Locals.java
new file mode 120000
index 0000000..2998386
--- /dev/null
+++ b/test/1935-get-set-current-frame-jit/src/art/Locals.java
@@ -0,0 +1 @@
+../../../jvmti-common/Locals.java
\ No newline at end of file
diff --git a/test/1935-get-set-current-frame-jit/src/art/StackTrace.java b/test/1935-get-set-current-frame-jit/src/art/StackTrace.java
deleted file mode 100644
index 2ea2f20..0000000
--- a/test/1935-get-set-current-frame-jit/src/art/StackTrace.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Executable;
-
-public class StackTrace {
-  public static class StackFrameData {
-    public final Thread thr;
-    public final Executable method;
-    public final long current_location;
-    public final int depth;
-
-    public StackFrameData(Thread thr, Executable e, long loc, int depth) {
-      this.thr = thr;
-      this.method = e;
-      this.current_location = loc;
-      this.depth = depth;
-    }
-    @Override
-    public String toString() {
-      return String.format(
-          "StackFrameData { thr: '%s', method: '%s', loc: %d, depth: %d }",
-          this.thr,
-          this.method,
-          this.current_location,
-          this.depth);
-    }
-  }
-
-  public static native int GetStackDepth(Thread thr);
-
-  private static native StackFrameData[] nativeGetStackTrace(Thread thr);
-
-  public static StackFrameData[] GetStackTrace(Thread thr) {
-    // The RI seems to give inconsistent (and sometimes nonsensical) results if the thread is not
-    // suspended. The spec says that not being suspended is fine but since we want this to be
-    // consistent we will suspend for the RI.
-    boolean suspend_thread =
-        !System.getProperty("java.vm.name").equals("Dalvik") &&
-        !thr.equals(Thread.currentThread()) &&
-        !Suspension.isSuspended(thr);
-    if (suspend_thread) {
-      Suspension.suspend(thr);
-    }
-    StackFrameData[] out = nativeGetStackTrace(thr);
-    if (suspend_thread) {
-      Suspension.resume(thr);
-    }
-    return out;
-  }
-}
-
diff --git a/test/1935-get-set-current-frame-jit/src/art/StackTrace.java b/test/1935-get-set-current-frame-jit/src/art/StackTrace.java
new file mode 120000
index 0000000..e1a08aa
--- /dev/null
+++ b/test/1935-get-set-current-frame-jit/src/art/StackTrace.java
@@ -0,0 +1 @@
+../../../jvmti-common/StackTrace.java
\ No newline at end of file
diff --git a/test/1935-get-set-current-frame-jit/src/art/Suspension.java b/test/1935-get-set-current-frame-jit/src/art/Suspension.java
deleted file mode 100644
index 16e62cc..0000000
--- a/test/1935-get-set-current-frame-jit/src/art/Suspension.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-public class Suspension {
-  // Suspends a thread using jvmti.
-  public native static void suspend(Thread thr);
-
-  // Resumes a thread using jvmti.
-  public native static void resume(Thread thr);
-
-  public native static boolean isSuspended(Thread thr);
-
-  public native static int[] suspendList(Thread... threads);
-  public native static int[] resumeList(Thread... threads);
-}
diff --git a/test/1935-get-set-current-frame-jit/src/art/Suspension.java b/test/1935-get-set-current-frame-jit/src/art/Suspension.java
new file mode 120000
index 0000000..bcef96f
--- /dev/null
+++ b/test/1935-get-set-current-frame-jit/src/art/Suspension.java
@@ -0,0 +1 @@
+../../../jvmti-common/Suspension.java
\ No newline at end of file
diff --git a/test/1936-thread-end-events/src/art/Trace.java b/test/1936-thread-end-events/src/art/Trace.java
deleted file mode 100644
index 8999bb1..0000000
--- a/test/1936-thread-end-events/src/art/Trace.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-
-public class Trace {
-  public static native void enableTracing(Class<?> methodClass,
-                                          Method entryMethod,
-                                          Method exitMethod,
-                                          Method fieldAccess,
-                                          Method fieldModify,
-                                          Method singleStep,
-                                          Thread thr);
-  public static native void disableTracing(Thread thr);
-
-  public static void enableFieldTracing(Class<?> methodClass,
-                                        Method fieldAccess,
-                                        Method fieldModify,
-                                        Thread thr) {
-    enableTracing(methodClass, null, null, fieldAccess, fieldModify, null, thr);
-  }
-
-  public static void enableMethodTracing(Class<?> methodClass,
-                                         Method entryMethod,
-                                         Method exitMethod,
-                                         Thread thr) {
-    enableTracing(methodClass, entryMethod, exitMethod, null, null, null, thr);
-  }
-
-  public static void enableSingleStepTracing(Class<?> methodClass,
-                                             Method singleStep,
-                                             Thread thr) {
-    enableTracing(methodClass, null, null, null, null, singleStep, thr);
-  }
-
-  public static native void watchFieldAccess(Field f);
-  public static native void watchFieldModification(Field f);
-  public static native void watchAllFieldAccesses();
-  public static native void watchAllFieldModifications();
-
-  // the names, arguments, and even line numbers of these functions are embedded in the tests so we
-  // need to add to the bottom and not modify old ones to maintain compat.
-  public static native void enableTracing2(Class<?> methodClass,
-                                           Method entryMethod,
-                                           Method exitMethod,
-                                           Method fieldAccess,
-                                           Method fieldModify,
-                                           Method singleStep,
-                                           Method ThreadStart,
-                                           Method ThreadEnd,
-                                           Thread thr);
-}
diff --git a/test/1936-thread-end-events/src/art/Trace.java b/test/1936-thread-end-events/src/art/Trace.java
new file mode 120000
index 0000000..5d9b44b
--- /dev/null
+++ b/test/1936-thread-end-events/src/art/Trace.java
@@ -0,0 +1 @@
+../../../jvmti-common/Trace.java
\ No newline at end of file
diff --git a/test/1937-transform-soft-fail/src/art/Redefinition.java b/test/1937-transform-soft-fail/src/art/Redefinition.java
deleted file mode 100644
index 56d2938..0000000
--- a/test/1937-transform-soft-fail/src/art/Redefinition.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.util.ArrayList;
-// Common Redefinition functions. Placed here for use by CTS
-public class Redefinition {
-  public static final class CommonClassDefinition {
-    public final Class<?> target;
-    public final byte[] class_file_bytes;
-    public final byte[] dex_file_bytes;
-
-    public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
-      this.target = target;
-      this.class_file_bytes = class_file_bytes;
-      this.dex_file_bytes = dex_file_bytes;
-    }
-  }
-
-  // A set of possible test configurations. Test should set this if they need to.
-  // This must be kept in sync with the defines in ti-agent/common_helper.cc
-  public static enum Config {
-    COMMON_REDEFINE(0),
-    COMMON_RETRANSFORM(1),
-    COMMON_TRANSFORM(2);
-
-    private final int val;
-    private Config(int val) {
-      this.val = val;
-    }
-  }
-
-  public static void setTestConfiguration(Config type) {
-    nativeSetTestConfiguration(type.val);
-  }
-
-  private static native void nativeSetTestConfiguration(int type);
-
-  // Transforms the class
-  public static native void doCommonClassRedefinition(Class<?> target,
-                                                      byte[] classfile,
-                                                      byte[] dexfile);
-
-  public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
-    ArrayList<Class<?>> classes = new ArrayList<>();
-    ArrayList<byte[]> class_files = new ArrayList<>();
-    ArrayList<byte[]> dex_files = new ArrayList<>();
-
-    for (CommonClassDefinition d : defs) {
-      classes.add(d.target);
-      class_files.add(d.class_file_bytes);
-      dex_files.add(d.dex_file_bytes);
-    }
-    doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
-                                   class_files.toArray(new byte[0][]),
-                                   dex_files.toArray(new byte[0][]));
-  }
-
-  public static void addMultiTransformationResults(CommonClassDefinition... defs) {
-    for (CommonClassDefinition d : defs) {
-      addCommonTransformationResult(d.target.getCanonicalName(),
-                                    d.class_file_bytes,
-                                    d.dex_file_bytes);
-    }
-  }
-
-  public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
-                                                           byte[][] classfiles,
-                                                           byte[][] dexfiles);
-  public static native void doCommonClassRetransformation(Class<?>... target);
-  public static native void setPopRetransformations(boolean pop);
-  public static native void popTransformationFor(String name);
-  public static native void enableCommonRetransformation(boolean enable);
-  public static native void addCommonTransformationResult(String target_name,
-                                                          byte[] class_bytes,
-                                                          byte[] dex_bytes);
-}
diff --git a/test/1937-transform-soft-fail/src/art/Redefinition.java b/test/1937-transform-soft-fail/src/art/Redefinition.java
new file mode 120000
index 0000000..81eaf31
--- /dev/null
+++ b/test/1937-transform-soft-fail/src/art/Redefinition.java
@@ -0,0 +1 @@
+../../../jvmti-common/Redefinition.java
\ No newline at end of file
diff --git a/test/1938-transform-abstract-single-impl/src/art/Redefinition.java b/test/1938-transform-abstract-single-impl/src/art/Redefinition.java
deleted file mode 100644
index 56d2938..0000000
--- a/test/1938-transform-abstract-single-impl/src/art/Redefinition.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.util.ArrayList;
-// Common Redefinition functions. Placed here for use by CTS
-public class Redefinition {
-  public static final class CommonClassDefinition {
-    public final Class<?> target;
-    public final byte[] class_file_bytes;
-    public final byte[] dex_file_bytes;
-
-    public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
-      this.target = target;
-      this.class_file_bytes = class_file_bytes;
-      this.dex_file_bytes = dex_file_bytes;
-    }
-  }
-
-  // A set of possible test configurations. Test should set this if they need to.
-  // This must be kept in sync with the defines in ti-agent/common_helper.cc
-  public static enum Config {
-    COMMON_REDEFINE(0),
-    COMMON_RETRANSFORM(1),
-    COMMON_TRANSFORM(2);
-
-    private final int val;
-    private Config(int val) {
-      this.val = val;
-    }
-  }
-
-  public static void setTestConfiguration(Config type) {
-    nativeSetTestConfiguration(type.val);
-  }
-
-  private static native void nativeSetTestConfiguration(int type);
-
-  // Transforms the class
-  public static native void doCommonClassRedefinition(Class<?> target,
-                                                      byte[] classfile,
-                                                      byte[] dexfile);
-
-  public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
-    ArrayList<Class<?>> classes = new ArrayList<>();
-    ArrayList<byte[]> class_files = new ArrayList<>();
-    ArrayList<byte[]> dex_files = new ArrayList<>();
-
-    for (CommonClassDefinition d : defs) {
-      classes.add(d.target);
-      class_files.add(d.class_file_bytes);
-      dex_files.add(d.dex_file_bytes);
-    }
-    doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
-                                   class_files.toArray(new byte[0][]),
-                                   dex_files.toArray(new byte[0][]));
-  }
-
-  public static void addMultiTransformationResults(CommonClassDefinition... defs) {
-    for (CommonClassDefinition d : defs) {
-      addCommonTransformationResult(d.target.getCanonicalName(),
-                                    d.class_file_bytes,
-                                    d.dex_file_bytes);
-    }
-  }
-
-  public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
-                                                           byte[][] classfiles,
-                                                           byte[][] dexfiles);
-  public static native void doCommonClassRetransformation(Class<?>... target);
-  public static native void setPopRetransformations(boolean pop);
-  public static native void popTransformationFor(String name);
-  public static native void enableCommonRetransformation(boolean enable);
-  public static native void addCommonTransformationResult(String target_name,
-                                                          byte[] class_bytes,
-                                                          byte[] dex_bytes);
-}
diff --git a/test/1938-transform-abstract-single-impl/src/art/Redefinition.java b/test/1938-transform-abstract-single-impl/src/art/Redefinition.java
new file mode 120000
index 0000000..81eaf31
--- /dev/null
+++ b/test/1938-transform-abstract-single-impl/src/art/Redefinition.java
@@ -0,0 +1 @@
+../../../jvmti-common/Redefinition.java
\ No newline at end of file
diff --git a/test/1939-proxy-frames/src/art/Breakpoint.java b/test/1939-proxy-frames/src/art/Breakpoint.java
deleted file mode 100644
index bbb89f7..0000000
--- a/test/1939-proxy-frames/src/art/Breakpoint.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Executable;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.Objects;
-
-public class Breakpoint {
-  public static class Manager {
-    public static class BP {
-      public final Executable method;
-      public final long location;
-
-      public BP(Executable method) {
-        this(method, getStartLocation(method));
-      }
-
-      public BP(Executable method, long location) {
-        this.method = method;
-        this.location = location;
-      }
-
-      @Override
-      public boolean equals(Object other) {
-        return (other instanceof BP) &&
-            method.equals(((BP)other).method) &&
-            location == ((BP)other).location;
-      }
-
-      @Override
-      public String toString() {
-        return method.toString() + " @ " + getLine();
-      }
-
-      @Override
-      public int hashCode() {
-        return Objects.hash(method, location);
-      }
-
-      public int getLine() {
-        try {
-          LineNumber[] lines = getLineNumberTable(method);
-          int best = -1;
-          for (LineNumber l : lines) {
-            if (l.location > location) {
-              break;
-            } else {
-              best = l.line;
-            }
-          }
-          return best;
-        } catch (Exception e) {
-          return -1;
-        }
-      }
-    }
-
-    private Set<BP> breaks = new HashSet<>();
-
-    public void setBreakpoints(BP... bs) {
-      for (BP b : bs) {
-        if (breaks.add(b)) {
-          Breakpoint.setBreakpoint(b.method, b.location);
-        }
-      }
-    }
-    public void setBreakpoint(Executable method, long location) {
-      setBreakpoints(new BP(method, location));
-    }
-
-    public void clearBreakpoints(BP... bs) {
-      for (BP b : bs) {
-        if (breaks.remove(b)) {
-          Breakpoint.clearBreakpoint(b.method, b.location);
-        }
-      }
-    }
-    public void clearBreakpoint(Executable method, long location) {
-      clearBreakpoints(new BP(method, location));
-    }
-
-    public void clearAllBreakpoints() {
-      clearBreakpoints(breaks.toArray(new BP[0]));
-    }
-  }
-
-  public static void startBreakpointWatch(Class<?> methodClass,
-                                          Executable breakpointReached,
-                                          Thread thr) {
-    startBreakpointWatch(methodClass, breakpointReached, false, thr);
-  }
-
-  /**
-   * Enables the trapping of breakpoint events.
-   *
-   * If allowRecursive == true then breakpoints will be sent even if one is currently being handled.
-   */
-  public static native void startBreakpointWatch(Class<?> methodClass,
-                                                 Executable breakpointReached,
-                                                 boolean allowRecursive,
-                                                 Thread thr);
-  public static native void stopBreakpointWatch(Thread thr);
-
-  public static final class LineNumber implements Comparable<LineNumber> {
-    public final long location;
-    public final int line;
-
-    private LineNumber(long loc, int line) {
-      this.location = loc;
-      this.line = line;
-    }
-
-    public boolean equals(Object other) {
-      return other instanceof LineNumber && ((LineNumber)other).line == line &&
-          ((LineNumber)other).location == location;
-    }
-
-    public int compareTo(LineNumber other) {
-      int v = Integer.valueOf(line).compareTo(Integer.valueOf(other.line));
-      if (v != 0) {
-        return v;
-      } else {
-        return Long.valueOf(location).compareTo(Long.valueOf(other.location));
-      }
-    }
-  }
-
-  public static native void setBreakpoint(Executable m, long loc);
-  public static void setBreakpoint(Executable m, LineNumber l) {
-    setBreakpoint(m, l.location);
-  }
-
-  public static native void clearBreakpoint(Executable m, long loc);
-  public static void clearBreakpoint(Executable m, LineNumber l) {
-    clearBreakpoint(m, l.location);
-  }
-
-  private static native Object[] getLineNumberTableNative(Executable m);
-  public static LineNumber[] getLineNumberTable(Executable m) {
-    Object[] nativeTable = getLineNumberTableNative(m);
-    long[] location = (long[])(nativeTable[0]);
-    int[] lines = (int[])(nativeTable[1]);
-    if (lines.length != location.length) {
-      throw new Error("Lines and locations have different lengths!");
-    }
-    LineNumber[] out = new LineNumber[lines.length];
-    for (int i = 0; i < lines.length; i++) {
-      out[i] = new LineNumber(location[i], lines[i]);
-    }
-    return out;
-  }
-
-  public static native long getStartLocation(Executable m);
-
-  public static int locationToLine(Executable m, long location) {
-    try {
-      Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
-      int best = -1;
-      for (Breakpoint.LineNumber l : lines) {
-        if (l.location > location) {
-          break;
-        } else {
-          best = l.line;
-        }
-      }
-      return best;
-    } catch (Exception e) {
-      return -1;
-    }
-  }
-
-  public static long lineToLocation(Executable m, int line) throws Exception {
-    try {
-      Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
-      for (Breakpoint.LineNumber l : lines) {
-        if (l.line == line) {
-          return l.location;
-        }
-      }
-      throw new Exception("Unable to find line " + line + " in " + m);
-    } catch (Exception e) {
-      throw new Exception("Unable to get line number info for " + m, e);
-    }
-  }
-}
-
diff --git a/test/1939-proxy-frames/src/art/Breakpoint.java b/test/1939-proxy-frames/src/art/Breakpoint.java
new file mode 120000
index 0000000..3673916
--- /dev/null
+++ b/test/1939-proxy-frames/src/art/Breakpoint.java
@@ -0,0 +1 @@
+../../../jvmti-common/Breakpoint.java
\ No newline at end of file
diff --git a/test/1939-proxy-frames/src/art/Locals.java b/test/1939-proxy-frames/src/art/Locals.java
deleted file mode 100644
index 22e21be..0000000
--- a/test/1939-proxy-frames/src/art/Locals.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Executable;
-import java.util.Objects;
-
-public class Locals {
-  public static native void EnableLocalVariableAccess();
-
-  public static class VariableDescription {
-    public final long start_location;
-    public final int length;
-    public final String name;
-    public final String signature;
-    public final String generic_signature;
-    public final int slot;
-
-    public VariableDescription(
-        long start, int length, String name, String sig, String gen_sig, int slot) {
-      this.start_location = start;
-      this.length = length;
-      this.name = name;
-      this.signature = sig;
-      this.generic_signature = gen_sig;
-      this.slot = slot;
-    }
-
-    @Override
-    public String toString() {
-      return String.format(
-          "VariableDescription { " +
-            "Sig: '%s', Name: '%s', Gen_sig: '%s', slot: %d, start: %d, len: %d" +
-          "}",
-          this.signature,
-          this.name,
-          this.generic_signature,
-          this.slot,
-          this.start_location,
-          this.length);
-    }
-    public boolean equals(Object other) {
-      if (!(other instanceof VariableDescription)) {
-        return false;
-      } else {
-        VariableDescription v = (VariableDescription)other;
-        return Objects.equals(v.signature, signature) &&
-            Objects.equals(v.name, name) &&
-            Objects.equals(v.generic_signature, generic_signature) &&
-            v.slot == slot &&
-            v.start_location == start_location &&
-            v.length == length;
-      }
-    }
-    public int hashCode() {
-      return Objects.hash(this.signature, this.name, this.generic_signature, this.slot,
-          this.start_location, this.length);
-    }
-  }
-
-  public static native VariableDescription[] GetLocalVariableTable(Executable e);
-
-  public static VariableDescription GetVariableAtLine(
-      Executable e, String name, String sig, int line) throws Exception {
-    return GetVariableAtLocation(e, name, sig, Breakpoint.lineToLocation(e, line));
-  }
-
-  public static VariableDescription GetVariableAtLocation(
-      Executable e, String name, String sig, long loc) {
-    VariableDescription[] vars = GetLocalVariableTable(e);
-    for (VariableDescription var : vars) {
-      if (var.start_location <= loc &&
-          var.length + var.start_location > loc &&
-          var.name.equals(name) &&
-          var.signature.equals(sig)) {
-        return var;
-      }
-    }
-    throw new Error(
-        "Unable to find variable " + name + " (sig: " + sig + ") in " + e + " at loc " + loc);
-  }
-
-  public static native int GetLocalVariableInt(Thread thr, int depth, int slot);
-  public static native long GetLocalVariableLong(Thread thr, int depth, int slot);
-  public static native float GetLocalVariableFloat(Thread thr, int depth, int slot);
-  public static native double GetLocalVariableDouble(Thread thr, int depth, int slot);
-  public static native Object GetLocalVariableObject(Thread thr, int depth, int slot);
-  public static native Object GetLocalInstance(Thread thr, int depth);
-
-  public static void SetLocalVariableInt(Thread thr, int depth, int slot, Object val) {
-    SetLocalVariableInt(thr, depth, slot, ((Number)val).intValue());
-  }
-  public static void SetLocalVariableLong(Thread thr, int depth, int slot, Object val) {
-    SetLocalVariableLong(thr, depth, slot, ((Number)val).longValue());
-  }
-  public static void SetLocalVariableFloat(Thread thr, int depth, int slot, Object val) {
-    SetLocalVariableFloat(thr, depth, slot, ((Number)val).floatValue());
-  }
-  public static void SetLocalVariableDouble(Thread thr, int depth, int slot, Object val) {
-    SetLocalVariableDouble(thr, depth, slot, ((Number)val).doubleValue());
-  }
-  public static native void SetLocalVariableInt(Thread thr, int depth, int slot, int val);
-  public static native void SetLocalVariableLong(Thread thr, int depth, int slot, long val);
-  public static native void SetLocalVariableFloat(Thread thr, int depth, int slot, float val);
-  public static native void SetLocalVariableDouble(Thread thr, int depth, int slot, double val);
-  public static native void SetLocalVariableObject(Thread thr, int depth, int slot, Object val);
-}
diff --git a/test/1939-proxy-frames/src/art/Locals.java b/test/1939-proxy-frames/src/art/Locals.java
new file mode 120000
index 0000000..2998386
--- /dev/null
+++ b/test/1939-proxy-frames/src/art/Locals.java
@@ -0,0 +1 @@
+../../../jvmti-common/Locals.java
\ No newline at end of file
diff --git a/test/1939-proxy-frames/src/art/StackTrace.java b/test/1939-proxy-frames/src/art/StackTrace.java
deleted file mode 100644
index 2ea2f20..0000000
--- a/test/1939-proxy-frames/src/art/StackTrace.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Executable;
-
-public class StackTrace {
-  public static class StackFrameData {
-    public final Thread thr;
-    public final Executable method;
-    public final long current_location;
-    public final int depth;
-
-    public StackFrameData(Thread thr, Executable e, long loc, int depth) {
-      this.thr = thr;
-      this.method = e;
-      this.current_location = loc;
-      this.depth = depth;
-    }
-    @Override
-    public String toString() {
-      return String.format(
-          "StackFrameData { thr: '%s', method: '%s', loc: %d, depth: %d }",
-          this.thr,
-          this.method,
-          this.current_location,
-          this.depth);
-    }
-  }
-
-  public static native int GetStackDepth(Thread thr);
-
-  private static native StackFrameData[] nativeGetStackTrace(Thread thr);
-
-  public static StackFrameData[] GetStackTrace(Thread thr) {
-    // The RI seems to give inconsistent (and sometimes nonsensical) results if the thread is not
-    // suspended. The spec says that not being suspended is fine but since we want this to be
-    // consistent we will suspend for the RI.
-    boolean suspend_thread =
-        !System.getProperty("java.vm.name").equals("Dalvik") &&
-        !thr.equals(Thread.currentThread()) &&
-        !Suspension.isSuspended(thr);
-    if (suspend_thread) {
-      Suspension.suspend(thr);
-    }
-    StackFrameData[] out = nativeGetStackTrace(thr);
-    if (suspend_thread) {
-      Suspension.resume(thr);
-    }
-    return out;
-  }
-}
-
diff --git a/test/1939-proxy-frames/src/art/StackTrace.java b/test/1939-proxy-frames/src/art/StackTrace.java
new file mode 120000
index 0000000..e1a08aa
--- /dev/null
+++ b/test/1939-proxy-frames/src/art/StackTrace.java
@@ -0,0 +1 @@
+../../../jvmti-common/StackTrace.java
\ No newline at end of file
diff --git a/test/1939-proxy-frames/src/art/Suspension.java b/test/1939-proxy-frames/src/art/Suspension.java
deleted file mode 100644
index 16e62cc..0000000
--- a/test/1939-proxy-frames/src/art/Suspension.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-public class Suspension {
-  // Suspends a thread using jvmti.
-  public native static void suspend(Thread thr);
-
-  // Resumes a thread using jvmti.
-  public native static void resume(Thread thr);
-
-  public native static boolean isSuspended(Thread thr);
-
-  public native static int[] suspendList(Thread... threads);
-  public native static int[] resumeList(Thread... threads);
-}
diff --git a/test/1939-proxy-frames/src/art/Suspension.java b/test/1939-proxy-frames/src/art/Suspension.java
new file mode 120000
index 0000000..bcef96f
--- /dev/null
+++ b/test/1939-proxy-frames/src/art/Suspension.java
@@ -0,0 +1 @@
+../../../jvmti-common/Suspension.java
\ No newline at end of file
diff --git a/test/1941-dispose-stress/src/art/Breakpoint.java b/test/1941-dispose-stress/src/art/Breakpoint.java
deleted file mode 100644
index bbb89f7..0000000
--- a/test/1941-dispose-stress/src/art/Breakpoint.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Executable;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.Objects;
-
-public class Breakpoint {
-  public static class Manager {
-    public static class BP {
-      public final Executable method;
-      public final long location;
-
-      public BP(Executable method) {
-        this(method, getStartLocation(method));
-      }
-
-      public BP(Executable method, long location) {
-        this.method = method;
-        this.location = location;
-      }
-
-      @Override
-      public boolean equals(Object other) {
-        return (other instanceof BP) &&
-            method.equals(((BP)other).method) &&
-            location == ((BP)other).location;
-      }
-
-      @Override
-      public String toString() {
-        return method.toString() + " @ " + getLine();
-      }
-
-      @Override
-      public int hashCode() {
-        return Objects.hash(method, location);
-      }
-
-      public int getLine() {
-        try {
-          LineNumber[] lines = getLineNumberTable(method);
-          int best = -1;
-          for (LineNumber l : lines) {
-            if (l.location > location) {
-              break;
-            } else {
-              best = l.line;
-            }
-          }
-          return best;
-        } catch (Exception e) {
-          return -1;
-        }
-      }
-    }
-
-    private Set<BP> breaks = new HashSet<>();
-
-    public void setBreakpoints(BP... bs) {
-      for (BP b : bs) {
-        if (breaks.add(b)) {
-          Breakpoint.setBreakpoint(b.method, b.location);
-        }
-      }
-    }
-    public void setBreakpoint(Executable method, long location) {
-      setBreakpoints(new BP(method, location));
-    }
-
-    public void clearBreakpoints(BP... bs) {
-      for (BP b : bs) {
-        if (breaks.remove(b)) {
-          Breakpoint.clearBreakpoint(b.method, b.location);
-        }
-      }
-    }
-    public void clearBreakpoint(Executable method, long location) {
-      clearBreakpoints(new BP(method, location));
-    }
-
-    public void clearAllBreakpoints() {
-      clearBreakpoints(breaks.toArray(new BP[0]));
-    }
-  }
-
-  public static void startBreakpointWatch(Class<?> methodClass,
-                                          Executable breakpointReached,
-                                          Thread thr) {
-    startBreakpointWatch(methodClass, breakpointReached, false, thr);
-  }
-
-  /**
-   * Enables the trapping of breakpoint events.
-   *
-   * If allowRecursive == true then breakpoints will be sent even if one is currently being handled.
-   */
-  public static native void startBreakpointWatch(Class<?> methodClass,
-                                                 Executable breakpointReached,
-                                                 boolean allowRecursive,
-                                                 Thread thr);
-  public static native void stopBreakpointWatch(Thread thr);
-
-  public static final class LineNumber implements Comparable<LineNumber> {
-    public final long location;
-    public final int line;
-
-    private LineNumber(long loc, int line) {
-      this.location = loc;
-      this.line = line;
-    }
-
-    public boolean equals(Object other) {
-      return other instanceof LineNumber && ((LineNumber)other).line == line &&
-          ((LineNumber)other).location == location;
-    }
-
-    public int compareTo(LineNumber other) {
-      int v = Integer.valueOf(line).compareTo(Integer.valueOf(other.line));
-      if (v != 0) {
-        return v;
-      } else {
-        return Long.valueOf(location).compareTo(Long.valueOf(other.location));
-      }
-    }
-  }
-
-  public static native void setBreakpoint(Executable m, long loc);
-  public static void setBreakpoint(Executable m, LineNumber l) {
-    setBreakpoint(m, l.location);
-  }
-
-  public static native void clearBreakpoint(Executable m, long loc);
-  public static void clearBreakpoint(Executable m, LineNumber l) {
-    clearBreakpoint(m, l.location);
-  }
-
-  private static native Object[] getLineNumberTableNative(Executable m);
-  public static LineNumber[] getLineNumberTable(Executable m) {
-    Object[] nativeTable = getLineNumberTableNative(m);
-    long[] location = (long[])(nativeTable[0]);
-    int[] lines = (int[])(nativeTable[1]);
-    if (lines.length != location.length) {
-      throw new Error("Lines and locations have different lengths!");
-    }
-    LineNumber[] out = new LineNumber[lines.length];
-    for (int i = 0; i < lines.length; i++) {
-      out[i] = new LineNumber(location[i], lines[i]);
-    }
-    return out;
-  }
-
-  public static native long getStartLocation(Executable m);
-
-  public static int locationToLine(Executable m, long location) {
-    try {
-      Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
-      int best = -1;
-      for (Breakpoint.LineNumber l : lines) {
-        if (l.location > location) {
-          break;
-        } else {
-          best = l.line;
-        }
-      }
-      return best;
-    } catch (Exception e) {
-      return -1;
-    }
-  }
-
-  public static long lineToLocation(Executable m, int line) throws Exception {
-    try {
-      Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
-      for (Breakpoint.LineNumber l : lines) {
-        if (l.line == line) {
-          return l.location;
-        }
-      }
-      throw new Exception("Unable to find line " + line + " in " + m);
-    } catch (Exception e) {
-      throw new Exception("Unable to get line number info for " + m, e);
-    }
-  }
-}
-
diff --git a/test/1941-dispose-stress/src/art/Breakpoint.java b/test/1941-dispose-stress/src/art/Breakpoint.java
new file mode 120000
index 0000000..3673916
--- /dev/null
+++ b/test/1941-dispose-stress/src/art/Breakpoint.java
@@ -0,0 +1 @@
+../../../jvmti-common/Breakpoint.java
\ No newline at end of file
diff --git a/test/1941-dispose-stress/src/art/Trace.java b/test/1941-dispose-stress/src/art/Trace.java
deleted file mode 100644
index 8999bb1..0000000
--- a/test/1941-dispose-stress/src/art/Trace.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-
-public class Trace {
-  public static native void enableTracing(Class<?> methodClass,
-                                          Method entryMethod,
-                                          Method exitMethod,
-                                          Method fieldAccess,
-                                          Method fieldModify,
-                                          Method singleStep,
-                                          Thread thr);
-  public static native void disableTracing(Thread thr);
-
-  public static void enableFieldTracing(Class<?> methodClass,
-                                        Method fieldAccess,
-                                        Method fieldModify,
-                                        Thread thr) {
-    enableTracing(methodClass, null, null, fieldAccess, fieldModify, null, thr);
-  }
-
-  public static void enableMethodTracing(Class<?> methodClass,
-                                         Method entryMethod,
-                                         Method exitMethod,
-                                         Thread thr) {
-    enableTracing(methodClass, entryMethod, exitMethod, null, null, null, thr);
-  }
-
-  public static void enableSingleStepTracing(Class<?> methodClass,
-                                             Method singleStep,
-                                             Thread thr) {
-    enableTracing(methodClass, null, null, null, null, singleStep, thr);
-  }
-
-  public static native void watchFieldAccess(Field f);
-  public static native void watchFieldModification(Field f);
-  public static native void watchAllFieldAccesses();
-  public static native void watchAllFieldModifications();
-
-  // the names, arguments, and even line numbers of these functions are embedded in the tests so we
-  // need to add to the bottom and not modify old ones to maintain compat.
-  public static native void enableTracing2(Class<?> methodClass,
-                                           Method entryMethod,
-                                           Method exitMethod,
-                                           Method fieldAccess,
-                                           Method fieldModify,
-                                           Method singleStep,
-                                           Method ThreadStart,
-                                           Method ThreadEnd,
-                                           Thread thr);
-}
diff --git a/test/1941-dispose-stress/src/art/Trace.java b/test/1941-dispose-stress/src/art/Trace.java
new file mode 120000
index 0000000..5d9b44b
--- /dev/null
+++ b/test/1941-dispose-stress/src/art/Trace.java
@@ -0,0 +1 @@
+../../../jvmti-common/Trace.java
\ No newline at end of file
diff --git a/test/1942-suspend-raw-monitor-exit/src/art/Suspension.java b/test/1942-suspend-raw-monitor-exit/src/art/Suspension.java
deleted file mode 100644
index 16e62cc..0000000
--- a/test/1942-suspend-raw-monitor-exit/src/art/Suspension.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-public class Suspension {
-  // Suspends a thread using jvmti.
-  public native static void suspend(Thread thr);
-
-  // Resumes a thread using jvmti.
-  public native static void resume(Thread thr);
-
-  public native static boolean isSuspended(Thread thr);
-
-  public native static int[] suspendList(Thread... threads);
-  public native static int[] resumeList(Thread... threads);
-}
diff --git a/test/1942-suspend-raw-monitor-exit/src/art/Suspension.java b/test/1942-suspend-raw-monitor-exit/src/art/Suspension.java
new file mode 120000
index 0000000..bcef96f
--- /dev/null
+++ b/test/1942-suspend-raw-monitor-exit/src/art/Suspension.java
@@ -0,0 +1 @@
+../../../jvmti-common/Suspension.java
\ No newline at end of file
diff --git a/test/1943-suspend-raw-monitor-wait/src/art/Suspension.java b/test/1943-suspend-raw-monitor-wait/src/art/Suspension.java
deleted file mode 100644
index 16e62cc..0000000
--- a/test/1943-suspend-raw-monitor-wait/src/art/Suspension.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-public class Suspension {
-  // Suspends a thread using jvmti.
-  public native static void suspend(Thread thr);
-
-  // Resumes a thread using jvmti.
-  public native static void resume(Thread thr);
-
-  public native static boolean isSuspended(Thread thr);
-
-  public native static int[] suspendList(Thread... threads);
-  public native static int[] resumeList(Thread... threads);
-}
diff --git a/test/1943-suspend-raw-monitor-wait/src/art/Suspension.java b/test/1943-suspend-raw-monitor-wait/src/art/Suspension.java
new file mode 120000
index 0000000..bcef96f
--- /dev/null
+++ b/test/1943-suspend-raw-monitor-wait/src/art/Suspension.java
@@ -0,0 +1 @@
+../../../jvmti-common/Suspension.java
\ No newline at end of file
diff --git a/test/1944-sudden-exit/src/art/Trace.java b/test/1944-sudden-exit/src/art/Trace.java
deleted file mode 100644
index 8999bb1..0000000
--- a/test/1944-sudden-exit/src/art/Trace.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-
-public class Trace {
-  public static native void enableTracing(Class<?> methodClass,
-                                          Method entryMethod,
-                                          Method exitMethod,
-                                          Method fieldAccess,
-                                          Method fieldModify,
-                                          Method singleStep,
-                                          Thread thr);
-  public static native void disableTracing(Thread thr);
-
-  public static void enableFieldTracing(Class<?> methodClass,
-                                        Method fieldAccess,
-                                        Method fieldModify,
-                                        Thread thr) {
-    enableTracing(methodClass, null, null, fieldAccess, fieldModify, null, thr);
-  }
-
-  public static void enableMethodTracing(Class<?> methodClass,
-                                         Method entryMethod,
-                                         Method exitMethod,
-                                         Thread thr) {
-    enableTracing(methodClass, entryMethod, exitMethod, null, null, null, thr);
-  }
-
-  public static void enableSingleStepTracing(Class<?> methodClass,
-                                             Method singleStep,
-                                             Thread thr) {
-    enableTracing(methodClass, null, null, null, null, singleStep, thr);
-  }
-
-  public static native void watchFieldAccess(Field f);
-  public static native void watchFieldModification(Field f);
-  public static native void watchAllFieldAccesses();
-  public static native void watchAllFieldModifications();
-
-  // the names, arguments, and even line numbers of these functions are embedded in the tests so we
-  // need to add to the bottom and not modify old ones to maintain compat.
-  public static native void enableTracing2(Class<?> methodClass,
-                                           Method entryMethod,
-                                           Method exitMethod,
-                                           Method fieldAccess,
-                                           Method fieldModify,
-                                           Method singleStep,
-                                           Method ThreadStart,
-                                           Method ThreadEnd,
-                                           Thread thr);
-}
diff --git a/test/1944-sudden-exit/src/art/Trace.java b/test/1944-sudden-exit/src/art/Trace.java
new file mode 120000
index 0000000..5d9b44b
--- /dev/null
+++ b/test/1944-sudden-exit/src/art/Trace.java
@@ -0,0 +1 @@
+../../../jvmti-common/Trace.java
\ No newline at end of file
diff --git a/test/1947-breakpoint-redefine-deopt/src/art/Breakpoint.java b/test/1947-breakpoint-redefine-deopt/src/art/Breakpoint.java
deleted file mode 100644
index bbb89f7..0000000
--- a/test/1947-breakpoint-redefine-deopt/src/art/Breakpoint.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Executable;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.Objects;
-
-public class Breakpoint {
-  public static class Manager {
-    public static class BP {
-      public final Executable method;
-      public final long location;
-
-      public BP(Executable method) {
-        this(method, getStartLocation(method));
-      }
-
-      public BP(Executable method, long location) {
-        this.method = method;
-        this.location = location;
-      }
-
-      @Override
-      public boolean equals(Object other) {
-        return (other instanceof BP) &&
-            method.equals(((BP)other).method) &&
-            location == ((BP)other).location;
-      }
-
-      @Override
-      public String toString() {
-        return method.toString() + " @ " + getLine();
-      }
-
-      @Override
-      public int hashCode() {
-        return Objects.hash(method, location);
-      }
-
-      public int getLine() {
-        try {
-          LineNumber[] lines = getLineNumberTable(method);
-          int best = -1;
-          for (LineNumber l : lines) {
-            if (l.location > location) {
-              break;
-            } else {
-              best = l.line;
-            }
-          }
-          return best;
-        } catch (Exception e) {
-          return -1;
-        }
-      }
-    }
-
-    private Set<BP> breaks = new HashSet<>();
-
-    public void setBreakpoints(BP... bs) {
-      for (BP b : bs) {
-        if (breaks.add(b)) {
-          Breakpoint.setBreakpoint(b.method, b.location);
-        }
-      }
-    }
-    public void setBreakpoint(Executable method, long location) {
-      setBreakpoints(new BP(method, location));
-    }
-
-    public void clearBreakpoints(BP... bs) {
-      for (BP b : bs) {
-        if (breaks.remove(b)) {
-          Breakpoint.clearBreakpoint(b.method, b.location);
-        }
-      }
-    }
-    public void clearBreakpoint(Executable method, long location) {
-      clearBreakpoints(new BP(method, location));
-    }
-
-    public void clearAllBreakpoints() {
-      clearBreakpoints(breaks.toArray(new BP[0]));
-    }
-  }
-
-  public static void startBreakpointWatch(Class<?> methodClass,
-                                          Executable breakpointReached,
-                                          Thread thr) {
-    startBreakpointWatch(methodClass, breakpointReached, false, thr);
-  }
-
-  /**
-   * Enables the trapping of breakpoint events.
-   *
-   * If allowRecursive == true then breakpoints will be sent even if one is currently being handled.
-   */
-  public static native void startBreakpointWatch(Class<?> methodClass,
-                                                 Executable breakpointReached,
-                                                 boolean allowRecursive,
-                                                 Thread thr);
-  public static native void stopBreakpointWatch(Thread thr);
-
-  public static final class LineNumber implements Comparable<LineNumber> {
-    public final long location;
-    public final int line;
-
-    private LineNumber(long loc, int line) {
-      this.location = loc;
-      this.line = line;
-    }
-
-    public boolean equals(Object other) {
-      return other instanceof LineNumber && ((LineNumber)other).line == line &&
-          ((LineNumber)other).location == location;
-    }
-
-    public int compareTo(LineNumber other) {
-      int v = Integer.valueOf(line).compareTo(Integer.valueOf(other.line));
-      if (v != 0) {
-        return v;
-      } else {
-        return Long.valueOf(location).compareTo(Long.valueOf(other.location));
-      }
-    }
-  }
-
-  public static native void setBreakpoint(Executable m, long loc);
-  public static void setBreakpoint(Executable m, LineNumber l) {
-    setBreakpoint(m, l.location);
-  }
-
-  public static native void clearBreakpoint(Executable m, long loc);
-  public static void clearBreakpoint(Executable m, LineNumber l) {
-    clearBreakpoint(m, l.location);
-  }
-
-  private static native Object[] getLineNumberTableNative(Executable m);
-  public static LineNumber[] getLineNumberTable(Executable m) {
-    Object[] nativeTable = getLineNumberTableNative(m);
-    long[] location = (long[])(nativeTable[0]);
-    int[] lines = (int[])(nativeTable[1]);
-    if (lines.length != location.length) {
-      throw new Error("Lines and locations have different lengths!");
-    }
-    LineNumber[] out = new LineNumber[lines.length];
-    for (int i = 0; i < lines.length; i++) {
-      out[i] = new LineNumber(location[i], lines[i]);
-    }
-    return out;
-  }
-
-  public static native long getStartLocation(Executable m);
-
-  public static int locationToLine(Executable m, long location) {
-    try {
-      Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
-      int best = -1;
-      for (Breakpoint.LineNumber l : lines) {
-        if (l.location > location) {
-          break;
-        } else {
-          best = l.line;
-        }
-      }
-      return best;
-    } catch (Exception e) {
-      return -1;
-    }
-  }
-
-  public static long lineToLocation(Executable m, int line) throws Exception {
-    try {
-      Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
-      for (Breakpoint.LineNumber l : lines) {
-        if (l.line == line) {
-          return l.location;
-        }
-      }
-      throw new Exception("Unable to find line " + line + " in " + m);
-    } catch (Exception e) {
-      throw new Exception("Unable to get line number info for " + m, e);
-    }
-  }
-}
-
diff --git a/test/1947-breakpoint-redefine-deopt/src/art/Breakpoint.java b/test/1947-breakpoint-redefine-deopt/src/art/Breakpoint.java
new file mode 120000
index 0000000..3673916
--- /dev/null
+++ b/test/1947-breakpoint-redefine-deopt/src/art/Breakpoint.java
@@ -0,0 +1 @@
+../../../jvmti-common/Breakpoint.java
\ No newline at end of file
diff --git a/test/1947-breakpoint-redefine-deopt/src/art/Redefinition.java b/test/1947-breakpoint-redefine-deopt/src/art/Redefinition.java
deleted file mode 100644
index 56d2938..0000000
--- a/test/1947-breakpoint-redefine-deopt/src/art/Redefinition.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.util.ArrayList;
-// Common Redefinition functions. Placed here for use by CTS
-public class Redefinition {
-  public static final class CommonClassDefinition {
-    public final Class<?> target;
-    public final byte[] class_file_bytes;
-    public final byte[] dex_file_bytes;
-
-    public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
-      this.target = target;
-      this.class_file_bytes = class_file_bytes;
-      this.dex_file_bytes = dex_file_bytes;
-    }
-  }
-
-  // A set of possible test configurations. Test should set this if they need to.
-  // This must be kept in sync with the defines in ti-agent/common_helper.cc
-  public static enum Config {
-    COMMON_REDEFINE(0),
-    COMMON_RETRANSFORM(1),
-    COMMON_TRANSFORM(2);
-
-    private final int val;
-    private Config(int val) {
-      this.val = val;
-    }
-  }
-
-  public static void setTestConfiguration(Config type) {
-    nativeSetTestConfiguration(type.val);
-  }
-
-  private static native void nativeSetTestConfiguration(int type);
-
-  // Transforms the class
-  public static native void doCommonClassRedefinition(Class<?> target,
-                                                      byte[] classfile,
-                                                      byte[] dexfile);
-
-  public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
-    ArrayList<Class<?>> classes = new ArrayList<>();
-    ArrayList<byte[]> class_files = new ArrayList<>();
-    ArrayList<byte[]> dex_files = new ArrayList<>();
-
-    for (CommonClassDefinition d : defs) {
-      classes.add(d.target);
-      class_files.add(d.class_file_bytes);
-      dex_files.add(d.dex_file_bytes);
-    }
-    doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
-                                   class_files.toArray(new byte[0][]),
-                                   dex_files.toArray(new byte[0][]));
-  }
-
-  public static void addMultiTransformationResults(CommonClassDefinition... defs) {
-    for (CommonClassDefinition d : defs) {
-      addCommonTransformationResult(d.target.getCanonicalName(),
-                                    d.class_file_bytes,
-                                    d.dex_file_bytes);
-    }
-  }
-
-  public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
-                                                           byte[][] classfiles,
-                                                           byte[][] dexfiles);
-  public static native void doCommonClassRetransformation(Class<?>... target);
-  public static native void setPopRetransformations(boolean pop);
-  public static native void popTransformationFor(String name);
-  public static native void enableCommonRetransformation(boolean enable);
-  public static native void addCommonTransformationResult(String target_name,
-                                                          byte[] class_bytes,
-                                                          byte[] dex_bytes);
-}
diff --git a/test/1947-breakpoint-redefine-deopt/src/art/Redefinition.java b/test/1947-breakpoint-redefine-deopt/src/art/Redefinition.java
new file mode 120000
index 0000000..81eaf31
--- /dev/null
+++ b/test/1947-breakpoint-redefine-deopt/src/art/Redefinition.java
@@ -0,0 +1 @@
+../../../jvmti-common/Redefinition.java
\ No newline at end of file
diff --git a/test/1949-short-dex-file/src/art/Redefinition.java b/test/1949-short-dex-file/src/art/Redefinition.java
deleted file mode 100644
index 56d2938..0000000
--- a/test/1949-short-dex-file/src/art/Redefinition.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.util.ArrayList;
-// Common Redefinition functions. Placed here for use by CTS
-public class Redefinition {
-  public static final class CommonClassDefinition {
-    public final Class<?> target;
-    public final byte[] class_file_bytes;
-    public final byte[] dex_file_bytes;
-
-    public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
-      this.target = target;
-      this.class_file_bytes = class_file_bytes;
-      this.dex_file_bytes = dex_file_bytes;
-    }
-  }
-
-  // A set of possible test configurations. Test should set this if they need to.
-  // This must be kept in sync with the defines in ti-agent/common_helper.cc
-  public static enum Config {
-    COMMON_REDEFINE(0),
-    COMMON_RETRANSFORM(1),
-    COMMON_TRANSFORM(2);
-
-    private final int val;
-    private Config(int val) {
-      this.val = val;
-    }
-  }
-
-  public static void setTestConfiguration(Config type) {
-    nativeSetTestConfiguration(type.val);
-  }
-
-  private static native void nativeSetTestConfiguration(int type);
-
-  // Transforms the class
-  public static native void doCommonClassRedefinition(Class<?> target,
-                                                      byte[] classfile,
-                                                      byte[] dexfile);
-
-  public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
-    ArrayList<Class<?>> classes = new ArrayList<>();
-    ArrayList<byte[]> class_files = new ArrayList<>();
-    ArrayList<byte[]> dex_files = new ArrayList<>();
-
-    for (CommonClassDefinition d : defs) {
-      classes.add(d.target);
-      class_files.add(d.class_file_bytes);
-      dex_files.add(d.dex_file_bytes);
-    }
-    doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
-                                   class_files.toArray(new byte[0][]),
-                                   dex_files.toArray(new byte[0][]));
-  }
-
-  public static void addMultiTransformationResults(CommonClassDefinition... defs) {
-    for (CommonClassDefinition d : defs) {
-      addCommonTransformationResult(d.target.getCanonicalName(),
-                                    d.class_file_bytes,
-                                    d.dex_file_bytes);
-    }
-  }
-
-  public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
-                                                           byte[][] classfiles,
-                                                           byte[][] dexfiles);
-  public static native void doCommonClassRetransformation(Class<?>... target);
-  public static native void setPopRetransformations(boolean pop);
-  public static native void popTransformationFor(String name);
-  public static native void enableCommonRetransformation(boolean enable);
-  public static native void addCommonTransformationResult(String target_name,
-                                                          byte[] class_bytes,
-                                                          byte[] dex_bytes);
-}
diff --git a/test/1949-short-dex-file/src/art/Redefinition.java b/test/1949-short-dex-file/src/art/Redefinition.java
new file mode 120000
index 0000000..81eaf31
--- /dev/null
+++ b/test/1949-short-dex-file/src/art/Redefinition.java
@@ -0,0 +1 @@
+../../../jvmti-common/Redefinition.java
\ No newline at end of file
diff --git a/test/1950-unprepared-transform/src/art/Redefinition.java b/test/1950-unprepared-transform/src/art/Redefinition.java
deleted file mode 100644
index 56d2938..0000000
--- a/test/1950-unprepared-transform/src/art/Redefinition.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.util.ArrayList;
-// Common Redefinition functions. Placed here for use by CTS
-public class Redefinition {
-  public static final class CommonClassDefinition {
-    public final Class<?> target;
-    public final byte[] class_file_bytes;
-    public final byte[] dex_file_bytes;
-
-    public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
-      this.target = target;
-      this.class_file_bytes = class_file_bytes;
-      this.dex_file_bytes = dex_file_bytes;
-    }
-  }
-
-  // A set of possible test configurations. Test should set this if they need to.
-  // This must be kept in sync with the defines in ti-agent/common_helper.cc
-  public static enum Config {
-    COMMON_REDEFINE(0),
-    COMMON_RETRANSFORM(1),
-    COMMON_TRANSFORM(2);
-
-    private final int val;
-    private Config(int val) {
-      this.val = val;
-    }
-  }
-
-  public static void setTestConfiguration(Config type) {
-    nativeSetTestConfiguration(type.val);
-  }
-
-  private static native void nativeSetTestConfiguration(int type);
-
-  // Transforms the class
-  public static native void doCommonClassRedefinition(Class<?> target,
-                                                      byte[] classfile,
-                                                      byte[] dexfile);
-
-  public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
-    ArrayList<Class<?>> classes = new ArrayList<>();
-    ArrayList<byte[]> class_files = new ArrayList<>();
-    ArrayList<byte[]> dex_files = new ArrayList<>();
-
-    for (CommonClassDefinition d : defs) {
-      classes.add(d.target);
-      class_files.add(d.class_file_bytes);
-      dex_files.add(d.dex_file_bytes);
-    }
-    doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
-                                   class_files.toArray(new byte[0][]),
-                                   dex_files.toArray(new byte[0][]));
-  }
-
-  public static void addMultiTransformationResults(CommonClassDefinition... defs) {
-    for (CommonClassDefinition d : defs) {
-      addCommonTransformationResult(d.target.getCanonicalName(),
-                                    d.class_file_bytes,
-                                    d.dex_file_bytes);
-    }
-  }
-
-  public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
-                                                           byte[][] classfiles,
-                                                           byte[][] dexfiles);
-  public static native void doCommonClassRetransformation(Class<?>... target);
-  public static native void setPopRetransformations(boolean pop);
-  public static native void popTransformationFor(String name);
-  public static native void enableCommonRetransformation(boolean enable);
-  public static native void addCommonTransformationResult(String target_name,
-                                                          byte[] class_bytes,
-                                                          byte[] dex_bytes);
-}
diff --git a/test/1950-unprepared-transform/src/art/Redefinition.java b/test/1950-unprepared-transform/src/art/Redefinition.java
new file mode 120000
index 0000000..81eaf31
--- /dev/null
+++ b/test/1950-unprepared-transform/src/art/Redefinition.java
@@ -0,0 +1 @@
+../../../jvmti-common/Redefinition.java
\ No newline at end of file
diff --git a/test/1951-monitor-enter-no-suspend/src/art/Main.java b/test/1951-monitor-enter-no-suspend/src/art/Main.java
deleted file mode 100644
index aa5498b..0000000
--- a/test/1951-monitor-enter-no-suspend/src/art/Main.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-// Binder class so the agent's C code has something that can be bound and exposed to tests.
-// In a package to separate cleanly and work around CTS reference issues (though this class
-// should be replaced in the CTS version).
-public class Main {
-  // Load the given class with the given classloader, and bind all native methods to corresponding
-  // C methods in the agent. Will abort if any of the steps fail.
-  public static native void bindAgentJNI(String className, ClassLoader classLoader);
-  // Same as above, giving the class directly.
-  public static native void bindAgentJNIForClass(Class<?> klass);
-
-  // Common infrastructure.
-  public static native void setTag(Object o, long tag);
-  public static native long getTag(Object o);
-}
diff --git a/test/1951-monitor-enter-no-suspend/src/art/Main.java b/test/1951-monitor-enter-no-suspend/src/art/Main.java
new file mode 120000
index 0000000..84ae4ac
--- /dev/null
+++ b/test/1951-monitor-enter-no-suspend/src/art/Main.java
@@ -0,0 +1 @@
+../../../jvmti-common/Main.java
\ No newline at end of file
diff --git a/test/1951-monitor-enter-no-suspend/src/art/Suspension.java b/test/1951-monitor-enter-no-suspend/src/art/Suspension.java
deleted file mode 100644
index 16e62cc..0000000
--- a/test/1951-monitor-enter-no-suspend/src/art/Suspension.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-public class Suspension {
-  // Suspends a thread using jvmti.
-  public native static void suspend(Thread thr);
-
-  // Resumes a thread using jvmti.
-  public native static void resume(Thread thr);
-
-  public native static boolean isSuspended(Thread thr);
-
-  public native static int[] suspendList(Thread... threads);
-  public native static int[] resumeList(Thread... threads);
-}
diff --git a/test/1951-monitor-enter-no-suspend/src/art/Suspension.java b/test/1951-monitor-enter-no-suspend/src/art/Suspension.java
new file mode 120000
index 0000000..bcef96f
--- /dev/null
+++ b/test/1951-monitor-enter-no-suspend/src/art/Suspension.java
@@ -0,0 +1 @@
+../../../jvmti-common/Suspension.java
\ No newline at end of file
diff --git a/test/1953-pop-frame/src/art/Breakpoint.java b/test/1953-pop-frame/src/art/Breakpoint.java
deleted file mode 100644
index bbb89f7..0000000
--- a/test/1953-pop-frame/src/art/Breakpoint.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Executable;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.Objects;
-
-public class Breakpoint {
-  public static class Manager {
-    public static class BP {
-      public final Executable method;
-      public final long location;
-
-      public BP(Executable method) {
-        this(method, getStartLocation(method));
-      }
-
-      public BP(Executable method, long location) {
-        this.method = method;
-        this.location = location;
-      }
-
-      @Override
-      public boolean equals(Object other) {
-        return (other instanceof BP) &&
-            method.equals(((BP)other).method) &&
-            location == ((BP)other).location;
-      }
-
-      @Override
-      public String toString() {
-        return method.toString() + " @ " + getLine();
-      }
-
-      @Override
-      public int hashCode() {
-        return Objects.hash(method, location);
-      }
-
-      public int getLine() {
-        try {
-          LineNumber[] lines = getLineNumberTable(method);
-          int best = -1;
-          for (LineNumber l : lines) {
-            if (l.location > location) {
-              break;
-            } else {
-              best = l.line;
-            }
-          }
-          return best;
-        } catch (Exception e) {
-          return -1;
-        }
-      }
-    }
-
-    private Set<BP> breaks = new HashSet<>();
-
-    public void setBreakpoints(BP... bs) {
-      for (BP b : bs) {
-        if (breaks.add(b)) {
-          Breakpoint.setBreakpoint(b.method, b.location);
-        }
-      }
-    }
-    public void setBreakpoint(Executable method, long location) {
-      setBreakpoints(new BP(method, location));
-    }
-
-    public void clearBreakpoints(BP... bs) {
-      for (BP b : bs) {
-        if (breaks.remove(b)) {
-          Breakpoint.clearBreakpoint(b.method, b.location);
-        }
-      }
-    }
-    public void clearBreakpoint(Executable method, long location) {
-      clearBreakpoints(new BP(method, location));
-    }
-
-    public void clearAllBreakpoints() {
-      clearBreakpoints(breaks.toArray(new BP[0]));
-    }
-  }
-
-  public static void startBreakpointWatch(Class<?> methodClass,
-                                          Executable breakpointReached,
-                                          Thread thr) {
-    startBreakpointWatch(methodClass, breakpointReached, false, thr);
-  }
-
-  /**
-   * Enables the trapping of breakpoint events.
-   *
-   * If allowRecursive == true then breakpoints will be sent even if one is currently being handled.
-   */
-  public static native void startBreakpointWatch(Class<?> methodClass,
-                                                 Executable breakpointReached,
-                                                 boolean allowRecursive,
-                                                 Thread thr);
-  public static native void stopBreakpointWatch(Thread thr);
-
-  public static final class LineNumber implements Comparable<LineNumber> {
-    public final long location;
-    public final int line;
-
-    private LineNumber(long loc, int line) {
-      this.location = loc;
-      this.line = line;
-    }
-
-    public boolean equals(Object other) {
-      return other instanceof LineNumber && ((LineNumber)other).line == line &&
-          ((LineNumber)other).location == location;
-    }
-
-    public int compareTo(LineNumber other) {
-      int v = Integer.valueOf(line).compareTo(Integer.valueOf(other.line));
-      if (v != 0) {
-        return v;
-      } else {
-        return Long.valueOf(location).compareTo(Long.valueOf(other.location));
-      }
-    }
-  }
-
-  public static native void setBreakpoint(Executable m, long loc);
-  public static void setBreakpoint(Executable m, LineNumber l) {
-    setBreakpoint(m, l.location);
-  }
-
-  public static native void clearBreakpoint(Executable m, long loc);
-  public static void clearBreakpoint(Executable m, LineNumber l) {
-    clearBreakpoint(m, l.location);
-  }
-
-  private static native Object[] getLineNumberTableNative(Executable m);
-  public static LineNumber[] getLineNumberTable(Executable m) {
-    Object[] nativeTable = getLineNumberTableNative(m);
-    long[] location = (long[])(nativeTable[0]);
-    int[] lines = (int[])(nativeTable[1]);
-    if (lines.length != location.length) {
-      throw new Error("Lines and locations have different lengths!");
-    }
-    LineNumber[] out = new LineNumber[lines.length];
-    for (int i = 0; i < lines.length; i++) {
-      out[i] = new LineNumber(location[i], lines[i]);
-    }
-    return out;
-  }
-
-  public static native long getStartLocation(Executable m);
-
-  public static int locationToLine(Executable m, long location) {
-    try {
-      Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
-      int best = -1;
-      for (Breakpoint.LineNumber l : lines) {
-        if (l.location > location) {
-          break;
-        } else {
-          best = l.line;
-        }
-      }
-      return best;
-    } catch (Exception e) {
-      return -1;
-    }
-  }
-
-  public static long lineToLocation(Executable m, int line) throws Exception {
-    try {
-      Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
-      for (Breakpoint.LineNumber l : lines) {
-        if (l.line == line) {
-          return l.location;
-        }
-      }
-      throw new Exception("Unable to find line " + line + " in " + m);
-    } catch (Exception e) {
-      throw new Exception("Unable to get line number info for " + m, e);
-    }
-  }
-}
-
diff --git a/test/1953-pop-frame/src/art/Breakpoint.java b/test/1953-pop-frame/src/art/Breakpoint.java
new file mode 120000
index 0000000..3673916
--- /dev/null
+++ b/test/1953-pop-frame/src/art/Breakpoint.java
@@ -0,0 +1 @@
+../../../jvmti-common/Breakpoint.java
\ No newline at end of file
diff --git a/test/1953-pop-frame/src/art/Redefinition.java b/test/1953-pop-frame/src/art/Redefinition.java
new file mode 120000
index 0000000..81eaf31
--- /dev/null
+++ b/test/1953-pop-frame/src/art/Redefinition.java
@@ -0,0 +1 @@
+../../../jvmti-common/Redefinition.java
\ No newline at end of file
diff --git a/test/1953-pop-frame/src/art/StackTrace.java b/test/1953-pop-frame/src/art/StackTrace.java
deleted file mode 100644
index 2ea2f20..0000000
--- a/test/1953-pop-frame/src/art/StackTrace.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Executable;
-
-public class StackTrace {
-  public static class StackFrameData {
-    public final Thread thr;
-    public final Executable method;
-    public final long current_location;
-    public final int depth;
-
-    public StackFrameData(Thread thr, Executable e, long loc, int depth) {
-      this.thr = thr;
-      this.method = e;
-      this.current_location = loc;
-      this.depth = depth;
-    }
-    @Override
-    public String toString() {
-      return String.format(
-          "StackFrameData { thr: '%s', method: '%s', loc: %d, depth: %d }",
-          this.thr,
-          this.method,
-          this.current_location,
-          this.depth);
-    }
-  }
-
-  public static native int GetStackDepth(Thread thr);
-
-  private static native StackFrameData[] nativeGetStackTrace(Thread thr);
-
-  public static StackFrameData[] GetStackTrace(Thread thr) {
-    // The RI seems to give inconsistent (and sometimes nonsensical) results if the thread is not
-    // suspended. The spec says that not being suspended is fine but since we want this to be
-    // consistent we will suspend for the RI.
-    boolean suspend_thread =
-        !System.getProperty("java.vm.name").equals("Dalvik") &&
-        !thr.equals(Thread.currentThread()) &&
-        !Suspension.isSuspended(thr);
-    if (suspend_thread) {
-      Suspension.suspend(thr);
-    }
-    StackFrameData[] out = nativeGetStackTrace(thr);
-    if (suspend_thread) {
-      Suspension.resume(thr);
-    }
-    return out;
-  }
-}
-
diff --git a/test/1953-pop-frame/src/art/StackTrace.java b/test/1953-pop-frame/src/art/StackTrace.java
new file mode 120000
index 0000000..e1a08aa
--- /dev/null
+++ b/test/1953-pop-frame/src/art/StackTrace.java
@@ -0,0 +1 @@
+../../../jvmti-common/StackTrace.java
\ No newline at end of file
diff --git a/test/1953-pop-frame/src/art/SuspendEvents.java b/test/1953-pop-frame/src/art/SuspendEvents.java
new file mode 120000
index 0000000..f7a5f7e
--- /dev/null
+++ b/test/1953-pop-frame/src/art/SuspendEvents.java
@@ -0,0 +1 @@
+../../../jvmti-common/SuspendEvents.java
\ No newline at end of file
diff --git a/test/1953-pop-frame/src/art/Suspension.java b/test/1953-pop-frame/src/art/Suspension.java
deleted file mode 100644
index 16e62cc..0000000
--- a/test/1953-pop-frame/src/art/Suspension.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-public class Suspension {
-  // Suspends a thread using jvmti.
-  public native static void suspend(Thread thr);
-
-  // Resumes a thread using jvmti.
-  public native static void resume(Thread thr);
-
-  public native static boolean isSuspended(Thread thr);
-
-  public native static int[] suspendList(Thread... threads);
-  public native static int[] resumeList(Thread... threads);
-}
diff --git a/test/1953-pop-frame/src/art/Suspension.java b/test/1953-pop-frame/src/art/Suspension.java
new file mode 120000
index 0000000..bcef96f
--- /dev/null
+++ b/test/1953-pop-frame/src/art/Suspension.java
@@ -0,0 +1 @@
+../../../jvmti-common/Suspension.java
\ No newline at end of file
diff --git a/test/1954-pop-frame-jit/src/art/Breakpoint.java b/test/1954-pop-frame-jit/src/art/Breakpoint.java
deleted file mode 100644
index bbb89f7..0000000
--- a/test/1954-pop-frame-jit/src/art/Breakpoint.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Executable;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.Objects;
-
-public class Breakpoint {
-  public static class Manager {
-    public static class BP {
-      public final Executable method;
-      public final long location;
-
-      public BP(Executable method) {
-        this(method, getStartLocation(method));
-      }
-
-      public BP(Executable method, long location) {
-        this.method = method;
-        this.location = location;
-      }
-
-      @Override
-      public boolean equals(Object other) {
-        return (other instanceof BP) &&
-            method.equals(((BP)other).method) &&
-            location == ((BP)other).location;
-      }
-
-      @Override
-      public String toString() {
-        return method.toString() + " @ " + getLine();
-      }
-
-      @Override
-      public int hashCode() {
-        return Objects.hash(method, location);
-      }
-
-      public int getLine() {
-        try {
-          LineNumber[] lines = getLineNumberTable(method);
-          int best = -1;
-          for (LineNumber l : lines) {
-            if (l.location > location) {
-              break;
-            } else {
-              best = l.line;
-            }
-          }
-          return best;
-        } catch (Exception e) {
-          return -1;
-        }
-      }
-    }
-
-    private Set<BP> breaks = new HashSet<>();
-
-    public void setBreakpoints(BP... bs) {
-      for (BP b : bs) {
-        if (breaks.add(b)) {
-          Breakpoint.setBreakpoint(b.method, b.location);
-        }
-      }
-    }
-    public void setBreakpoint(Executable method, long location) {
-      setBreakpoints(new BP(method, location));
-    }
-
-    public void clearBreakpoints(BP... bs) {
-      for (BP b : bs) {
-        if (breaks.remove(b)) {
-          Breakpoint.clearBreakpoint(b.method, b.location);
-        }
-      }
-    }
-    public void clearBreakpoint(Executable method, long location) {
-      clearBreakpoints(new BP(method, location));
-    }
-
-    public void clearAllBreakpoints() {
-      clearBreakpoints(breaks.toArray(new BP[0]));
-    }
-  }
-
-  public static void startBreakpointWatch(Class<?> methodClass,
-                                          Executable breakpointReached,
-                                          Thread thr) {
-    startBreakpointWatch(methodClass, breakpointReached, false, thr);
-  }
-
-  /**
-   * Enables the trapping of breakpoint events.
-   *
-   * If allowRecursive == true then breakpoints will be sent even if one is currently being handled.
-   */
-  public static native void startBreakpointWatch(Class<?> methodClass,
-                                                 Executable breakpointReached,
-                                                 boolean allowRecursive,
-                                                 Thread thr);
-  public static native void stopBreakpointWatch(Thread thr);
-
-  public static final class LineNumber implements Comparable<LineNumber> {
-    public final long location;
-    public final int line;
-
-    private LineNumber(long loc, int line) {
-      this.location = loc;
-      this.line = line;
-    }
-
-    public boolean equals(Object other) {
-      return other instanceof LineNumber && ((LineNumber)other).line == line &&
-          ((LineNumber)other).location == location;
-    }
-
-    public int compareTo(LineNumber other) {
-      int v = Integer.valueOf(line).compareTo(Integer.valueOf(other.line));
-      if (v != 0) {
-        return v;
-      } else {
-        return Long.valueOf(location).compareTo(Long.valueOf(other.location));
-      }
-    }
-  }
-
-  public static native void setBreakpoint(Executable m, long loc);
-  public static void setBreakpoint(Executable m, LineNumber l) {
-    setBreakpoint(m, l.location);
-  }
-
-  public static native void clearBreakpoint(Executable m, long loc);
-  public static void clearBreakpoint(Executable m, LineNumber l) {
-    clearBreakpoint(m, l.location);
-  }
-
-  private static native Object[] getLineNumberTableNative(Executable m);
-  public static LineNumber[] getLineNumberTable(Executable m) {
-    Object[] nativeTable = getLineNumberTableNative(m);
-    long[] location = (long[])(nativeTable[0]);
-    int[] lines = (int[])(nativeTable[1]);
-    if (lines.length != location.length) {
-      throw new Error("Lines and locations have different lengths!");
-    }
-    LineNumber[] out = new LineNumber[lines.length];
-    for (int i = 0; i < lines.length; i++) {
-      out[i] = new LineNumber(location[i], lines[i]);
-    }
-    return out;
-  }
-
-  public static native long getStartLocation(Executable m);
-
-  public static int locationToLine(Executable m, long location) {
-    try {
-      Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
-      int best = -1;
-      for (Breakpoint.LineNumber l : lines) {
-        if (l.location > location) {
-          break;
-        } else {
-          best = l.line;
-        }
-      }
-      return best;
-    } catch (Exception e) {
-      return -1;
-    }
-  }
-
-  public static long lineToLocation(Executable m, int line) throws Exception {
-    try {
-      Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
-      for (Breakpoint.LineNumber l : lines) {
-        if (l.line == line) {
-          return l.location;
-        }
-      }
-      throw new Exception("Unable to find line " + line + " in " + m);
-    } catch (Exception e) {
-      throw new Exception("Unable to get line number info for " + m, e);
-    }
-  }
-}
-
diff --git a/test/1954-pop-frame-jit/src/art/Breakpoint.java b/test/1954-pop-frame-jit/src/art/Breakpoint.java
new file mode 120000
index 0000000..3673916
--- /dev/null
+++ b/test/1954-pop-frame-jit/src/art/Breakpoint.java
@@ -0,0 +1 @@
+../../../jvmti-common/Breakpoint.java
\ No newline at end of file
diff --git a/test/1954-pop-frame-jit/src/art/Redefinition.java b/test/1954-pop-frame-jit/src/art/Redefinition.java
deleted file mode 100644
index 56d2938..0000000
--- a/test/1954-pop-frame-jit/src/art/Redefinition.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.util.ArrayList;
-// Common Redefinition functions. Placed here for use by CTS
-public class Redefinition {
-  public static final class CommonClassDefinition {
-    public final Class<?> target;
-    public final byte[] class_file_bytes;
-    public final byte[] dex_file_bytes;
-
-    public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
-      this.target = target;
-      this.class_file_bytes = class_file_bytes;
-      this.dex_file_bytes = dex_file_bytes;
-    }
-  }
-
-  // A set of possible test configurations. Test should set this if they need to.
-  // This must be kept in sync with the defines in ti-agent/common_helper.cc
-  public static enum Config {
-    COMMON_REDEFINE(0),
-    COMMON_RETRANSFORM(1),
-    COMMON_TRANSFORM(2);
-
-    private final int val;
-    private Config(int val) {
-      this.val = val;
-    }
-  }
-
-  public static void setTestConfiguration(Config type) {
-    nativeSetTestConfiguration(type.val);
-  }
-
-  private static native void nativeSetTestConfiguration(int type);
-
-  // Transforms the class
-  public static native void doCommonClassRedefinition(Class<?> target,
-                                                      byte[] classfile,
-                                                      byte[] dexfile);
-
-  public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
-    ArrayList<Class<?>> classes = new ArrayList<>();
-    ArrayList<byte[]> class_files = new ArrayList<>();
-    ArrayList<byte[]> dex_files = new ArrayList<>();
-
-    for (CommonClassDefinition d : defs) {
-      classes.add(d.target);
-      class_files.add(d.class_file_bytes);
-      dex_files.add(d.dex_file_bytes);
-    }
-    doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
-                                   class_files.toArray(new byte[0][]),
-                                   dex_files.toArray(new byte[0][]));
-  }
-
-  public static void addMultiTransformationResults(CommonClassDefinition... defs) {
-    for (CommonClassDefinition d : defs) {
-      addCommonTransformationResult(d.target.getCanonicalName(),
-                                    d.class_file_bytes,
-                                    d.dex_file_bytes);
-    }
-  }
-
-  public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
-                                                           byte[][] classfiles,
-                                                           byte[][] dexfiles);
-  public static native void doCommonClassRetransformation(Class<?>... target);
-  public static native void setPopRetransformations(boolean pop);
-  public static native void popTransformationFor(String name);
-  public static native void enableCommonRetransformation(boolean enable);
-  public static native void addCommonTransformationResult(String target_name,
-                                                          byte[] class_bytes,
-                                                          byte[] dex_bytes);
-}
diff --git a/test/1954-pop-frame-jit/src/art/Redefinition.java b/test/1954-pop-frame-jit/src/art/Redefinition.java
new file mode 120000
index 0000000..81eaf31
--- /dev/null
+++ b/test/1954-pop-frame-jit/src/art/Redefinition.java
@@ -0,0 +1 @@
+../../../jvmti-common/Redefinition.java
\ No newline at end of file
diff --git a/test/1954-pop-frame-jit/src/art/StackTrace.java b/test/1954-pop-frame-jit/src/art/StackTrace.java
deleted file mode 100644
index 2ea2f20..0000000
--- a/test/1954-pop-frame-jit/src/art/StackTrace.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Executable;
-
-public class StackTrace {
-  public static class StackFrameData {
-    public final Thread thr;
-    public final Executable method;
-    public final long current_location;
-    public final int depth;
-
-    public StackFrameData(Thread thr, Executable e, long loc, int depth) {
-      this.thr = thr;
-      this.method = e;
-      this.current_location = loc;
-      this.depth = depth;
-    }
-    @Override
-    public String toString() {
-      return String.format(
-          "StackFrameData { thr: '%s', method: '%s', loc: %d, depth: %d }",
-          this.thr,
-          this.method,
-          this.current_location,
-          this.depth);
-    }
-  }
-
-  public static native int GetStackDepth(Thread thr);
-
-  private static native StackFrameData[] nativeGetStackTrace(Thread thr);
-
-  public static StackFrameData[] GetStackTrace(Thread thr) {
-    // The RI seems to give inconsistent (and sometimes nonsensical) results if the thread is not
-    // suspended. The spec says that not being suspended is fine but since we want this to be
-    // consistent we will suspend for the RI.
-    boolean suspend_thread =
-        !System.getProperty("java.vm.name").equals("Dalvik") &&
-        !thr.equals(Thread.currentThread()) &&
-        !Suspension.isSuspended(thr);
-    if (suspend_thread) {
-      Suspension.suspend(thr);
-    }
-    StackFrameData[] out = nativeGetStackTrace(thr);
-    if (suspend_thread) {
-      Suspension.resume(thr);
-    }
-    return out;
-  }
-}
-
diff --git a/test/1954-pop-frame-jit/src/art/StackTrace.java b/test/1954-pop-frame-jit/src/art/StackTrace.java
new file mode 120000
index 0000000..e1a08aa
--- /dev/null
+++ b/test/1954-pop-frame-jit/src/art/StackTrace.java
@@ -0,0 +1 @@
+../../../jvmti-common/StackTrace.java
\ No newline at end of file
diff --git a/test/1954-pop-frame-jit/src/art/Suspension.java b/test/1954-pop-frame-jit/src/art/Suspension.java
deleted file mode 100644
index 16e62cc..0000000
--- a/test/1954-pop-frame-jit/src/art/Suspension.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-public class Suspension {
-  // Suspends a thread using jvmti.
-  public native static void suspend(Thread thr);
-
-  // Resumes a thread using jvmti.
-  public native static void resume(Thread thr);
-
-  public native static boolean isSuspended(Thread thr);
-
-  public native static int[] suspendList(Thread... threads);
-  public native static int[] resumeList(Thread... threads);
-}
diff --git a/test/1954-pop-frame-jit/src/art/Suspension.java b/test/1954-pop-frame-jit/src/art/Suspension.java
new file mode 120000
index 0000000..bcef96f
--- /dev/null
+++ b/test/1954-pop-frame-jit/src/art/Suspension.java
@@ -0,0 +1 @@
+../../../jvmti-common/Suspension.java
\ No newline at end of file
diff --git a/test/1955-pop-frame-jit-called/src/art/Breakpoint.java b/test/1955-pop-frame-jit-called/src/art/Breakpoint.java
deleted file mode 100644
index bbb89f7..0000000
--- a/test/1955-pop-frame-jit-called/src/art/Breakpoint.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Executable;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.Objects;
-
-public class Breakpoint {
-  public static class Manager {
-    public static class BP {
-      public final Executable method;
-      public final long location;
-
-      public BP(Executable method) {
-        this(method, getStartLocation(method));
-      }
-
-      public BP(Executable method, long location) {
-        this.method = method;
-        this.location = location;
-      }
-
-      @Override
-      public boolean equals(Object other) {
-        return (other instanceof BP) &&
-            method.equals(((BP)other).method) &&
-            location == ((BP)other).location;
-      }
-
-      @Override
-      public String toString() {
-        return method.toString() + " @ " + getLine();
-      }
-
-      @Override
-      public int hashCode() {
-        return Objects.hash(method, location);
-      }
-
-      public int getLine() {
-        try {
-          LineNumber[] lines = getLineNumberTable(method);
-          int best = -1;
-          for (LineNumber l : lines) {
-            if (l.location > location) {
-              break;
-            } else {
-              best = l.line;
-            }
-          }
-          return best;
-        } catch (Exception e) {
-          return -1;
-        }
-      }
-    }
-
-    private Set<BP> breaks = new HashSet<>();
-
-    public void setBreakpoints(BP... bs) {
-      for (BP b : bs) {
-        if (breaks.add(b)) {
-          Breakpoint.setBreakpoint(b.method, b.location);
-        }
-      }
-    }
-    public void setBreakpoint(Executable method, long location) {
-      setBreakpoints(new BP(method, location));
-    }
-
-    public void clearBreakpoints(BP... bs) {
-      for (BP b : bs) {
-        if (breaks.remove(b)) {
-          Breakpoint.clearBreakpoint(b.method, b.location);
-        }
-      }
-    }
-    public void clearBreakpoint(Executable method, long location) {
-      clearBreakpoints(new BP(method, location));
-    }
-
-    public void clearAllBreakpoints() {
-      clearBreakpoints(breaks.toArray(new BP[0]));
-    }
-  }
-
-  public static void startBreakpointWatch(Class<?> methodClass,
-                                          Executable breakpointReached,
-                                          Thread thr) {
-    startBreakpointWatch(methodClass, breakpointReached, false, thr);
-  }
-
-  /**
-   * Enables the trapping of breakpoint events.
-   *
-   * If allowRecursive == true then breakpoints will be sent even if one is currently being handled.
-   */
-  public static native void startBreakpointWatch(Class<?> methodClass,
-                                                 Executable breakpointReached,
-                                                 boolean allowRecursive,
-                                                 Thread thr);
-  public static native void stopBreakpointWatch(Thread thr);
-
-  public static final class LineNumber implements Comparable<LineNumber> {
-    public final long location;
-    public final int line;
-
-    private LineNumber(long loc, int line) {
-      this.location = loc;
-      this.line = line;
-    }
-
-    public boolean equals(Object other) {
-      return other instanceof LineNumber && ((LineNumber)other).line == line &&
-          ((LineNumber)other).location == location;
-    }
-
-    public int compareTo(LineNumber other) {
-      int v = Integer.valueOf(line).compareTo(Integer.valueOf(other.line));
-      if (v != 0) {
-        return v;
-      } else {
-        return Long.valueOf(location).compareTo(Long.valueOf(other.location));
-      }
-    }
-  }
-
-  public static native void setBreakpoint(Executable m, long loc);
-  public static void setBreakpoint(Executable m, LineNumber l) {
-    setBreakpoint(m, l.location);
-  }
-
-  public static native void clearBreakpoint(Executable m, long loc);
-  public static void clearBreakpoint(Executable m, LineNumber l) {
-    clearBreakpoint(m, l.location);
-  }
-
-  private static native Object[] getLineNumberTableNative(Executable m);
-  public static LineNumber[] getLineNumberTable(Executable m) {
-    Object[] nativeTable = getLineNumberTableNative(m);
-    long[] location = (long[])(nativeTable[0]);
-    int[] lines = (int[])(nativeTable[1]);
-    if (lines.length != location.length) {
-      throw new Error("Lines and locations have different lengths!");
-    }
-    LineNumber[] out = new LineNumber[lines.length];
-    for (int i = 0; i < lines.length; i++) {
-      out[i] = new LineNumber(location[i], lines[i]);
-    }
-    return out;
-  }
-
-  public static native long getStartLocation(Executable m);
-
-  public static int locationToLine(Executable m, long location) {
-    try {
-      Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
-      int best = -1;
-      for (Breakpoint.LineNumber l : lines) {
-        if (l.location > location) {
-          break;
-        } else {
-          best = l.line;
-        }
-      }
-      return best;
-    } catch (Exception e) {
-      return -1;
-    }
-  }
-
-  public static long lineToLocation(Executable m, int line) throws Exception {
-    try {
-      Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
-      for (Breakpoint.LineNumber l : lines) {
-        if (l.line == line) {
-          return l.location;
-        }
-      }
-      throw new Exception("Unable to find line " + line + " in " + m);
-    } catch (Exception e) {
-      throw new Exception("Unable to get line number info for " + m, e);
-    }
-  }
-}
-
diff --git a/test/1955-pop-frame-jit-called/src/art/Breakpoint.java b/test/1955-pop-frame-jit-called/src/art/Breakpoint.java
new file mode 120000
index 0000000..3673916
--- /dev/null
+++ b/test/1955-pop-frame-jit-called/src/art/Breakpoint.java
@@ -0,0 +1 @@
+../../../jvmti-common/Breakpoint.java
\ No newline at end of file
diff --git a/test/1955-pop-frame-jit-called/src/art/Redefinition.java b/test/1955-pop-frame-jit-called/src/art/Redefinition.java
deleted file mode 100644
index 56d2938..0000000
--- a/test/1955-pop-frame-jit-called/src/art/Redefinition.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.util.ArrayList;
-// Common Redefinition functions. Placed here for use by CTS
-public class Redefinition {
-  public static final class CommonClassDefinition {
-    public final Class<?> target;
-    public final byte[] class_file_bytes;
-    public final byte[] dex_file_bytes;
-
-    public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
-      this.target = target;
-      this.class_file_bytes = class_file_bytes;
-      this.dex_file_bytes = dex_file_bytes;
-    }
-  }
-
-  // A set of possible test configurations. Test should set this if they need to.
-  // This must be kept in sync with the defines in ti-agent/common_helper.cc
-  public static enum Config {
-    COMMON_REDEFINE(0),
-    COMMON_RETRANSFORM(1),
-    COMMON_TRANSFORM(2);
-
-    private final int val;
-    private Config(int val) {
-      this.val = val;
-    }
-  }
-
-  public static void setTestConfiguration(Config type) {
-    nativeSetTestConfiguration(type.val);
-  }
-
-  private static native void nativeSetTestConfiguration(int type);
-
-  // Transforms the class
-  public static native void doCommonClassRedefinition(Class<?> target,
-                                                      byte[] classfile,
-                                                      byte[] dexfile);
-
-  public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
-    ArrayList<Class<?>> classes = new ArrayList<>();
-    ArrayList<byte[]> class_files = new ArrayList<>();
-    ArrayList<byte[]> dex_files = new ArrayList<>();
-
-    for (CommonClassDefinition d : defs) {
-      classes.add(d.target);
-      class_files.add(d.class_file_bytes);
-      dex_files.add(d.dex_file_bytes);
-    }
-    doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
-                                   class_files.toArray(new byte[0][]),
-                                   dex_files.toArray(new byte[0][]));
-  }
-
-  public static void addMultiTransformationResults(CommonClassDefinition... defs) {
-    for (CommonClassDefinition d : defs) {
-      addCommonTransformationResult(d.target.getCanonicalName(),
-                                    d.class_file_bytes,
-                                    d.dex_file_bytes);
-    }
-  }
-
-  public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
-                                                           byte[][] classfiles,
-                                                           byte[][] dexfiles);
-  public static native void doCommonClassRetransformation(Class<?>... target);
-  public static native void setPopRetransformations(boolean pop);
-  public static native void popTransformationFor(String name);
-  public static native void enableCommonRetransformation(boolean enable);
-  public static native void addCommonTransformationResult(String target_name,
-                                                          byte[] class_bytes,
-                                                          byte[] dex_bytes);
-}
diff --git a/test/1955-pop-frame-jit-called/src/art/Redefinition.java b/test/1955-pop-frame-jit-called/src/art/Redefinition.java
new file mode 120000
index 0000000..81eaf31
--- /dev/null
+++ b/test/1955-pop-frame-jit-called/src/art/Redefinition.java
@@ -0,0 +1 @@
+../../../jvmti-common/Redefinition.java
\ No newline at end of file
diff --git a/test/1955-pop-frame-jit-called/src/art/StackTrace.java b/test/1955-pop-frame-jit-called/src/art/StackTrace.java
deleted file mode 100644
index 2ea2f20..0000000
--- a/test/1955-pop-frame-jit-called/src/art/StackTrace.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Executable;
-
-public class StackTrace {
-  public static class StackFrameData {
-    public final Thread thr;
-    public final Executable method;
-    public final long current_location;
-    public final int depth;
-
-    public StackFrameData(Thread thr, Executable e, long loc, int depth) {
-      this.thr = thr;
-      this.method = e;
-      this.current_location = loc;
-      this.depth = depth;
-    }
-    @Override
-    public String toString() {
-      return String.format(
-          "StackFrameData { thr: '%s', method: '%s', loc: %d, depth: %d }",
-          this.thr,
-          this.method,
-          this.current_location,
-          this.depth);
-    }
-  }
-
-  public static native int GetStackDepth(Thread thr);
-
-  private static native StackFrameData[] nativeGetStackTrace(Thread thr);
-
-  public static StackFrameData[] GetStackTrace(Thread thr) {
-    // The RI seems to give inconsistent (and sometimes nonsensical) results if the thread is not
-    // suspended. The spec says that not being suspended is fine but since we want this to be
-    // consistent we will suspend for the RI.
-    boolean suspend_thread =
-        !System.getProperty("java.vm.name").equals("Dalvik") &&
-        !thr.equals(Thread.currentThread()) &&
-        !Suspension.isSuspended(thr);
-    if (suspend_thread) {
-      Suspension.suspend(thr);
-    }
-    StackFrameData[] out = nativeGetStackTrace(thr);
-    if (suspend_thread) {
-      Suspension.resume(thr);
-    }
-    return out;
-  }
-}
-
diff --git a/test/1955-pop-frame-jit-called/src/art/StackTrace.java b/test/1955-pop-frame-jit-called/src/art/StackTrace.java
new file mode 120000
index 0000000..e1a08aa
--- /dev/null
+++ b/test/1955-pop-frame-jit-called/src/art/StackTrace.java
@@ -0,0 +1 @@
+../../../jvmti-common/StackTrace.java
\ No newline at end of file
diff --git a/test/1955-pop-frame-jit-called/src/art/Suspension.java b/test/1955-pop-frame-jit-called/src/art/Suspension.java
deleted file mode 100644
index 16e62cc..0000000
--- a/test/1955-pop-frame-jit-called/src/art/Suspension.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-public class Suspension {
-  // Suspends a thread using jvmti.
-  public native static void suspend(Thread thr);
-
-  // Resumes a thread using jvmti.
-  public native static void resume(Thread thr);
-
-  public native static boolean isSuspended(Thread thr);
-
-  public native static int[] suspendList(Thread... threads);
-  public native static int[] resumeList(Thread... threads);
-}
diff --git a/test/1955-pop-frame-jit-called/src/art/Suspension.java b/test/1955-pop-frame-jit-called/src/art/Suspension.java
new file mode 120000
index 0000000..bcef96f
--- /dev/null
+++ b/test/1955-pop-frame-jit-called/src/art/Suspension.java
@@ -0,0 +1 @@
+../../../jvmti-common/Suspension.java
\ No newline at end of file
diff --git a/test/1956-pop-frame-jit-calling/src/art/Breakpoint.java b/test/1956-pop-frame-jit-calling/src/art/Breakpoint.java
deleted file mode 100644
index bbb89f7..0000000
--- a/test/1956-pop-frame-jit-calling/src/art/Breakpoint.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Executable;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.Objects;
-
-public class Breakpoint {
-  public static class Manager {
-    public static class BP {
-      public final Executable method;
-      public final long location;
-
-      public BP(Executable method) {
-        this(method, getStartLocation(method));
-      }
-
-      public BP(Executable method, long location) {
-        this.method = method;
-        this.location = location;
-      }
-
-      @Override
-      public boolean equals(Object other) {
-        return (other instanceof BP) &&
-            method.equals(((BP)other).method) &&
-            location == ((BP)other).location;
-      }
-
-      @Override
-      public String toString() {
-        return method.toString() + " @ " + getLine();
-      }
-
-      @Override
-      public int hashCode() {
-        return Objects.hash(method, location);
-      }
-
-      public int getLine() {
-        try {
-          LineNumber[] lines = getLineNumberTable(method);
-          int best = -1;
-          for (LineNumber l : lines) {
-            if (l.location > location) {
-              break;
-            } else {
-              best = l.line;
-            }
-          }
-          return best;
-        } catch (Exception e) {
-          return -1;
-        }
-      }
-    }
-
-    private Set<BP> breaks = new HashSet<>();
-
-    public void setBreakpoints(BP... bs) {
-      for (BP b : bs) {
-        if (breaks.add(b)) {
-          Breakpoint.setBreakpoint(b.method, b.location);
-        }
-      }
-    }
-    public void setBreakpoint(Executable method, long location) {
-      setBreakpoints(new BP(method, location));
-    }
-
-    public void clearBreakpoints(BP... bs) {
-      for (BP b : bs) {
-        if (breaks.remove(b)) {
-          Breakpoint.clearBreakpoint(b.method, b.location);
-        }
-      }
-    }
-    public void clearBreakpoint(Executable method, long location) {
-      clearBreakpoints(new BP(method, location));
-    }
-
-    public void clearAllBreakpoints() {
-      clearBreakpoints(breaks.toArray(new BP[0]));
-    }
-  }
-
-  public static void startBreakpointWatch(Class<?> methodClass,
-                                          Executable breakpointReached,
-                                          Thread thr) {
-    startBreakpointWatch(methodClass, breakpointReached, false, thr);
-  }
-
-  /**
-   * Enables the trapping of breakpoint events.
-   *
-   * If allowRecursive == true then breakpoints will be sent even if one is currently being handled.
-   */
-  public static native void startBreakpointWatch(Class<?> methodClass,
-                                                 Executable breakpointReached,
-                                                 boolean allowRecursive,
-                                                 Thread thr);
-  public static native void stopBreakpointWatch(Thread thr);
-
-  public static final class LineNumber implements Comparable<LineNumber> {
-    public final long location;
-    public final int line;
-
-    private LineNumber(long loc, int line) {
-      this.location = loc;
-      this.line = line;
-    }
-
-    public boolean equals(Object other) {
-      return other instanceof LineNumber && ((LineNumber)other).line == line &&
-          ((LineNumber)other).location == location;
-    }
-
-    public int compareTo(LineNumber other) {
-      int v = Integer.valueOf(line).compareTo(Integer.valueOf(other.line));
-      if (v != 0) {
-        return v;
-      } else {
-        return Long.valueOf(location).compareTo(Long.valueOf(other.location));
-      }
-    }
-  }
-
-  public static native void setBreakpoint(Executable m, long loc);
-  public static void setBreakpoint(Executable m, LineNumber l) {
-    setBreakpoint(m, l.location);
-  }
-
-  public static native void clearBreakpoint(Executable m, long loc);
-  public static void clearBreakpoint(Executable m, LineNumber l) {
-    clearBreakpoint(m, l.location);
-  }
-
-  private static native Object[] getLineNumberTableNative(Executable m);
-  public static LineNumber[] getLineNumberTable(Executable m) {
-    Object[] nativeTable = getLineNumberTableNative(m);
-    long[] location = (long[])(nativeTable[0]);
-    int[] lines = (int[])(nativeTable[1]);
-    if (lines.length != location.length) {
-      throw new Error("Lines and locations have different lengths!");
-    }
-    LineNumber[] out = new LineNumber[lines.length];
-    for (int i = 0; i < lines.length; i++) {
-      out[i] = new LineNumber(location[i], lines[i]);
-    }
-    return out;
-  }
-
-  public static native long getStartLocation(Executable m);
-
-  public static int locationToLine(Executable m, long location) {
-    try {
-      Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
-      int best = -1;
-      for (Breakpoint.LineNumber l : lines) {
-        if (l.location > location) {
-          break;
-        } else {
-          best = l.line;
-        }
-      }
-      return best;
-    } catch (Exception e) {
-      return -1;
-    }
-  }
-
-  public static long lineToLocation(Executable m, int line) throws Exception {
-    try {
-      Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
-      for (Breakpoint.LineNumber l : lines) {
-        if (l.line == line) {
-          return l.location;
-        }
-      }
-      throw new Exception("Unable to find line " + line + " in " + m);
-    } catch (Exception e) {
-      throw new Exception("Unable to get line number info for " + m, e);
-    }
-  }
-}
-
diff --git a/test/1956-pop-frame-jit-calling/src/art/Breakpoint.java b/test/1956-pop-frame-jit-calling/src/art/Breakpoint.java
new file mode 120000
index 0000000..3673916
--- /dev/null
+++ b/test/1956-pop-frame-jit-calling/src/art/Breakpoint.java
@@ -0,0 +1 @@
+../../../jvmti-common/Breakpoint.java
\ No newline at end of file
diff --git a/test/1956-pop-frame-jit-calling/src/art/Redefinition.java b/test/1956-pop-frame-jit-calling/src/art/Redefinition.java
deleted file mode 100644
index 56d2938..0000000
--- a/test/1956-pop-frame-jit-calling/src/art/Redefinition.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.util.ArrayList;
-// Common Redefinition functions. Placed here for use by CTS
-public class Redefinition {
-  public static final class CommonClassDefinition {
-    public final Class<?> target;
-    public final byte[] class_file_bytes;
-    public final byte[] dex_file_bytes;
-
-    public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
-      this.target = target;
-      this.class_file_bytes = class_file_bytes;
-      this.dex_file_bytes = dex_file_bytes;
-    }
-  }
-
-  // A set of possible test configurations. Test should set this if they need to.
-  // This must be kept in sync with the defines in ti-agent/common_helper.cc
-  public static enum Config {
-    COMMON_REDEFINE(0),
-    COMMON_RETRANSFORM(1),
-    COMMON_TRANSFORM(2);
-
-    private final int val;
-    private Config(int val) {
-      this.val = val;
-    }
-  }
-
-  public static void setTestConfiguration(Config type) {
-    nativeSetTestConfiguration(type.val);
-  }
-
-  private static native void nativeSetTestConfiguration(int type);
-
-  // Transforms the class
-  public static native void doCommonClassRedefinition(Class<?> target,
-                                                      byte[] classfile,
-                                                      byte[] dexfile);
-
-  public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
-    ArrayList<Class<?>> classes = new ArrayList<>();
-    ArrayList<byte[]> class_files = new ArrayList<>();
-    ArrayList<byte[]> dex_files = new ArrayList<>();
-
-    for (CommonClassDefinition d : defs) {
-      classes.add(d.target);
-      class_files.add(d.class_file_bytes);
-      dex_files.add(d.dex_file_bytes);
-    }
-    doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
-                                   class_files.toArray(new byte[0][]),
-                                   dex_files.toArray(new byte[0][]));
-  }
-
-  public static void addMultiTransformationResults(CommonClassDefinition... defs) {
-    for (CommonClassDefinition d : defs) {
-      addCommonTransformationResult(d.target.getCanonicalName(),
-                                    d.class_file_bytes,
-                                    d.dex_file_bytes);
-    }
-  }
-
-  public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
-                                                           byte[][] classfiles,
-                                                           byte[][] dexfiles);
-  public static native void doCommonClassRetransformation(Class<?>... target);
-  public static native void setPopRetransformations(boolean pop);
-  public static native void popTransformationFor(String name);
-  public static native void enableCommonRetransformation(boolean enable);
-  public static native void addCommonTransformationResult(String target_name,
-                                                          byte[] class_bytes,
-                                                          byte[] dex_bytes);
-}
diff --git a/test/1956-pop-frame-jit-calling/src/art/Redefinition.java b/test/1956-pop-frame-jit-calling/src/art/Redefinition.java
new file mode 120000
index 0000000..81eaf31
--- /dev/null
+++ b/test/1956-pop-frame-jit-calling/src/art/Redefinition.java
@@ -0,0 +1 @@
+../../../jvmti-common/Redefinition.java
\ No newline at end of file
diff --git a/test/1956-pop-frame-jit-calling/src/art/StackTrace.java b/test/1956-pop-frame-jit-calling/src/art/StackTrace.java
deleted file mode 100644
index 2ea2f20..0000000
--- a/test/1956-pop-frame-jit-calling/src/art/StackTrace.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Executable;
-
-public class StackTrace {
-  public static class StackFrameData {
-    public final Thread thr;
-    public final Executable method;
-    public final long current_location;
-    public final int depth;
-
-    public StackFrameData(Thread thr, Executable e, long loc, int depth) {
-      this.thr = thr;
-      this.method = e;
-      this.current_location = loc;
-      this.depth = depth;
-    }
-    @Override
-    public String toString() {
-      return String.format(
-          "StackFrameData { thr: '%s', method: '%s', loc: %d, depth: %d }",
-          this.thr,
-          this.method,
-          this.current_location,
-          this.depth);
-    }
-  }
-
-  public static native int GetStackDepth(Thread thr);
-
-  private static native StackFrameData[] nativeGetStackTrace(Thread thr);
-
-  public static StackFrameData[] GetStackTrace(Thread thr) {
-    // The RI seems to give inconsistent (and sometimes nonsensical) results if the thread is not
-    // suspended. The spec says that not being suspended is fine but since we want this to be
-    // consistent we will suspend for the RI.
-    boolean suspend_thread =
-        !System.getProperty("java.vm.name").equals("Dalvik") &&
-        !thr.equals(Thread.currentThread()) &&
-        !Suspension.isSuspended(thr);
-    if (suspend_thread) {
-      Suspension.suspend(thr);
-    }
-    StackFrameData[] out = nativeGetStackTrace(thr);
-    if (suspend_thread) {
-      Suspension.resume(thr);
-    }
-    return out;
-  }
-}
-
diff --git a/test/1956-pop-frame-jit-calling/src/art/StackTrace.java b/test/1956-pop-frame-jit-calling/src/art/StackTrace.java
new file mode 120000
index 0000000..e1a08aa
--- /dev/null
+++ b/test/1956-pop-frame-jit-calling/src/art/StackTrace.java
@@ -0,0 +1 @@
+../../../jvmti-common/StackTrace.java
\ No newline at end of file
diff --git a/test/1956-pop-frame-jit-calling/src/art/Suspension.java b/test/1956-pop-frame-jit-calling/src/art/Suspension.java
deleted file mode 100644
index 16e62cc..0000000
--- a/test/1956-pop-frame-jit-calling/src/art/Suspension.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-public class Suspension {
-  // Suspends a thread using jvmti.
-  public native static void suspend(Thread thr);
-
-  // Resumes a thread using jvmti.
-  public native static void resume(Thread thr);
-
-  public native static boolean isSuspended(Thread thr);
-
-  public native static int[] suspendList(Thread... threads);
-  public native static int[] resumeList(Thread... threads);
-}
diff --git a/test/1956-pop-frame-jit-calling/src/art/Suspension.java b/test/1956-pop-frame-jit-calling/src/art/Suspension.java
new file mode 120000
index 0000000..bcef96f
--- /dev/null
+++ b/test/1956-pop-frame-jit-calling/src/art/Suspension.java
@@ -0,0 +1 @@
+../../../jvmti-common/Suspension.java
\ No newline at end of file
diff --git a/test/1957-error-ext/src/art/Redefinition.java b/test/1957-error-ext/src/art/Redefinition.java
deleted file mode 100644
index 56d2938..0000000
--- a/test/1957-error-ext/src/art/Redefinition.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.util.ArrayList;
-// Common Redefinition functions. Placed here for use by CTS
-public class Redefinition {
-  public static final class CommonClassDefinition {
-    public final Class<?> target;
-    public final byte[] class_file_bytes;
-    public final byte[] dex_file_bytes;
-
-    public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
-      this.target = target;
-      this.class_file_bytes = class_file_bytes;
-      this.dex_file_bytes = dex_file_bytes;
-    }
-  }
-
-  // A set of possible test configurations. Test should set this if they need to.
-  // This must be kept in sync with the defines in ti-agent/common_helper.cc
-  public static enum Config {
-    COMMON_REDEFINE(0),
-    COMMON_RETRANSFORM(1),
-    COMMON_TRANSFORM(2);
-
-    private final int val;
-    private Config(int val) {
-      this.val = val;
-    }
-  }
-
-  public static void setTestConfiguration(Config type) {
-    nativeSetTestConfiguration(type.val);
-  }
-
-  private static native void nativeSetTestConfiguration(int type);
-
-  // Transforms the class
-  public static native void doCommonClassRedefinition(Class<?> target,
-                                                      byte[] classfile,
-                                                      byte[] dexfile);
-
-  public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
-    ArrayList<Class<?>> classes = new ArrayList<>();
-    ArrayList<byte[]> class_files = new ArrayList<>();
-    ArrayList<byte[]> dex_files = new ArrayList<>();
-
-    for (CommonClassDefinition d : defs) {
-      classes.add(d.target);
-      class_files.add(d.class_file_bytes);
-      dex_files.add(d.dex_file_bytes);
-    }
-    doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
-                                   class_files.toArray(new byte[0][]),
-                                   dex_files.toArray(new byte[0][]));
-  }
-
-  public static void addMultiTransformationResults(CommonClassDefinition... defs) {
-    for (CommonClassDefinition d : defs) {
-      addCommonTransformationResult(d.target.getCanonicalName(),
-                                    d.class_file_bytes,
-                                    d.dex_file_bytes);
-    }
-  }
-
-  public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
-                                                           byte[][] classfiles,
-                                                           byte[][] dexfiles);
-  public static native void doCommonClassRetransformation(Class<?>... target);
-  public static native void setPopRetransformations(boolean pop);
-  public static native void popTransformationFor(String name);
-  public static native void enableCommonRetransformation(boolean enable);
-  public static native void addCommonTransformationResult(String target_name,
-                                                          byte[] class_bytes,
-                                                          byte[] dex_bytes);
-}
diff --git a/test/1957-error-ext/src/art/Redefinition.java b/test/1957-error-ext/src/art/Redefinition.java
new file mode 120000
index 0000000..81eaf31
--- /dev/null
+++ b/test/1957-error-ext/src/art/Redefinition.java
@@ -0,0 +1 @@
+../../../jvmti-common/Redefinition.java
\ No newline at end of file
diff --git a/test/1958-transform-try-jit/src/art/Redefinition.java b/test/1958-transform-try-jit/src/art/Redefinition.java
deleted file mode 100644
index 56d2938..0000000
--- a/test/1958-transform-try-jit/src/art/Redefinition.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.util.ArrayList;
-// Common Redefinition functions. Placed here for use by CTS
-public class Redefinition {
-  public static final class CommonClassDefinition {
-    public final Class<?> target;
-    public final byte[] class_file_bytes;
-    public final byte[] dex_file_bytes;
-
-    public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
-      this.target = target;
-      this.class_file_bytes = class_file_bytes;
-      this.dex_file_bytes = dex_file_bytes;
-    }
-  }
-
-  // A set of possible test configurations. Test should set this if they need to.
-  // This must be kept in sync with the defines in ti-agent/common_helper.cc
-  public static enum Config {
-    COMMON_REDEFINE(0),
-    COMMON_RETRANSFORM(1),
-    COMMON_TRANSFORM(2);
-
-    private final int val;
-    private Config(int val) {
-      this.val = val;
-    }
-  }
-
-  public static void setTestConfiguration(Config type) {
-    nativeSetTestConfiguration(type.val);
-  }
-
-  private static native void nativeSetTestConfiguration(int type);
-
-  // Transforms the class
-  public static native void doCommonClassRedefinition(Class<?> target,
-                                                      byte[] classfile,
-                                                      byte[] dexfile);
-
-  public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
-    ArrayList<Class<?>> classes = new ArrayList<>();
-    ArrayList<byte[]> class_files = new ArrayList<>();
-    ArrayList<byte[]> dex_files = new ArrayList<>();
-
-    for (CommonClassDefinition d : defs) {
-      classes.add(d.target);
-      class_files.add(d.class_file_bytes);
-      dex_files.add(d.dex_file_bytes);
-    }
-    doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
-                                   class_files.toArray(new byte[0][]),
-                                   dex_files.toArray(new byte[0][]));
-  }
-
-  public static void addMultiTransformationResults(CommonClassDefinition... defs) {
-    for (CommonClassDefinition d : defs) {
-      addCommonTransformationResult(d.target.getCanonicalName(),
-                                    d.class_file_bytes,
-                                    d.dex_file_bytes);
-    }
-  }
-
-  public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
-                                                           byte[][] classfiles,
-                                                           byte[][] dexfiles);
-  public static native void doCommonClassRetransformation(Class<?>... target);
-  public static native void setPopRetransformations(boolean pop);
-  public static native void popTransformationFor(String name);
-  public static native void enableCommonRetransformation(boolean enable);
-  public static native void addCommonTransformationResult(String target_name,
-                                                          byte[] class_bytes,
-                                                          byte[] dex_bytes);
-}
diff --git a/test/1958-transform-try-jit/src/art/Redefinition.java b/test/1958-transform-try-jit/src/art/Redefinition.java
new file mode 120000
index 0000000..81eaf31
--- /dev/null
+++ b/test/1958-transform-try-jit/src/art/Redefinition.java
@@ -0,0 +1 @@
+../../../jvmti-common/Redefinition.java
\ No newline at end of file
diff --git a/test/1959-redefine-object-instrument/src/art/Breakpoint.java b/test/1959-redefine-object-instrument/src/art/Breakpoint.java
deleted file mode 100644
index bbb89f7..0000000
--- a/test/1959-redefine-object-instrument/src/art/Breakpoint.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Executable;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.Objects;
-
-public class Breakpoint {
-  public static class Manager {
-    public static class BP {
-      public final Executable method;
-      public final long location;
-
-      public BP(Executable method) {
-        this(method, getStartLocation(method));
-      }
-
-      public BP(Executable method, long location) {
-        this.method = method;
-        this.location = location;
-      }
-
-      @Override
-      public boolean equals(Object other) {
-        return (other instanceof BP) &&
-            method.equals(((BP)other).method) &&
-            location == ((BP)other).location;
-      }
-
-      @Override
-      public String toString() {
-        return method.toString() + " @ " + getLine();
-      }
-
-      @Override
-      public int hashCode() {
-        return Objects.hash(method, location);
-      }
-
-      public int getLine() {
-        try {
-          LineNumber[] lines = getLineNumberTable(method);
-          int best = -1;
-          for (LineNumber l : lines) {
-            if (l.location > location) {
-              break;
-            } else {
-              best = l.line;
-            }
-          }
-          return best;
-        } catch (Exception e) {
-          return -1;
-        }
-      }
-    }
-
-    private Set<BP> breaks = new HashSet<>();
-
-    public void setBreakpoints(BP... bs) {
-      for (BP b : bs) {
-        if (breaks.add(b)) {
-          Breakpoint.setBreakpoint(b.method, b.location);
-        }
-      }
-    }
-    public void setBreakpoint(Executable method, long location) {
-      setBreakpoints(new BP(method, location));
-    }
-
-    public void clearBreakpoints(BP... bs) {
-      for (BP b : bs) {
-        if (breaks.remove(b)) {
-          Breakpoint.clearBreakpoint(b.method, b.location);
-        }
-      }
-    }
-    public void clearBreakpoint(Executable method, long location) {
-      clearBreakpoints(new BP(method, location));
-    }
-
-    public void clearAllBreakpoints() {
-      clearBreakpoints(breaks.toArray(new BP[0]));
-    }
-  }
-
-  public static void startBreakpointWatch(Class<?> methodClass,
-                                          Executable breakpointReached,
-                                          Thread thr) {
-    startBreakpointWatch(methodClass, breakpointReached, false, thr);
-  }
-
-  /**
-   * Enables the trapping of breakpoint events.
-   *
-   * If allowRecursive == true then breakpoints will be sent even if one is currently being handled.
-   */
-  public static native void startBreakpointWatch(Class<?> methodClass,
-                                                 Executable breakpointReached,
-                                                 boolean allowRecursive,
-                                                 Thread thr);
-  public static native void stopBreakpointWatch(Thread thr);
-
-  public static final class LineNumber implements Comparable<LineNumber> {
-    public final long location;
-    public final int line;
-
-    private LineNumber(long loc, int line) {
-      this.location = loc;
-      this.line = line;
-    }
-
-    public boolean equals(Object other) {
-      return other instanceof LineNumber && ((LineNumber)other).line == line &&
-          ((LineNumber)other).location == location;
-    }
-
-    public int compareTo(LineNumber other) {
-      int v = Integer.valueOf(line).compareTo(Integer.valueOf(other.line));
-      if (v != 0) {
-        return v;
-      } else {
-        return Long.valueOf(location).compareTo(Long.valueOf(other.location));
-      }
-    }
-  }
-
-  public static native void setBreakpoint(Executable m, long loc);
-  public static void setBreakpoint(Executable m, LineNumber l) {
-    setBreakpoint(m, l.location);
-  }
-
-  public static native void clearBreakpoint(Executable m, long loc);
-  public static void clearBreakpoint(Executable m, LineNumber l) {
-    clearBreakpoint(m, l.location);
-  }
-
-  private static native Object[] getLineNumberTableNative(Executable m);
-  public static LineNumber[] getLineNumberTable(Executable m) {
-    Object[] nativeTable = getLineNumberTableNative(m);
-    long[] location = (long[])(nativeTable[0]);
-    int[] lines = (int[])(nativeTable[1]);
-    if (lines.length != location.length) {
-      throw new Error("Lines and locations have different lengths!");
-    }
-    LineNumber[] out = new LineNumber[lines.length];
-    for (int i = 0; i < lines.length; i++) {
-      out[i] = new LineNumber(location[i], lines[i]);
-    }
-    return out;
-  }
-
-  public static native long getStartLocation(Executable m);
-
-  public static int locationToLine(Executable m, long location) {
-    try {
-      Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
-      int best = -1;
-      for (Breakpoint.LineNumber l : lines) {
-        if (l.location > location) {
-          break;
-        } else {
-          best = l.line;
-        }
-      }
-      return best;
-    } catch (Exception e) {
-      return -1;
-    }
-  }
-
-  public static long lineToLocation(Executable m, int line) throws Exception {
-    try {
-      Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
-      for (Breakpoint.LineNumber l : lines) {
-        if (l.line == line) {
-          return l.location;
-        }
-      }
-      throw new Exception("Unable to find line " + line + " in " + m);
-    } catch (Exception e) {
-      throw new Exception("Unable to get line number info for " + m, e);
-    }
-  }
-}
-
diff --git a/test/1959-redefine-object-instrument/src/art/Breakpoint.java b/test/1959-redefine-object-instrument/src/art/Breakpoint.java
new file mode 120000
index 0000000..3673916
--- /dev/null
+++ b/test/1959-redefine-object-instrument/src/art/Breakpoint.java
@@ -0,0 +1 @@
+../../../jvmti-common/Breakpoint.java
\ No newline at end of file
diff --git a/test/1960-obsolete-jit-multithread-native/src/art/Redefinition.java b/test/1960-obsolete-jit-multithread-native/src/art/Redefinition.java
deleted file mode 100644
index 56d2938..0000000
--- a/test/1960-obsolete-jit-multithread-native/src/art/Redefinition.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.util.ArrayList;
-// Common Redefinition functions. Placed here for use by CTS
-public class Redefinition {
-  public static final class CommonClassDefinition {
-    public final Class<?> target;
-    public final byte[] class_file_bytes;
-    public final byte[] dex_file_bytes;
-
-    public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
-      this.target = target;
-      this.class_file_bytes = class_file_bytes;
-      this.dex_file_bytes = dex_file_bytes;
-    }
-  }
-
-  // A set of possible test configurations. Test should set this if they need to.
-  // This must be kept in sync with the defines in ti-agent/common_helper.cc
-  public static enum Config {
-    COMMON_REDEFINE(0),
-    COMMON_RETRANSFORM(1),
-    COMMON_TRANSFORM(2);
-
-    private final int val;
-    private Config(int val) {
-      this.val = val;
-    }
-  }
-
-  public static void setTestConfiguration(Config type) {
-    nativeSetTestConfiguration(type.val);
-  }
-
-  private static native void nativeSetTestConfiguration(int type);
-
-  // Transforms the class
-  public static native void doCommonClassRedefinition(Class<?> target,
-                                                      byte[] classfile,
-                                                      byte[] dexfile);
-
-  public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
-    ArrayList<Class<?>> classes = new ArrayList<>();
-    ArrayList<byte[]> class_files = new ArrayList<>();
-    ArrayList<byte[]> dex_files = new ArrayList<>();
-
-    for (CommonClassDefinition d : defs) {
-      classes.add(d.target);
-      class_files.add(d.class_file_bytes);
-      dex_files.add(d.dex_file_bytes);
-    }
-    doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
-                                   class_files.toArray(new byte[0][]),
-                                   dex_files.toArray(new byte[0][]));
-  }
-
-  public static void addMultiTransformationResults(CommonClassDefinition... defs) {
-    for (CommonClassDefinition d : defs) {
-      addCommonTransformationResult(d.target.getCanonicalName(),
-                                    d.class_file_bytes,
-                                    d.dex_file_bytes);
-    }
-  }
-
-  public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
-                                                           byte[][] classfiles,
-                                                           byte[][] dexfiles);
-  public static native void doCommonClassRetransformation(Class<?>... target);
-  public static native void setPopRetransformations(boolean pop);
-  public static native void popTransformationFor(String name);
-  public static native void enableCommonRetransformation(boolean enable);
-  public static native void addCommonTransformationResult(String target_name,
-                                                          byte[] class_bytes,
-                                                          byte[] dex_bytes);
-}
diff --git a/test/1960-obsolete-jit-multithread-native/src/art/Redefinition.java b/test/1960-obsolete-jit-multithread-native/src/art/Redefinition.java
new file mode 120000
index 0000000..81eaf31
--- /dev/null
+++ b/test/1960-obsolete-jit-multithread-native/src/art/Redefinition.java
@@ -0,0 +1 @@
+../../../jvmti-common/Redefinition.java
\ No newline at end of file
diff --git a/test/1961-obsolete-jit-multithread/src/art/Redefinition.java b/test/1961-obsolete-jit-multithread/src/art/Redefinition.java
deleted file mode 100644
index 56d2938..0000000
--- a/test/1961-obsolete-jit-multithread/src/art/Redefinition.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.util.ArrayList;
-// Common Redefinition functions. Placed here for use by CTS
-public class Redefinition {
-  public static final class CommonClassDefinition {
-    public final Class<?> target;
-    public final byte[] class_file_bytes;
-    public final byte[] dex_file_bytes;
-
-    public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
-      this.target = target;
-      this.class_file_bytes = class_file_bytes;
-      this.dex_file_bytes = dex_file_bytes;
-    }
-  }
-
-  // A set of possible test configurations. Test should set this if they need to.
-  // This must be kept in sync with the defines in ti-agent/common_helper.cc
-  public static enum Config {
-    COMMON_REDEFINE(0),
-    COMMON_RETRANSFORM(1),
-    COMMON_TRANSFORM(2);
-
-    private final int val;
-    private Config(int val) {
-      this.val = val;
-    }
-  }
-
-  public static void setTestConfiguration(Config type) {
-    nativeSetTestConfiguration(type.val);
-  }
-
-  private static native void nativeSetTestConfiguration(int type);
-
-  // Transforms the class
-  public static native void doCommonClassRedefinition(Class<?> target,
-                                                      byte[] classfile,
-                                                      byte[] dexfile);
-
-  public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
-    ArrayList<Class<?>> classes = new ArrayList<>();
-    ArrayList<byte[]> class_files = new ArrayList<>();
-    ArrayList<byte[]> dex_files = new ArrayList<>();
-
-    for (CommonClassDefinition d : defs) {
-      classes.add(d.target);
-      class_files.add(d.class_file_bytes);
-      dex_files.add(d.dex_file_bytes);
-    }
-    doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
-                                   class_files.toArray(new byte[0][]),
-                                   dex_files.toArray(new byte[0][]));
-  }
-
-  public static void addMultiTransformationResults(CommonClassDefinition... defs) {
-    for (CommonClassDefinition d : defs) {
-      addCommonTransformationResult(d.target.getCanonicalName(),
-                                    d.class_file_bytes,
-                                    d.dex_file_bytes);
-    }
-  }
-
-  public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
-                                                           byte[][] classfiles,
-                                                           byte[][] dexfiles);
-  public static native void doCommonClassRetransformation(Class<?>... target);
-  public static native void setPopRetransformations(boolean pop);
-  public static native void popTransformationFor(String name);
-  public static native void enableCommonRetransformation(boolean enable);
-  public static native void addCommonTransformationResult(String target_name,
-                                                          byte[] class_bytes,
-                                                          byte[] dex_bytes);
-}
diff --git a/test/1961-obsolete-jit-multithread/src/art/Redefinition.java b/test/1961-obsolete-jit-multithread/src/art/Redefinition.java
new file mode 120000
index 0000000..81eaf31
--- /dev/null
+++ b/test/1961-obsolete-jit-multithread/src/art/Redefinition.java
@@ -0,0 +1 @@
+../../../jvmti-common/Redefinition.java
\ No newline at end of file
diff --git a/test/901-hello-ti-agent/src/art/Main.java b/test/901-hello-ti-agent/src/art/Main.java
deleted file mode 100644
index 8b01920..0000000
--- a/test/901-hello-ti-agent/src/art/Main.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-// Binder class so the agent's C code has something that can be bound and exposed to tests.
-// In a package to separate cleanly and work around CTS reference issues (though this class
-// should be replaced in the CTS version).
-public class Main {
-  // Load the given class with the given classloader, and bind all native methods to corresponding
-  // C methods in the agent. Will abort if any of the steps fail.
-  public static native void bindAgentJNI(String className, ClassLoader classLoader);
-  // Same as above, giving the class directly.
-  public static native void bindAgentJNIForClass(Class<?> klass);
-}
diff --git a/test/901-hello-ti-agent/src/art/Main.java b/test/901-hello-ti-agent/src/art/Main.java
new file mode 120000
index 0000000..84ae4ac
--- /dev/null
+++ b/test/901-hello-ti-agent/src/art/Main.java
@@ -0,0 +1 @@
+../../../jvmti-common/Main.java
\ No newline at end of file
diff --git a/test/902-hello-transformation/src/art/Redefinition.java b/test/902-hello-transformation/src/art/Redefinition.java
deleted file mode 100644
index 56d2938..0000000
--- a/test/902-hello-transformation/src/art/Redefinition.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.util.ArrayList;
-// Common Redefinition functions. Placed here for use by CTS
-public class Redefinition {
-  public static final class CommonClassDefinition {
-    public final Class<?> target;
-    public final byte[] class_file_bytes;
-    public final byte[] dex_file_bytes;
-
-    public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
-      this.target = target;
-      this.class_file_bytes = class_file_bytes;
-      this.dex_file_bytes = dex_file_bytes;
-    }
-  }
-
-  // A set of possible test configurations. Test should set this if they need to.
-  // This must be kept in sync with the defines in ti-agent/common_helper.cc
-  public static enum Config {
-    COMMON_REDEFINE(0),
-    COMMON_RETRANSFORM(1),
-    COMMON_TRANSFORM(2);
-
-    private final int val;
-    private Config(int val) {
-      this.val = val;
-    }
-  }
-
-  public static void setTestConfiguration(Config type) {
-    nativeSetTestConfiguration(type.val);
-  }
-
-  private static native void nativeSetTestConfiguration(int type);
-
-  // Transforms the class
-  public static native void doCommonClassRedefinition(Class<?> target,
-                                                      byte[] classfile,
-                                                      byte[] dexfile);
-
-  public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
-    ArrayList<Class<?>> classes = new ArrayList<>();
-    ArrayList<byte[]> class_files = new ArrayList<>();
-    ArrayList<byte[]> dex_files = new ArrayList<>();
-
-    for (CommonClassDefinition d : defs) {
-      classes.add(d.target);
-      class_files.add(d.class_file_bytes);
-      dex_files.add(d.dex_file_bytes);
-    }
-    doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
-                                   class_files.toArray(new byte[0][]),
-                                   dex_files.toArray(new byte[0][]));
-  }
-
-  public static void addMultiTransformationResults(CommonClassDefinition... defs) {
-    for (CommonClassDefinition d : defs) {
-      addCommonTransformationResult(d.target.getCanonicalName(),
-                                    d.class_file_bytes,
-                                    d.dex_file_bytes);
-    }
-  }
-
-  public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
-                                                           byte[][] classfiles,
-                                                           byte[][] dexfiles);
-  public static native void doCommonClassRetransformation(Class<?>... target);
-  public static native void setPopRetransformations(boolean pop);
-  public static native void popTransformationFor(String name);
-  public static native void enableCommonRetransformation(boolean enable);
-  public static native void addCommonTransformationResult(String target_name,
-                                                          byte[] class_bytes,
-                                                          byte[] dex_bytes);
-}
diff --git a/test/902-hello-transformation/src/art/Redefinition.java b/test/902-hello-transformation/src/art/Redefinition.java
new file mode 120000
index 0000000..81eaf31
--- /dev/null
+++ b/test/902-hello-transformation/src/art/Redefinition.java
@@ -0,0 +1 @@
+../../../jvmti-common/Redefinition.java
\ No newline at end of file
diff --git a/test/903-hello-tagging/src/art/Main.java b/test/903-hello-tagging/src/art/Main.java
deleted file mode 100644
index aa5498b..0000000
--- a/test/903-hello-tagging/src/art/Main.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-// Binder class so the agent's C code has something that can be bound and exposed to tests.
-// In a package to separate cleanly and work around CTS reference issues (though this class
-// should be replaced in the CTS version).
-public class Main {
-  // Load the given class with the given classloader, and bind all native methods to corresponding
-  // C methods in the agent. Will abort if any of the steps fail.
-  public static native void bindAgentJNI(String className, ClassLoader classLoader);
-  // Same as above, giving the class directly.
-  public static native void bindAgentJNIForClass(Class<?> klass);
-
-  // Common infrastructure.
-  public static native void setTag(Object o, long tag);
-  public static native long getTag(Object o);
-}
diff --git a/test/903-hello-tagging/src/art/Main.java b/test/903-hello-tagging/src/art/Main.java
new file mode 120000
index 0000000..84ae4ac
--- /dev/null
+++ b/test/903-hello-tagging/src/art/Main.java
@@ -0,0 +1 @@
+../../../jvmti-common/Main.java
\ No newline at end of file
diff --git a/test/905-object-free/src/art/Main.java b/test/905-object-free/src/art/Main.java
deleted file mode 100644
index aa5498b..0000000
--- a/test/905-object-free/src/art/Main.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-// Binder class so the agent's C code has something that can be bound and exposed to tests.
-// In a package to separate cleanly and work around CTS reference issues (though this class
-// should be replaced in the CTS version).
-public class Main {
-  // Load the given class with the given classloader, and bind all native methods to corresponding
-  // C methods in the agent. Will abort if any of the steps fail.
-  public static native void bindAgentJNI(String className, ClassLoader classLoader);
-  // Same as above, giving the class directly.
-  public static native void bindAgentJNIForClass(Class<?> klass);
-
-  // Common infrastructure.
-  public static native void setTag(Object o, long tag);
-  public static native long getTag(Object o);
-}
diff --git a/test/905-object-free/src/art/Main.java b/test/905-object-free/src/art/Main.java
new file mode 120000
index 0000000..84ae4ac
--- /dev/null
+++ b/test/905-object-free/src/art/Main.java
@@ -0,0 +1 @@
+../../../jvmti-common/Main.java
\ No newline at end of file
diff --git a/test/906-iterate-heap/src/art/Main.java b/test/906-iterate-heap/src/art/Main.java
deleted file mode 100644
index aa5498b..0000000
--- a/test/906-iterate-heap/src/art/Main.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-// Binder class so the agent's C code has something that can be bound and exposed to tests.
-// In a package to separate cleanly and work around CTS reference issues (though this class
-// should be replaced in the CTS version).
-public class Main {
-  // Load the given class with the given classloader, and bind all native methods to corresponding
-  // C methods in the agent. Will abort if any of the steps fail.
-  public static native void bindAgentJNI(String className, ClassLoader classLoader);
-  // Same as above, giving the class directly.
-  public static native void bindAgentJNIForClass(Class<?> klass);
-
-  // Common infrastructure.
-  public static native void setTag(Object o, long tag);
-  public static native long getTag(Object o);
-}
diff --git a/test/906-iterate-heap/src/art/Main.java b/test/906-iterate-heap/src/art/Main.java
new file mode 120000
index 0000000..84ae4ac
--- /dev/null
+++ b/test/906-iterate-heap/src/art/Main.java
@@ -0,0 +1 @@
+../../../jvmti-common/Main.java
\ No newline at end of file
diff --git a/test/913-heaps/src/art/Main.java b/test/913-heaps/src/art/Main.java
new file mode 120000
index 0000000..84ae4ac
--- /dev/null
+++ b/test/913-heaps/src/art/Main.java
@@ -0,0 +1 @@
+../../../jvmti-common/Main.java
\ No newline at end of file
diff --git a/test/914-hello-obsolescence/src/art/Redefinition.java b/test/914-hello-obsolescence/src/art/Redefinition.java
deleted file mode 100644
index 56d2938..0000000
--- a/test/914-hello-obsolescence/src/art/Redefinition.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.util.ArrayList;
-// Common Redefinition functions. Placed here for use by CTS
-public class Redefinition {
-  public static final class CommonClassDefinition {
-    public final Class<?> target;
-    public final byte[] class_file_bytes;
-    public final byte[] dex_file_bytes;
-
-    public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
-      this.target = target;
-      this.class_file_bytes = class_file_bytes;
-      this.dex_file_bytes = dex_file_bytes;
-    }
-  }
-
-  // A set of possible test configurations. Test should set this if they need to.
-  // This must be kept in sync with the defines in ti-agent/common_helper.cc
-  public static enum Config {
-    COMMON_REDEFINE(0),
-    COMMON_RETRANSFORM(1),
-    COMMON_TRANSFORM(2);
-
-    private final int val;
-    private Config(int val) {
-      this.val = val;
-    }
-  }
-
-  public static void setTestConfiguration(Config type) {
-    nativeSetTestConfiguration(type.val);
-  }
-
-  private static native void nativeSetTestConfiguration(int type);
-
-  // Transforms the class
-  public static native void doCommonClassRedefinition(Class<?> target,
-                                                      byte[] classfile,
-                                                      byte[] dexfile);
-
-  public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
-    ArrayList<Class<?>> classes = new ArrayList<>();
-    ArrayList<byte[]> class_files = new ArrayList<>();
-    ArrayList<byte[]> dex_files = new ArrayList<>();
-
-    for (CommonClassDefinition d : defs) {
-      classes.add(d.target);
-      class_files.add(d.class_file_bytes);
-      dex_files.add(d.dex_file_bytes);
-    }
-    doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
-                                   class_files.toArray(new byte[0][]),
-                                   dex_files.toArray(new byte[0][]));
-  }
-
-  public static void addMultiTransformationResults(CommonClassDefinition... defs) {
-    for (CommonClassDefinition d : defs) {
-      addCommonTransformationResult(d.target.getCanonicalName(),
-                                    d.class_file_bytes,
-                                    d.dex_file_bytes);
-    }
-  }
-
-  public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
-                                                           byte[][] classfiles,
-                                                           byte[][] dexfiles);
-  public static native void doCommonClassRetransformation(Class<?>... target);
-  public static native void setPopRetransformations(boolean pop);
-  public static native void popTransformationFor(String name);
-  public static native void enableCommonRetransformation(boolean enable);
-  public static native void addCommonTransformationResult(String target_name,
-                                                          byte[] class_bytes,
-                                                          byte[] dex_bytes);
-}
diff --git a/test/914-hello-obsolescence/src/art/Redefinition.java b/test/914-hello-obsolescence/src/art/Redefinition.java
new file mode 120000
index 0000000..81eaf31
--- /dev/null
+++ b/test/914-hello-obsolescence/src/art/Redefinition.java
@@ -0,0 +1 @@
+../../../jvmti-common/Redefinition.java
\ No newline at end of file
diff --git a/test/915-obsolete-2/src/art/Redefinition.java b/test/915-obsolete-2/src/art/Redefinition.java
deleted file mode 100644
index 56d2938..0000000
--- a/test/915-obsolete-2/src/art/Redefinition.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.util.ArrayList;
-// Common Redefinition functions. Placed here for use by CTS
-public class Redefinition {
-  public static final class CommonClassDefinition {
-    public final Class<?> target;
-    public final byte[] class_file_bytes;
-    public final byte[] dex_file_bytes;
-
-    public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
-      this.target = target;
-      this.class_file_bytes = class_file_bytes;
-      this.dex_file_bytes = dex_file_bytes;
-    }
-  }
-
-  // A set of possible test configurations. Test should set this if they need to.
-  // This must be kept in sync with the defines in ti-agent/common_helper.cc
-  public static enum Config {
-    COMMON_REDEFINE(0),
-    COMMON_RETRANSFORM(1),
-    COMMON_TRANSFORM(2);
-
-    private final int val;
-    private Config(int val) {
-      this.val = val;
-    }
-  }
-
-  public static void setTestConfiguration(Config type) {
-    nativeSetTestConfiguration(type.val);
-  }
-
-  private static native void nativeSetTestConfiguration(int type);
-
-  // Transforms the class
-  public static native void doCommonClassRedefinition(Class<?> target,
-                                                      byte[] classfile,
-                                                      byte[] dexfile);
-
-  public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
-    ArrayList<Class<?>> classes = new ArrayList<>();
-    ArrayList<byte[]> class_files = new ArrayList<>();
-    ArrayList<byte[]> dex_files = new ArrayList<>();
-
-    for (CommonClassDefinition d : defs) {
-      classes.add(d.target);
-      class_files.add(d.class_file_bytes);
-      dex_files.add(d.dex_file_bytes);
-    }
-    doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
-                                   class_files.toArray(new byte[0][]),
-                                   dex_files.toArray(new byte[0][]));
-  }
-
-  public static void addMultiTransformationResults(CommonClassDefinition... defs) {
-    for (CommonClassDefinition d : defs) {
-      addCommonTransformationResult(d.target.getCanonicalName(),
-                                    d.class_file_bytes,
-                                    d.dex_file_bytes);
-    }
-  }
-
-  public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
-                                                           byte[][] classfiles,
-                                                           byte[][] dexfiles);
-  public static native void doCommonClassRetransformation(Class<?>... target);
-  public static native void setPopRetransformations(boolean pop);
-  public static native void popTransformationFor(String name);
-  public static native void enableCommonRetransformation(boolean enable);
-  public static native void addCommonTransformationResult(String target_name,
-                                                          byte[] class_bytes,
-                                                          byte[] dex_bytes);
-}
diff --git a/test/915-obsolete-2/src/art/Redefinition.java b/test/915-obsolete-2/src/art/Redefinition.java
new file mode 120000
index 0000000..81eaf31
--- /dev/null
+++ b/test/915-obsolete-2/src/art/Redefinition.java
@@ -0,0 +1 @@
+../../../jvmti-common/Redefinition.java
\ No newline at end of file
diff --git a/test/916-obsolete-jit/src/art/Redefinition.java b/test/916-obsolete-jit/src/art/Redefinition.java
deleted file mode 100644
index 56d2938..0000000
--- a/test/916-obsolete-jit/src/art/Redefinition.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.util.ArrayList;
-// Common Redefinition functions. Placed here for use by CTS
-public class Redefinition {
-  public static final class CommonClassDefinition {
-    public final Class<?> target;
-    public final byte[] class_file_bytes;
-    public final byte[] dex_file_bytes;
-
-    public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
-      this.target = target;
-      this.class_file_bytes = class_file_bytes;
-      this.dex_file_bytes = dex_file_bytes;
-    }
-  }
-
-  // A set of possible test configurations. Test should set this if they need to.
-  // This must be kept in sync with the defines in ti-agent/common_helper.cc
-  public static enum Config {
-    COMMON_REDEFINE(0),
-    COMMON_RETRANSFORM(1),
-    COMMON_TRANSFORM(2);
-
-    private final int val;
-    private Config(int val) {
-      this.val = val;
-    }
-  }
-
-  public static void setTestConfiguration(Config type) {
-    nativeSetTestConfiguration(type.val);
-  }
-
-  private static native void nativeSetTestConfiguration(int type);
-
-  // Transforms the class
-  public static native void doCommonClassRedefinition(Class<?> target,
-                                                      byte[] classfile,
-                                                      byte[] dexfile);
-
-  public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
-    ArrayList<Class<?>> classes = new ArrayList<>();
-    ArrayList<byte[]> class_files = new ArrayList<>();
-    ArrayList<byte[]> dex_files = new ArrayList<>();
-
-    for (CommonClassDefinition d : defs) {
-      classes.add(d.target);
-      class_files.add(d.class_file_bytes);
-      dex_files.add(d.dex_file_bytes);
-    }
-    doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
-                                   class_files.toArray(new byte[0][]),
-                                   dex_files.toArray(new byte[0][]));
-  }
-
-  public static void addMultiTransformationResults(CommonClassDefinition... defs) {
-    for (CommonClassDefinition d : defs) {
-      addCommonTransformationResult(d.target.getCanonicalName(),
-                                    d.class_file_bytes,
-                                    d.dex_file_bytes);
-    }
-  }
-
-  public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
-                                                           byte[][] classfiles,
-                                                           byte[][] dexfiles);
-  public static native void doCommonClassRetransformation(Class<?>... target);
-  public static native void setPopRetransformations(boolean pop);
-  public static native void popTransformationFor(String name);
-  public static native void enableCommonRetransformation(boolean enable);
-  public static native void addCommonTransformationResult(String target_name,
-                                                          byte[] class_bytes,
-                                                          byte[] dex_bytes);
-}
diff --git a/test/916-obsolete-jit/src/art/Redefinition.java b/test/916-obsolete-jit/src/art/Redefinition.java
new file mode 120000
index 0000000..81eaf31
--- /dev/null
+++ b/test/916-obsolete-jit/src/art/Redefinition.java
@@ -0,0 +1 @@
+../../../jvmti-common/Redefinition.java
\ No newline at end of file
diff --git a/test/917-fields-transformation/src/art/Redefinition.java b/test/917-fields-transformation/src/art/Redefinition.java
deleted file mode 100644
index 56d2938..0000000
--- a/test/917-fields-transformation/src/art/Redefinition.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.util.ArrayList;
-// Common Redefinition functions. Placed here for use by CTS
-public class Redefinition {
-  public static final class CommonClassDefinition {
-    public final Class<?> target;
-    public final byte[] class_file_bytes;
-    public final byte[] dex_file_bytes;
-
-    public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
-      this.target = target;
-      this.class_file_bytes = class_file_bytes;
-      this.dex_file_bytes = dex_file_bytes;
-    }
-  }
-
-  // A set of possible test configurations. Test should set this if they need to.
-  // This must be kept in sync with the defines in ti-agent/common_helper.cc
-  public static enum Config {
-    COMMON_REDEFINE(0),
-    COMMON_RETRANSFORM(1),
-    COMMON_TRANSFORM(2);
-
-    private final int val;
-    private Config(int val) {
-      this.val = val;
-    }
-  }
-
-  public static void setTestConfiguration(Config type) {
-    nativeSetTestConfiguration(type.val);
-  }
-
-  private static native void nativeSetTestConfiguration(int type);
-
-  // Transforms the class
-  public static native void doCommonClassRedefinition(Class<?> target,
-                                                      byte[] classfile,
-                                                      byte[] dexfile);
-
-  public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
-    ArrayList<Class<?>> classes = new ArrayList<>();
-    ArrayList<byte[]> class_files = new ArrayList<>();
-    ArrayList<byte[]> dex_files = new ArrayList<>();
-
-    for (CommonClassDefinition d : defs) {
-      classes.add(d.target);
-      class_files.add(d.class_file_bytes);
-      dex_files.add(d.dex_file_bytes);
-    }
-    doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
-                                   class_files.toArray(new byte[0][]),
-                                   dex_files.toArray(new byte[0][]));
-  }
-
-  public static void addMultiTransformationResults(CommonClassDefinition... defs) {
-    for (CommonClassDefinition d : defs) {
-      addCommonTransformationResult(d.target.getCanonicalName(),
-                                    d.class_file_bytes,
-                                    d.dex_file_bytes);
-    }
-  }
-
-  public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
-                                                           byte[][] classfiles,
-                                                           byte[][] dexfiles);
-  public static native void doCommonClassRetransformation(Class<?>... target);
-  public static native void setPopRetransformations(boolean pop);
-  public static native void popTransformationFor(String name);
-  public static native void enableCommonRetransformation(boolean enable);
-  public static native void addCommonTransformationResult(String target_name,
-                                                          byte[] class_bytes,
-                                                          byte[] dex_bytes);
-}
diff --git a/test/917-fields-transformation/src/art/Redefinition.java b/test/917-fields-transformation/src/art/Redefinition.java
new file mode 120000
index 0000000..81eaf31
--- /dev/null
+++ b/test/917-fields-transformation/src/art/Redefinition.java
@@ -0,0 +1 @@
+../../../jvmti-common/Redefinition.java
\ No newline at end of file
diff --git a/test/919-obsolete-fields/src/art/Redefinition.java b/test/919-obsolete-fields/src/art/Redefinition.java
deleted file mode 100644
index 56d2938..0000000
--- a/test/919-obsolete-fields/src/art/Redefinition.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.util.ArrayList;
-// Common Redefinition functions. Placed here for use by CTS
-public class Redefinition {
-  public static final class CommonClassDefinition {
-    public final Class<?> target;
-    public final byte[] class_file_bytes;
-    public final byte[] dex_file_bytes;
-
-    public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
-      this.target = target;
-      this.class_file_bytes = class_file_bytes;
-      this.dex_file_bytes = dex_file_bytes;
-    }
-  }
-
-  // A set of possible test configurations. Test should set this if they need to.
-  // This must be kept in sync with the defines in ti-agent/common_helper.cc
-  public static enum Config {
-    COMMON_REDEFINE(0),
-    COMMON_RETRANSFORM(1),
-    COMMON_TRANSFORM(2);
-
-    private final int val;
-    private Config(int val) {
-      this.val = val;
-    }
-  }
-
-  public static void setTestConfiguration(Config type) {
-    nativeSetTestConfiguration(type.val);
-  }
-
-  private static native void nativeSetTestConfiguration(int type);
-
-  // Transforms the class
-  public static native void doCommonClassRedefinition(Class<?> target,
-                                                      byte[] classfile,
-                                                      byte[] dexfile);
-
-  public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
-    ArrayList<Class<?>> classes = new ArrayList<>();
-    ArrayList<byte[]> class_files = new ArrayList<>();
-    ArrayList<byte[]> dex_files = new ArrayList<>();
-
-    for (CommonClassDefinition d : defs) {
-      classes.add(d.target);
-      class_files.add(d.class_file_bytes);
-      dex_files.add(d.dex_file_bytes);
-    }
-    doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
-                                   class_files.toArray(new byte[0][]),
-                                   dex_files.toArray(new byte[0][]));
-  }
-
-  public static void addMultiTransformationResults(CommonClassDefinition... defs) {
-    for (CommonClassDefinition d : defs) {
-      addCommonTransformationResult(d.target.getCanonicalName(),
-                                    d.class_file_bytes,
-                                    d.dex_file_bytes);
-    }
-  }
-
-  public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
-                                                           byte[][] classfiles,
-                                                           byte[][] dexfiles);
-  public static native void doCommonClassRetransformation(Class<?>... target);
-  public static native void setPopRetransformations(boolean pop);
-  public static native void popTransformationFor(String name);
-  public static native void enableCommonRetransformation(boolean enable);
-  public static native void addCommonTransformationResult(String target_name,
-                                                          byte[] class_bytes,
-                                                          byte[] dex_bytes);
-}
diff --git a/test/919-obsolete-fields/src/art/Redefinition.java b/test/919-obsolete-fields/src/art/Redefinition.java
new file mode 120000
index 0000000..81eaf31
--- /dev/null
+++ b/test/919-obsolete-fields/src/art/Redefinition.java
@@ -0,0 +1 @@
+../../../jvmti-common/Redefinition.java
\ No newline at end of file
diff --git a/test/921-hello-failure/src/art/Redefinition.java b/test/921-hello-failure/src/art/Redefinition.java
deleted file mode 100644
index 56d2938..0000000
--- a/test/921-hello-failure/src/art/Redefinition.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.util.ArrayList;
-// Common Redefinition functions. Placed here for use by CTS
-public class Redefinition {
-  public static final class CommonClassDefinition {
-    public final Class<?> target;
-    public final byte[] class_file_bytes;
-    public final byte[] dex_file_bytes;
-
-    public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
-      this.target = target;
-      this.class_file_bytes = class_file_bytes;
-      this.dex_file_bytes = dex_file_bytes;
-    }
-  }
-
-  // A set of possible test configurations. Test should set this if they need to.
-  // This must be kept in sync with the defines in ti-agent/common_helper.cc
-  public static enum Config {
-    COMMON_REDEFINE(0),
-    COMMON_RETRANSFORM(1),
-    COMMON_TRANSFORM(2);
-
-    private final int val;
-    private Config(int val) {
-      this.val = val;
-    }
-  }
-
-  public static void setTestConfiguration(Config type) {
-    nativeSetTestConfiguration(type.val);
-  }
-
-  private static native void nativeSetTestConfiguration(int type);
-
-  // Transforms the class
-  public static native void doCommonClassRedefinition(Class<?> target,
-                                                      byte[] classfile,
-                                                      byte[] dexfile);
-
-  public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
-    ArrayList<Class<?>> classes = new ArrayList<>();
-    ArrayList<byte[]> class_files = new ArrayList<>();
-    ArrayList<byte[]> dex_files = new ArrayList<>();
-
-    for (CommonClassDefinition d : defs) {
-      classes.add(d.target);
-      class_files.add(d.class_file_bytes);
-      dex_files.add(d.dex_file_bytes);
-    }
-    doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
-                                   class_files.toArray(new byte[0][]),
-                                   dex_files.toArray(new byte[0][]));
-  }
-
-  public static void addMultiTransformationResults(CommonClassDefinition... defs) {
-    for (CommonClassDefinition d : defs) {
-      addCommonTransformationResult(d.target.getCanonicalName(),
-                                    d.class_file_bytes,
-                                    d.dex_file_bytes);
-    }
-  }
-
-  public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
-                                                           byte[][] classfiles,
-                                                           byte[][] dexfiles);
-  public static native void doCommonClassRetransformation(Class<?>... target);
-  public static native void setPopRetransformations(boolean pop);
-  public static native void popTransformationFor(String name);
-  public static native void enableCommonRetransformation(boolean enable);
-  public static native void addCommonTransformationResult(String target_name,
-                                                          byte[] class_bytes,
-                                                          byte[] dex_bytes);
-}
diff --git a/test/921-hello-failure/src/art/Redefinition.java b/test/921-hello-failure/src/art/Redefinition.java
new file mode 120000
index 0000000..81eaf31
--- /dev/null
+++ b/test/921-hello-failure/src/art/Redefinition.java
@@ -0,0 +1 @@
+../../../jvmti-common/Redefinition.java
\ No newline at end of file
diff --git a/test/926-multi-obsolescence/src/art/Redefinition.java b/test/926-multi-obsolescence/src/art/Redefinition.java
deleted file mode 100644
index 56d2938..0000000
--- a/test/926-multi-obsolescence/src/art/Redefinition.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.util.ArrayList;
-// Common Redefinition functions. Placed here for use by CTS
-public class Redefinition {
-  public static final class CommonClassDefinition {
-    public final Class<?> target;
-    public final byte[] class_file_bytes;
-    public final byte[] dex_file_bytes;
-
-    public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
-      this.target = target;
-      this.class_file_bytes = class_file_bytes;
-      this.dex_file_bytes = dex_file_bytes;
-    }
-  }
-
-  // A set of possible test configurations. Test should set this if they need to.
-  // This must be kept in sync with the defines in ti-agent/common_helper.cc
-  public static enum Config {
-    COMMON_REDEFINE(0),
-    COMMON_RETRANSFORM(1),
-    COMMON_TRANSFORM(2);
-
-    private final int val;
-    private Config(int val) {
-      this.val = val;
-    }
-  }
-
-  public static void setTestConfiguration(Config type) {
-    nativeSetTestConfiguration(type.val);
-  }
-
-  private static native void nativeSetTestConfiguration(int type);
-
-  // Transforms the class
-  public static native void doCommonClassRedefinition(Class<?> target,
-                                                      byte[] classfile,
-                                                      byte[] dexfile);
-
-  public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
-    ArrayList<Class<?>> classes = new ArrayList<>();
-    ArrayList<byte[]> class_files = new ArrayList<>();
-    ArrayList<byte[]> dex_files = new ArrayList<>();
-
-    for (CommonClassDefinition d : defs) {
-      classes.add(d.target);
-      class_files.add(d.class_file_bytes);
-      dex_files.add(d.dex_file_bytes);
-    }
-    doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
-                                   class_files.toArray(new byte[0][]),
-                                   dex_files.toArray(new byte[0][]));
-  }
-
-  public static void addMultiTransformationResults(CommonClassDefinition... defs) {
-    for (CommonClassDefinition d : defs) {
-      addCommonTransformationResult(d.target.getCanonicalName(),
-                                    d.class_file_bytes,
-                                    d.dex_file_bytes);
-    }
-  }
-
-  public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
-                                                           byte[][] classfiles,
-                                                           byte[][] dexfiles);
-  public static native void doCommonClassRetransformation(Class<?>... target);
-  public static native void setPopRetransformations(boolean pop);
-  public static native void popTransformationFor(String name);
-  public static native void enableCommonRetransformation(boolean enable);
-  public static native void addCommonTransformationResult(String target_name,
-                                                          byte[] class_bytes,
-                                                          byte[] dex_bytes);
-}
diff --git a/test/926-multi-obsolescence/src/art/Redefinition.java b/test/926-multi-obsolescence/src/art/Redefinition.java
new file mode 120000
index 0000000..81eaf31
--- /dev/null
+++ b/test/926-multi-obsolescence/src/art/Redefinition.java
@@ -0,0 +1 @@
+../../../jvmti-common/Redefinition.java
\ No newline at end of file
diff --git a/test/930-hello-retransform/src/art/Redefinition.java b/test/930-hello-retransform/src/art/Redefinition.java
deleted file mode 100644
index 56d2938..0000000
--- a/test/930-hello-retransform/src/art/Redefinition.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.util.ArrayList;
-// Common Redefinition functions. Placed here for use by CTS
-public class Redefinition {
-  public static final class CommonClassDefinition {
-    public final Class<?> target;
-    public final byte[] class_file_bytes;
-    public final byte[] dex_file_bytes;
-
-    public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
-      this.target = target;
-      this.class_file_bytes = class_file_bytes;
-      this.dex_file_bytes = dex_file_bytes;
-    }
-  }
-
-  // A set of possible test configurations. Test should set this if they need to.
-  // This must be kept in sync with the defines in ti-agent/common_helper.cc
-  public static enum Config {
-    COMMON_REDEFINE(0),
-    COMMON_RETRANSFORM(1),
-    COMMON_TRANSFORM(2);
-
-    private final int val;
-    private Config(int val) {
-      this.val = val;
-    }
-  }
-
-  public static void setTestConfiguration(Config type) {
-    nativeSetTestConfiguration(type.val);
-  }
-
-  private static native void nativeSetTestConfiguration(int type);
-
-  // Transforms the class
-  public static native void doCommonClassRedefinition(Class<?> target,
-                                                      byte[] classfile,
-                                                      byte[] dexfile);
-
-  public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
-    ArrayList<Class<?>> classes = new ArrayList<>();
-    ArrayList<byte[]> class_files = new ArrayList<>();
-    ArrayList<byte[]> dex_files = new ArrayList<>();
-
-    for (CommonClassDefinition d : defs) {
-      classes.add(d.target);
-      class_files.add(d.class_file_bytes);
-      dex_files.add(d.dex_file_bytes);
-    }
-    doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
-                                   class_files.toArray(new byte[0][]),
-                                   dex_files.toArray(new byte[0][]));
-  }
-
-  public static void addMultiTransformationResults(CommonClassDefinition... defs) {
-    for (CommonClassDefinition d : defs) {
-      addCommonTransformationResult(d.target.getCanonicalName(),
-                                    d.class_file_bytes,
-                                    d.dex_file_bytes);
-    }
-  }
-
-  public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
-                                                           byte[][] classfiles,
-                                                           byte[][] dexfiles);
-  public static native void doCommonClassRetransformation(Class<?>... target);
-  public static native void setPopRetransformations(boolean pop);
-  public static native void popTransformationFor(String name);
-  public static native void enableCommonRetransformation(boolean enable);
-  public static native void addCommonTransformationResult(String target_name,
-                                                          byte[] class_bytes,
-                                                          byte[] dex_bytes);
-}
diff --git a/test/930-hello-retransform/src/art/Redefinition.java b/test/930-hello-retransform/src/art/Redefinition.java
new file mode 120000
index 0000000..81eaf31
--- /dev/null
+++ b/test/930-hello-retransform/src/art/Redefinition.java
@@ -0,0 +1 @@
+../../../jvmti-common/Redefinition.java
\ No newline at end of file
diff --git a/test/932-transform-saves/src/art/Redefinition.java b/test/932-transform-saves/src/art/Redefinition.java
deleted file mode 100644
index 56d2938..0000000
--- a/test/932-transform-saves/src/art/Redefinition.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.util.ArrayList;
-// Common Redefinition functions. Placed here for use by CTS
-public class Redefinition {
-  public static final class CommonClassDefinition {
-    public final Class<?> target;
-    public final byte[] class_file_bytes;
-    public final byte[] dex_file_bytes;
-
-    public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
-      this.target = target;
-      this.class_file_bytes = class_file_bytes;
-      this.dex_file_bytes = dex_file_bytes;
-    }
-  }
-
-  // A set of possible test configurations. Test should set this if they need to.
-  // This must be kept in sync with the defines in ti-agent/common_helper.cc
-  public static enum Config {
-    COMMON_REDEFINE(0),
-    COMMON_RETRANSFORM(1),
-    COMMON_TRANSFORM(2);
-
-    private final int val;
-    private Config(int val) {
-      this.val = val;
-    }
-  }
-
-  public static void setTestConfiguration(Config type) {
-    nativeSetTestConfiguration(type.val);
-  }
-
-  private static native void nativeSetTestConfiguration(int type);
-
-  // Transforms the class
-  public static native void doCommonClassRedefinition(Class<?> target,
-                                                      byte[] classfile,
-                                                      byte[] dexfile);
-
-  public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
-    ArrayList<Class<?>> classes = new ArrayList<>();
-    ArrayList<byte[]> class_files = new ArrayList<>();
-    ArrayList<byte[]> dex_files = new ArrayList<>();
-
-    for (CommonClassDefinition d : defs) {
-      classes.add(d.target);
-      class_files.add(d.class_file_bytes);
-      dex_files.add(d.dex_file_bytes);
-    }
-    doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
-                                   class_files.toArray(new byte[0][]),
-                                   dex_files.toArray(new byte[0][]));
-  }
-
-  public static void addMultiTransformationResults(CommonClassDefinition... defs) {
-    for (CommonClassDefinition d : defs) {
-      addCommonTransformationResult(d.target.getCanonicalName(),
-                                    d.class_file_bytes,
-                                    d.dex_file_bytes);
-    }
-  }
-
-  public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
-                                                           byte[][] classfiles,
-                                                           byte[][] dexfiles);
-  public static native void doCommonClassRetransformation(Class<?>... target);
-  public static native void setPopRetransformations(boolean pop);
-  public static native void popTransformationFor(String name);
-  public static native void enableCommonRetransformation(boolean enable);
-  public static native void addCommonTransformationResult(String target_name,
-                                                          byte[] class_bytes,
-                                                          byte[] dex_bytes);
-}
diff --git a/test/932-transform-saves/src/art/Redefinition.java b/test/932-transform-saves/src/art/Redefinition.java
new file mode 120000
index 0000000..81eaf31
--- /dev/null
+++ b/test/932-transform-saves/src/art/Redefinition.java
@@ -0,0 +1 @@
+../../../jvmti-common/Redefinition.java
\ No newline at end of file
diff --git a/test/934-load-transform/src/art/Redefinition.java b/test/934-load-transform/src/art/Redefinition.java
deleted file mode 100644
index 56d2938..0000000
--- a/test/934-load-transform/src/art/Redefinition.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.util.ArrayList;
-// Common Redefinition functions. Placed here for use by CTS
-public class Redefinition {
-  public static final class CommonClassDefinition {
-    public final Class<?> target;
-    public final byte[] class_file_bytes;
-    public final byte[] dex_file_bytes;
-
-    public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
-      this.target = target;
-      this.class_file_bytes = class_file_bytes;
-      this.dex_file_bytes = dex_file_bytes;
-    }
-  }
-
-  // A set of possible test configurations. Test should set this if they need to.
-  // This must be kept in sync with the defines in ti-agent/common_helper.cc
-  public static enum Config {
-    COMMON_REDEFINE(0),
-    COMMON_RETRANSFORM(1),
-    COMMON_TRANSFORM(2);
-
-    private final int val;
-    private Config(int val) {
-      this.val = val;
-    }
-  }
-
-  public static void setTestConfiguration(Config type) {
-    nativeSetTestConfiguration(type.val);
-  }
-
-  private static native void nativeSetTestConfiguration(int type);
-
-  // Transforms the class
-  public static native void doCommonClassRedefinition(Class<?> target,
-                                                      byte[] classfile,
-                                                      byte[] dexfile);
-
-  public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
-    ArrayList<Class<?>> classes = new ArrayList<>();
-    ArrayList<byte[]> class_files = new ArrayList<>();
-    ArrayList<byte[]> dex_files = new ArrayList<>();
-
-    for (CommonClassDefinition d : defs) {
-      classes.add(d.target);
-      class_files.add(d.class_file_bytes);
-      dex_files.add(d.dex_file_bytes);
-    }
-    doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
-                                   class_files.toArray(new byte[0][]),
-                                   dex_files.toArray(new byte[0][]));
-  }
-
-  public static void addMultiTransformationResults(CommonClassDefinition... defs) {
-    for (CommonClassDefinition d : defs) {
-      addCommonTransformationResult(d.target.getCanonicalName(),
-                                    d.class_file_bytes,
-                                    d.dex_file_bytes);
-    }
-  }
-
-  public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
-                                                           byte[][] classfiles,
-                                                           byte[][] dexfiles);
-  public static native void doCommonClassRetransformation(Class<?>... target);
-  public static native void setPopRetransformations(boolean pop);
-  public static native void popTransformationFor(String name);
-  public static native void enableCommonRetransformation(boolean enable);
-  public static native void addCommonTransformationResult(String target_name,
-                                                          byte[] class_bytes,
-                                                          byte[] dex_bytes);
-}
diff --git a/test/934-load-transform/src/art/Redefinition.java b/test/934-load-transform/src/art/Redefinition.java
new file mode 120000
index 0000000..81eaf31
--- /dev/null
+++ b/test/934-load-transform/src/art/Redefinition.java
@@ -0,0 +1 @@
+../../../jvmti-common/Redefinition.java
\ No newline at end of file
diff --git a/test/935-non-retransformable/src/art/Redefinition.java b/test/935-non-retransformable/src/art/Redefinition.java
deleted file mode 100644
index 56d2938..0000000
--- a/test/935-non-retransformable/src/art/Redefinition.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.util.ArrayList;
-// Common Redefinition functions. Placed here for use by CTS
-public class Redefinition {
-  public static final class CommonClassDefinition {
-    public final Class<?> target;
-    public final byte[] class_file_bytes;
-    public final byte[] dex_file_bytes;
-
-    public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
-      this.target = target;
-      this.class_file_bytes = class_file_bytes;
-      this.dex_file_bytes = dex_file_bytes;
-    }
-  }
-
-  // A set of possible test configurations. Test should set this if they need to.
-  // This must be kept in sync with the defines in ti-agent/common_helper.cc
-  public static enum Config {
-    COMMON_REDEFINE(0),
-    COMMON_RETRANSFORM(1),
-    COMMON_TRANSFORM(2);
-
-    private final int val;
-    private Config(int val) {
-      this.val = val;
-    }
-  }
-
-  public static void setTestConfiguration(Config type) {
-    nativeSetTestConfiguration(type.val);
-  }
-
-  private static native void nativeSetTestConfiguration(int type);
-
-  // Transforms the class
-  public static native void doCommonClassRedefinition(Class<?> target,
-                                                      byte[] classfile,
-                                                      byte[] dexfile);
-
-  public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
-    ArrayList<Class<?>> classes = new ArrayList<>();
-    ArrayList<byte[]> class_files = new ArrayList<>();
-    ArrayList<byte[]> dex_files = new ArrayList<>();
-
-    for (CommonClassDefinition d : defs) {
-      classes.add(d.target);
-      class_files.add(d.class_file_bytes);
-      dex_files.add(d.dex_file_bytes);
-    }
-    doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
-                                   class_files.toArray(new byte[0][]),
-                                   dex_files.toArray(new byte[0][]));
-  }
-
-  public static void addMultiTransformationResults(CommonClassDefinition... defs) {
-    for (CommonClassDefinition d : defs) {
-      addCommonTransformationResult(d.target.getCanonicalName(),
-                                    d.class_file_bytes,
-                                    d.dex_file_bytes);
-    }
-  }
-
-  public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
-                                                           byte[][] classfiles,
-                                                           byte[][] dexfiles);
-  public static native void doCommonClassRetransformation(Class<?>... target);
-  public static native void setPopRetransformations(boolean pop);
-  public static native void popTransformationFor(String name);
-  public static native void enableCommonRetransformation(boolean enable);
-  public static native void addCommonTransformationResult(String target_name,
-                                                          byte[] class_bytes,
-                                                          byte[] dex_bytes);
-}
diff --git a/test/935-non-retransformable/src/art/Redefinition.java b/test/935-non-retransformable/src/art/Redefinition.java
new file mode 120000
index 0000000..81eaf31
--- /dev/null
+++ b/test/935-non-retransformable/src/art/Redefinition.java
@@ -0,0 +1 @@
+../../../jvmti-common/Redefinition.java
\ No newline at end of file
diff --git a/test/937-hello-retransform-package/src/art/Redefinition.java b/test/937-hello-retransform-package/src/art/Redefinition.java
deleted file mode 100644
index 56d2938..0000000
--- a/test/937-hello-retransform-package/src/art/Redefinition.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.util.ArrayList;
-// Common Redefinition functions. Placed here for use by CTS
-public class Redefinition {
-  public static final class CommonClassDefinition {
-    public final Class<?> target;
-    public final byte[] class_file_bytes;
-    public final byte[] dex_file_bytes;
-
-    public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
-      this.target = target;
-      this.class_file_bytes = class_file_bytes;
-      this.dex_file_bytes = dex_file_bytes;
-    }
-  }
-
-  // A set of possible test configurations. Test should set this if they need to.
-  // This must be kept in sync with the defines in ti-agent/common_helper.cc
-  public static enum Config {
-    COMMON_REDEFINE(0),
-    COMMON_RETRANSFORM(1),
-    COMMON_TRANSFORM(2);
-
-    private final int val;
-    private Config(int val) {
-      this.val = val;
-    }
-  }
-
-  public static void setTestConfiguration(Config type) {
-    nativeSetTestConfiguration(type.val);
-  }
-
-  private static native void nativeSetTestConfiguration(int type);
-
-  // Transforms the class
-  public static native void doCommonClassRedefinition(Class<?> target,
-                                                      byte[] classfile,
-                                                      byte[] dexfile);
-
-  public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
-    ArrayList<Class<?>> classes = new ArrayList<>();
-    ArrayList<byte[]> class_files = new ArrayList<>();
-    ArrayList<byte[]> dex_files = new ArrayList<>();
-
-    for (CommonClassDefinition d : defs) {
-      classes.add(d.target);
-      class_files.add(d.class_file_bytes);
-      dex_files.add(d.dex_file_bytes);
-    }
-    doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
-                                   class_files.toArray(new byte[0][]),
-                                   dex_files.toArray(new byte[0][]));
-  }
-
-  public static void addMultiTransformationResults(CommonClassDefinition... defs) {
-    for (CommonClassDefinition d : defs) {
-      addCommonTransformationResult(d.target.getCanonicalName(),
-                                    d.class_file_bytes,
-                                    d.dex_file_bytes);
-    }
-  }
-
-  public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
-                                                           byte[][] classfiles,
-                                                           byte[][] dexfiles);
-  public static native void doCommonClassRetransformation(Class<?>... target);
-  public static native void setPopRetransformations(boolean pop);
-  public static native void popTransformationFor(String name);
-  public static native void enableCommonRetransformation(boolean enable);
-  public static native void addCommonTransformationResult(String target_name,
-                                                          byte[] class_bytes,
-                                                          byte[] dex_bytes);
-}
diff --git a/test/937-hello-retransform-package/src/art/Redefinition.java b/test/937-hello-retransform-package/src/art/Redefinition.java
new file mode 120000
index 0000000..81eaf31
--- /dev/null
+++ b/test/937-hello-retransform-package/src/art/Redefinition.java
@@ -0,0 +1 @@
+../../../jvmti-common/Redefinition.java
\ No newline at end of file
diff --git a/test/938-load-transform-bcp/src/art/Redefinition.java b/test/938-load-transform-bcp/src/art/Redefinition.java
deleted file mode 100644
index 56d2938..0000000
--- a/test/938-load-transform-bcp/src/art/Redefinition.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.util.ArrayList;
-// Common Redefinition functions. Placed here for use by CTS
-public class Redefinition {
-  public static final class CommonClassDefinition {
-    public final Class<?> target;
-    public final byte[] class_file_bytes;
-    public final byte[] dex_file_bytes;
-
-    public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
-      this.target = target;
-      this.class_file_bytes = class_file_bytes;
-      this.dex_file_bytes = dex_file_bytes;
-    }
-  }
-
-  // A set of possible test configurations. Test should set this if they need to.
-  // This must be kept in sync with the defines in ti-agent/common_helper.cc
-  public static enum Config {
-    COMMON_REDEFINE(0),
-    COMMON_RETRANSFORM(1),
-    COMMON_TRANSFORM(2);
-
-    private final int val;
-    private Config(int val) {
-      this.val = val;
-    }
-  }
-
-  public static void setTestConfiguration(Config type) {
-    nativeSetTestConfiguration(type.val);
-  }
-
-  private static native void nativeSetTestConfiguration(int type);
-
-  // Transforms the class
-  public static native void doCommonClassRedefinition(Class<?> target,
-                                                      byte[] classfile,
-                                                      byte[] dexfile);
-
-  public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
-    ArrayList<Class<?>> classes = new ArrayList<>();
-    ArrayList<byte[]> class_files = new ArrayList<>();
-    ArrayList<byte[]> dex_files = new ArrayList<>();
-
-    for (CommonClassDefinition d : defs) {
-      classes.add(d.target);
-      class_files.add(d.class_file_bytes);
-      dex_files.add(d.dex_file_bytes);
-    }
-    doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
-                                   class_files.toArray(new byte[0][]),
-                                   dex_files.toArray(new byte[0][]));
-  }
-
-  public static void addMultiTransformationResults(CommonClassDefinition... defs) {
-    for (CommonClassDefinition d : defs) {
-      addCommonTransformationResult(d.target.getCanonicalName(),
-                                    d.class_file_bytes,
-                                    d.dex_file_bytes);
-    }
-  }
-
-  public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
-                                                           byte[][] classfiles,
-                                                           byte[][] dexfiles);
-  public static native void doCommonClassRetransformation(Class<?>... target);
-  public static native void setPopRetransformations(boolean pop);
-  public static native void popTransformationFor(String name);
-  public static native void enableCommonRetransformation(boolean enable);
-  public static native void addCommonTransformationResult(String target_name,
-                                                          byte[] class_bytes,
-                                                          byte[] dex_bytes);
-}
diff --git a/test/938-load-transform-bcp/src/art/Redefinition.java b/test/938-load-transform-bcp/src/art/Redefinition.java
new file mode 120000
index 0000000..81eaf31
--- /dev/null
+++ b/test/938-load-transform-bcp/src/art/Redefinition.java
@@ -0,0 +1 @@
+../../../jvmti-common/Redefinition.java
\ No newline at end of file
diff --git a/test/939-hello-transformation-bcp/src/art/Redefinition.java b/test/939-hello-transformation-bcp/src/art/Redefinition.java
deleted file mode 100644
index 56d2938..0000000
--- a/test/939-hello-transformation-bcp/src/art/Redefinition.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.util.ArrayList;
-// Common Redefinition functions. Placed here for use by CTS
-public class Redefinition {
-  public static final class CommonClassDefinition {
-    public final Class<?> target;
-    public final byte[] class_file_bytes;
-    public final byte[] dex_file_bytes;
-
-    public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
-      this.target = target;
-      this.class_file_bytes = class_file_bytes;
-      this.dex_file_bytes = dex_file_bytes;
-    }
-  }
-
-  // A set of possible test configurations. Test should set this if they need to.
-  // This must be kept in sync with the defines in ti-agent/common_helper.cc
-  public static enum Config {
-    COMMON_REDEFINE(0),
-    COMMON_RETRANSFORM(1),
-    COMMON_TRANSFORM(2);
-
-    private final int val;
-    private Config(int val) {
-      this.val = val;
-    }
-  }
-
-  public static void setTestConfiguration(Config type) {
-    nativeSetTestConfiguration(type.val);
-  }
-
-  private static native void nativeSetTestConfiguration(int type);
-
-  // Transforms the class
-  public static native void doCommonClassRedefinition(Class<?> target,
-                                                      byte[] classfile,
-                                                      byte[] dexfile);
-
-  public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
-    ArrayList<Class<?>> classes = new ArrayList<>();
-    ArrayList<byte[]> class_files = new ArrayList<>();
-    ArrayList<byte[]> dex_files = new ArrayList<>();
-
-    for (CommonClassDefinition d : defs) {
-      classes.add(d.target);
-      class_files.add(d.class_file_bytes);
-      dex_files.add(d.dex_file_bytes);
-    }
-    doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
-                                   class_files.toArray(new byte[0][]),
-                                   dex_files.toArray(new byte[0][]));
-  }
-
-  public static void addMultiTransformationResults(CommonClassDefinition... defs) {
-    for (CommonClassDefinition d : defs) {
-      addCommonTransformationResult(d.target.getCanonicalName(),
-                                    d.class_file_bytes,
-                                    d.dex_file_bytes);
-    }
-  }
-
-  public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
-                                                           byte[][] classfiles,
-                                                           byte[][] dexfiles);
-  public static native void doCommonClassRetransformation(Class<?>... target);
-  public static native void setPopRetransformations(boolean pop);
-  public static native void popTransformationFor(String name);
-  public static native void enableCommonRetransformation(boolean enable);
-  public static native void addCommonTransformationResult(String target_name,
-                                                          byte[] class_bytes,
-                                                          byte[] dex_bytes);
-}
diff --git a/test/939-hello-transformation-bcp/src/art/Redefinition.java b/test/939-hello-transformation-bcp/src/art/Redefinition.java
new file mode 120000
index 0000000..81eaf31
--- /dev/null
+++ b/test/939-hello-transformation-bcp/src/art/Redefinition.java
@@ -0,0 +1 @@
+../../../jvmti-common/Redefinition.java
\ No newline at end of file
diff --git a/test/940-recursive-obsolete/src/art/Redefinition.java b/test/940-recursive-obsolete/src/art/Redefinition.java
deleted file mode 100644
index 56d2938..0000000
--- a/test/940-recursive-obsolete/src/art/Redefinition.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.util.ArrayList;
-// Common Redefinition functions. Placed here for use by CTS
-public class Redefinition {
-  public static final class CommonClassDefinition {
-    public final Class<?> target;
-    public final byte[] class_file_bytes;
-    public final byte[] dex_file_bytes;
-
-    public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
-      this.target = target;
-      this.class_file_bytes = class_file_bytes;
-      this.dex_file_bytes = dex_file_bytes;
-    }
-  }
-
-  // A set of possible test configurations. Test should set this if they need to.
-  // This must be kept in sync with the defines in ti-agent/common_helper.cc
-  public static enum Config {
-    COMMON_REDEFINE(0),
-    COMMON_RETRANSFORM(1),
-    COMMON_TRANSFORM(2);
-
-    private final int val;
-    private Config(int val) {
-      this.val = val;
-    }
-  }
-
-  public static void setTestConfiguration(Config type) {
-    nativeSetTestConfiguration(type.val);
-  }
-
-  private static native void nativeSetTestConfiguration(int type);
-
-  // Transforms the class
-  public static native void doCommonClassRedefinition(Class<?> target,
-                                                      byte[] classfile,
-                                                      byte[] dexfile);
-
-  public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
-    ArrayList<Class<?>> classes = new ArrayList<>();
-    ArrayList<byte[]> class_files = new ArrayList<>();
-    ArrayList<byte[]> dex_files = new ArrayList<>();
-
-    for (CommonClassDefinition d : defs) {
-      classes.add(d.target);
-      class_files.add(d.class_file_bytes);
-      dex_files.add(d.dex_file_bytes);
-    }
-    doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
-                                   class_files.toArray(new byte[0][]),
-                                   dex_files.toArray(new byte[0][]));
-  }
-
-  public static void addMultiTransformationResults(CommonClassDefinition... defs) {
-    for (CommonClassDefinition d : defs) {
-      addCommonTransformationResult(d.target.getCanonicalName(),
-                                    d.class_file_bytes,
-                                    d.dex_file_bytes);
-    }
-  }
-
-  public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
-                                                           byte[][] classfiles,
-                                                           byte[][] dexfiles);
-  public static native void doCommonClassRetransformation(Class<?>... target);
-  public static native void setPopRetransformations(boolean pop);
-  public static native void popTransformationFor(String name);
-  public static native void enableCommonRetransformation(boolean enable);
-  public static native void addCommonTransformationResult(String target_name,
-                                                          byte[] class_bytes,
-                                                          byte[] dex_bytes);
-}
diff --git a/test/940-recursive-obsolete/src/art/Redefinition.java b/test/940-recursive-obsolete/src/art/Redefinition.java
new file mode 120000
index 0000000..81eaf31
--- /dev/null
+++ b/test/940-recursive-obsolete/src/art/Redefinition.java
@@ -0,0 +1 @@
+../../../jvmti-common/Redefinition.java
\ No newline at end of file
diff --git a/test/941-recurive-obsolete-jit/src/art/Redefinition.java b/test/941-recurive-obsolete-jit/src/art/Redefinition.java
deleted file mode 100644
index 56d2938..0000000
--- a/test/941-recurive-obsolete-jit/src/art/Redefinition.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.util.ArrayList;
-// Common Redefinition functions. Placed here for use by CTS
-public class Redefinition {
-  public static final class CommonClassDefinition {
-    public final Class<?> target;
-    public final byte[] class_file_bytes;
-    public final byte[] dex_file_bytes;
-
-    public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
-      this.target = target;
-      this.class_file_bytes = class_file_bytes;
-      this.dex_file_bytes = dex_file_bytes;
-    }
-  }
-
-  // A set of possible test configurations. Test should set this if they need to.
-  // This must be kept in sync with the defines in ti-agent/common_helper.cc
-  public static enum Config {
-    COMMON_REDEFINE(0),
-    COMMON_RETRANSFORM(1),
-    COMMON_TRANSFORM(2);
-
-    private final int val;
-    private Config(int val) {
-      this.val = val;
-    }
-  }
-
-  public static void setTestConfiguration(Config type) {
-    nativeSetTestConfiguration(type.val);
-  }
-
-  private static native void nativeSetTestConfiguration(int type);
-
-  // Transforms the class
-  public static native void doCommonClassRedefinition(Class<?> target,
-                                                      byte[] classfile,
-                                                      byte[] dexfile);
-
-  public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
-    ArrayList<Class<?>> classes = new ArrayList<>();
-    ArrayList<byte[]> class_files = new ArrayList<>();
-    ArrayList<byte[]> dex_files = new ArrayList<>();
-
-    for (CommonClassDefinition d : defs) {
-      classes.add(d.target);
-      class_files.add(d.class_file_bytes);
-      dex_files.add(d.dex_file_bytes);
-    }
-    doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
-                                   class_files.toArray(new byte[0][]),
-                                   dex_files.toArray(new byte[0][]));
-  }
-
-  public static void addMultiTransformationResults(CommonClassDefinition... defs) {
-    for (CommonClassDefinition d : defs) {
-      addCommonTransformationResult(d.target.getCanonicalName(),
-                                    d.class_file_bytes,
-                                    d.dex_file_bytes);
-    }
-  }
-
-  public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
-                                                           byte[][] classfiles,
-                                                           byte[][] dexfiles);
-  public static native void doCommonClassRetransformation(Class<?>... target);
-  public static native void setPopRetransformations(boolean pop);
-  public static native void popTransformationFor(String name);
-  public static native void enableCommonRetransformation(boolean enable);
-  public static native void addCommonTransformationResult(String target_name,
-                                                          byte[] class_bytes,
-                                                          byte[] dex_bytes);
-}
diff --git a/test/941-recurive-obsolete-jit/src/art/Redefinition.java b/test/941-recurive-obsolete-jit/src/art/Redefinition.java
new file mode 120000
index 0000000..81eaf31
--- /dev/null
+++ b/test/941-recurive-obsolete-jit/src/art/Redefinition.java
@@ -0,0 +1 @@
+../../../jvmti-common/Redefinition.java
\ No newline at end of file
diff --git a/test/942-private-recursive/src/art/Redefinition.java b/test/942-private-recursive/src/art/Redefinition.java
deleted file mode 100644
index 56d2938..0000000
--- a/test/942-private-recursive/src/art/Redefinition.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.util.ArrayList;
-// Common Redefinition functions. Placed here for use by CTS
-public class Redefinition {
-  public static final class CommonClassDefinition {
-    public final Class<?> target;
-    public final byte[] class_file_bytes;
-    public final byte[] dex_file_bytes;
-
-    public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
-      this.target = target;
-      this.class_file_bytes = class_file_bytes;
-      this.dex_file_bytes = dex_file_bytes;
-    }
-  }
-
-  // A set of possible test configurations. Test should set this if they need to.
-  // This must be kept in sync with the defines in ti-agent/common_helper.cc
-  public static enum Config {
-    COMMON_REDEFINE(0),
-    COMMON_RETRANSFORM(1),
-    COMMON_TRANSFORM(2);
-
-    private final int val;
-    private Config(int val) {
-      this.val = val;
-    }
-  }
-
-  public static void setTestConfiguration(Config type) {
-    nativeSetTestConfiguration(type.val);
-  }
-
-  private static native void nativeSetTestConfiguration(int type);
-
-  // Transforms the class
-  public static native void doCommonClassRedefinition(Class<?> target,
-                                                      byte[] classfile,
-                                                      byte[] dexfile);
-
-  public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
-    ArrayList<Class<?>> classes = new ArrayList<>();
-    ArrayList<byte[]> class_files = new ArrayList<>();
-    ArrayList<byte[]> dex_files = new ArrayList<>();
-
-    for (CommonClassDefinition d : defs) {
-      classes.add(d.target);
-      class_files.add(d.class_file_bytes);
-      dex_files.add(d.dex_file_bytes);
-    }
-    doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
-                                   class_files.toArray(new byte[0][]),
-                                   dex_files.toArray(new byte[0][]));
-  }
-
-  public static void addMultiTransformationResults(CommonClassDefinition... defs) {
-    for (CommonClassDefinition d : defs) {
-      addCommonTransformationResult(d.target.getCanonicalName(),
-                                    d.class_file_bytes,
-                                    d.dex_file_bytes);
-    }
-  }
-
-  public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
-                                                           byte[][] classfiles,
-                                                           byte[][] dexfiles);
-  public static native void doCommonClassRetransformation(Class<?>... target);
-  public static native void setPopRetransformations(boolean pop);
-  public static native void popTransformationFor(String name);
-  public static native void enableCommonRetransformation(boolean enable);
-  public static native void addCommonTransformationResult(String target_name,
-                                                          byte[] class_bytes,
-                                                          byte[] dex_bytes);
-}
diff --git a/test/942-private-recursive/src/art/Redefinition.java b/test/942-private-recursive/src/art/Redefinition.java
new file mode 120000
index 0000000..81eaf31
--- /dev/null
+++ b/test/942-private-recursive/src/art/Redefinition.java
@@ -0,0 +1 @@
+../../../jvmti-common/Redefinition.java
\ No newline at end of file
diff --git a/test/943-private-recursive-jit/src/art/Redefinition.java b/test/943-private-recursive-jit/src/art/Redefinition.java
deleted file mode 100644
index 56d2938..0000000
--- a/test/943-private-recursive-jit/src/art/Redefinition.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.util.ArrayList;
-// Common Redefinition functions. Placed here for use by CTS
-public class Redefinition {
-  public static final class CommonClassDefinition {
-    public final Class<?> target;
-    public final byte[] class_file_bytes;
-    public final byte[] dex_file_bytes;
-
-    public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
-      this.target = target;
-      this.class_file_bytes = class_file_bytes;
-      this.dex_file_bytes = dex_file_bytes;
-    }
-  }
-
-  // A set of possible test configurations. Test should set this if they need to.
-  // This must be kept in sync with the defines in ti-agent/common_helper.cc
-  public static enum Config {
-    COMMON_REDEFINE(0),
-    COMMON_RETRANSFORM(1),
-    COMMON_TRANSFORM(2);
-
-    private final int val;
-    private Config(int val) {
-      this.val = val;
-    }
-  }
-
-  public static void setTestConfiguration(Config type) {
-    nativeSetTestConfiguration(type.val);
-  }
-
-  private static native void nativeSetTestConfiguration(int type);
-
-  // Transforms the class
-  public static native void doCommonClassRedefinition(Class<?> target,
-                                                      byte[] classfile,
-                                                      byte[] dexfile);
-
-  public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
-    ArrayList<Class<?>> classes = new ArrayList<>();
-    ArrayList<byte[]> class_files = new ArrayList<>();
-    ArrayList<byte[]> dex_files = new ArrayList<>();
-
-    for (CommonClassDefinition d : defs) {
-      classes.add(d.target);
-      class_files.add(d.class_file_bytes);
-      dex_files.add(d.dex_file_bytes);
-    }
-    doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
-                                   class_files.toArray(new byte[0][]),
-                                   dex_files.toArray(new byte[0][]));
-  }
-
-  public static void addMultiTransformationResults(CommonClassDefinition... defs) {
-    for (CommonClassDefinition d : defs) {
-      addCommonTransformationResult(d.target.getCanonicalName(),
-                                    d.class_file_bytes,
-                                    d.dex_file_bytes);
-    }
-  }
-
-  public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
-                                                           byte[][] classfiles,
-                                                           byte[][] dexfiles);
-  public static native void doCommonClassRetransformation(Class<?>... target);
-  public static native void setPopRetransformations(boolean pop);
-  public static native void popTransformationFor(String name);
-  public static native void enableCommonRetransformation(boolean enable);
-  public static native void addCommonTransformationResult(String target_name,
-                                                          byte[] class_bytes,
-                                                          byte[] dex_bytes);
-}
diff --git a/test/943-private-recursive-jit/src/art/Redefinition.java b/test/943-private-recursive-jit/src/art/Redefinition.java
new file mode 120000
index 0000000..81eaf31
--- /dev/null
+++ b/test/943-private-recursive-jit/src/art/Redefinition.java
@@ -0,0 +1 @@
+../../../jvmti-common/Redefinition.java
\ No newline at end of file
diff --git a/test/944-transform-classloaders/src/art/Redefinition.java b/test/944-transform-classloaders/src/art/Redefinition.java
deleted file mode 100644
index 56d2938..0000000
--- a/test/944-transform-classloaders/src/art/Redefinition.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.util.ArrayList;
-// Common Redefinition functions. Placed here for use by CTS
-public class Redefinition {
-  public static final class CommonClassDefinition {
-    public final Class<?> target;
-    public final byte[] class_file_bytes;
-    public final byte[] dex_file_bytes;
-
-    public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
-      this.target = target;
-      this.class_file_bytes = class_file_bytes;
-      this.dex_file_bytes = dex_file_bytes;
-    }
-  }
-
-  // A set of possible test configurations. Test should set this if they need to.
-  // This must be kept in sync with the defines in ti-agent/common_helper.cc
-  public static enum Config {
-    COMMON_REDEFINE(0),
-    COMMON_RETRANSFORM(1),
-    COMMON_TRANSFORM(2);
-
-    private final int val;
-    private Config(int val) {
-      this.val = val;
-    }
-  }
-
-  public static void setTestConfiguration(Config type) {
-    nativeSetTestConfiguration(type.val);
-  }
-
-  private static native void nativeSetTestConfiguration(int type);
-
-  // Transforms the class
-  public static native void doCommonClassRedefinition(Class<?> target,
-                                                      byte[] classfile,
-                                                      byte[] dexfile);
-
-  public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
-    ArrayList<Class<?>> classes = new ArrayList<>();
-    ArrayList<byte[]> class_files = new ArrayList<>();
-    ArrayList<byte[]> dex_files = new ArrayList<>();
-
-    for (CommonClassDefinition d : defs) {
-      classes.add(d.target);
-      class_files.add(d.class_file_bytes);
-      dex_files.add(d.dex_file_bytes);
-    }
-    doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
-                                   class_files.toArray(new byte[0][]),
-                                   dex_files.toArray(new byte[0][]));
-  }
-
-  public static void addMultiTransformationResults(CommonClassDefinition... defs) {
-    for (CommonClassDefinition d : defs) {
-      addCommonTransformationResult(d.target.getCanonicalName(),
-                                    d.class_file_bytes,
-                                    d.dex_file_bytes);
-    }
-  }
-
-  public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
-                                                           byte[][] classfiles,
-                                                           byte[][] dexfiles);
-  public static native void doCommonClassRetransformation(Class<?>... target);
-  public static native void setPopRetransformations(boolean pop);
-  public static native void popTransformationFor(String name);
-  public static native void enableCommonRetransformation(boolean enable);
-  public static native void addCommonTransformationResult(String target_name,
-                                                          byte[] class_bytes,
-                                                          byte[] dex_bytes);
-}
diff --git a/test/944-transform-classloaders/src/art/Redefinition.java b/test/944-transform-classloaders/src/art/Redefinition.java
new file mode 120000
index 0000000..81eaf31
--- /dev/null
+++ b/test/944-transform-classloaders/src/art/Redefinition.java
@@ -0,0 +1 @@
+../../../jvmti-common/Redefinition.java
\ No newline at end of file
diff --git a/test/945-obsolete-native/src/art/Redefinition.java b/test/945-obsolete-native/src/art/Redefinition.java
deleted file mode 100644
index 56d2938..0000000
--- a/test/945-obsolete-native/src/art/Redefinition.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.util.ArrayList;
-// Common Redefinition functions. Placed here for use by CTS
-public class Redefinition {
-  public static final class CommonClassDefinition {
-    public final Class<?> target;
-    public final byte[] class_file_bytes;
-    public final byte[] dex_file_bytes;
-
-    public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
-      this.target = target;
-      this.class_file_bytes = class_file_bytes;
-      this.dex_file_bytes = dex_file_bytes;
-    }
-  }
-
-  // A set of possible test configurations. Test should set this if they need to.
-  // This must be kept in sync with the defines in ti-agent/common_helper.cc
-  public static enum Config {
-    COMMON_REDEFINE(0),
-    COMMON_RETRANSFORM(1),
-    COMMON_TRANSFORM(2);
-
-    private final int val;
-    private Config(int val) {
-      this.val = val;
-    }
-  }
-
-  public static void setTestConfiguration(Config type) {
-    nativeSetTestConfiguration(type.val);
-  }
-
-  private static native void nativeSetTestConfiguration(int type);
-
-  // Transforms the class
-  public static native void doCommonClassRedefinition(Class<?> target,
-                                                      byte[] classfile,
-                                                      byte[] dexfile);
-
-  public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
-    ArrayList<Class<?>> classes = new ArrayList<>();
-    ArrayList<byte[]> class_files = new ArrayList<>();
-    ArrayList<byte[]> dex_files = new ArrayList<>();
-
-    for (CommonClassDefinition d : defs) {
-      classes.add(d.target);
-      class_files.add(d.class_file_bytes);
-      dex_files.add(d.dex_file_bytes);
-    }
-    doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
-                                   class_files.toArray(new byte[0][]),
-                                   dex_files.toArray(new byte[0][]));
-  }
-
-  public static void addMultiTransformationResults(CommonClassDefinition... defs) {
-    for (CommonClassDefinition d : defs) {
-      addCommonTransformationResult(d.target.getCanonicalName(),
-                                    d.class_file_bytes,
-                                    d.dex_file_bytes);
-    }
-  }
-
-  public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
-                                                           byte[][] classfiles,
-                                                           byte[][] dexfiles);
-  public static native void doCommonClassRetransformation(Class<?>... target);
-  public static native void setPopRetransformations(boolean pop);
-  public static native void popTransformationFor(String name);
-  public static native void enableCommonRetransformation(boolean enable);
-  public static native void addCommonTransformationResult(String target_name,
-                                                          byte[] class_bytes,
-                                                          byte[] dex_bytes);
-}
diff --git a/test/945-obsolete-native/src/art/Redefinition.java b/test/945-obsolete-native/src/art/Redefinition.java
new file mode 120000
index 0000000..81eaf31
--- /dev/null
+++ b/test/945-obsolete-native/src/art/Redefinition.java
@@ -0,0 +1 @@
+../../../jvmti-common/Redefinition.java
\ No newline at end of file
diff --git a/test/946-obsolete-throw/src/art/Redefinition.java b/test/946-obsolete-throw/src/art/Redefinition.java
deleted file mode 100644
index 56d2938..0000000
--- a/test/946-obsolete-throw/src/art/Redefinition.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.util.ArrayList;
-// Common Redefinition functions. Placed here for use by CTS
-public class Redefinition {
-  public static final class CommonClassDefinition {
-    public final Class<?> target;
-    public final byte[] class_file_bytes;
-    public final byte[] dex_file_bytes;
-
-    public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
-      this.target = target;
-      this.class_file_bytes = class_file_bytes;
-      this.dex_file_bytes = dex_file_bytes;
-    }
-  }
-
-  // A set of possible test configurations. Test should set this if they need to.
-  // This must be kept in sync with the defines in ti-agent/common_helper.cc
-  public static enum Config {
-    COMMON_REDEFINE(0),
-    COMMON_RETRANSFORM(1),
-    COMMON_TRANSFORM(2);
-
-    private final int val;
-    private Config(int val) {
-      this.val = val;
-    }
-  }
-
-  public static void setTestConfiguration(Config type) {
-    nativeSetTestConfiguration(type.val);
-  }
-
-  private static native void nativeSetTestConfiguration(int type);
-
-  // Transforms the class
-  public static native void doCommonClassRedefinition(Class<?> target,
-                                                      byte[] classfile,
-                                                      byte[] dexfile);
-
-  public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
-    ArrayList<Class<?>> classes = new ArrayList<>();
-    ArrayList<byte[]> class_files = new ArrayList<>();
-    ArrayList<byte[]> dex_files = new ArrayList<>();
-
-    for (CommonClassDefinition d : defs) {
-      classes.add(d.target);
-      class_files.add(d.class_file_bytes);
-      dex_files.add(d.dex_file_bytes);
-    }
-    doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
-                                   class_files.toArray(new byte[0][]),
-                                   dex_files.toArray(new byte[0][]));
-  }
-
-  public static void addMultiTransformationResults(CommonClassDefinition... defs) {
-    for (CommonClassDefinition d : defs) {
-      addCommonTransformationResult(d.target.getCanonicalName(),
-                                    d.class_file_bytes,
-                                    d.dex_file_bytes);
-    }
-  }
-
-  public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
-                                                           byte[][] classfiles,
-                                                           byte[][] dexfiles);
-  public static native void doCommonClassRetransformation(Class<?>... target);
-  public static native void setPopRetransformations(boolean pop);
-  public static native void popTransformationFor(String name);
-  public static native void enableCommonRetransformation(boolean enable);
-  public static native void addCommonTransformationResult(String target_name,
-                                                          byte[] class_bytes,
-                                                          byte[] dex_bytes);
-}
diff --git a/test/946-obsolete-throw/src/art/Redefinition.java b/test/946-obsolete-throw/src/art/Redefinition.java
new file mode 120000
index 0000000..81eaf31
--- /dev/null
+++ b/test/946-obsolete-throw/src/art/Redefinition.java
@@ -0,0 +1 @@
+../../../jvmti-common/Redefinition.java
\ No newline at end of file
diff --git a/test/947-reflect-method/src/art/Redefinition.java b/test/947-reflect-method/src/art/Redefinition.java
deleted file mode 100644
index 56d2938..0000000
--- a/test/947-reflect-method/src/art/Redefinition.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.util.ArrayList;
-// Common Redefinition functions. Placed here for use by CTS
-public class Redefinition {
-  public static final class CommonClassDefinition {
-    public final Class<?> target;
-    public final byte[] class_file_bytes;
-    public final byte[] dex_file_bytes;
-
-    public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
-      this.target = target;
-      this.class_file_bytes = class_file_bytes;
-      this.dex_file_bytes = dex_file_bytes;
-    }
-  }
-
-  // A set of possible test configurations. Test should set this if they need to.
-  // This must be kept in sync with the defines in ti-agent/common_helper.cc
-  public static enum Config {
-    COMMON_REDEFINE(0),
-    COMMON_RETRANSFORM(1),
-    COMMON_TRANSFORM(2);
-
-    private final int val;
-    private Config(int val) {
-      this.val = val;
-    }
-  }
-
-  public static void setTestConfiguration(Config type) {
-    nativeSetTestConfiguration(type.val);
-  }
-
-  private static native void nativeSetTestConfiguration(int type);
-
-  // Transforms the class
-  public static native void doCommonClassRedefinition(Class<?> target,
-                                                      byte[] classfile,
-                                                      byte[] dexfile);
-
-  public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
-    ArrayList<Class<?>> classes = new ArrayList<>();
-    ArrayList<byte[]> class_files = new ArrayList<>();
-    ArrayList<byte[]> dex_files = new ArrayList<>();
-
-    for (CommonClassDefinition d : defs) {
-      classes.add(d.target);
-      class_files.add(d.class_file_bytes);
-      dex_files.add(d.dex_file_bytes);
-    }
-    doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
-                                   class_files.toArray(new byte[0][]),
-                                   dex_files.toArray(new byte[0][]));
-  }
-
-  public static void addMultiTransformationResults(CommonClassDefinition... defs) {
-    for (CommonClassDefinition d : defs) {
-      addCommonTransformationResult(d.target.getCanonicalName(),
-                                    d.class_file_bytes,
-                                    d.dex_file_bytes);
-    }
-  }
-
-  public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
-                                                           byte[][] classfiles,
-                                                           byte[][] dexfiles);
-  public static native void doCommonClassRetransformation(Class<?>... target);
-  public static native void setPopRetransformations(boolean pop);
-  public static native void popTransformationFor(String name);
-  public static native void enableCommonRetransformation(boolean enable);
-  public static native void addCommonTransformationResult(String target_name,
-                                                          byte[] class_bytes,
-                                                          byte[] dex_bytes);
-}
diff --git a/test/947-reflect-method/src/art/Redefinition.java b/test/947-reflect-method/src/art/Redefinition.java
new file mode 120000
index 0000000..81eaf31
--- /dev/null
+++ b/test/947-reflect-method/src/art/Redefinition.java
@@ -0,0 +1 @@
+../../../jvmti-common/Redefinition.java
\ No newline at end of file
diff --git a/test/948-change-annotations/src/art/Redefinition.java b/test/948-change-annotations/src/art/Redefinition.java
deleted file mode 100644
index 56d2938..0000000
--- a/test/948-change-annotations/src/art/Redefinition.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.util.ArrayList;
-// Common Redefinition functions. Placed here for use by CTS
-public class Redefinition {
-  public static final class CommonClassDefinition {
-    public final Class<?> target;
-    public final byte[] class_file_bytes;
-    public final byte[] dex_file_bytes;
-
-    public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
-      this.target = target;
-      this.class_file_bytes = class_file_bytes;
-      this.dex_file_bytes = dex_file_bytes;
-    }
-  }
-
-  // A set of possible test configurations. Test should set this if they need to.
-  // This must be kept in sync with the defines in ti-agent/common_helper.cc
-  public static enum Config {
-    COMMON_REDEFINE(0),
-    COMMON_RETRANSFORM(1),
-    COMMON_TRANSFORM(2);
-
-    private final int val;
-    private Config(int val) {
-      this.val = val;
-    }
-  }
-
-  public static void setTestConfiguration(Config type) {
-    nativeSetTestConfiguration(type.val);
-  }
-
-  private static native void nativeSetTestConfiguration(int type);
-
-  // Transforms the class
-  public static native void doCommonClassRedefinition(Class<?> target,
-                                                      byte[] classfile,
-                                                      byte[] dexfile);
-
-  public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
-    ArrayList<Class<?>> classes = new ArrayList<>();
-    ArrayList<byte[]> class_files = new ArrayList<>();
-    ArrayList<byte[]> dex_files = new ArrayList<>();
-
-    for (CommonClassDefinition d : defs) {
-      classes.add(d.target);
-      class_files.add(d.class_file_bytes);
-      dex_files.add(d.dex_file_bytes);
-    }
-    doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
-                                   class_files.toArray(new byte[0][]),
-                                   dex_files.toArray(new byte[0][]));
-  }
-
-  public static void addMultiTransformationResults(CommonClassDefinition... defs) {
-    for (CommonClassDefinition d : defs) {
-      addCommonTransformationResult(d.target.getCanonicalName(),
-                                    d.class_file_bytes,
-                                    d.dex_file_bytes);
-    }
-  }
-
-  public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
-                                                           byte[][] classfiles,
-                                                           byte[][] dexfiles);
-  public static native void doCommonClassRetransformation(Class<?>... target);
-  public static native void setPopRetransformations(boolean pop);
-  public static native void popTransformationFor(String name);
-  public static native void enableCommonRetransformation(boolean enable);
-  public static native void addCommonTransformationResult(String target_name,
-                                                          byte[] class_bytes,
-                                                          byte[] dex_bytes);
-}
diff --git a/test/948-change-annotations/src/art/Redefinition.java b/test/948-change-annotations/src/art/Redefinition.java
new file mode 120000
index 0000000..81eaf31
--- /dev/null
+++ b/test/948-change-annotations/src/art/Redefinition.java
@@ -0,0 +1 @@
+../../../jvmti-common/Redefinition.java
\ No newline at end of file
diff --git a/test/949-in-memory-transform/src/art/Redefinition.java b/test/949-in-memory-transform/src/art/Redefinition.java
deleted file mode 100644
index 56d2938..0000000
--- a/test/949-in-memory-transform/src/art/Redefinition.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.util.ArrayList;
-// Common Redefinition functions. Placed here for use by CTS
-public class Redefinition {
-  public static final class CommonClassDefinition {
-    public final Class<?> target;
-    public final byte[] class_file_bytes;
-    public final byte[] dex_file_bytes;
-
-    public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
-      this.target = target;
-      this.class_file_bytes = class_file_bytes;
-      this.dex_file_bytes = dex_file_bytes;
-    }
-  }
-
-  // A set of possible test configurations. Test should set this if they need to.
-  // This must be kept in sync with the defines in ti-agent/common_helper.cc
-  public static enum Config {
-    COMMON_REDEFINE(0),
-    COMMON_RETRANSFORM(1),
-    COMMON_TRANSFORM(2);
-
-    private final int val;
-    private Config(int val) {
-      this.val = val;
-    }
-  }
-
-  public static void setTestConfiguration(Config type) {
-    nativeSetTestConfiguration(type.val);
-  }
-
-  private static native void nativeSetTestConfiguration(int type);
-
-  // Transforms the class
-  public static native void doCommonClassRedefinition(Class<?> target,
-                                                      byte[] classfile,
-                                                      byte[] dexfile);
-
-  public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
-    ArrayList<Class<?>> classes = new ArrayList<>();
-    ArrayList<byte[]> class_files = new ArrayList<>();
-    ArrayList<byte[]> dex_files = new ArrayList<>();
-
-    for (CommonClassDefinition d : defs) {
-      classes.add(d.target);
-      class_files.add(d.class_file_bytes);
-      dex_files.add(d.dex_file_bytes);
-    }
-    doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
-                                   class_files.toArray(new byte[0][]),
-                                   dex_files.toArray(new byte[0][]));
-  }
-
-  public static void addMultiTransformationResults(CommonClassDefinition... defs) {
-    for (CommonClassDefinition d : defs) {
-      addCommonTransformationResult(d.target.getCanonicalName(),
-                                    d.class_file_bytes,
-                                    d.dex_file_bytes);
-    }
-  }
-
-  public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
-                                                           byte[][] classfiles,
-                                                           byte[][] dexfiles);
-  public static native void doCommonClassRetransformation(Class<?>... target);
-  public static native void setPopRetransformations(boolean pop);
-  public static native void popTransformationFor(String name);
-  public static native void enableCommonRetransformation(boolean enable);
-  public static native void addCommonTransformationResult(String target_name,
-                                                          byte[] class_bytes,
-                                                          byte[] dex_bytes);
-}
diff --git a/test/949-in-memory-transform/src/art/Redefinition.java b/test/949-in-memory-transform/src/art/Redefinition.java
new file mode 120000
index 0000000..81eaf31
--- /dev/null
+++ b/test/949-in-memory-transform/src/art/Redefinition.java
@@ -0,0 +1 @@
+../../../jvmti-common/Redefinition.java
\ No newline at end of file
diff --git a/test/950-redefine-intrinsic/src/art/Redefinition.java b/test/950-redefine-intrinsic/src/art/Redefinition.java
deleted file mode 100644
index 56d2938..0000000
--- a/test/950-redefine-intrinsic/src/art/Redefinition.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.util.ArrayList;
-// Common Redefinition functions. Placed here for use by CTS
-public class Redefinition {
-  public static final class CommonClassDefinition {
-    public final Class<?> target;
-    public final byte[] class_file_bytes;
-    public final byte[] dex_file_bytes;
-
-    public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
-      this.target = target;
-      this.class_file_bytes = class_file_bytes;
-      this.dex_file_bytes = dex_file_bytes;
-    }
-  }
-
-  // A set of possible test configurations. Test should set this if they need to.
-  // This must be kept in sync with the defines in ti-agent/common_helper.cc
-  public static enum Config {
-    COMMON_REDEFINE(0),
-    COMMON_RETRANSFORM(1),
-    COMMON_TRANSFORM(2);
-
-    private final int val;
-    private Config(int val) {
-      this.val = val;
-    }
-  }
-
-  public static void setTestConfiguration(Config type) {
-    nativeSetTestConfiguration(type.val);
-  }
-
-  private static native void nativeSetTestConfiguration(int type);
-
-  // Transforms the class
-  public static native void doCommonClassRedefinition(Class<?> target,
-                                                      byte[] classfile,
-                                                      byte[] dexfile);
-
-  public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
-    ArrayList<Class<?>> classes = new ArrayList<>();
-    ArrayList<byte[]> class_files = new ArrayList<>();
-    ArrayList<byte[]> dex_files = new ArrayList<>();
-
-    for (CommonClassDefinition d : defs) {
-      classes.add(d.target);
-      class_files.add(d.class_file_bytes);
-      dex_files.add(d.dex_file_bytes);
-    }
-    doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
-                                   class_files.toArray(new byte[0][]),
-                                   dex_files.toArray(new byte[0][]));
-  }
-
-  public static void addMultiTransformationResults(CommonClassDefinition... defs) {
-    for (CommonClassDefinition d : defs) {
-      addCommonTransformationResult(d.target.getCanonicalName(),
-                                    d.class_file_bytes,
-                                    d.dex_file_bytes);
-    }
-  }
-
-  public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
-                                                           byte[][] classfiles,
-                                                           byte[][] dexfiles);
-  public static native void doCommonClassRetransformation(Class<?>... target);
-  public static native void setPopRetransformations(boolean pop);
-  public static native void popTransformationFor(String name);
-  public static native void enableCommonRetransformation(boolean enable);
-  public static native void addCommonTransformationResult(String target_name,
-                                                          byte[] class_bytes,
-                                                          byte[] dex_bytes);
-}
diff --git a/test/950-redefine-intrinsic/src/art/Redefinition.java b/test/950-redefine-intrinsic/src/art/Redefinition.java
new file mode 120000
index 0000000..81eaf31
--- /dev/null
+++ b/test/950-redefine-intrinsic/src/art/Redefinition.java
@@ -0,0 +1 @@
+../../../jvmti-common/Redefinition.java
\ No newline at end of file
diff --git a/test/951-threaded-obsolete/src/art/Redefinition.java b/test/951-threaded-obsolete/src/art/Redefinition.java
deleted file mode 100644
index 56d2938..0000000
--- a/test/951-threaded-obsolete/src/art/Redefinition.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.util.ArrayList;
-// Common Redefinition functions. Placed here for use by CTS
-public class Redefinition {
-  public static final class CommonClassDefinition {
-    public final Class<?> target;
-    public final byte[] class_file_bytes;
-    public final byte[] dex_file_bytes;
-
-    public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
-      this.target = target;
-      this.class_file_bytes = class_file_bytes;
-      this.dex_file_bytes = dex_file_bytes;
-    }
-  }
-
-  // A set of possible test configurations. Test should set this if they need to.
-  // This must be kept in sync with the defines in ti-agent/common_helper.cc
-  public static enum Config {
-    COMMON_REDEFINE(0),
-    COMMON_RETRANSFORM(1),
-    COMMON_TRANSFORM(2);
-
-    private final int val;
-    private Config(int val) {
-      this.val = val;
-    }
-  }
-
-  public static void setTestConfiguration(Config type) {
-    nativeSetTestConfiguration(type.val);
-  }
-
-  private static native void nativeSetTestConfiguration(int type);
-
-  // Transforms the class
-  public static native void doCommonClassRedefinition(Class<?> target,
-                                                      byte[] classfile,
-                                                      byte[] dexfile);
-
-  public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
-    ArrayList<Class<?>> classes = new ArrayList<>();
-    ArrayList<byte[]> class_files = new ArrayList<>();
-    ArrayList<byte[]> dex_files = new ArrayList<>();
-
-    for (CommonClassDefinition d : defs) {
-      classes.add(d.target);
-      class_files.add(d.class_file_bytes);
-      dex_files.add(d.dex_file_bytes);
-    }
-    doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
-                                   class_files.toArray(new byte[0][]),
-                                   dex_files.toArray(new byte[0][]));
-  }
-
-  public static void addMultiTransformationResults(CommonClassDefinition... defs) {
-    for (CommonClassDefinition d : defs) {
-      addCommonTransformationResult(d.target.getCanonicalName(),
-                                    d.class_file_bytes,
-                                    d.dex_file_bytes);
-    }
-  }
-
-  public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
-                                                           byte[][] classfiles,
-                                                           byte[][] dexfiles);
-  public static native void doCommonClassRetransformation(Class<?>... target);
-  public static native void setPopRetransformations(boolean pop);
-  public static native void popTransformationFor(String name);
-  public static native void enableCommonRetransformation(boolean enable);
-  public static native void addCommonTransformationResult(String target_name,
-                                                          byte[] class_bytes,
-                                                          byte[] dex_bytes);
-}
diff --git a/test/951-threaded-obsolete/src/art/Redefinition.java b/test/951-threaded-obsolete/src/art/Redefinition.java
new file mode 120000
index 0000000..81eaf31
--- /dev/null
+++ b/test/951-threaded-obsolete/src/art/Redefinition.java
@@ -0,0 +1 @@
+../../../jvmti-common/Redefinition.java
\ No newline at end of file
diff --git a/test/982-ok-no-retransform/src/art/Redefinition.java b/test/982-ok-no-retransform/src/art/Redefinition.java
deleted file mode 100644
index 56d2938..0000000
--- a/test/982-ok-no-retransform/src/art/Redefinition.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.util.ArrayList;
-// Common Redefinition functions. Placed here for use by CTS
-public class Redefinition {
-  public static final class CommonClassDefinition {
-    public final Class<?> target;
-    public final byte[] class_file_bytes;
-    public final byte[] dex_file_bytes;
-
-    public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
-      this.target = target;
-      this.class_file_bytes = class_file_bytes;
-      this.dex_file_bytes = dex_file_bytes;
-    }
-  }
-
-  // A set of possible test configurations. Test should set this if they need to.
-  // This must be kept in sync with the defines in ti-agent/common_helper.cc
-  public static enum Config {
-    COMMON_REDEFINE(0),
-    COMMON_RETRANSFORM(1),
-    COMMON_TRANSFORM(2);
-
-    private final int val;
-    private Config(int val) {
-      this.val = val;
-    }
-  }
-
-  public static void setTestConfiguration(Config type) {
-    nativeSetTestConfiguration(type.val);
-  }
-
-  private static native void nativeSetTestConfiguration(int type);
-
-  // Transforms the class
-  public static native void doCommonClassRedefinition(Class<?> target,
-                                                      byte[] classfile,
-                                                      byte[] dexfile);
-
-  public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
-    ArrayList<Class<?>> classes = new ArrayList<>();
-    ArrayList<byte[]> class_files = new ArrayList<>();
-    ArrayList<byte[]> dex_files = new ArrayList<>();
-
-    for (CommonClassDefinition d : defs) {
-      classes.add(d.target);
-      class_files.add(d.class_file_bytes);
-      dex_files.add(d.dex_file_bytes);
-    }
-    doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
-                                   class_files.toArray(new byte[0][]),
-                                   dex_files.toArray(new byte[0][]));
-  }
-
-  public static void addMultiTransformationResults(CommonClassDefinition... defs) {
-    for (CommonClassDefinition d : defs) {
-      addCommonTransformationResult(d.target.getCanonicalName(),
-                                    d.class_file_bytes,
-                                    d.dex_file_bytes);
-    }
-  }
-
-  public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
-                                                           byte[][] classfiles,
-                                                           byte[][] dexfiles);
-  public static native void doCommonClassRetransformation(Class<?>... target);
-  public static native void setPopRetransformations(boolean pop);
-  public static native void popTransformationFor(String name);
-  public static native void enableCommonRetransformation(boolean enable);
-  public static native void addCommonTransformationResult(String target_name,
-                                                          byte[] class_bytes,
-                                                          byte[] dex_bytes);
-}
diff --git a/test/982-ok-no-retransform/src/art/Redefinition.java b/test/982-ok-no-retransform/src/art/Redefinition.java
new file mode 120000
index 0000000..81eaf31
--- /dev/null
+++ b/test/982-ok-no-retransform/src/art/Redefinition.java
@@ -0,0 +1 @@
+../../../jvmti-common/Redefinition.java
\ No newline at end of file
diff --git a/test/983-source-transform-verify/src/art/Redefinition.java b/test/983-source-transform-verify/src/art/Redefinition.java
deleted file mode 100644
index 56d2938..0000000
--- a/test/983-source-transform-verify/src/art/Redefinition.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.util.ArrayList;
-// Common Redefinition functions. Placed here for use by CTS
-public class Redefinition {
-  public static final class CommonClassDefinition {
-    public final Class<?> target;
-    public final byte[] class_file_bytes;
-    public final byte[] dex_file_bytes;
-
-    public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
-      this.target = target;
-      this.class_file_bytes = class_file_bytes;
-      this.dex_file_bytes = dex_file_bytes;
-    }
-  }
-
-  // A set of possible test configurations. Test should set this if they need to.
-  // This must be kept in sync with the defines in ti-agent/common_helper.cc
-  public static enum Config {
-    COMMON_REDEFINE(0),
-    COMMON_RETRANSFORM(1),
-    COMMON_TRANSFORM(2);
-
-    private final int val;
-    private Config(int val) {
-      this.val = val;
-    }
-  }
-
-  public static void setTestConfiguration(Config type) {
-    nativeSetTestConfiguration(type.val);
-  }
-
-  private static native void nativeSetTestConfiguration(int type);
-
-  // Transforms the class
-  public static native void doCommonClassRedefinition(Class<?> target,
-                                                      byte[] classfile,
-                                                      byte[] dexfile);
-
-  public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
-    ArrayList<Class<?>> classes = new ArrayList<>();
-    ArrayList<byte[]> class_files = new ArrayList<>();
-    ArrayList<byte[]> dex_files = new ArrayList<>();
-
-    for (CommonClassDefinition d : defs) {
-      classes.add(d.target);
-      class_files.add(d.class_file_bytes);
-      dex_files.add(d.dex_file_bytes);
-    }
-    doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
-                                   class_files.toArray(new byte[0][]),
-                                   dex_files.toArray(new byte[0][]));
-  }
-
-  public static void addMultiTransformationResults(CommonClassDefinition... defs) {
-    for (CommonClassDefinition d : defs) {
-      addCommonTransformationResult(d.target.getCanonicalName(),
-                                    d.class_file_bytes,
-                                    d.dex_file_bytes);
-    }
-  }
-
-  public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
-                                                           byte[][] classfiles,
-                                                           byte[][] dexfiles);
-  public static native void doCommonClassRetransformation(Class<?>... target);
-  public static native void setPopRetransformations(boolean pop);
-  public static native void popTransformationFor(String name);
-  public static native void enableCommonRetransformation(boolean enable);
-  public static native void addCommonTransformationResult(String target_name,
-                                                          byte[] class_bytes,
-                                                          byte[] dex_bytes);
-}
diff --git a/test/983-source-transform-verify/src/art/Redefinition.java b/test/983-source-transform-verify/src/art/Redefinition.java
new file mode 120000
index 0000000..81eaf31
--- /dev/null
+++ b/test/983-source-transform-verify/src/art/Redefinition.java
@@ -0,0 +1 @@
+../../../jvmti-common/Redefinition.java
\ No newline at end of file
diff --git a/test/984-obsolete-invoke/src/art/Redefinition.java b/test/984-obsolete-invoke/src/art/Redefinition.java
deleted file mode 100644
index 56d2938..0000000
--- a/test/984-obsolete-invoke/src/art/Redefinition.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.util.ArrayList;
-// Common Redefinition functions. Placed here for use by CTS
-public class Redefinition {
-  public static final class CommonClassDefinition {
-    public final Class<?> target;
-    public final byte[] class_file_bytes;
-    public final byte[] dex_file_bytes;
-
-    public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
-      this.target = target;
-      this.class_file_bytes = class_file_bytes;
-      this.dex_file_bytes = dex_file_bytes;
-    }
-  }
-
-  // A set of possible test configurations. Test should set this if they need to.
-  // This must be kept in sync with the defines in ti-agent/common_helper.cc
-  public static enum Config {
-    COMMON_REDEFINE(0),
-    COMMON_RETRANSFORM(1),
-    COMMON_TRANSFORM(2);
-
-    private final int val;
-    private Config(int val) {
-      this.val = val;
-    }
-  }
-
-  public static void setTestConfiguration(Config type) {
-    nativeSetTestConfiguration(type.val);
-  }
-
-  private static native void nativeSetTestConfiguration(int type);
-
-  // Transforms the class
-  public static native void doCommonClassRedefinition(Class<?> target,
-                                                      byte[] classfile,
-                                                      byte[] dexfile);
-
-  public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
-    ArrayList<Class<?>> classes = new ArrayList<>();
-    ArrayList<byte[]> class_files = new ArrayList<>();
-    ArrayList<byte[]> dex_files = new ArrayList<>();
-
-    for (CommonClassDefinition d : defs) {
-      classes.add(d.target);
-      class_files.add(d.class_file_bytes);
-      dex_files.add(d.dex_file_bytes);
-    }
-    doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
-                                   class_files.toArray(new byte[0][]),
-                                   dex_files.toArray(new byte[0][]));
-  }
-
-  public static void addMultiTransformationResults(CommonClassDefinition... defs) {
-    for (CommonClassDefinition d : defs) {
-      addCommonTransformationResult(d.target.getCanonicalName(),
-                                    d.class_file_bytes,
-                                    d.dex_file_bytes);
-    }
-  }
-
-  public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
-                                                           byte[][] classfiles,
-                                                           byte[][] dexfiles);
-  public static native void doCommonClassRetransformation(Class<?>... target);
-  public static native void setPopRetransformations(boolean pop);
-  public static native void popTransformationFor(String name);
-  public static native void enableCommonRetransformation(boolean enable);
-  public static native void addCommonTransformationResult(String target_name,
-                                                          byte[] class_bytes,
-                                                          byte[] dex_bytes);
-}
diff --git a/test/984-obsolete-invoke/src/art/Redefinition.java b/test/984-obsolete-invoke/src/art/Redefinition.java
new file mode 120000
index 0000000..81eaf31
--- /dev/null
+++ b/test/984-obsolete-invoke/src/art/Redefinition.java
@@ -0,0 +1 @@
+../../../jvmti-common/Redefinition.java
\ No newline at end of file
diff --git a/test/985-re-obsolete/src/art/Redefinition.java b/test/985-re-obsolete/src/art/Redefinition.java
deleted file mode 100644
index 56d2938..0000000
--- a/test/985-re-obsolete/src/art/Redefinition.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.util.ArrayList;
-// Common Redefinition functions. Placed here for use by CTS
-public class Redefinition {
-  public static final class CommonClassDefinition {
-    public final Class<?> target;
-    public final byte[] class_file_bytes;
-    public final byte[] dex_file_bytes;
-
-    public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
-      this.target = target;
-      this.class_file_bytes = class_file_bytes;
-      this.dex_file_bytes = dex_file_bytes;
-    }
-  }
-
-  // A set of possible test configurations. Test should set this if they need to.
-  // This must be kept in sync with the defines in ti-agent/common_helper.cc
-  public static enum Config {
-    COMMON_REDEFINE(0),
-    COMMON_RETRANSFORM(1),
-    COMMON_TRANSFORM(2);
-
-    private final int val;
-    private Config(int val) {
-      this.val = val;
-    }
-  }
-
-  public static void setTestConfiguration(Config type) {
-    nativeSetTestConfiguration(type.val);
-  }
-
-  private static native void nativeSetTestConfiguration(int type);
-
-  // Transforms the class
-  public static native void doCommonClassRedefinition(Class<?> target,
-                                                      byte[] classfile,
-                                                      byte[] dexfile);
-
-  public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
-    ArrayList<Class<?>> classes = new ArrayList<>();
-    ArrayList<byte[]> class_files = new ArrayList<>();
-    ArrayList<byte[]> dex_files = new ArrayList<>();
-
-    for (CommonClassDefinition d : defs) {
-      classes.add(d.target);
-      class_files.add(d.class_file_bytes);
-      dex_files.add(d.dex_file_bytes);
-    }
-    doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
-                                   class_files.toArray(new byte[0][]),
-                                   dex_files.toArray(new byte[0][]));
-  }
-
-  public static void addMultiTransformationResults(CommonClassDefinition... defs) {
-    for (CommonClassDefinition d : defs) {
-      addCommonTransformationResult(d.target.getCanonicalName(),
-                                    d.class_file_bytes,
-                                    d.dex_file_bytes);
-    }
-  }
-
-  public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
-                                                           byte[][] classfiles,
-                                                           byte[][] dexfiles);
-  public static native void doCommonClassRetransformation(Class<?>... target);
-  public static native void setPopRetransformations(boolean pop);
-  public static native void popTransformationFor(String name);
-  public static native void enableCommonRetransformation(boolean enable);
-  public static native void addCommonTransformationResult(String target_name,
-                                                          byte[] class_bytes,
-                                                          byte[] dex_bytes);
-}
diff --git a/test/985-re-obsolete/src/art/Redefinition.java b/test/985-re-obsolete/src/art/Redefinition.java
new file mode 120000
index 0000000..81eaf31
--- /dev/null
+++ b/test/985-re-obsolete/src/art/Redefinition.java
@@ -0,0 +1 @@
+../../../jvmti-common/Redefinition.java
\ No newline at end of file
diff --git a/test/988-method-trace/src/art/Trace.java b/test/988-method-trace/src/art/Trace.java
deleted file mode 100644
index 8999bb1..0000000
--- a/test/988-method-trace/src/art/Trace.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-
-public class Trace {
-  public static native void enableTracing(Class<?> methodClass,
-                                          Method entryMethod,
-                                          Method exitMethod,
-                                          Method fieldAccess,
-                                          Method fieldModify,
-                                          Method singleStep,
-                                          Thread thr);
-  public static native void disableTracing(Thread thr);
-
-  public static void enableFieldTracing(Class<?> methodClass,
-                                        Method fieldAccess,
-                                        Method fieldModify,
-                                        Thread thr) {
-    enableTracing(methodClass, null, null, fieldAccess, fieldModify, null, thr);
-  }
-
-  public static void enableMethodTracing(Class<?> methodClass,
-                                         Method entryMethod,
-                                         Method exitMethod,
-                                         Thread thr) {
-    enableTracing(methodClass, entryMethod, exitMethod, null, null, null, thr);
-  }
-
-  public static void enableSingleStepTracing(Class<?> methodClass,
-                                             Method singleStep,
-                                             Thread thr) {
-    enableTracing(methodClass, null, null, null, null, singleStep, thr);
-  }
-
-  public static native void watchFieldAccess(Field f);
-  public static native void watchFieldModification(Field f);
-  public static native void watchAllFieldAccesses();
-  public static native void watchAllFieldModifications();
-
-  // the names, arguments, and even line numbers of these functions are embedded in the tests so we
-  // need to add to the bottom and not modify old ones to maintain compat.
-  public static native void enableTracing2(Class<?> methodClass,
-                                           Method entryMethod,
-                                           Method exitMethod,
-                                           Method fieldAccess,
-                                           Method fieldModify,
-                                           Method singleStep,
-                                           Method ThreadStart,
-                                           Method ThreadEnd,
-                                           Thread thr);
-}
diff --git a/test/988-method-trace/src/art/Trace.java b/test/988-method-trace/src/art/Trace.java
new file mode 120000
index 0000000..5d9b44b
--- /dev/null
+++ b/test/988-method-trace/src/art/Trace.java
@@ -0,0 +1 @@
+../../../jvmti-common/Trace.java
\ No newline at end of file
diff --git a/test/989-method-trace-throw/src/art/Trace.java b/test/989-method-trace-throw/src/art/Trace.java
deleted file mode 100644
index 8999bb1..0000000
--- a/test/989-method-trace-throw/src/art/Trace.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-
-public class Trace {
-  public static native void enableTracing(Class<?> methodClass,
-                                          Method entryMethod,
-                                          Method exitMethod,
-                                          Method fieldAccess,
-                                          Method fieldModify,
-                                          Method singleStep,
-                                          Thread thr);
-  public static native void disableTracing(Thread thr);
-
-  public static void enableFieldTracing(Class<?> methodClass,
-                                        Method fieldAccess,
-                                        Method fieldModify,
-                                        Thread thr) {
-    enableTracing(methodClass, null, null, fieldAccess, fieldModify, null, thr);
-  }
-
-  public static void enableMethodTracing(Class<?> methodClass,
-                                         Method entryMethod,
-                                         Method exitMethod,
-                                         Thread thr) {
-    enableTracing(methodClass, entryMethod, exitMethod, null, null, null, thr);
-  }
-
-  public static void enableSingleStepTracing(Class<?> methodClass,
-                                             Method singleStep,
-                                             Thread thr) {
-    enableTracing(methodClass, null, null, null, null, singleStep, thr);
-  }
-
-  public static native void watchFieldAccess(Field f);
-  public static native void watchFieldModification(Field f);
-  public static native void watchAllFieldAccesses();
-  public static native void watchAllFieldModifications();
-
-  // the names, arguments, and even line numbers of these functions are embedded in the tests so we
-  // need to add to the bottom and not modify old ones to maintain compat.
-  public static native void enableTracing2(Class<?> methodClass,
-                                           Method entryMethod,
-                                           Method exitMethod,
-                                           Method fieldAccess,
-                                           Method fieldModify,
-                                           Method singleStep,
-                                           Method ThreadStart,
-                                           Method ThreadEnd,
-                                           Thread thr);
-}
diff --git a/test/989-method-trace-throw/src/art/Trace.java b/test/989-method-trace-throw/src/art/Trace.java
new file mode 120000
index 0000000..5d9b44b
--- /dev/null
+++ b/test/989-method-trace-throw/src/art/Trace.java
@@ -0,0 +1 @@
+../../../jvmti-common/Trace.java
\ No newline at end of file
diff --git a/test/990-field-trace/src/art/Trace.java b/test/990-field-trace/src/art/Trace.java
deleted file mode 100644
index 8999bb1..0000000
--- a/test/990-field-trace/src/art/Trace.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-
-public class Trace {
-  public static native void enableTracing(Class<?> methodClass,
-                                          Method entryMethod,
-                                          Method exitMethod,
-                                          Method fieldAccess,
-                                          Method fieldModify,
-                                          Method singleStep,
-                                          Thread thr);
-  public static native void disableTracing(Thread thr);
-
-  public static void enableFieldTracing(Class<?> methodClass,
-                                        Method fieldAccess,
-                                        Method fieldModify,
-                                        Thread thr) {
-    enableTracing(methodClass, null, null, fieldAccess, fieldModify, null, thr);
-  }
-
-  public static void enableMethodTracing(Class<?> methodClass,
-                                         Method entryMethod,
-                                         Method exitMethod,
-                                         Thread thr) {
-    enableTracing(methodClass, entryMethod, exitMethod, null, null, null, thr);
-  }
-
-  public static void enableSingleStepTracing(Class<?> methodClass,
-                                             Method singleStep,
-                                             Thread thr) {
-    enableTracing(methodClass, null, null, null, null, singleStep, thr);
-  }
-
-  public static native void watchFieldAccess(Field f);
-  public static native void watchFieldModification(Field f);
-  public static native void watchAllFieldAccesses();
-  public static native void watchAllFieldModifications();
-
-  // the names, arguments, and even line numbers of these functions are embedded in the tests so we
-  // need to add to the bottom and not modify old ones to maintain compat.
-  public static native void enableTracing2(Class<?> methodClass,
-                                           Method entryMethod,
-                                           Method exitMethod,
-                                           Method fieldAccess,
-                                           Method fieldModify,
-                                           Method singleStep,
-                                           Method ThreadStart,
-                                           Method ThreadEnd,
-                                           Thread thr);
-}
diff --git a/test/990-field-trace/src/art/Trace.java b/test/990-field-trace/src/art/Trace.java
new file mode 120000
index 0000000..5d9b44b
--- /dev/null
+++ b/test/990-field-trace/src/art/Trace.java
@@ -0,0 +1 @@
+../../../jvmti-common/Trace.java
\ No newline at end of file
diff --git a/test/991-field-trace-2/src/art/Trace.java b/test/991-field-trace-2/src/art/Trace.java
deleted file mode 100644
index 8999bb1..0000000
--- a/test/991-field-trace-2/src/art/Trace.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-
-public class Trace {
-  public static native void enableTracing(Class<?> methodClass,
-                                          Method entryMethod,
-                                          Method exitMethod,
-                                          Method fieldAccess,
-                                          Method fieldModify,
-                                          Method singleStep,
-                                          Thread thr);
-  public static native void disableTracing(Thread thr);
-
-  public static void enableFieldTracing(Class<?> methodClass,
-                                        Method fieldAccess,
-                                        Method fieldModify,
-                                        Thread thr) {
-    enableTracing(methodClass, null, null, fieldAccess, fieldModify, null, thr);
-  }
-
-  public static void enableMethodTracing(Class<?> methodClass,
-                                         Method entryMethod,
-                                         Method exitMethod,
-                                         Thread thr) {
-    enableTracing(methodClass, entryMethod, exitMethod, null, null, null, thr);
-  }
-
-  public static void enableSingleStepTracing(Class<?> methodClass,
-                                             Method singleStep,
-                                             Thread thr) {
-    enableTracing(methodClass, null, null, null, null, singleStep, thr);
-  }
-
-  public static native void watchFieldAccess(Field f);
-  public static native void watchFieldModification(Field f);
-  public static native void watchAllFieldAccesses();
-  public static native void watchAllFieldModifications();
-
-  // the names, arguments, and even line numbers of these functions are embedded in the tests so we
-  // need to add to the bottom and not modify old ones to maintain compat.
-  public static native void enableTracing2(Class<?> methodClass,
-                                           Method entryMethod,
-                                           Method exitMethod,
-                                           Method fieldAccess,
-                                           Method fieldModify,
-                                           Method singleStep,
-                                           Method ThreadStart,
-                                           Method ThreadEnd,
-                                           Thread thr);
-}
diff --git a/test/991-field-trace-2/src/art/Trace.java b/test/991-field-trace-2/src/art/Trace.java
new file mode 120000
index 0000000..5d9b44b
--- /dev/null
+++ b/test/991-field-trace-2/src/art/Trace.java
@@ -0,0 +1 @@
+../../../jvmti-common/Trace.java
\ No newline at end of file
diff --git a/test/993-breakpoints/src/art/Breakpoint.java b/test/993-breakpoints/src/art/Breakpoint.java
deleted file mode 100644
index bbb89f7..0000000
--- a/test/993-breakpoints/src/art/Breakpoint.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Executable;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.Objects;
-
-public class Breakpoint {
-  public static class Manager {
-    public static class BP {
-      public final Executable method;
-      public final long location;
-
-      public BP(Executable method) {
-        this(method, getStartLocation(method));
-      }
-
-      public BP(Executable method, long location) {
-        this.method = method;
-        this.location = location;
-      }
-
-      @Override
-      public boolean equals(Object other) {
-        return (other instanceof BP) &&
-            method.equals(((BP)other).method) &&
-            location == ((BP)other).location;
-      }
-
-      @Override
-      public String toString() {
-        return method.toString() + " @ " + getLine();
-      }
-
-      @Override
-      public int hashCode() {
-        return Objects.hash(method, location);
-      }
-
-      public int getLine() {
-        try {
-          LineNumber[] lines = getLineNumberTable(method);
-          int best = -1;
-          for (LineNumber l : lines) {
-            if (l.location > location) {
-              break;
-            } else {
-              best = l.line;
-            }
-          }
-          return best;
-        } catch (Exception e) {
-          return -1;
-        }
-      }
-    }
-
-    private Set<BP> breaks = new HashSet<>();
-
-    public void setBreakpoints(BP... bs) {
-      for (BP b : bs) {
-        if (breaks.add(b)) {
-          Breakpoint.setBreakpoint(b.method, b.location);
-        }
-      }
-    }
-    public void setBreakpoint(Executable method, long location) {
-      setBreakpoints(new BP(method, location));
-    }
-
-    public void clearBreakpoints(BP... bs) {
-      for (BP b : bs) {
-        if (breaks.remove(b)) {
-          Breakpoint.clearBreakpoint(b.method, b.location);
-        }
-      }
-    }
-    public void clearBreakpoint(Executable method, long location) {
-      clearBreakpoints(new BP(method, location));
-    }
-
-    public void clearAllBreakpoints() {
-      clearBreakpoints(breaks.toArray(new BP[0]));
-    }
-  }
-
-  public static void startBreakpointWatch(Class<?> methodClass,
-                                          Executable breakpointReached,
-                                          Thread thr) {
-    startBreakpointWatch(methodClass, breakpointReached, false, thr);
-  }
-
-  /**
-   * Enables the trapping of breakpoint events.
-   *
-   * If allowRecursive == true then breakpoints will be sent even if one is currently being handled.
-   */
-  public static native void startBreakpointWatch(Class<?> methodClass,
-                                                 Executable breakpointReached,
-                                                 boolean allowRecursive,
-                                                 Thread thr);
-  public static native void stopBreakpointWatch(Thread thr);
-
-  public static final class LineNumber implements Comparable<LineNumber> {
-    public final long location;
-    public final int line;
-
-    private LineNumber(long loc, int line) {
-      this.location = loc;
-      this.line = line;
-    }
-
-    public boolean equals(Object other) {
-      return other instanceof LineNumber && ((LineNumber)other).line == line &&
-          ((LineNumber)other).location == location;
-    }
-
-    public int compareTo(LineNumber other) {
-      int v = Integer.valueOf(line).compareTo(Integer.valueOf(other.line));
-      if (v != 0) {
-        return v;
-      } else {
-        return Long.valueOf(location).compareTo(Long.valueOf(other.location));
-      }
-    }
-  }
-
-  public static native void setBreakpoint(Executable m, long loc);
-  public static void setBreakpoint(Executable m, LineNumber l) {
-    setBreakpoint(m, l.location);
-  }
-
-  public static native void clearBreakpoint(Executable m, long loc);
-  public static void clearBreakpoint(Executable m, LineNumber l) {
-    clearBreakpoint(m, l.location);
-  }
-
-  private static native Object[] getLineNumberTableNative(Executable m);
-  public static LineNumber[] getLineNumberTable(Executable m) {
-    Object[] nativeTable = getLineNumberTableNative(m);
-    long[] location = (long[])(nativeTable[0]);
-    int[] lines = (int[])(nativeTable[1]);
-    if (lines.length != location.length) {
-      throw new Error("Lines and locations have different lengths!");
-    }
-    LineNumber[] out = new LineNumber[lines.length];
-    for (int i = 0; i < lines.length; i++) {
-      out[i] = new LineNumber(location[i], lines[i]);
-    }
-    return out;
-  }
-
-  public static native long getStartLocation(Executable m);
-
-  public static int locationToLine(Executable m, long location) {
-    try {
-      Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
-      int best = -1;
-      for (Breakpoint.LineNumber l : lines) {
-        if (l.location > location) {
-          break;
-        } else {
-          best = l.line;
-        }
-      }
-      return best;
-    } catch (Exception e) {
-      return -1;
-    }
-  }
-
-  public static long lineToLocation(Executable m, int line) throws Exception {
-    try {
-      Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
-      for (Breakpoint.LineNumber l : lines) {
-        if (l.line == line) {
-          return l.location;
-        }
-      }
-      throw new Exception("Unable to find line " + line + " in " + m);
-    } catch (Exception e) {
-      throw new Exception("Unable to get line number info for " + m, e);
-    }
-  }
-}
-
diff --git a/test/993-breakpoints/src/art/Breakpoint.java b/test/993-breakpoints/src/art/Breakpoint.java
new file mode 120000
index 0000000..3673916
--- /dev/null
+++ b/test/993-breakpoints/src/art/Breakpoint.java
@@ -0,0 +1 @@
+../../../jvmti-common/Breakpoint.java
\ No newline at end of file
diff --git a/test/994-breakpoint-line/src/art/Breakpoint.java b/test/994-breakpoint-line/src/art/Breakpoint.java
deleted file mode 100644
index bbb89f7..0000000
--- a/test/994-breakpoint-line/src/art/Breakpoint.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Executable;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.Objects;
-
-public class Breakpoint {
-  public static class Manager {
-    public static class BP {
-      public final Executable method;
-      public final long location;
-
-      public BP(Executable method) {
-        this(method, getStartLocation(method));
-      }
-
-      public BP(Executable method, long location) {
-        this.method = method;
-        this.location = location;
-      }
-
-      @Override
-      public boolean equals(Object other) {
-        return (other instanceof BP) &&
-            method.equals(((BP)other).method) &&
-            location == ((BP)other).location;
-      }
-
-      @Override
-      public String toString() {
-        return method.toString() + " @ " + getLine();
-      }
-
-      @Override
-      public int hashCode() {
-        return Objects.hash(method, location);
-      }
-
-      public int getLine() {
-        try {
-          LineNumber[] lines = getLineNumberTable(method);
-          int best = -1;
-          for (LineNumber l : lines) {
-            if (l.location > location) {
-              break;
-            } else {
-              best = l.line;
-            }
-          }
-          return best;
-        } catch (Exception e) {
-          return -1;
-        }
-      }
-    }
-
-    private Set<BP> breaks = new HashSet<>();
-
-    public void setBreakpoints(BP... bs) {
-      for (BP b : bs) {
-        if (breaks.add(b)) {
-          Breakpoint.setBreakpoint(b.method, b.location);
-        }
-      }
-    }
-    public void setBreakpoint(Executable method, long location) {
-      setBreakpoints(new BP(method, location));
-    }
-
-    public void clearBreakpoints(BP... bs) {
-      for (BP b : bs) {
-        if (breaks.remove(b)) {
-          Breakpoint.clearBreakpoint(b.method, b.location);
-        }
-      }
-    }
-    public void clearBreakpoint(Executable method, long location) {
-      clearBreakpoints(new BP(method, location));
-    }
-
-    public void clearAllBreakpoints() {
-      clearBreakpoints(breaks.toArray(new BP[0]));
-    }
-  }
-
-  public static void startBreakpointWatch(Class<?> methodClass,
-                                          Executable breakpointReached,
-                                          Thread thr) {
-    startBreakpointWatch(methodClass, breakpointReached, false, thr);
-  }
-
-  /**
-   * Enables the trapping of breakpoint events.
-   *
-   * If allowRecursive == true then breakpoints will be sent even if one is currently being handled.
-   */
-  public static native void startBreakpointWatch(Class<?> methodClass,
-                                                 Executable breakpointReached,
-                                                 boolean allowRecursive,
-                                                 Thread thr);
-  public static native void stopBreakpointWatch(Thread thr);
-
-  public static final class LineNumber implements Comparable<LineNumber> {
-    public final long location;
-    public final int line;
-
-    private LineNumber(long loc, int line) {
-      this.location = loc;
-      this.line = line;
-    }
-
-    public boolean equals(Object other) {
-      return other instanceof LineNumber && ((LineNumber)other).line == line &&
-          ((LineNumber)other).location == location;
-    }
-
-    public int compareTo(LineNumber other) {
-      int v = Integer.valueOf(line).compareTo(Integer.valueOf(other.line));
-      if (v != 0) {
-        return v;
-      } else {
-        return Long.valueOf(location).compareTo(Long.valueOf(other.location));
-      }
-    }
-  }
-
-  public static native void setBreakpoint(Executable m, long loc);
-  public static void setBreakpoint(Executable m, LineNumber l) {
-    setBreakpoint(m, l.location);
-  }
-
-  public static native void clearBreakpoint(Executable m, long loc);
-  public static void clearBreakpoint(Executable m, LineNumber l) {
-    clearBreakpoint(m, l.location);
-  }
-
-  private static native Object[] getLineNumberTableNative(Executable m);
-  public static LineNumber[] getLineNumberTable(Executable m) {
-    Object[] nativeTable = getLineNumberTableNative(m);
-    long[] location = (long[])(nativeTable[0]);
-    int[] lines = (int[])(nativeTable[1]);
-    if (lines.length != location.length) {
-      throw new Error("Lines and locations have different lengths!");
-    }
-    LineNumber[] out = new LineNumber[lines.length];
-    for (int i = 0; i < lines.length; i++) {
-      out[i] = new LineNumber(location[i], lines[i]);
-    }
-    return out;
-  }
-
-  public static native long getStartLocation(Executable m);
-
-  public static int locationToLine(Executable m, long location) {
-    try {
-      Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
-      int best = -1;
-      for (Breakpoint.LineNumber l : lines) {
-        if (l.location > location) {
-          break;
-        } else {
-          best = l.line;
-        }
-      }
-      return best;
-    } catch (Exception e) {
-      return -1;
-    }
-  }
-
-  public static long lineToLocation(Executable m, int line) throws Exception {
-    try {
-      Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
-      for (Breakpoint.LineNumber l : lines) {
-        if (l.line == line) {
-          return l.location;
-        }
-      }
-      throw new Exception("Unable to find line " + line + " in " + m);
-    } catch (Exception e) {
-      throw new Exception("Unable to get line number info for " + m, e);
-    }
-  }
-}
-
diff --git a/test/994-breakpoint-line/src/art/Breakpoint.java b/test/994-breakpoint-line/src/art/Breakpoint.java
new file mode 120000
index 0000000..3673916
--- /dev/null
+++ b/test/994-breakpoint-line/src/art/Breakpoint.java
@@ -0,0 +1 @@
+../../../jvmti-common/Breakpoint.java
\ No newline at end of file
diff --git a/test/995-breakpoints-throw/src/art/Breakpoint.java b/test/995-breakpoints-throw/src/art/Breakpoint.java
deleted file mode 100644
index bbb89f7..0000000
--- a/test/995-breakpoints-throw/src/art/Breakpoint.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Executable;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.Objects;
-
-public class Breakpoint {
-  public static class Manager {
-    public static class BP {
-      public final Executable method;
-      public final long location;
-
-      public BP(Executable method) {
-        this(method, getStartLocation(method));
-      }
-
-      public BP(Executable method, long location) {
-        this.method = method;
-        this.location = location;
-      }
-
-      @Override
-      public boolean equals(Object other) {
-        return (other instanceof BP) &&
-            method.equals(((BP)other).method) &&
-            location == ((BP)other).location;
-      }
-
-      @Override
-      public String toString() {
-        return method.toString() + " @ " + getLine();
-      }
-
-      @Override
-      public int hashCode() {
-        return Objects.hash(method, location);
-      }
-
-      public int getLine() {
-        try {
-          LineNumber[] lines = getLineNumberTable(method);
-          int best = -1;
-          for (LineNumber l : lines) {
-            if (l.location > location) {
-              break;
-            } else {
-              best = l.line;
-            }
-          }
-          return best;
-        } catch (Exception e) {
-          return -1;
-        }
-      }
-    }
-
-    private Set<BP> breaks = new HashSet<>();
-
-    public void setBreakpoints(BP... bs) {
-      for (BP b : bs) {
-        if (breaks.add(b)) {
-          Breakpoint.setBreakpoint(b.method, b.location);
-        }
-      }
-    }
-    public void setBreakpoint(Executable method, long location) {
-      setBreakpoints(new BP(method, location));
-    }
-
-    public void clearBreakpoints(BP... bs) {
-      for (BP b : bs) {
-        if (breaks.remove(b)) {
-          Breakpoint.clearBreakpoint(b.method, b.location);
-        }
-      }
-    }
-    public void clearBreakpoint(Executable method, long location) {
-      clearBreakpoints(new BP(method, location));
-    }
-
-    public void clearAllBreakpoints() {
-      clearBreakpoints(breaks.toArray(new BP[0]));
-    }
-  }
-
-  public static void startBreakpointWatch(Class<?> methodClass,
-                                          Executable breakpointReached,
-                                          Thread thr) {
-    startBreakpointWatch(methodClass, breakpointReached, false, thr);
-  }
-
-  /**
-   * Enables the trapping of breakpoint events.
-   *
-   * If allowRecursive == true then breakpoints will be sent even if one is currently being handled.
-   */
-  public static native void startBreakpointWatch(Class<?> methodClass,
-                                                 Executable breakpointReached,
-                                                 boolean allowRecursive,
-                                                 Thread thr);
-  public static native void stopBreakpointWatch(Thread thr);
-
-  public static final class LineNumber implements Comparable<LineNumber> {
-    public final long location;
-    public final int line;
-
-    private LineNumber(long loc, int line) {
-      this.location = loc;
-      this.line = line;
-    }
-
-    public boolean equals(Object other) {
-      return other instanceof LineNumber && ((LineNumber)other).line == line &&
-          ((LineNumber)other).location == location;
-    }
-
-    public int compareTo(LineNumber other) {
-      int v = Integer.valueOf(line).compareTo(Integer.valueOf(other.line));
-      if (v != 0) {
-        return v;
-      } else {
-        return Long.valueOf(location).compareTo(Long.valueOf(other.location));
-      }
-    }
-  }
-
-  public static native void setBreakpoint(Executable m, long loc);
-  public static void setBreakpoint(Executable m, LineNumber l) {
-    setBreakpoint(m, l.location);
-  }
-
-  public static native void clearBreakpoint(Executable m, long loc);
-  public static void clearBreakpoint(Executable m, LineNumber l) {
-    clearBreakpoint(m, l.location);
-  }
-
-  private static native Object[] getLineNumberTableNative(Executable m);
-  public static LineNumber[] getLineNumberTable(Executable m) {
-    Object[] nativeTable = getLineNumberTableNative(m);
-    long[] location = (long[])(nativeTable[0]);
-    int[] lines = (int[])(nativeTable[1]);
-    if (lines.length != location.length) {
-      throw new Error("Lines and locations have different lengths!");
-    }
-    LineNumber[] out = new LineNumber[lines.length];
-    for (int i = 0; i < lines.length; i++) {
-      out[i] = new LineNumber(location[i], lines[i]);
-    }
-    return out;
-  }
-
-  public static native long getStartLocation(Executable m);
-
-  public static int locationToLine(Executable m, long location) {
-    try {
-      Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
-      int best = -1;
-      for (Breakpoint.LineNumber l : lines) {
-        if (l.location > location) {
-          break;
-        } else {
-          best = l.line;
-        }
-      }
-      return best;
-    } catch (Exception e) {
-      return -1;
-    }
-  }
-
-  public static long lineToLocation(Executable m, int line) throws Exception {
-    try {
-      Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
-      for (Breakpoint.LineNumber l : lines) {
-        if (l.line == line) {
-          return l.location;
-        }
-      }
-      throw new Exception("Unable to find line " + line + " in " + m);
-    } catch (Exception e) {
-      throw new Exception("Unable to get line number info for " + m, e);
-    }
-  }
-}
-
diff --git a/test/995-breakpoints-throw/src/art/Breakpoint.java b/test/995-breakpoints-throw/src/art/Breakpoint.java
new file mode 120000
index 0000000..3673916
--- /dev/null
+++ b/test/995-breakpoints-throw/src/art/Breakpoint.java
@@ -0,0 +1 @@
+../../../jvmti-common/Breakpoint.java
\ No newline at end of file
diff --git a/test/996-breakpoint-obsolete/src/art/Breakpoint.java b/test/996-breakpoint-obsolete/src/art/Breakpoint.java
deleted file mode 100644
index bbb89f7..0000000
--- a/test/996-breakpoint-obsolete/src/art/Breakpoint.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Executable;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.Objects;
-
-public class Breakpoint {
-  public static class Manager {
-    public static class BP {
-      public final Executable method;
-      public final long location;
-
-      public BP(Executable method) {
-        this(method, getStartLocation(method));
-      }
-
-      public BP(Executable method, long location) {
-        this.method = method;
-        this.location = location;
-      }
-
-      @Override
-      public boolean equals(Object other) {
-        return (other instanceof BP) &&
-            method.equals(((BP)other).method) &&
-            location == ((BP)other).location;
-      }
-
-      @Override
-      public String toString() {
-        return method.toString() + " @ " + getLine();
-      }
-
-      @Override
-      public int hashCode() {
-        return Objects.hash(method, location);
-      }
-
-      public int getLine() {
-        try {
-          LineNumber[] lines = getLineNumberTable(method);
-          int best = -1;
-          for (LineNumber l : lines) {
-            if (l.location > location) {
-              break;
-            } else {
-              best = l.line;
-            }
-          }
-          return best;
-        } catch (Exception e) {
-          return -1;
-        }
-      }
-    }
-
-    private Set<BP> breaks = new HashSet<>();
-
-    public void setBreakpoints(BP... bs) {
-      for (BP b : bs) {
-        if (breaks.add(b)) {
-          Breakpoint.setBreakpoint(b.method, b.location);
-        }
-      }
-    }
-    public void setBreakpoint(Executable method, long location) {
-      setBreakpoints(new BP(method, location));
-    }
-
-    public void clearBreakpoints(BP... bs) {
-      for (BP b : bs) {
-        if (breaks.remove(b)) {
-          Breakpoint.clearBreakpoint(b.method, b.location);
-        }
-      }
-    }
-    public void clearBreakpoint(Executable method, long location) {
-      clearBreakpoints(new BP(method, location));
-    }
-
-    public void clearAllBreakpoints() {
-      clearBreakpoints(breaks.toArray(new BP[0]));
-    }
-  }
-
-  public static void startBreakpointWatch(Class<?> methodClass,
-                                          Executable breakpointReached,
-                                          Thread thr) {
-    startBreakpointWatch(methodClass, breakpointReached, false, thr);
-  }
-
-  /**
-   * Enables the trapping of breakpoint events.
-   *
-   * If allowRecursive == true then breakpoints will be sent even if one is currently being handled.
-   */
-  public static native void startBreakpointWatch(Class<?> methodClass,
-                                                 Executable breakpointReached,
-                                                 boolean allowRecursive,
-                                                 Thread thr);
-  public static native void stopBreakpointWatch(Thread thr);
-
-  public static final class LineNumber implements Comparable<LineNumber> {
-    public final long location;
-    public final int line;
-
-    private LineNumber(long loc, int line) {
-      this.location = loc;
-      this.line = line;
-    }
-
-    public boolean equals(Object other) {
-      return other instanceof LineNumber && ((LineNumber)other).line == line &&
-          ((LineNumber)other).location == location;
-    }
-
-    public int compareTo(LineNumber other) {
-      int v = Integer.valueOf(line).compareTo(Integer.valueOf(other.line));
-      if (v != 0) {
-        return v;
-      } else {
-        return Long.valueOf(location).compareTo(Long.valueOf(other.location));
-      }
-    }
-  }
-
-  public static native void setBreakpoint(Executable m, long loc);
-  public static void setBreakpoint(Executable m, LineNumber l) {
-    setBreakpoint(m, l.location);
-  }
-
-  public static native void clearBreakpoint(Executable m, long loc);
-  public static void clearBreakpoint(Executable m, LineNumber l) {
-    clearBreakpoint(m, l.location);
-  }
-
-  private static native Object[] getLineNumberTableNative(Executable m);
-  public static LineNumber[] getLineNumberTable(Executable m) {
-    Object[] nativeTable = getLineNumberTableNative(m);
-    long[] location = (long[])(nativeTable[0]);
-    int[] lines = (int[])(nativeTable[1]);
-    if (lines.length != location.length) {
-      throw new Error("Lines and locations have different lengths!");
-    }
-    LineNumber[] out = new LineNumber[lines.length];
-    for (int i = 0; i < lines.length; i++) {
-      out[i] = new LineNumber(location[i], lines[i]);
-    }
-    return out;
-  }
-
-  public static native long getStartLocation(Executable m);
-
-  public static int locationToLine(Executable m, long location) {
-    try {
-      Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
-      int best = -1;
-      for (Breakpoint.LineNumber l : lines) {
-        if (l.location > location) {
-          break;
-        } else {
-          best = l.line;
-        }
-      }
-      return best;
-    } catch (Exception e) {
-      return -1;
-    }
-  }
-
-  public static long lineToLocation(Executable m, int line) throws Exception {
-    try {
-      Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
-      for (Breakpoint.LineNumber l : lines) {
-        if (l.line == line) {
-          return l.location;
-        }
-      }
-      throw new Exception("Unable to find line " + line + " in " + m);
-    } catch (Exception e) {
-      throw new Exception("Unable to get line number info for " + m, e);
-    }
-  }
-}
-
diff --git a/test/996-breakpoint-obsolete/src/art/Breakpoint.java b/test/996-breakpoint-obsolete/src/art/Breakpoint.java
new file mode 120000
index 0000000..3673916
--- /dev/null
+++ b/test/996-breakpoint-obsolete/src/art/Breakpoint.java
@@ -0,0 +1 @@
+../../../jvmti-common/Breakpoint.java
\ No newline at end of file
diff --git a/test/996-breakpoint-obsolete/src/art/Redefinition.java b/test/996-breakpoint-obsolete/src/art/Redefinition.java
deleted file mode 100644
index 56d2938..0000000
--- a/test/996-breakpoint-obsolete/src/art/Redefinition.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.util.ArrayList;
-// Common Redefinition functions. Placed here for use by CTS
-public class Redefinition {
-  public static final class CommonClassDefinition {
-    public final Class<?> target;
-    public final byte[] class_file_bytes;
-    public final byte[] dex_file_bytes;
-
-    public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
-      this.target = target;
-      this.class_file_bytes = class_file_bytes;
-      this.dex_file_bytes = dex_file_bytes;
-    }
-  }
-
-  // A set of possible test configurations. Test should set this if they need to.
-  // This must be kept in sync with the defines in ti-agent/common_helper.cc
-  public static enum Config {
-    COMMON_REDEFINE(0),
-    COMMON_RETRANSFORM(1),
-    COMMON_TRANSFORM(2);
-
-    private final int val;
-    private Config(int val) {
-      this.val = val;
-    }
-  }
-
-  public static void setTestConfiguration(Config type) {
-    nativeSetTestConfiguration(type.val);
-  }
-
-  private static native void nativeSetTestConfiguration(int type);
-
-  // Transforms the class
-  public static native void doCommonClassRedefinition(Class<?> target,
-                                                      byte[] classfile,
-                                                      byte[] dexfile);
-
-  public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
-    ArrayList<Class<?>> classes = new ArrayList<>();
-    ArrayList<byte[]> class_files = new ArrayList<>();
-    ArrayList<byte[]> dex_files = new ArrayList<>();
-
-    for (CommonClassDefinition d : defs) {
-      classes.add(d.target);
-      class_files.add(d.class_file_bytes);
-      dex_files.add(d.dex_file_bytes);
-    }
-    doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
-                                   class_files.toArray(new byte[0][]),
-                                   dex_files.toArray(new byte[0][]));
-  }
-
-  public static void addMultiTransformationResults(CommonClassDefinition... defs) {
-    for (CommonClassDefinition d : defs) {
-      addCommonTransformationResult(d.target.getCanonicalName(),
-                                    d.class_file_bytes,
-                                    d.dex_file_bytes);
-    }
-  }
-
-  public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
-                                                           byte[][] classfiles,
-                                                           byte[][] dexfiles);
-  public static native void doCommonClassRetransformation(Class<?>... target);
-  public static native void setPopRetransformations(boolean pop);
-  public static native void popTransformationFor(String name);
-  public static native void enableCommonRetransformation(boolean enable);
-  public static native void addCommonTransformationResult(String target_name,
-                                                          byte[] class_bytes,
-                                                          byte[] dex_bytes);
-}
diff --git a/test/996-breakpoint-obsolete/src/art/Redefinition.java b/test/996-breakpoint-obsolete/src/art/Redefinition.java
new file mode 120000
index 0000000..81eaf31
--- /dev/null
+++ b/test/996-breakpoint-obsolete/src/art/Redefinition.java
@@ -0,0 +1 @@
+../../../jvmti-common/Redefinition.java
\ No newline at end of file
diff --git a/test/997-single-step/src/art/Breakpoint.java b/test/997-single-step/src/art/Breakpoint.java
deleted file mode 100644
index bbb89f7..0000000
--- a/test/997-single-step/src/art/Breakpoint.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Executable;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.Objects;
-
-public class Breakpoint {
-  public static class Manager {
-    public static class BP {
-      public final Executable method;
-      public final long location;
-
-      public BP(Executable method) {
-        this(method, getStartLocation(method));
-      }
-
-      public BP(Executable method, long location) {
-        this.method = method;
-        this.location = location;
-      }
-
-      @Override
-      public boolean equals(Object other) {
-        return (other instanceof BP) &&
-            method.equals(((BP)other).method) &&
-            location == ((BP)other).location;
-      }
-
-      @Override
-      public String toString() {
-        return method.toString() + " @ " + getLine();
-      }
-
-      @Override
-      public int hashCode() {
-        return Objects.hash(method, location);
-      }
-
-      public int getLine() {
-        try {
-          LineNumber[] lines = getLineNumberTable(method);
-          int best = -1;
-          for (LineNumber l : lines) {
-            if (l.location > location) {
-              break;
-            } else {
-              best = l.line;
-            }
-          }
-          return best;
-        } catch (Exception e) {
-          return -1;
-        }
-      }
-    }
-
-    private Set<BP> breaks = new HashSet<>();
-
-    public void setBreakpoints(BP... bs) {
-      for (BP b : bs) {
-        if (breaks.add(b)) {
-          Breakpoint.setBreakpoint(b.method, b.location);
-        }
-      }
-    }
-    public void setBreakpoint(Executable method, long location) {
-      setBreakpoints(new BP(method, location));
-    }
-
-    public void clearBreakpoints(BP... bs) {
-      for (BP b : bs) {
-        if (breaks.remove(b)) {
-          Breakpoint.clearBreakpoint(b.method, b.location);
-        }
-      }
-    }
-    public void clearBreakpoint(Executable method, long location) {
-      clearBreakpoints(new BP(method, location));
-    }
-
-    public void clearAllBreakpoints() {
-      clearBreakpoints(breaks.toArray(new BP[0]));
-    }
-  }
-
-  public static void startBreakpointWatch(Class<?> methodClass,
-                                          Executable breakpointReached,
-                                          Thread thr) {
-    startBreakpointWatch(methodClass, breakpointReached, false, thr);
-  }
-
-  /**
-   * Enables the trapping of breakpoint events.
-   *
-   * If allowRecursive == true then breakpoints will be sent even if one is currently being handled.
-   */
-  public static native void startBreakpointWatch(Class<?> methodClass,
-                                                 Executable breakpointReached,
-                                                 boolean allowRecursive,
-                                                 Thread thr);
-  public static native void stopBreakpointWatch(Thread thr);
-
-  public static final class LineNumber implements Comparable<LineNumber> {
-    public final long location;
-    public final int line;
-
-    private LineNumber(long loc, int line) {
-      this.location = loc;
-      this.line = line;
-    }
-
-    public boolean equals(Object other) {
-      return other instanceof LineNumber && ((LineNumber)other).line == line &&
-          ((LineNumber)other).location == location;
-    }
-
-    public int compareTo(LineNumber other) {
-      int v = Integer.valueOf(line).compareTo(Integer.valueOf(other.line));
-      if (v != 0) {
-        return v;
-      } else {
-        return Long.valueOf(location).compareTo(Long.valueOf(other.location));
-      }
-    }
-  }
-
-  public static native void setBreakpoint(Executable m, long loc);
-  public static void setBreakpoint(Executable m, LineNumber l) {
-    setBreakpoint(m, l.location);
-  }
-
-  public static native void clearBreakpoint(Executable m, long loc);
-  public static void clearBreakpoint(Executable m, LineNumber l) {
-    clearBreakpoint(m, l.location);
-  }
-
-  private static native Object[] getLineNumberTableNative(Executable m);
-  public static LineNumber[] getLineNumberTable(Executable m) {
-    Object[] nativeTable = getLineNumberTableNative(m);
-    long[] location = (long[])(nativeTable[0]);
-    int[] lines = (int[])(nativeTable[1]);
-    if (lines.length != location.length) {
-      throw new Error("Lines and locations have different lengths!");
-    }
-    LineNumber[] out = new LineNumber[lines.length];
-    for (int i = 0; i < lines.length; i++) {
-      out[i] = new LineNumber(location[i], lines[i]);
-    }
-    return out;
-  }
-
-  public static native long getStartLocation(Executable m);
-
-  public static int locationToLine(Executable m, long location) {
-    try {
-      Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
-      int best = -1;
-      for (Breakpoint.LineNumber l : lines) {
-        if (l.location > location) {
-          break;
-        } else {
-          best = l.line;
-        }
-      }
-      return best;
-    } catch (Exception e) {
-      return -1;
-    }
-  }
-
-  public static long lineToLocation(Executable m, int line) throws Exception {
-    try {
-      Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
-      for (Breakpoint.LineNumber l : lines) {
-        if (l.line == line) {
-          return l.location;
-        }
-      }
-      throw new Exception("Unable to find line " + line + " in " + m);
-    } catch (Exception e) {
-      throw new Exception("Unable to get line number info for " + m, e);
-    }
-  }
-}
-
diff --git a/test/997-single-step/src/art/Breakpoint.java b/test/997-single-step/src/art/Breakpoint.java
new file mode 120000
index 0000000..3673916
--- /dev/null
+++ b/test/997-single-step/src/art/Breakpoint.java
@@ -0,0 +1 @@
+../../../jvmti-common/Breakpoint.java
\ No newline at end of file
diff --git a/test/997-single-step/src/art/Trace.java b/test/997-single-step/src/art/Trace.java
deleted file mode 100644
index 8999bb1..0000000
--- a/test/997-single-step/src/art/Trace.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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.
- */
-
-package art;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-
-public class Trace {
-  public static native void enableTracing(Class<?> methodClass,
-                                          Method entryMethod,
-                                          Method exitMethod,
-                                          Method fieldAccess,
-                                          Method fieldModify,
-                                          Method singleStep,
-                                          Thread thr);
-  public static native void disableTracing(Thread thr);
-
-  public static void enableFieldTracing(Class<?> methodClass,
-                                        Method fieldAccess,
-                                        Method fieldModify,
-                                        Thread thr) {
-    enableTracing(methodClass, null, null, fieldAccess, fieldModify, null, thr);
-  }
-
-  public static void enableMethodTracing(Class<?> methodClass,
-                                         Method entryMethod,
-                                         Method exitMethod,
-                                         Thread thr) {
-    enableTracing(methodClass, entryMethod, exitMethod, null, null, null, thr);
-  }
-
-  public static void enableSingleStepTracing(Class<?> methodClass,
-                                             Method singleStep,
-                                             Thread thr) {
-    enableTracing(methodClass, null, null, null, null, singleStep, thr);
-  }
-
-  public static native void watchFieldAccess(Field f);
-  public static native void watchFieldModification(Field f);
-  public static native void watchAllFieldAccesses();
-  public static native void watchAllFieldModifications();
-
-  // the names, arguments, and even line numbers of these functions are embedded in the tests so we
-  // need to add to the bottom and not modify old ones to maintain compat.
-  public static native void enableTracing2(Class<?> methodClass,
-                                           Method entryMethod,
-                                           Method exitMethod,
-                                           Method fieldAccess,
-                                           Method fieldModify,
-                                           Method singleStep,
-                                           Method ThreadStart,
-                                           Method ThreadEnd,
-                                           Thread thr);
-}
diff --git a/test/997-single-step/src/art/Trace.java b/test/997-single-step/src/art/Trace.java
new file mode 120000
index 0000000..5d9b44b
--- /dev/null
+++ b/test/997-single-step/src/art/Trace.java
@@ -0,0 +1 @@
+../../../jvmti-common/Trace.java
\ No newline at end of file
diff --git a/test/999-redefine-hiddenapi/src/art/Redefinition.java b/test/999-redefine-hiddenapi/src/art/Redefinition.java
deleted file mode 100644
index 1eec70b..0000000
--- a/test/999-redefine-hiddenapi/src/art/Redefinition.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2018 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.ArrayList;
-// Common Redefinition functions. Placed here for use by CTS
-public class Redefinition {
-  public static final class CommonClassDefinition {
-    public final Class<?> target;
-    public final byte[] class_file_bytes;
-    public final byte[] dex_file_bytes;
-
-    public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
-      this.target = target;
-      this.class_file_bytes = class_file_bytes;
-      this.dex_file_bytes = dex_file_bytes;
-    }
-  }
-
-  // A set of possible test configurations. Test should set this if they need to.
-  // This must be kept in sync with the defines in ti-agent/common_helper.cc
-  public static enum Config {
-    COMMON_REDEFINE(0),
-    COMMON_RETRANSFORM(1),
-    COMMON_TRANSFORM(2);
-
-    private final int val;
-    private Config(int val) {
-      this.val = val;
-    }
-  }
-
-  public static void setTestConfiguration(Config type) {
-    nativeSetTestConfiguration(type.val);
-  }
-
-  private static native void nativeSetTestConfiguration(int type);
-
-  // Transforms the class
-  public static native void doCommonClassRedefinition(Class<?> target,
-                                                      byte[] classfile,
-                                                      byte[] dexfile);
-
-  public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
-    ArrayList<Class<?>> classes = new ArrayList<>();
-    ArrayList<byte[]> class_files = new ArrayList<>();
-    ArrayList<byte[]> dex_files = new ArrayList<>();
-
-    for (CommonClassDefinition d : defs) {
-      classes.add(d.target);
-      class_files.add(d.class_file_bytes);
-      dex_files.add(d.dex_file_bytes);
-    }
-    doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
-                                   class_files.toArray(new byte[0][]),
-                                   dex_files.toArray(new byte[0][]));
-  }
-
-  public static void addMultiTransformationResults(CommonClassDefinition... defs) {
-    for (CommonClassDefinition d : defs) {
-      addCommonTransformationResult(d.target.getCanonicalName(),
-                                    d.class_file_bytes,
-                                    d.dex_file_bytes);
-    }
-  }
-
-  public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
-                                                           byte[][] classfiles,
-                                                           byte[][] dexfiles);
-  public static native void doCommonClassRetransformation(Class<?>... target);
-  public static native void setPopRetransformations(boolean pop);
-  public static native void popTransformationFor(String name);
-  public static native void enableCommonRetransformation(boolean enable);
-  public static native void addCommonTransformationResult(String target_name,
-                                                          byte[] class_bytes,
-                                                          byte[] dex_bytes);
-}
diff --git a/test/999-redefine-hiddenapi/src/art/Redefinition.java b/test/999-redefine-hiddenapi/src/art/Redefinition.java
new file mode 120000
index 0000000..81eaf31
--- /dev/null
+++ b/test/999-redefine-hiddenapi/src/art/Redefinition.java
@@ -0,0 +1 @@
+../../../jvmti-common/Redefinition.java
\ No newline at end of file
diff --git a/test/Android.bp b/test/Android.bp
index 380a25d..5ebca66 100644
--- a/test/Android.bp
+++ b/test/Android.bp
@@ -568,18 +568,18 @@
     name: "art_cts_jvmti_test_library",
     srcs: [
         // shim classes. We use one that exposes the common functionality.
-        "902-hello-transformation/src/art/Redefinition.java",
-        "903-hello-tagging/src/art/Main.java",
-        "989-method-trace-throw/src/art/Trace.java",
-        "993-breakpoints/src/art/Breakpoint.java",
-        "1902-suspend/src/art/Suspension.java",
-        "1911-get-local-var-table/src/art/Locals.java",
-        "1912-get-set-local-primitive/src/art/StackTrace.java",
-        "1923-frame-pop/src/art/FramePop.java",
-        "1927-exception-event/src/art/Exceptions.java",
-        "1930-monitor-info/src/art/Monitors.java",
-        "1934-jvmti-signal-thread/src/art/Threads.java",
-        "1953-pop-frame/src/art/SuspendEvents.java",
+        "jvmti-common/Redefinition.java",
+        "jvmti-common/Main.java",
+        "jvmti-common/Trace.java",
+        "jvmti-common/Breakpoint.java",
+        "jvmti-common/Suspension.java",
+        "jvmti-common/Locals.java",
+        "jvmti-common/StackTrace.java",
+        "jvmti-common/FramePop.java",
+        "jvmti-common/Exceptions.java",
+        "jvmti-common/Monitors.java",
+        "jvmti-common/Threads.java",
+        "jvmti-common/SuspendEvents.java",
 
         // Actual test classes.
         "901-hello-ti-agent/src/art/Test901.java",
diff --git a/test/1923-frame-pop/src/art/Breakpoint.java b/test/jvmti-common/Breakpoint.java
similarity index 100%
rename from test/1923-frame-pop/src/art/Breakpoint.java
rename to test/jvmti-common/Breakpoint.java
diff --git a/test/1927-exception-event/src/art/Exceptions.java b/test/jvmti-common/Exceptions.java
similarity index 100%
rename from test/1927-exception-event/src/art/Exceptions.java
rename to test/jvmti-common/Exceptions.java
diff --git a/test/1923-frame-pop/src/art/FramePop.java b/test/jvmti-common/FramePop.java
similarity index 100%
rename from test/1923-frame-pop/src/art/FramePop.java
rename to test/jvmti-common/FramePop.java
diff --git a/test/1923-frame-pop/src/art/Locals.java b/test/jvmti-common/Locals.java
similarity index 100%
rename from test/1923-frame-pop/src/art/Locals.java
rename to test/jvmti-common/Locals.java
diff --git a/test/913-heaps/src/art/Main.java b/test/jvmti-common/Main.java
similarity index 100%
rename from test/913-heaps/src/art/Main.java
rename to test/jvmti-common/Main.java
diff --git a/test/1930-monitor-info/src/art/Monitors.java b/test/jvmti-common/Monitors.java
similarity index 100%
rename from test/1930-monitor-info/src/art/Monitors.java
rename to test/jvmti-common/Monitors.java
diff --git a/test/1953-pop-frame/src/art/Redefinition.java b/test/jvmti-common/Redefinition.java
similarity index 100%
rename from test/1953-pop-frame/src/art/Redefinition.java
rename to test/jvmti-common/Redefinition.java
diff --git a/test/1923-frame-pop/src/art/StackTrace.java b/test/jvmti-common/StackTrace.java
similarity index 100%
rename from test/1923-frame-pop/src/art/StackTrace.java
rename to test/jvmti-common/StackTrace.java
diff --git a/test/1953-pop-frame/src/art/SuspendEvents.java b/test/jvmti-common/SuspendEvents.java
similarity index 100%
rename from test/1953-pop-frame/src/art/SuspendEvents.java
rename to test/jvmti-common/SuspendEvents.java
diff --git a/test/1902-suspend/src/art/Suspension.java b/test/jvmti-common/Suspension.java
similarity index 100%
rename from test/1902-suspend/src/art/Suspension.java
rename to test/jvmti-common/Suspension.java
diff --git a/test/1934-jvmti-signal-thread/src/art/Threads.java b/test/jvmti-common/Threads.java
similarity index 100%
rename from test/1934-jvmti-signal-thread/src/art/Threads.java
rename to test/jvmti-common/Threads.java
diff --git a/test/1923-frame-pop/src/art/Trace.java b/test/jvmti-common/Trace.java
similarity index 100%
rename from test/1923-frame-pop/src/art/Trace.java
rename to test/jvmti-common/Trace.java