Centralize all the jvmti common test classes

We share many common JVMTI test classes between our various JVMTI
tests. We have always shared them by simply copying the .java files to
any tests that need them. This leads to very large code-reviews and
requires manual work if we ever need to update any of the helper
files.

To ensure everything stays in sync this moves all classes to a single
test/ti-common directory that tests then contain symlinks into.

Test: ./test.py --host
Change-Id: I82238a63d281429196ed0e640e4a9ec3234d954c
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