[RFC][debuginfo-test] Rename debug-info lit tests for general purposes

Discussion thread:
https://lists.llvm.org/pipermail/llvm-dev/2021-January/148048.html

Move debuginfo-test into a subdirectory of a new top-level directory,
called cross-project-tests. The new name replaces "debuginfo-test" as an
LLVM project enabled via LLVM_ENABLE_PROJECTS.

Differential Revision: https://reviews.llvm.org/D95339

Reviewed by: aprantl

GitOrigin-RevId: 1364750dadbb56032ef73b4d0d8cbc88a51392da
diff --git a/CMakeLists.txt b/CMakeLists.txt
deleted file mode 100644
index 0b01202..0000000
--- a/CMakeLists.txt
+++ /dev/null
@@ -1,74 +0,0 @@
-# Debug Info tests.  These tests invoke clang to generate programs with
-# various types of debug info, and then run those programs under a debugger
-# such as GDB or LLDB to verify the results.
-
-find_package(Python3 COMPONENTS Interpreter)
-
-add_llvm_executable(check-gdb-llvm-support
-        llvm-prettyprinters/gdb/llvm-support.cpp
-)
-target_link_libraries(check-gdb-llvm-support PRIVATE LLVMSupport)
-
-set(DEBUGINFO_TESTS_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
-set(DEBUGINFO_TESTS_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
-
-set(DEBUGINFO_TEST_DEPS
-  clang
-  FileCheck
-  count
-  llvm-config
-  llvm-objdump
-  check-gdb-llvm-support
-  not
-  )
-
-if ("mlir" IN_LIST LLVM_ENABLE_PROJECTS)
-  add_llvm_executable(check-gdb-mlir-support
-        llvm-prettyprinters/gdb/mlir-support.cpp
-  )
-  target_include_directories(check-gdb-mlir-support PRIVATE
-                               ${LLVM_EXTERNAL_MLIR_SOURCE_DIR}/include
-                               ${LLVM_BINARY_DIR}/tools/mlir/include)
-  target_link_libraries(check-gdb-mlir-support PRIVATE MLIRIR)
-  list(APPEND DEBUGINFO_TEST_DEPS check-gdb-mlir-support)
-  set(MLIR_SOURCE_DIR  ${LLVM_EXTERNAL_MLIR_SOURCE_DIR})
-endif()
-
-if("compiler-rt" IN_LIST LLVM_ENABLE_PROJECTS)
-  # llgdb-tests/asan.c and other asan* files.
-  if(TARGET asan)
-    list(APPEND DEBUGINFO_TEST_DEPS asan)
-  endif()
-  # llgdb-tests/safestack.c
-  if(TARGET safestack)
-    list(APPEND DEBUGINFO_TEST_DEPS safestack)
-  endif()
-endif()
-# Many dexter tests depend on lldb.
-if("lldb" IN_LIST LLVM_ENABLE_PROJECTS)
-  list(APPEND DEBUGINFO_TEST_DEPS lldb lldb-server)
-endif()
-
-# The Windows builder scripts pass -fuse-ld=lld.
-if (WIN32)
-  set(DEBUGINFO_TEST_DEPS ${DEBUGINFO_TEST_DEPS} lld)
-endif()
-
-configure_lit_site_cfg(
-  ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in
-  ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg.py
-  MAIN_CONFIG
-  ${CMAKE_CURRENT_SOURCE_DIR}/lit.cfg.py
-  )
-
-add_lit_testsuite(check-debuginfo "Running debug info integration tests"
-  ${CMAKE_CURRENT_BINARY_DIR}
-  DEPENDS ${DEBUGINFO_TEST_DEPS}
-  )
-
-# Add check-debuginfo-* targets.
-add_lit_testsuites(DEBUGINFO ${CMAKE_CURRENT_SOURCE_DIR}
-  DEPENDS ${DEBUGINFO_TEST_DEPS}
-  )
-
-set_target_properties(check-debuginfo PROPERTIES FOLDER "Debug info tests")
diff --git a/README.txt b/README.txt
deleted file mode 100644
index 544e6ff..0000000
--- a/README.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-                                                                   -*- rst -*-
-This is a collection of tests to check debugging information generated by 
-compiler. This test suite can be checked out inside clang/test folder. This 
-will enable 'make test' for clang to pick up these tests.
-
-Some tests (in the 'llgdb-tests' directory) are written with debugger
-commands and checks for the intended debugger output in the source file,
-using DEBUGGER: and CHECK: as prefixes respectively.
-
-For example::
-
-  define i32 @f1(i32 %i) nounwind ssp {
-  ; DEBUGGER: break f1
-  ; DEBUGGER: r
-  ; DEBUGGER: p i 
-  ; CHECK: $1 = 42 
-  entry:
-  }
-
-is a testcase where the debugger is asked to break at function 'f1' and 
-print value of argument 'i'. The expected value of 'i' is 42 in this case.
-
-Other tests are written for use with the 'Dexter' tool (in the 'dexter-tests'
-and 'dexter' directories respectively). These use a domain specific language
-in comments to describe the intended debugger experience in a more abstract
-way than debugger commands. This allows for testing integration across
-multiple debuggers from one input language.
-
-For example::
-
-  void __attribute__((noinline, optnone)) bar(int *test) {}
-  int main() {
-    int test;
-    test = 23;
-    bar(&test); // DexLabel('before_bar')
-    return test; // DexLabel('after_bar')
-  }
-
-  // DexExpectWatchValue('test', '23', on_line='before_bar')
-  // DexExpectWatchValue('test', '23', on_line='after_bar')
-
-Labels two lines with the names 'before_bar' and 'after_bar', and records that
-the 'test' variable is expected to have the value 23 on both of them.
diff --git a/dexter-tests/aggregate-indirect-arg.cpp b/dexter-tests/aggregate-indirect-arg.cpp
deleted file mode 100644
index f59777b..0000000
--- a/dexter-tests/aggregate-indirect-arg.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-// REQUIRES: lldb
-// UNSUPPORTED: system-windows
-//
-// RUN: %dexter --fail-lt 1.0 -w \
-// RUN:     --builder 'clang' --debugger 'lldb' --cflags "-O0 -g" \
-// RUN:     --ldflags="-lstdc++" -- %s
-// Radar 8945514
-
-class SVal {
-public:
-  ~SVal() {}
-  const void* Data;
-  unsigned Kind;
-};
-
-void bar(SVal &v) {}
-class A {
-public:
-  void foo(SVal v) { bar(v); } // DexLabel('foo')
-};
-
-int main() {
-  SVal v;
-  v.Data = 0;
-  v.Kind = 2142;
-  A a;
-  a.foo(v);
-  return 0;
-}
-
-/*
-DexExpectProgramState({
-  'frames': [
-    {
-      'location': { 'lineno': ref('foo') },
-      'watches': {
-        'v.Data == 0': 'true',
-        'v.Kind': '2142'
-      }
-    }
-  ]
-})
-*/
-
diff --git a/dexter-tests/asan-deque.cpp b/dexter-tests/asan-deque.cpp
deleted file mode 100644
index 373187f..0000000
--- a/dexter-tests/asan-deque.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-// REQUIRES: !asan, lldb
-// UNSUPPORTED: system-windows
-//           Zorg configures the ASAN stage2 bots to not build the asan
-//           compiler-rt. Only run this test on non-asanified configurations.
-// UNSUPPORTED: apple-lldb-pre-1000
-
-// XFAIL: lldb
-// lldb-8, even outside of dexter, will sometimes trigger an asan fault in
-// the debugged process and generally freak out.
-
-// RUN: %dexter --fail-lt 1.0 -w \
-// RUN:     --builder 'clang' --debugger 'lldb' \
-// RUN:     --cflags "-O1 -glldb -fsanitize=address -arch x86_64" \
-// RUN:     --ldflags="-fsanitize=address" -- %s
-#include <deque>
-
-struct A {
-  int a;
-  A(int a) : a(a) {}
-  A() : a(0) {}
-};
-
-using deq_t = std::deque<A>;
-
-template class std::deque<A>;
-
-static void __attribute__((noinline, optnone)) escape(deq_t &deq) {
-  static volatile deq_t *sink;
-  sink = &deq;
-}
-
-int main() {
-  deq_t deq;
-  deq.push_back(1234);
-  deq.push_back(56789);
-  escape(deq); // DexLabel('first')
-  while (!deq.empty()) {
-    auto record = deq.front();
-    deq.pop_front();
-    escape(deq); // DexLabel('second')
-  }
-}
-
-// DexExpectWatchValue('deq[0].a', '1234', on_line=ref('first'))
-// DexExpectWatchValue('deq[1].a', '56789', on_line=ref('first'))
-
-// DexExpectWatchValue('deq[0].a', '56789', '0', on_line=ref('second'))
-
diff --git a/dexter-tests/asan.c b/dexter-tests/asan.c
deleted file mode 100644
index 202f125..0000000
--- a/dexter-tests/asan.c
+++ /dev/null
@@ -1,29 +0,0 @@
-// REQUIRES: !asan, lldb
-// UNSUPPORTED: system-windows
-//           Zorg configures the ASAN stage2 bots to not build the asan
-//           compiler-rt. Only run this test on non-asanified configurations.
-//
-// RUN: %dexter --fail-lt 1.0 -w \
-// RUN:     --builder 'clang-c' --debugger 'lldb' \
-// RUN:     --cflags "--driver-mode=gcc -O0 -glldb -fblocks -arch x86_64 \
-// RUN:     -fsanitize=address" --ldflags="-fsanitize=address" -- %s
-
-struct S {
-  int a[8];
-};
-
-int f(struct S s, unsigned i) {
-  return s.a[i]; // DexLabel('asan')
-}
-
-int main(int argc, const char **argv) {
-  struct S s = {{0, 1, 2, 3, 4, 5, 6, 7}};
-  if (f(s, 4) == 4)
-    return f(s, 0);
-  return 0;
-}
-
-// DexExpectWatchValue('s.a[0]', '0', on_line=ref('asan'))
-// DexExpectWatchValue('s.a[1]', '1', on_line=ref('asan'))
-// DexExpectWatchValue('s.a[7]', '7', on_line=ref('asan'))
-
diff --git a/dexter-tests/ctor.cpp b/dexter-tests/ctor.cpp
deleted file mode 100644
index 219e902..0000000
--- a/dexter-tests/ctor.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-// REQUIRES: lldb
-// UNSUPPORTED: system-windows
-//
-// RUN: %dexter --fail-lt 1.0 -w \
-// RUN:     --builder 'clang' --debugger 'lldb' --cflags "-O0 -glldb" -- %s
-
-class A {
-public:
-	A() : zero(0), data(42) { // DexLabel('ctor_start')
-	}
-private:
-	int zero;
-	int data;
-};
-
-int main() {
-	A a;
-	return 0;
-}
-
-
-/*
-DexExpectProgramState({
-	'frames': [
-		{
-			'location': {
-				'lineno': ref('ctor_start')
-			},
-			'watches': {
-				'*this': {'is_irretrievable': False}
-			}
-		}
-	]
-})
-*/
-
diff --git a/dexter-tests/dbg-arg.c b/dexter-tests/dbg-arg.c
deleted file mode 100644
index 0ef27a0..0000000
--- a/dexter-tests/dbg-arg.c
+++ /dev/null
@@ -1,59 +0,0 @@
-// REQUIRES: lldb
-// UNSUPPORTED: system-windows
-//
-// This test case checks debug info during register moves for an argument.
-// RUN: %dexter --fail-lt 1.0 -w \
-// RUN:     --builder clang-c --debugger 'lldb' \
-// RUN:     --cflags "-m64 -mllvm -fast-isel=false -g" -- %s
-//
-// Radar 8412415
-
-struct _mtx
-{
-  long unsigned int ptr;
-  int waiters;
-  struct {
-    int tag;
-    int pad;
-  } mtxi;
-};
-
-
-int foobar(struct _mtx *mutex) {
-  int r = 1;
-  int l = 0; // DexLabel('l_assign')
-  int j = 0;
-  do {
-    if (mutex->waiters) {
-      r = 2;
-    }
-    j = bar(r, l);
-    ++l;
-  } while (l < j);
-  return r + j;
-}
-
-int bar(int i, int j) {
-  return i + j;
-}
-
-int main() {
-  struct _mtx m;
-  m.waiters = 0;
-  return foobar(&m);
-}
-
-
-/*
-DexExpectProgramState({
-  'frames': [
-    {
-      'location': { 'lineno': ref('l_assign') },
-      'watches': {
-        '*mutex': { 'is_irretrievable': False }
-      }
-    }
-  ]
-})
-*/
-
diff --git a/dexter-tests/deferred_globals.cpp b/dexter-tests/deferred_globals.cpp
deleted file mode 100644
index dfc632e..0000000
--- a/dexter-tests/deferred_globals.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-// Purpose:
-// Ensure that debug information for a local variable does not hide
-// a global definition that has the same name.
-
-// REQUIRES: lldb
-// UNSUPPORTED: system-windows
-
-// RUN: %dexter --fail-lt 1.0 -w \
-// RUN:     --builder 'clang' --debugger 'lldb' \
-// RUN:     --cflags "-g -O0" -v -- %s
-
-const int d = 100;
-
-extern int foo();
-
-int main() {
-  const int d = 4;
-  const float e = 4; // DexLabel("main")
-  const char *f = "Woopy";
-  return d + foo();
-}
-
-int foo() {
-  return d; // DexLabel("foo")
-}
-
-// DexExpectWatchValue('d', '4', on_line=ref('main'))
-// DexExpectWatchValue('d', '100', on_line=ref('foo'))
-
diff --git a/dexter-tests/global-constant.cpp b/dexter-tests/global-constant.cpp
deleted file mode 100644
index 4d35633..0000000
--- a/dexter-tests/global-constant.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-// REQUIRES: system-windows
-//
-// RUN: %dexter --fail-lt 1.0 -w --builder 'clang-cl_vs2015' \
-// RUN:      --debugger 'dbgeng' --cflags '/Z7 /Zi' --ldflags '/Z7 /Zi' -- %s
-
-// Check that global constants have debug info.
-
-const float TestPi = 3.14;
-struct S {
-  static const char TestCharA = 'a';
-};
-enum TestEnum : int {
-  ENUM_POS = 2147000000,
-  ENUM_NEG = -2147000000,
-};
-void useConst(int) {}
-int main() {
-  useConst(TestPi);
-  useConst(S::TestCharA);
-  useConst(ENUM_NEG); // DexLabel('stop')
-  return 0;
-}
-
-// DexExpectWatchValue('TestPi', 3.140000104904175, on_line=ref('stop'))
-// DexExpectWatchValue('S::TestCharA', 97, on_line=ref('stop'))
-// DexExpectWatchValue('ENUM_NEG', -2147000000, on_line=ref('stop'))
-/* DexExpectProgramState({'frames': [{
-               'location': {'lineno' : ref('stop')},
-               'watches': {'ENUM_POS' : {'is_irretrievable': True}}
-}]}) */
diff --git a/dexter-tests/hello.c b/dexter-tests/hello.c
deleted file mode 100644
index 89b2a9f..0000000
--- a/dexter-tests/hello.c
+++ /dev/null
@@ -1,13 +0,0 @@
-// REQUIRES: system-windows
-//
-// RUN: %dexter --fail-lt 1.0 -w --builder 'clang-cl_vs2015' \
-// RUN:      --debugger 'dbgeng' --cflags '/Z7 /Zi' --ldflags '/Z7 /Zi' -- %s
-
-#include <stdio.h>
-int main() {
-  printf("hello world\n");
-  int x = 42;
-  __debugbreak(); // DexLabel('stop')
-}
-
-// DexExpectWatchValue('x', 42, on_line=ref('stop'))
diff --git a/dexter-tests/inline-line-gap.cpp b/dexter-tests/inline-line-gap.cpp
deleted file mode 100644
index 75e3b63..0000000
--- a/dexter-tests/inline-line-gap.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-// REQUIRES: system-windows
-//
-// RUN: %dexter --fail-lt 1.0 -w --builder 'clang-cl_vs2015' \
-// RUN:      --debugger 'dbgeng' --cflags '/Od /Z7 /Zi' \
-// RUN:      --ldflags '/Od /Z7 /Zi' -- %s
-//
-// RUN: %dexter --fail-lt 1.0 -w --builder 'clang-cl_vs2015' \
-// RUN:      --debugger 'dbgeng' --cflags '/O2 /Z7 /Zi' \
-// RUN:      --ldflags '/O2 /Z7 /Zi' -- %s
-
-// This code is structured to have an early exit with an epilogue in the middle
-// of the function, which creates a gap between the beginning of the inlined
-// code region and the end. Previously, this confused cdb.
-
-volatile bool shutting_down_ = true;
-volatile bool tearing_down_ = true;
-
-void __attribute__((optnone)) setCrashString(const char *) {}
-void __attribute__((optnone)) doTailCall() {}
-extern "C" void __declspec(noreturn) abort();
-
-void __forceinline inlineCrashFrame() {
-  if (shutting_down_ || tearing_down_) {
-    setCrashString("crashing");
-    // MSVC lays out calls to abort out of line, gets the layout we want.
-    abort(); // DexLabel('stop')
-  }
-}
-
-void __declspec(noinline) callerOfInlineCrashFrame(bool is_keeping_alive) {
-  if (is_keeping_alive)
-    inlineCrashFrame();
-  else
-    doTailCall();
-}
-
-int __attribute__((optnone)) main() {
-  callerOfInlineCrashFrame(true);
-}
-
-/*
-DexExpectProgramState({'frames':[
-     {'function': 'inlineCrashFrame', 'location':{'lineno' : ref('stop')} },
-     {'function': 'callerOfInlineCrashFrame'},
-     {'function': 'main'}
-]})
-*/
diff --git a/dexter-tests/lit.local.cfg b/dexter-tests/lit.local.cfg
deleted file mode 100644
index a081e8e..0000000
--- a/dexter-tests/lit.local.cfg
+++ /dev/null
@@ -1,2 +0,0 @@
-if 'dexter' not in config.available_features:
-    config.unsupported = True
diff --git a/dexter-tests/memvars/bitcast.c b/dexter-tests/memvars/bitcast.c
deleted file mode 100644
index 70047c9..0000000
--- a/dexter-tests/memvars/bitcast.c
+++ /dev/null
@@ -1,77 +0,0 @@
-// XFAIL:*
-//// Suboptimal coverage, see description below.
-
-// REQUIRES: lldb
-// UNSUPPORTED: system-windows
-// RUN: %dexter --fail-lt 1.0 -w --debugger lldb \
-// RUN:     --builder 'clang-c' --cflags "-O3 -glldb" -- %s
-
-//// Adapted from https://bugs.llvm.org/show_bug.cgi?id=34136#c1
-//// LowerDbgDeclare has since been updated to look through bitcasts. We still
-//// get suboptimal coverage at the beginning of 'main' though. For each local,
-//// LowerDbgDeclare inserts a dbg.value and a dbg.value+DW_OP_deref before the
-//// store (after the call to 'getint') and the call to 'alias' respectively.
-//// The first dbg.value describes the result of the 'getint' call, eventually
-//// becoming a register location. The second points back into the stack
-//// home. There is a gap in the coverage between the quickly clobbered register
-//// location and the stack location, even though the stack location is valid
-//// during that gap. For x86 we end up with this code at the start of main:
-//// 00000000004004b0 <main>:
-////   4004b0:  sub    rsp,0x18
-////   4004b4:  mov    edi,0x5
-////   4004b9:  call   400480 <getint>
-////   4004be:  mov    DWORD PTR [rsp+0x14],eax
-////   4004c2:  mov    edi,0x5
-////   4004c7:  call   400480 <getint>
-////   4004cc:  mov    DWORD PTR [rsp+0x10],eax
-////   4004d0:  mov    edi,0x5
-////   4004d5:  call   400480 <getint>
-////   4004da:  mov    DWORD PTR [rsp+0xc],eax
-////   ...
-//// With these variable locations:
-////  DW_TAG_variable
-////    DW_AT_location        (0x00000000:
-////       [0x00000000004004be, 0x00000000004004cc): DW_OP_reg0 RAX
-////       [0x00000000004004de, 0x0000000000400503): DW_OP_breg7 RSP+20)
-////    DW_AT_name    ("x")
-////    ...
-////  DW_TAG_variable
-////    DW_AT_location        (0x00000037:
-////       [0x00000000004004cc, 0x00000000004004da): DW_OP_reg0 RAX
-////       [0x00000000004004e8, 0x0000000000400503): DW_OP_breg7 RSP+16)
-////    DW_AT_name    ("y")
-////    ...
-////  DW_TAG_variable
-////    DW_AT_location        (0x0000006e:
-////       [0x00000000004004da, 0x00000000004004e8): DW_OP_reg0 RAX
-////       [0x00000000004004f2, 0x0000000000400503): DW_OP_breg7 RSP+12)
-////    DW_AT_name    ("z")
-////    ...
-
-char g = 1;
-int five = 5;
-__attribute__((__noinline__))
-int getint(int x) {
-  g = x - 4;
-  return x * g;
-}
-
-__attribute__((__noinline__))
-void alias(char* c) {
-  g = *c;
-  *c = (char)five;
-}
-
-int main() {
-  int x = getint(5);
-  int y = getint(5); // DexLabel('s1')
-  int z = getint(5); // DexLabel('s2')
-  alias((char*)&x);  // DexLabel('s3')
-  alias((char*)&y);
-  alias((char*)&z);
-  return 0;          // DexLabel('s4')
-}
-
-// DexExpectWatchValue('x', '5',  from_line=ref('s1'), to_line=ref('s4'))
-// DexExpectWatchValue('y', '5',  from_line=ref('s2'), to_line=ref('s4'))
-// DexExpectWatchValue('z', '5',  from_line=ref('s3'), to_line=ref('s4'))
diff --git a/dexter-tests/memvars/const-branch.c b/dexter-tests/memvars/const-branch.c
deleted file mode 100644
index ab23926..0000000
--- a/dexter-tests/memvars/const-branch.c
+++ /dev/null
@@ -1,52 +0,0 @@
-// XFAIL:*
-//// Suboptimal coverage, see inlined comments.
-
-// REQUIRES: lldb
-// UNSUPPORTED: system-windows
-// RUN: %dexter --fail-lt 1.0 -w --debugger lldb \
-// RUN:     --builder 'clang-c' --cflags "-O3 -glldb" -- %s
-
-//// Adapted from https://bugs.llvm.org/show_bug.cgi?id=34136#c4
-
-int g;
-
-__attribute__((__noinline__))
-void esc(int* p) {
-  g = *p;
-  *p = 5;
-}
-
-__attribute__((__noinline__))
-void thing(int x) {
-  g = x;
-}
-
-__attribute__((__noinline__))
-int fun(int param) {
-  esc(&param);      //// alloca is live until here        DexLabel('s1')
-  if (param == 0) { //// end of alloca live range
-    //// param is now a constant, but without lowering to dbg.value we can't
-    //// capture that and would still point to the stack slot that may even have
-    //// been reused by now.
-    ////
-    //// Right now we get suboptimal coverage for x86: the param load below is
-    //// CSE'd with the if condition.
-    //// Instcombine runs LowerDbgDeclare and inserts a dbg.value after the load.
-    //// SelectionDAG combines the load and cmp. We go from this IR:
-    ////   %0 = load i32, i32* %param.addr, align 4, !dbg !42, !tbaa !20
-    ////   call void @llvm.dbg.value(metadata i32 %0, ...
-    ////   %cmp = icmp eq i32 %0, 0, !dbg !44
-    //// to this MIR:
-    ////   DBG_VALUE $noreg, $noreg, !"param"...
-    ////   CMP32mi8 %param.addr, 1, $noreg, 0, $noreg, 0, implicit-def $eflags, debug-location !44
-    thing(param);
-  }
-  return 0; //                                            DexLabel('s2')
-}
-
-int main() {
-  return fun(5);
-}
-
-// DexExpectWatchValue('param', '5',  from_line=ref('s1'), to_line=ref('s2'))
-
diff --git a/dexter-tests/memvars/ctrl-flow.c b/dexter-tests/memvars/ctrl-flow.c
deleted file mode 100644
index 4dbb3ff..0000000
--- a/dexter-tests/memvars/ctrl-flow.c
+++ /dev/null
@@ -1,34 +0,0 @@
-// REQUIRES: lldb
-// UNSUPPORTED: system-windows
-// RUN: %dexter --fail-lt 1.0 -w --debugger lldb \
-// RUN:     --builder clang-c  --cflags "-O2 -glldb" -- %s
-
-//// Check that we give good locations to a variable ('local') which is escaped
-//// down some control paths and not others. This example is handled well currently.
-
-int g;
-__attribute__((__noinline__))
-void leak(int *ptr) {
-  g = *ptr;
-  *ptr = 2;
-}
-
-__attribute__((__noinline__))
-int fun(int cond) {
-  int local = 0;   // DexLabel('s1')
-  if (cond)
-    leak(&local);
-  else
-    local = 1;
-  return local;    // DexLabel('s2')
-}
-
-int main() {
-  int a = fun(1);
-  int b = fun(0);
-  return a + b;
-}
-
-////                           fun(1)  fun(0)
-// DexExpectWatchValue('local',   '0',    '0', on_line=ref('s1'))
-// DexExpectWatchValue('local',   '2',    '1', on_line=ref('s2'))
diff --git a/dexter-tests/memvars/implicit-ptr.c b/dexter-tests/memvars/implicit-ptr.c
deleted file mode 100644
index 7b59afb..0000000
--- a/dexter-tests/memvars/implicit-ptr.c
+++ /dev/null
@@ -1,45 +0,0 @@
-// XFAIL:*
-//// We don't yet support DW_OP_implicit_pointer in llvm.
-
-// REQUIRES: lldb
-// UNSUPPORTED: system-windows
-// RUN: %dexter --fail-lt 1.0 -w --debugger lldb \
-// RUN:     --builder 'clang-c'  --cflags "-O3 -glldb" -- %s
-
-//// Check that 'param' in 'fun' can be read throughout, and that 'pa' and 'pb'
-//// can be dereferenced in the debugger even if we can't provide the pointer
-//// value itself.
-
-int globa;
-int globb;
-
-//// A no-inline, read-only function with internal linkage is a good candidate
-//// for arg promotion.
-__attribute__((__noinline__))
-static void use_promote(const int* pa) {
-  //// Promoted args would be a good candidate for an DW_OP_implicit_pointer.
-  globa = *pa; // DexLabel('s2')
-}
-
-__attribute__((__always_inline__))
-static void use_inline(const int* pb) {
-  //// Inlined pointer to callee local would be a good candidate for an
-  //// DW_OP_implicit_pointer.
-  globb = *pb; // DexLabel('s3')
-}
-
-__attribute__((__noinline__))
-int fun(int param) {
-  volatile int step = 0;   // DexLabel('s1')
-  use_promote(&param);
-  use_inline(&param);
-  return step;             // DexLabel('s4')
-}
-
-int main() {
-  return fun(5);
-}
-
-// DexExpectWatchValue('param', 5, from_line=ref('s1'), to_line=ref('s4'))
-// DexExpectWatchValue('*pa', 5, on_line=ref('s2'))
-// DexExpectWatchValue('*pb', 5, on_line=ref('s3'))
diff --git a/dexter-tests/memvars/inline-escaping-function.c b/dexter-tests/memvars/inline-escaping-function.c
deleted file mode 100644
index 1da3106..0000000
--- a/dexter-tests/memvars/inline-escaping-function.c
+++ /dev/null
@@ -1,45 +0,0 @@
-// XFAIL: *
-// Incorrect location for variable "param", see PR48719.
-
-// REQUIRES: lldb
-// UNSUPPORTED: system-windows
-// RUN: %dexter --fail-lt 1.0 -w --debugger lldb \
-// RUN:     --builder 'clang-c'  --cflags "-O3 -glldb" -- %s
-
-// 1. param is escaped by inlineme(&param) so it is not promoted by
-//    SROA/mem2reg.
-// 2. InstCombine's LowerDbgDeclare converts the dbg.declare to a set of
-//    dbg.values.
-// 3. inlineme(&param) is inlined.
-// 4. SROA/mem2reg fully promotes param. It does not insert a dbg.value after the
-//    PHI it inserts which merges the values out of entry and if.then in the
-//    sucessor block. This behaviour is inconsistent. If the dbg.declare was
-//    still around (i.e.  if param was promoted in the first round of mem2reg
-//    BEFORE LowerDbgDeclare) we would see a dbg.value insered for the PHI.
-// 5. JumpThreading removes the if.then block, changing entry to
-//    unconditionally branch to if.end.
-// 6. SimplifyCFG stitches entry and if.end together.
-
-// The debug info is not updated to account for the merged value prior to or
-// during JumpThreading/SimplifyCFG so we end up seeing param=5 for the entire
-// function, when we'd expect to see param=10 when stepping onto fluff().
-
-__attribute__((always_inline))
-int inlineme(int* p) { return *p * 2; }
-
-__attribute__((optnone))
-void fluff() {}
-
-__attribute__((noinline))
-int fun(int param) {
-  if (param)
-    param = inlineme(&param);
-  fluff();           // DexLabel('s0')
-  return param;
-}
-
-int main() {
-  return fun(5);
-}
-
-// DexExpectWatchValue('param', 10, on_line=ref('s0'))
diff --git a/dexter-tests/memvars/inlining-dse.c b/dexter-tests/memvars/inlining-dse.c
deleted file mode 100644
index 59a0a4a..0000000
--- a/dexter-tests/memvars/inlining-dse.c
+++ /dev/null
@@ -1,52 +0,0 @@
-// XFAIL:*
-//// See PR47946.
-
-// REQUIRES: lldb
-// UNSUPPORTED: system-windows
-// RUN: %dexter --fail-lt 1.0 -w --debugger lldb \
-// RUN:     --builder clang-c  --cflags "-O2 -glldb" -- %s
-//
-//// Check that once-escaped variable 'param' can still be read after we
-//// perform inlining + mem2reg, and that we see the DSE'd value 255.
-
-
-int g;
-__attribute__((__always_inline__))
-static void use(int* p) {
-  g = *p;
-  *p = 255;
-  volatile int step = 0;  // DexLabel('use1')
-}
-
-__attribute__((__noinline__))
-void fun(int param) {
-  //// Make sure first step is in 'fun'.
-  volatile int step = 0;  // DexLabel('fun1')
-  use(&param);
-  return;                 // DexLabel('fun2')
-}
-
-int main() {
-  fun(5);
-}
-
-/*
-# Expect param == 5 before stepping through inlined 'use'.
-DexExpectWatchValue('param', '5', on_line=ref('fun1'))
-
-# Expect param == 255 after assignment in inlined frame 'use'.
-DexExpectProgramState({
-  'frames': [
-    { 'function': 'use',
-      'location': { 'lineno': ref('use1') },
-    },
-    { 'function': 'fun',
-      'location': { 'lineno': 20 },
-      'watches':  { 'param': '255' }
-    },
-  ]
-})
-
-# Expect param == 255 after inlined call to 'use'.
-DexExpectWatchValue('param', '255', on_line=ref('fun2'))
-*/
diff --git a/dexter-tests/memvars/inlining.c b/dexter-tests/memvars/inlining.c
deleted file mode 100644
index b8468fb..0000000
--- a/dexter-tests/memvars/inlining.c
+++ /dev/null
@@ -1,26 +0,0 @@
-// REQUIRES: lldb
-// UNSUPPORTED: system-windows
-// RUN: %dexter --fail-lt 1.0 -w --debugger lldb \
-// RUN:     --builder clang-c  --cflags "-O2 -glldb" -- %s
-//
-//// Check that the once-escaped variable 'param' can still be read after
-//// we perform inlining + mem2reg. See D89810 and D85555.
-
-int g;
-__attribute__((__always_inline__))
-static void use(int* p) {
-  g = *p;
-}
-
-__attribute__((__noinline__))
-void fun(int param) {
-  volatile int step1 = 0;  // DexLabel('s1')
-  use(&param);
-  volatile int step2 = 0;  // DexLabel('s2')
-}
-
-int main() {
-  fun(5);
-}
-
-// DexExpectWatchValue('param', '5', from_line=ref('s1'), to_line=ref('s2'))
diff --git a/dexter-tests/memvars/loop.c b/dexter-tests/memvars/loop.c
deleted file mode 100644
index 97aba17..0000000
--- a/dexter-tests/memvars/loop.c
+++ /dev/null
@@ -1,56 +0,0 @@
-// XFAIL: *
-//// Suboptimal coverage, see below.
-
-// REQUIRES: lldb
-// UNSUPPORTED: system-windows
-// RUN: %dexter --fail-lt 1.0 -w --debugger lldb \
-// RUN:     --builder 'clang-c'  --cflags "-O3 -glldb" -- %s
-
-//// Check that escaped local 'param' in function 'fun' has sensible debug info
-//// after the escaping function 'use' gets arg promotion (int* -> int). Currently
-//// we lose track of param after the loop header.
-
-int g = 0;
-//// A no-inline, read-only function with internal linkage is a good candidate
-//// for arg promotion.
-__attribute__((__noinline__))
-static void use(const int* p) {
-  //// Promoted args would be a good candidate for an DW_OP_implicit_pointer.
-  //// This desirable behaviour is checked for in the test implicit-ptr.c.
-  g = *p;
-}
-
-__attribute__((__noinline__))
-void do_thing(int x) {
-  g *= x;
-}
-
-__attribute__((__noinline__))
-int fun(int param) {
-  do_thing(0);                        // DexLabel('s2')
-  for (int i = 0; i < param; ++i) {
-    use(&param);
-  }
-
-  //// x86 loop body looks like this, with param in ebx:
-  //// 4004b0: mov    edi,ebx
-  //// 4004b2: call   4004d0 <_ZL3usePKi>
-  //// 4004b7: add    ebp,0xffffffff
-  //// 4004ba: jne    4004b0 <_Z3funi+0x20>
-
-  //// But we lose track of param's location before the loop:
-  //// DW_TAG_formal_parameter
-  //// DW_AT_location   (0x00000039:
-  ////    [0x0000000000400490, 0x0000000000400495): DW_OP_reg5 RDI
-  ////    [0x0000000000400495, 0x00000000004004a2): DW_OP_reg3 RBX)
-  //// DW_AT_name       ("param")
-
-  return g;                           // DexLabel('s3')
-}
-
-int main() {
-  return fun(5);
-}
-
-// DexExpectWatchValue('*p', 5, 5, 5, 5, 5, on_line=ref('s1'))
-// DexExpectWatchValue('param', 5, from_line=ref('s2'), to_line=ref('s3'))
diff --git a/dexter-tests/memvars/merged-store.c b/dexter-tests/memvars/merged-store.c
deleted file mode 100644
index 3cf96ec..0000000
--- a/dexter-tests/memvars/merged-store.c
+++ /dev/null
@@ -1,43 +0,0 @@
-// XFAIL: *
-// Incorrect location for variable "parama", see PR48719.
-
-// REQUIRES: lldb
-// UNSUPPORTED: system-windows
-// RUN: %dexter --fail-lt 1.0 -w --debugger lldb \
-// RUN:     --builder 'clang-c'  --cflags "-O3 -glldb" -- %s
-
-// 1. parama is escaped by esc(&parama) so it is not promoted by
-//    SROA/mem2reg.
-// 2. InstCombine's LowerDbgDeclare converts the dbg.declare to a set of
-//    dbg.values (tracking the stored SSA values).
-// 3. InstCombine replaces the two stores to parama's alloca (the initial
-//    parameter register store in entry and the assignment in if.then) with a
-//    PHI+store in the common sucessor.
-// 4. SimplifyCFG folds the blocks together and converts the PHI to a
-//    select.
-
-// The debug info is not updated to account for the merged value in the
-// sucessor prior to SimplifyCFG when it exists as a PHI, or during when it
-// becomes a select. As a result we see parama=5 for the entire function, when
-// we'd expect to see param=20 when stepping onto fluff().
-
-__attribute__((optnone))
-void esc(int* p) {}
-
-__attribute__((optnone))
-void fluff() {}
-
-__attribute__((noinline))
-int fun(int parama, int paramb) {
-  if (parama)
-    parama = paramb;
-  fluff();           // DexLabel('s0')
-  esc(&parama);
-  return 0;
-}
-
-int main() {
-  return fun(5, 20);
-}
-
-// DexExpectWatchValue('parama', 20, on_line=ref('s0'))
diff --git a/dexter-tests/memvars/ptr-to.c b/dexter-tests/memvars/ptr-to.c
deleted file mode 100644
index 4f0a9af..0000000
--- a/dexter-tests/memvars/ptr-to.c
+++ /dev/null
@@ -1,35 +0,0 @@
-// XFAIL:*
-//// Currently debug info for 'local' behaves, but 'plocal' dereferences to
-//// the incorrect value 0xFF after the call to esc.
-
-// REQUIRES: lldb
-// UNSUPPORTED: system-windows
-// RUN: %dexter --fail-lt 1.0 -w --debugger lldb \
-// RUN:     --builder clang-c --cflags "-O2 -glldb" -- %s
-//
-//// Check that a pointer to a variable living on the stack dereferences to the
-//// variable value.
-
-int glob;
-__attribute__((__noinline__))
-void esc(int* p) {
-  glob = *p;
-  *p = 0xFF;
-}
-
-int main() {
-  int local = 0xA;
-  int *plocal = &local;
-  esc(plocal);      // DexLabel('s1')
-  local = 0xB;      //// DSE
-  return 0;         // DexLabel('s2')
-}
-
-
-// DexExpectWatchValue('local', 0xA, on_line=ref('s1'))
-// DexExpectWatchValue('local', 0xB, on_line=ref('s2'))
-// DexExpectWatchValue('*plocal', 0xA, on_line=ref('s1'))
-// DexExpectWatchValue('*plocal', 0xB, on_line=ref('s2'))
-//// Ideally we should be able to observe the dead store to local (0xB) through
-//// plocal here.
-// DexExpectWatchValue('(local == *plocal)', 'true', from_line=ref('s1'), to_line=ref('s2'))
diff --git a/dexter-tests/memvars/struct-dse.c b/dexter-tests/memvars/struct-dse.c
deleted file mode 100644
index de2e219..0000000
--- a/dexter-tests/memvars/struct-dse.c
+++ /dev/null
@@ -1,33 +0,0 @@
-// XFAIL:*
-//// Currently, LowerDbgDeclare doesn't lower dbg.declares pointing at allocas
-//// for structs.
-
-// REQUIRES: lldb
-// UNSUPPORTED: system-windows
-// RUN: %dexter --fail-lt 1.0 -w --debugger lldb \
-// RUN:     --builder clang-c --cflags "-O2 -glldb" -- %s
-//
-//// Check debug-info for the escaped struct variable num is reasonable.
-
-#include <stdio.h>
-struct Nums { int a, b, c; };
-struct Nums glob;
-__attribute__((__noinline__))
-void esc(struct Nums* nums) {
-  glob = *nums;
-}
-
-__attribute__((__noinline__))
-int main() {
-  struct Nums nums = { .c=1 };       //// Dead store.
-  printf("s1 nums.c: %d\n", nums.c); // DexLabel('s1')
-
-  nums.c = 2;                        //// Killing store.
-  printf("s2 nums.c: %d\n", nums.c); // DexLabel('s2')
-
-  esc(&nums);                        //// Force nums to live on the stack.
-  return 0;                          // DexLabel('s3')
-}
-
-// DexExpectWatchValue('nums.c', '1', on_line=ref('s1'))
-// DexExpectWatchValue('nums.c', '2', from_line=ref('s2'), to_line=ref('s3'))
diff --git a/dexter-tests/memvars/unused-merged-value.c b/dexter-tests/memvars/unused-merged-value.c
deleted file mode 100644
index 805062c..0000000
--- a/dexter-tests/memvars/unused-merged-value.c
+++ /dev/null
@@ -1,44 +0,0 @@
-// XFAIL: *
-// Incorrect location for variable "parama", see PR48719.
-
-// REQUIRES: lldb
-// UNSUPPORTED: system-windows
-// RUN: %dexter --fail-lt 0.1 -w --debugger lldb \
-// RUN:     --builder 'clang-c'  --cflags "-O3 -glldb" -- %s
-// See NOTE at end for more info about the RUN command.
-
-// 1. SROA/mem2reg fully promotes parama.
-// 2. parama's value in the final block is the merge of values for it coming
-//    out of entry and if.then. If the variable were used later in the function
-//    mem2reg would insert a PHI here and add a dbg.value to track the merged
-//    value in debug info. Because it is not used there is no PHI (the merged
-//    value is implicit) and subsequently no dbg.value.
-// 3. SimplifyCFG later folds the blocks together (if.then does nothing besides
-//    provide debug info so it is removed and if.end is folded into the entry
-//    block).
-
-// The debug info is not updated to account for the implicit merged value prior
-// to (e.g. during mem2reg) or during SimplifyCFG so we end up seeing parama=5
-// for the entire function, which is incorrect.
-
-__attribute__((optnone))
-void fluff() {}
-
-__attribute__((noinline))
-int fun(int parama, int paramb) {
-  if (parama)
-    parama = paramb;
-  fluff();            // DexLabel('s0')
-  return paramb;
-}
-
-int main() {
-  return fun(5, 20);
-}
-
-// DexExpectWatchValue('parama', 20, on_line=ref('s0'))
-//
-// NOTE: the dexter command uses --fail-lt 0.1 (instead of the standard 1.0)
-// because seeing 'optimized out' would still be a win; it's the best we can do
-// without using conditional DWARF operators in the location expression. Seeing
-// 'optimized out' should result in a score higher than 0.1.
diff --git a/dexter-tests/namespace.cpp b/dexter-tests/namespace.cpp
deleted file mode 100644
index fa89421..0000000
--- a/dexter-tests/namespace.cpp
+++ /dev/null
@@ -1,24 +0,0 @@
-// Purpose:
-// Ensure that the debug information for a global variable includes
-// namespace information.
-
-// REQUIRES: lldb
-// UNSUPPORTED: system-windows
-
-// RUN: %dexter --fail-lt 1.0 -w \
-// RUN:     --builder 'clang' --debugger 'lldb' \
-// RUN:     --cflags "-g -O0" -v -- %s
-
-#include <stdio.h>
-
-namespace monkey {
-const int ape = 32;
-}
-
-int main() {
-  printf("hello %d\n", monkey::ape); // DexLabel('main')
-  return 0;
-}
-
-// DexExpectWatchValue('monkey::ape', 32, on_line=ref('main'))
-
diff --git a/dexter-tests/nrvo-string.cpp b/dexter-tests/nrvo-string.cpp
deleted file mode 100644
index cccdaa1..0000000
--- a/dexter-tests/nrvo-string.cpp
+++ /dev/null
@@ -1,56 +0,0 @@
-// Purpose:
-//     This ensures that DW_OP_deref is inserted when necessary, such as when
-//     NRVO of a string object occurs in C++.
-//
-// REQUIRES: !asan, lldb
-// UNSUPPORTED: system-windows
-//           Zorg configures the ASAN stage2 bots to not build the asan
-//           compiler-rt. Only run this test on non-asanified configurations.
-//
-// RUN: %dexter --fail-lt 1.0 -w \
-// RUN:     --builder 'clang' --debugger 'lldb' \
-// RUN:     --cflags "-O0 -glldb -fno-exceptions" -- %s
-//
-// RUN: %dexter --fail-lt 1.0 -w \
-// RUN:     --builder 'clang' --debugger 'lldb' \
-// RUN:     --cflags "-O1 -glldb -fno-exceptions" -- %s
-//
-// PR34513
-volatile int sideeffect = 0;
-void __attribute__((noinline)) stop() { sideeffect++; }
-
-struct string {
-  string() {}
-  string(int i) : i(i) {}
-  ~string() {}
-  int i = 0;
-};
-string __attribute__((noinline)) get_string() {
-  string unused;
-  string output = 3;
-  stop(); // DexLabel('string-nrvo')
-  return output;
-}
-void some_function(int) {}
-struct string2 {
-  string2() = default;
-  string2(string2 &&other) { i = other.i; }
-  int i;
-};
-string2 __attribute__((noinline)) get_string2() {
-  string2 output;
-  output.i = 5;
-  some_function(output.i);
-  // Test that the debugger can get the value of output after another
-  // function is called.
-  stop(); // DexLabel('string2-nrvo')
-  return output;
-}
-int main() {
-  get_string();
-  get_string2();
-}
-
-// DexExpectWatchValue('output.i', 3, on_line=ref('string-nrvo'))
-// DexExpectWatchValue('output.i', 5, on_line=ref('string2-nrvo'))
-
diff --git a/dexter-tests/nrvo.cpp b/dexter-tests/nrvo.cpp
deleted file mode 100644
index b94bc72..0000000
--- a/dexter-tests/nrvo.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-// This ensures that DW_OP_deref is inserted when necessary, such as when NRVO
-// of a string object occurs in C++.
-//
-// REQUIRES: system-windows
-//
-// RUN: %dexter --fail-lt 1.0 -w --builder 'clang-cl_vs2015' \
-// RUN:      --debugger 'dbgeng' --cflags '/Z7 /Zi' --ldflags '/Z7 /Zi' -- %s
-
-struct string {
-  string() {}
-  string(int i) : i(i) {}
-  ~string() {}
-  int i = 0;
-};
-string get_string() {
-  string unused;
-  string result = 3;
-  return result; // DexLabel('readresult1')
-}
-void some_function(int) {}
-struct string2 {
-  string2() = default;
-  string2(string2 &&other) { i = other.i; }
-  int i;
-};
-string2 get_string2() {
-  string2 result;
-  result.i = 5;
-  some_function(result.i);
-  // Test that the debugger can get the value of result after another
-  // function is called.
-  return result; // DexLabel('readresult2')
-}
-int main() {
-  get_string();
-  get_string2();
-}
-
-// DexExpectWatchValue('result.i', 3, on_line=ref('readresult1'))
-// DexExpectWatchValue('result.i', 5, on_line=ref('readresult2'))
diff --git a/dexter-tests/optnone-fastmath.cpp b/dexter-tests/optnone-fastmath.cpp
deleted file mode 100644
index 8de3fd7..0000000
--- a/dexter-tests/optnone-fastmath.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-// RUN: %dexter --fail-lt 1.0 -w \
-// RUN:     --builder 'clang' --debugger 'lldb' \
-// RUN:     --cflags "-ffast-math -O2 -g" -- %s
-// RUN: %dexter --fail-lt 1.0 -w \
-// RUN:     --builder 'clang' --debugger 'lldb' \
-// RUN:     --cflags "-ffast-math -O0 -g" -- %s
-
-// REQUIRES: lldb
-// UNSUPPORTED: system-windows
-
-//// Check that the debugging experience with __attribute__((optnone)) at O2
-//// matches O0. Test scalar floating point arithmetic with -ffast-math.
-
-//// Example of strength reduction.
-//// The division by 10.0f can be rewritten as a multiply by 0.1f.
-//// A / 10.f ==> A * 0.1f
-//// This is safe with fastmath since we treat the two operations
-//// as equally precise. However we don't want this to happen
-//// with optnone.
-__attribute__((optnone))
-float test_fdiv(float A) {
-  float result;
-  result = A / 10.f;  // DexLabel('fdiv_assign')
-  return result;      // DexLabel('fdiv_ret')
-}
-// DexExpectWatchValue('A', 4, on_line=ref('fdiv_assign'))
-// DexExpectWatchValue('result', '0.400000006', on_line=ref('fdiv_ret'))
-
-//// (A * B) - (A * C) ==> A * (B - C)
-__attribute__((optnone))
-float test_distributivity(float A, float B, float C) {
-  float result;
-  float op1 = A * B;
-  float op2 = A * C;    // DexLabel('distributivity_op2')
-  result = op1 - op2;   // DexLabel('distributivity_result')
-  return result;        // DexLabel('distributivity_ret')
-}
-// DexExpectWatchValue('op1', '20', on_line=ref('distributivity_op2'))
-// DexExpectWatchValue('op2', '24', on_line=ref('distributivity_result'))
-// DexExpectWatchValue('result', '-4', on_line=ref('distributivity_ret'))
-
-//// (A + B) + C  == A + (B + C)
-//// therefore, ((A + B) + C) + (A + (B + C)))
-//// can be rewritten as
-//// 2.0f * ((A + B) + C)
-//// Clang is currently unable to spot this optimization
-//// opportunity with fastmath.
-__attribute__((optnone))
-float test_associativity(float A, float B, float C) {
-  float result;
-  float op1 = A + B;
-  float op2 = B + C;
-  op1 += C;           // DexLabel('associativity_op1')
-  op2 += A;
-  result = op1 + op2; // DexLabel('associativity_result')
-  return result;      // DexLabel('associativity_ret')
-}
-// DexExpectWatchValue('op1', '9', '15', from_line=ref('associativity_op1'), to_line=ref('associativity_result'))
-// DexExpectWatchValue('op2', '11', '15', from_line=ref('associativity_op1'), to_line=ref('associativity_result'))
-// DexExpectWatchValue('result', '30', on_line=ref('associativity_ret'))
-
-//// With fastmath, the ordering of instructions doesn't matter
-//// since we work under the assumption that there is no loss
-//// in precision. This simplifies things for the optimizer which
-//// can then decide to reorder instructions and fold
-//// redundant operations like this:
-////   A += 5.0f
-////   A -= 5.0f
-////    -->
-////   A
-//// This function can be simplified to a return A + B.
-__attribute__((optnone))
-float test_simplify_fp_operations(float A, float B) {
-  float result = A + 10.0f; // DexLabel('fp_operations_result')
-  result += B;              // DexLabel('fp_operations_add')
-  result -= 10.0f;
-  return result;            // DexLabel('fp_operations_ret')
-}
-// DexExpectWatchValue('A', '8.25', on_line=ref('fp_operations_result'))
-// DexExpectWatchValue('B', '26.3999996', on_line=ref('fp_operations_result'))
-// DexExpectWatchValue('result', '18.25', '44.6500015', '34.6500015', from_line=ref('fp_operations_add'), to_line=ref('fp_operations_ret'))
-
-//// Again, this is a simple return A + B.
-//// Clang is unable to spot the opportunity to fold the code sequence.
-__attribute__((optnone))
-float test_simplify_fp_operations_2(float A, float B, float C) {
-  float result = A + C; // DexLabel('fp_operations_2_result')
-  result += B;
-  result -= C;          // DexLabel('fp_operations_2_subtract')
-  return result;        // DexLabel('fp_operations_2_ret')
-}
-// DexExpectWatchValue('A', '9.11999988', on_line=ref('fp_operations_2_result'))
-// DexExpectWatchValue('B', '61.050003', on_line=ref('fp_operations_2_result'))
-// DexExpectWatchValue('C', '1002.11102', on_line=ref('fp_operations_2_result'))
-// DexExpectWatchValue('result', '1072.28101', '70.1699829', from_line=ref('fp_operations_2_subtract'), to_line=ref('fp_operations_2_ret'))
-
-int main() {
-  float result = test_fdiv(4.0f);
-  result += test_distributivity(4.0f, 5.0f, 6.0f);
-  result += test_associativity(4.0f, 5.0f, 6.0f);
-  result += test_simplify_fp_operations(8.25, result);
-  result += test_simplify_fp_operations_2(9.12, result, 1002.111);
-  return static_cast<int>(result);
-}
diff --git a/dexter-tests/optnone-loops.cpp b/dexter-tests/optnone-loops.cpp
deleted file mode 100644
index acccd47..0000000
--- a/dexter-tests/optnone-loops.cpp
+++ /dev/null
@@ -1,161 +0,0 @@
-// Purpose:
-// Verifies that the debugging experience of loops marked optnone is as expected.
-
-// REQUIRES: lldb
-// UNSUPPORTED: system-windows
-// UNSUPPORTED: system-darwin
-
-// RUN: %dexter --fail-lt 1.0 -w \
-// RUN:     --builder 'clang' --debugger 'lldb' \
-// RUN:     --cflags "-O2 -g" -- %s
-
-// A simple loop of assignments.
-// With optimization level > 0 the compiler reorders basic blocks
-// based on the basic block frequency analysis information.
-// This also happens with optnone and it shouldn't.
-// This is not affecting debug info so it is a minor limitation.
-// Basic block placement based on the block frequency analysis
-// is normally done to improve i-Cache performances.
-__attribute__((optnone)) void simple_memcpy_loop(int *dest, const int *src,
-                                                 unsigned nelems) {
-  for (unsigned i = 0; i != nelems; ++i)
-    dest[i] = src[i]; // DexLabel('target_simple_memcpy_loop')
-}
-
-// DexLimitSteps('i', 0, 4, 8, on_line=ref('target_simple_memcpy_loop'))
-// DexExpectWatchValue('nelems', '16', on_line=ref('target_simple_memcpy_loop'))
-// DexExpectWatchValue('src[i]', '3', '7', '1', on_line=ref('target_simple_memcpy_loop'))
-
-
-// A trivial loop that could be optimized into a builtin memcpy
-// which is either expanded into a optimal sequence of mov
-// instructions or directly into a call to memset@plt
-__attribute__((optnone)) void trivial_memcpy_loop(int *dest, const int *src) {
-  for (unsigned i = 0; i != 16; ++i)
-    dest[i] = src[i]; // DexLabel('target_trivial_memcpy_loop')
-}
-
-// DexLimitSteps('i', 3, 7, 9, 14, 15, on_line=ref('target_trivial_memcpy_loop'))
-// DexExpectWatchValue('i', 3, 7, 9, 14, 15, on_line=ref('target_trivial_memcpy_loop'))
-// DexExpectWatchValue('dest[i-1] == src[i-1]', 'true', on_line=ref('target_trivial_memcpy_loop'))
-
-
-__attribute__((always_inline)) int foo(int a) { return a + 5; }
-
-// A trivial loop of calls to a 'always_inline' function.
-__attribute__((optnone)) void nonleaf_function_with_loop(int *dest,
-                                                         const int *src) {
-  for (unsigned i = 0; i != 16; ++i)
-    dest[i] = foo(src[i]); // DexLabel('target_nonleaf_function_with_loop')
-}
-
-// DexLimitSteps('i', 1, on_line=ref('target_nonleaf_function_with_loop'))
-// DexExpectWatchValue('dest[0]', '8', on_line=ref('target_nonleaf_function_with_loop'))
-// DexExpectWatchValue('dest[1]', '4', on_line=ref('target_nonleaf_function_with_loop'))
-// DexExpectWatchValue('dest[2]', '5', on_line=ref('target_nonleaf_function_with_loop'))
-// DexExpectWatchValue('src[0]', '8', on_line=ref('target_nonleaf_function_with_loop'))
-// DexExpectWatchValue('src[1]', '4', on_line=ref('target_nonleaf_function_with_loop'))
-// DexExpectWatchValue('src[2]', '5', on_line=ref('target_nonleaf_function_with_loop'))
-
-// DexExpectWatchValue('src[1] == dest[1]', 'true', on_line=ref('target_nonleaf_function_with_loop'))
-// DexExpectWatchValue('src[2] == dest[2]', 'true', on_line=ref('target_nonleaf_function_with_loop'))
-
-
-// This entire function could be optimized into a
-// simple movl %esi, %eax.
-// That is because we can compute the loop trip count
-// knowing that ind-var 'i' can never be negative.
-__attribute__((optnone)) int counting_loop(unsigned values) {
-  unsigned i = 0;
-  while (values--) // DexLabel('target_counting_loop')
-    i++;
-  return i;
-}
-
-// DexLimitSteps('i', 8, 16, on_line=ref('target_counting_loop'))
-// DexExpectWatchValue('i', 8, 16, on_line=ref('target_counting_loop'))
-
-
-// This loop could be rotated.
-// while(cond){
-//   ..
-//   cond--;
-// }
-//
-//  -->
-// if(cond) {
-//   do {
-//     ...
-//     cond--;
-//   } while(cond);
-// }
-//
-// the compiler will not try to optimize this function.
-// However the Machine BB Placement Pass will try
-// to reorder the basic block that computes the
-// expression 'count' in order to simplify the control
-// flow.
-__attribute__((optnone)) int loop_rotate_test(int *src, unsigned count) {
-  int result = 0;
-
-  while (count) {
-    result += src[count - 1]; // DexLabel('target_loop_rotate_test')
-    count--;
-  }
-  return result; // DexLabel('target_loop_rotate_test_ret')
-}
-
-// DexLimitSteps('result', 13, on_line=ref('target_loop_rotate_test'))
-// DexExpectWatchValue('src[count]', 13, on_line=ref('target_loop_rotate_test'))
-// DexLimitSteps('result', 158, on_line=ref('target_loop_rotate_test_ret'))
-// DexExpectWatchValue('result', 158, on_line=ref('target_loop_rotate_test_ret'))
-
-
-typedef int *intptr __attribute__((aligned(16)));
-
-// This loop can be vectorized if we enable
-// the loop vectorizer.
-__attribute__((optnone)) void loop_vectorize_test(intptr dest, intptr src) {
-  unsigned count = 0;
-
-  int tempArray[16];
-
-  while(count != 16) { // DexLabel('target_loop_vectorize_test')
-    tempArray[count] = src[count];
-    tempArray[count+1] = src[count+1]; // DexLabel('target_loop_vectorize_test_2')
-    tempArray[count+2] = src[count+2]; // DexLabel('target_loop_vectorize_test_3')
-    tempArray[count+3] = src[count+3]; // DexLabel('target_loop_vectorize_test_4')
-    dest[count] = tempArray[count]; // DexLabel('target_loop_vectorize_test_5')
-    dest[count+1] = tempArray[count+1]; // DexLabel('target_loop_vectorize_test_6')
-    dest[count+2] = tempArray[count+2]; // DexLabel('target_loop_vectorize_test_7')
-    dest[count+3] = tempArray[count+3]; // DexLabel('target_loop_vectorize_test_8')
-    count += 4; // DexLabel('target_loop_vectorize_test_9')
-  }
-}
-
-// DexLimitSteps('count', 4, 8, 12, 16, from_line=ref('target_loop_vectorize_test'), to_line=ref('target_loop_vectorize_test_9'))
-// DexExpectWatchValue('tempArray[count] == src[count]', 'true', on_line=ref('target_loop_vectorize_test_2'))
-// DexExpectWatchValue('tempArray[count+1] == src[count+1]', 'true', on_line=ref('target_loop_vectorize_test_3'))
-// DexExpectWatchValue('tempArray[count+2] == src[count+2]', 'true', on_line=ref('target_loop_vectorize_test_4'))
-// DexExpectWatchValue('tempArray[count+3] == src[count+3]', 'true', on_line=ref('target_loop_vectorize_test_5'))
-// DexExpectWatchValue('dest[count] == tempArray[count]', 'true', on_line=ref('target_loop_vectorize_test_6'))
-// DexExpectWatchValue('dest[count+1] == tempArray[count+1]', 'true', on_line=ref('target_loop_vectorize_test_7'))
-// DexExpectWatchValue('dest[count+2] == tempArray[count+2]', 'true', on_line=ref('target_loop_vectorize_test_8'))
-// DexExpectWatchValue('dest[count+3] == tempArray[count+3]', 'true', on_line=ref('target_loop_vectorize_test_9'))
-
-
-int main() {
-  int A[] = {3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
-  int B[] = {13, 14, 15, 16, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
-  int C[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-
-  simple_memcpy_loop(C, A, 16);
-  trivial_memcpy_loop(B, C);
-  nonleaf_function_with_loop(B, B);
-  int count = counting_loop(16);
-  count += loop_rotate_test(B, 16);
-  loop_vectorize_test(A, B);
-
-  return A[0] + count;
-}
-
diff --git a/dexter-tests/optnone-simple-functions.cpp b/dexter-tests/optnone-simple-functions.cpp
deleted file mode 100644
index 6db4652..0000000
--- a/dexter-tests/optnone-simple-functions.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-// RUN: %dexter --fail-lt 1.0 -w \
-// RUN:     --builder 'clang' --debugger 'lldb' \
-// RUN:     --cflags "-O2 -g" -- %s
-// RUN: %dexter --fail-lt 1.0 -w \
-// RUN:     --builder 'clang' --debugger 'lldb' \
-// RUN:     --cflags "-O0 -g" -- %s
-
-// REQUIRES: lldb
-// UNSUPPORTED: system-windows
-
-//// Check that the debugging experience with __attribute__((optnone)) at O2
-//// matches O0. Test simple functions performing simple arithmetic
-//// operations and small loops.
-
-__attribute__((optnone))
-int test1(int test1_a, int test1_b) {
-  int test1_result = 0;
-  // DexLabel('test1_start')
-  test1_result = test1_a + test1_b; // DexExpectStepOrder(1)
-  return test1_result; // DexExpectStepOrder(2)
-  // DexLabel('test1_end')
-}
-// DexExpectWatchValue('test1_a', 3, from_line=ref('test1_start'), to_line=ref('test1_end'))
-// DexExpectWatchValue('test1_b', 4, from_line=ref('test1_start'), to_line=ref('test1_end'))
-// DexExpectWatchValue('test1_result', 0, 7, from_line=ref('test1_start'), to_line=ref('test1_end'))
-
-__attribute__((optnone))
-int test2(int test2_a, int test2_b) {
-  int test2_result = test2_a + test2_a + test2_a + test2_a;  // DexExpectStepOrder(3)
-  // DexLabel('test2_start')
-  return test2_a << 2;   // DexExpectStepOrder(4)
-  // DexLabel('test2_end')
-}
-// DexExpectWatchValue('test2_a', 1, from_line=ref('test2_start'), to_line=ref('test2_end'))
-// DexExpectWatchValue('test2_b', 2, from_line=ref('test2_start'), to_line=ref('test2_end'))
-// DexExpectWatchValue('test2_result', 4, from_line=ref('test2_start'), to_line=ref('test2_end'))
-
-__attribute__((optnone))
-int test3(int test3_a, int test3_b) {
-  int test3_temp1 = 0, test3_temp2 = 0;
-  // DexLabel('test3_start')
-  test3_temp1 = test3_a + 5;   // DexExpectStepOrder(5)
-  test3_temp2 = test3_b + 5;   // DexExpectStepOrder(6)
-  if (test3_temp1 > test3_temp2) { // DexExpectStepOrder(7)
-    test3_temp1 *= test3_temp2;    // DexUnreachable()
-  }
-  return test3_temp1; // DexExpectStepOrder(8)
-  // DexLabel('test3_end')
-}
-// DexExpectWatchValue('test3_a', 5, from_line=ref('test3_start'), to_line=ref('test3_end'))
-// DexExpectWatchValue('test3_b', 6, from_line=ref('test3_start'), to_line=ref('test3_end'))
-// DexExpectWatchValue('test3_temp1', 0, 10, from_line=ref('test3_start'), to_line=ref('test3_end'))
-// DexExpectWatchValue('test3_temp2', 0, 11, from_line=ref('test3_start'), to_line=ref('test3_end'))
-
-unsigned num_iterations = 4;
-
-__attribute__((optnone))
-int test4(int test4_a, int test4_b) {
-  int val1 = 0, val2 = 0;
-  // DexLabel('test4_start')
-
-  val1 = (test4_a > test4_b) ? test4_a : test4_b; // DexExpectStepOrder(9)
-  val2 = val1;
-  val2 += val1; // DexExpectStepOrder(10)
-
-  for (unsigned i=0; i != num_iterations; ++i) { // DexExpectStepOrder(11, 13, 15, 17, 19)
-    val1--;
-    val2 += i;
-    if (val2 % 2 == 0) // DexExpectStepOrder(12, 14, 16, 18)
-      val2 /= 2;
-  }
-
-  return (val1 > val2) ? val2 : val1; // DexExpectStepOrder(20)
-  // DexLabel('test4_end')
-}
-// DexExpectWatchValue('test4_a', 1, from_line=ref('test4_start'), to_line=ref('test4_end'))
-// DexExpectWatchValue('test4_b', 9, from_line=ref('test4_start'), to_line=ref('test4_end'))
-// DexExpectWatchValue('val1', 0, 9, 8, 7, 6, 5, from_line=ref('test4_start'), to_line=ref('test4_end'))
-// DexExpectWatchValue('val2', 0, 9, 18, 9, 10, 5, 7, 10, 5, 9, from_line=ref('test4_start'), to_line=ref('test4_end'))
-
-__attribute__((optnone))
-int test5(int test5_val) {
-  int c = 1;      // DexExpectStepOrder(21)
-  // DexLabel('test5_start')
-  if (test5_val)  // DexExpectStepOrder(22)
-    c = 5;        // DexExpectStepOrder(23)
-  return c ? test5_val : test5_val; // DexExpectStepOrder(24)
-  // DexLabel('test5_end')
-}
-// DexExpectWatchValue('test5_val', 7, from_line=ref('test5_start'), to_line=ref('test5_end'))
-// DexExpectWatchValue('c', 1, 5, from_line=ref('test5_start'), to_line=ref('test5_end'))
-
-int main() {
-  int main_result = 0;
-  // DexLabel('main_start')
-  main_result = test1(3,4);
-  main_result += test2(1,2);
-  main_result += test3(5,6);
-  main_result += test4(1,9);
-  main_result += test5(7);
-  return main_result;
-  // DexLabel('main_end')
-}
-// DexExpectWatchValue('main_result', 0, 7, 11, 21, 26, 33, from_line=ref('main_start'), to_line=ref('main_end'))
diff --git a/dexter-tests/optnone-struct-and-methods.cpp b/dexter-tests/optnone-struct-and-methods.cpp
deleted file mode 100644
index 3542a9c..0000000
--- a/dexter-tests/optnone-struct-and-methods.cpp
+++ /dev/null
@@ -1,105 +0,0 @@
-// RUN: %dexter --fail-lt 1.0 -w \
-// RUN:     --builder 'clang' --debugger 'lldb' \
-// RUN:     --cflags "-g -O2" -v -- %s
-// RUN: %dexter --fail-lt 1.0 -w \
-// RUN:     --builder 'clang' --debugger 'lldb' \
-// RUN:     --cflags "-g -O0" -- %s
-
-// REQUIRES: lldb
-// UNSUPPORTED: system-windows
-
-//// Check that the debugging experience with __attribute__((optnone)) at O2
-//// matches O0. Test simple structs and methods.
-
-long a_global_ptr[] = { 0xCAFEBABEL, 0xFEEDBEEFL };
-
-namespace {
-
-struct A {
-  int a;
-  float b;
-
-  enum B {
-    A_VALUE = 0x1,
-    B_VALUE = 0x2
-  };
-
-  struct some_data {
-    enum B other_b;
-    enum B other_other_b;
-  };
-
-  struct other_data {
-    union {
-      void *raw_ptr;
-      long  *long_ptr;
-      float *float_ptr;
-    } a;
-    struct some_data b;
-    struct some_data c;
-  };
-private:
-  struct other_data _data;
-
-public:
-  struct other_data *getOtherData() { return &_data; }
-
-  __attribute__((always_inline,nodebug))
-  void setSomeData1(A::B value, A::B other_value) {
-    struct other_data *data = getOtherData();
-    data->b.other_b = value;
-    data->b.other_other_b = other_value;
-  }
-
-  __attribute__((always_inline))
-  void setSomeData2(A::B value, A::B other_value) {
-    struct other_data *data = getOtherData();
-    data->c.other_b = value;
-    data->c.other_other_b = other_value;
-  }
-
-  void setOtherData() {
-    setSomeData2(A_VALUE, B_VALUE);
-    getOtherData()->a.long_ptr = &a_global_ptr[0];
-  }
-
-  __attribute__((optnone))
-  A() {
-    __builtin_memset(this, 0xFF, sizeof(*this));
-  } //DexLabel('break_0')
-  // DexExpectWatchValue('a', '-1', on_line=ref('break_0'))
-  //// Check b is NaN by comparing it to itself.
-  // DexExpectWatchValue('this->b == this->b', 'false', on_line=ref('break_0'))
-  // DexExpectWatchValue('_data.a.raw_ptr == -1', 'true', on_line=ref('break_0'))
-  // DexExpectWatchValue('_data.a.float_ptr == -1', 'true', on_line=ref('break_0'))
-  // DexExpectWatchValue('_data.a.float_ptr == -1', 'true', on_line=ref('break_0'))
-  // DexExpectWatchValue('a_global_ptr[0]', 0xcafebabe, on_line=ref('break_0'))
-  // DexExpectWatchValue('a_global_ptr[1]', 0xfeedbeef, on_line=ref('break_0'))
-
-  __attribute__((optnone))
-  ~A() {
-    *getOtherData()->a.long_ptr = 0xADDF00DL;
-  } //DexLabel('break_1')
-  // DexExpectWatchValue('_data.a.raw_ptr == a_global_ptr', 'true', on_line=ref('break_1'))
-  // DexExpectWatchValue('a_global_ptr[0]', 0xaddf00d, on_line=ref('break_1'))
-
-  __attribute__((optnone))
-  long getData() {
-    setSomeData1(B_VALUE, A_VALUE);
-    setOtherData();
-    return getOtherData()->a.long_ptr[1]; //DexLabel('break_2')
-  }
-  // DexExpectWatchValue('_data.b.other_b', 'B_VALUE', on_line=ref('break_2'))
-  // DexExpectWatchValue('_data.b.other_other_b', 'A_VALUE', on_line=ref('break_2'))
-};
-
-} // anonymous namespace
-
-int main() {
-  int result = 0;
-  {
-    A a;
-    result = a.getData();
-  }
-  return result;
-}
diff --git a/dexter-tests/optnone-vectors-and-functions.cpp b/dexter-tests/optnone-vectors-and-functions.cpp
deleted file mode 100644
index 8957c5a..0000000
--- a/dexter-tests/optnone-vectors-and-functions.cpp
+++ /dev/null
@@ -1,135 +0,0 @@
-// RUN: %dexter --fail-lt 1.0 -w \
-// RUN:     --builder 'clang' --debugger 'lldb' \
-// RUN:     --cflags "-g -O2" -v -- %s
-// RUN: %dexter --fail-lt 1.0 -w \
-// RUN:     --builder 'clang' --debugger 'lldb' \
-// RUN:     --cflags "-g -O0" -- %s
-
-// REQUIRES: lldb
-// UNSUPPORTED: system-windows
-
-//// Check that the debugging experience with __attribute__((optnone)) at O2
-//// matches O0. Test simple template functions performing simple arithmetic
-//// vector operations and trivial loops.
-
-typedef int int4 __attribute__((ext_vector_type(4)));
-template<typename T> struct TypeTraits {};
-
-template<>
-struct TypeTraits<int4> {
-  static const unsigned NumElements = 4;
-  static const unsigned UnusedField = 0xDEADBEEFU;
-  static unsigned MysteryNumber;
-};
-unsigned TypeTraits<int4>::MysteryNumber = 3U;
-
-template<typename T>
-__attribute__((optnone))
-T test1(T x, T y) {
-  T tmp = x + y; // DexLabel('break_0')
-  T tmp2 = tmp + y;
-  return tmp; // DexLabel('break_1')
-}
-// DexLimitSteps('1', '1', from_line=ref('break_0'), to_line=ref('break_1'))
-//// FIXME: gdb can print this but lldb cannot. Perhaps PR42920?
-//     \DexExpectWatchValue('TypeTraits<int __attribute__((ext_vector_type(4)))>::NumElements', 4, on_line=ref('break_0'))
-//     \DexExpectWatchValue('TypeTraits<int __attribute__((ext_vector_type(4)))>::UnusedField', 0xdeadbeef, on_line=ref('break_0'))
-//   DexExpectWatchValue('x[0]', 1, on_line=ref('break_0'))
-//   DexExpectWatchValue('x[1]', 2, on_line=ref('break_0'))
-//   DexExpectWatchValue('x[2]', 3, on_line=ref('break_0'))
-//   DexExpectWatchValue('x[3]', 4, on_line=ref('break_0'))
-//   DexExpectWatchValue('y[0]', 5, on_line=ref('break_0'))
-//   DexExpectWatchValue('y[1]', 6, on_line=ref('break_0'))
-//   DexExpectWatchValue('y[2]', 7, on_line=ref('break_0'))
-//   DexExpectWatchValue('y[3]', 8, on_line=ref('break_0'))
-//   DexExpectWatchValue('tmp[0]', 6, on_line=ref('break_1'))
-//   DexExpectWatchValue('tmp[1]', 8, on_line=ref('break_1'))
-//   DexExpectWatchValue('tmp[2]', 10, on_line=ref('break_1'))
-//   DexExpectWatchValue('tmp[3]', 12, on_line=ref('break_1'))
-//   DexExpectWatchValue('tmp2[0]', 11, on_line=ref('break_1'))
-//   DexExpectWatchValue('tmp2[1]', 14, on_line=ref('break_1'))
-//   DexExpectWatchValue('tmp2[2]', 17, on_line=ref('break_1'))
-//   DexExpectWatchValue('tmp2[3]', 20, on_line=ref('break_1'))
-
-template<typename T>
-__attribute__((optnone))
-T test2(T x, T y) {
-  T tmp = x;
-  int break_2 = 0; // DexLabel('break_2')
-  for (unsigned i = 0; i != TypeTraits<T>::NumElements; ++i) {
-    tmp <<= 1; // DexLabel('break_3')
-    tmp |= y;
-  }
-
-  tmp[0] >>= TypeTraits<T>::MysteryNumber;
-  return tmp; // DexLabel('break_5')
-}
-// DexLimitSteps('1', '1', on_line=ref('break_2'))
-//   DexExpectWatchValue('x[0]', 6, on_line=ref('break_2'))
-//   DexExpectWatchValue('x[1]', 8, on_line=ref('break_2'))
-//   DexExpectWatchValue('x[2]', 10, on_line=ref('break_2'))
-//   DexExpectWatchValue('x[3]', 12, on_line=ref('break_2'))
-//   DexExpectWatchValue('y[0]', 5, on_line=ref('break_2'))
-//   DexExpectWatchValue('y[1]', 6, on_line=ref('break_2'))
-//   DexExpectWatchValue('y[2]', 7, on_line=ref('break_2'))
-//   DexExpectWatchValue('y[3]', 8, on_line=ref('break_2'))
-//   DexExpectWatchValue('tmp[0]', 6, on_line=ref('break_2'))
-//   DexExpectWatchValue('tmp[1]', 8, on_line=ref('break_2'))
-//   DexExpectWatchValue('tmp[2]', 10, on_line=ref('break_2'))
-//   DexExpectWatchValue('tmp[3]', 12, on_line=ref('break_2'))
-// DexLimitSteps('i', 3, on_line=ref('break_3'))
-//   DexExpectWatchValue('tmp[0]', 63, on_line=ref('break_3'))
-//   DexExpectWatchValue('tmp[1]', 94, on_line=ref('break_3'))
-//   DexExpectWatchValue('tmp[2]', 95, on_line=ref('break_3'))
-//   DexExpectWatchValue('tmp[3]', 120, on_line=ref('break_3'))
-// DexLimitSteps('i', 3, on_line=ref('break_5'))
-//   DexExpectWatchValue('tmp[0]', 15, on_line=ref('break_5'))
-
-template<typename T>
-__attribute__((optnone))
-T test3(T InVec) {
-  T result;
-  for (unsigned i=0; i != TypeTraits<T>::NumElements; ++i)
-    result[i] = InVec[i]; // DexLabel('break_6')
-  return result; // DexLabel('break_7')
-}
-// DexLimitSteps('i', '3', from_line=ref('break_6'), to_line=ref('break_7'))
-//   DexExpectWatchValue('InVec[0]', 15, from_line=ref('break_6'), to_line=ref('break_7'))
-//   DexExpectWatchValue('InVec[1]', 190, from_line=ref('break_6'), to_line=ref('break_7'))
-//   DexExpectWatchValue('InVec[2]', 191, from_line=ref('break_6'), to_line=ref('break_7'))
-//   DexExpectWatchValue('InVec[3]', 248, from_line=ref('break_6'), to_line=ref('break_7'))
-//   DexExpectWatchValue('result[0]', 15, from_line=ref('break_6'), to_line=ref('break_7'))
-//   DexExpectWatchValue('result[1]', 190, from_line=ref('break_6'), to_line=ref('break_7'))
-//   DexExpectWatchValue('result[2]', 191, from_line=ref('break_6'), to_line=ref('break_7'))
-//   DexExpectWatchValue('result[3]', 248, on_line=ref('break_7'))
-
-template<typename T>
-__attribute__((optnone))
-T test4(T x, T y) {
-  for (unsigned i=0; i != TypeTraits<T>::NumElements; ++i)
-    x[i] = (x[i] > y[i])? x[i] : y[i] + TypeTraits<T>::MysteryNumber; // DexLabel('break_11')
-  return x; // DexLabel('break_12')
-}
-// DexLimitSteps('1', '1', from_line=ref('break_11'), to_line=ref('break_12'))
-//// FIXME: lldb won't print this but gdb unexpectedly says it's optimized out, even at O0.
-//     \DexExpectWatchValue('TypeTraits<int __attribute__((ext_vector_type(4)))>::MysteryNumber', 3, on_line=ref('break_11'))
-//   DexExpectWatchValue('i', 0, 1, 2, 3, on_line=ref('break_11'))
-//   DexExpectWatchValue('x[0]', 1, 8, from_line=ref('break_11'), to_line=ref('break_12'))
-//   DexExpectWatchValue('x[1]', 2, 9, from_line=ref('break_11'), to_line=ref('break_12'))
-//   DexExpectWatchValue('x[2]', 3, 10, from_line=ref('break_11'), to_line=ref('break_12'))
-//   DexExpectWatchValue('x[3]', 4, 11, from_line=ref('break_11'), to_line=ref('break_12'))
-//   DexExpectWatchValue('y[0]', 5, from_line=ref('break_11'), to_line=ref('break_12'))
-//   DexExpectWatchValue('y[1]', 6, from_line=ref('break_11'), to_line=ref('break_12'))
-//   DexExpectWatchValue('y[2]', 7, from_line=ref('break_11'), to_line=ref('break_12'))
-//   DexExpectWatchValue('y[3]', 8, from_line=ref('break_11'), to_line=ref('break_12'))
-
-int main() {
-  int4 a = (int4){1,2,3,4};
-  int4 b = (int4){5,6,7,8};
-
-  int4 tmp = test1(a,b);
-  tmp = test2(tmp,b);
-  tmp = test3(tmp);
-  tmp += test4(a,b);
-  return tmp[0];
-}
diff --git a/dexter-tests/realigned-frame.cpp b/dexter-tests/realigned-frame.cpp
deleted file mode 100644
index 36d50ef..0000000
--- a/dexter-tests/realigned-frame.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-// REQUIRES: system-windows
-//
-// RUN: %dexter --fail-lt 1.0 -w --builder 'clang-cl_vs2015' \
-// RUN:      --debugger 'dbgeng' --cflags '/Z7 /Zi' --ldflags '/Z7 /Zi' -- %s
-
-// From https://llvm.org/pr38857, where we had issues with stack realignment.
-
-struct Foo {
-  int x = 42;
-  int __declspec(noinline) foo();
-  void __declspec(noinline) bar(int *a, int *b, double *c);
-};
-int Foo::foo() {
-  int a = 1;
-  int b = 2;
-  double __declspec(align(32)) force_alignment = 0.42;
-  bar(&a, &b, &force_alignment); // DexLabel('in_foo')
-  x += (int)force_alignment;
-  return x;
-}
-void Foo::bar(int *a, int *b, double *c) {
-  *c += *a + *b; // DexLabel('in_bar')
-}
-int main() {
-  Foo o;
-  o.foo();
-}
-/*
-DexExpectProgramState({'frames':[
-    {'function': 'Foo::bar', 'location' : {'lineno' : ref('in_bar')} },
-    {'function': 'Foo::foo',
-     'watches' : {
-       'a' : '1',
-       'b' : '2',
-       'force_alignment' : '0.42'
-     }
-    }
-]})
-*/
diff --git a/dexter-tests/stack-var.c b/dexter-tests/stack-var.c
deleted file mode 100644
index 2c70ec2..0000000
--- a/dexter-tests/stack-var.c
+++ /dev/null
@@ -1,17 +0,0 @@
-// REQUIRES: lldb
-// UNSUPPORTED: system-windows
-//
-// RUN: %dexter --fail-lt 1.0 -w \
-// RUN:     --builder clang-c --debugger 'lldb' --cflags "-O -glldb" -- %s
-
-void __attribute__((noinline, optnone)) bar(int *test) {}
-int main() {
-  int test;
-  test = 23;
-  bar(&test); // DexLabel('before_bar')
-  return test; // DexLabel('after_bar')
-}
-
-// DexExpectWatchValue('test', '23', on_line=ref('before_bar'))
-// DexExpectWatchValue('test', '23', on_line=ref('after_bar'))
-
diff --git a/dexter-tests/vla.c b/dexter-tests/vla.c
deleted file mode 100644
index f0b400f..0000000
--- a/dexter-tests/vla.c
+++ /dev/null
@@ -1,23 +0,0 @@
-// This test case verifies the debug location for variable-length arrays.
-// REQUIRES: lldb
-// UNSUPPORTED: system-windows
-//
-// RUN: %dexter --fail-lt 1.0 -w \
-// RUN:     --builder clang-c --debugger 'lldb' --cflags "-O0 -glldb" -- %s
-
-void init_vla(int size) {
-  int i;
-  int vla[size];
-  for (i = 0; i < size; i++)
-    vla[i] = size-i;
-  vla[0] = size; // DexLabel('end_init')
-}
-
-int main(int argc, const char **argv) {
-  init_vla(23);
-  return 0;
-}
-
-// DexExpectWatchValue('vla[0]', '23', on_line=ref('end_init'))
-// DexExpectWatchValue('vla[1]', '22', on_line=ref('end_init'))
-
diff --git a/dexter/.gitignore b/dexter/.gitignore
deleted file mode 100644
index 042c4e0..0000000
--- a/dexter/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-/build/
-/results/
-
diff --git a/dexter/Commands.md b/dexter/Commands.md
deleted file mode 100644
index da14b8d..0000000
--- a/dexter/Commands.md
+++ /dev/null
@@ -1,265 +0,0 @@
-# Dexter commands
-
-* [DexExpectProgramState](Commands.md#DexExpectProgramState)
-* [DexExpectStepKind](Commands.md#DexExpectStepKind)
-* [DexExpectStepOrder](Commands.md#DexExpectStepOrder)
-* [DexExpectWatchType](Commands.md#DexExpectWatchType)
-* [DexExpectWatchValue](Commands.md#DexExpectWatchValue)
-* [DexUnreachable](Commands.md#DexUnreachable)
-* [DexLimitSteps](Commands.md#DexLimitSteps)
-* [DexLabel](Commands.md#DexLabel)
-* [DexWatch](Commands.md#DexWatch)
-* [DexDeclareFile](Commands.md#DexDeclareFile)
-
----
-## DexExpectProgramState
-    DexExpectProgramState(state [,**times])
-
-    Args:
-        state (dict): { 'frames': [
-                        {
-                          # StackFrame #
-                          'function': name (str),
-                          'is_inlined': bool,
-                          'location': {
-                            # SourceLocation #
-                            'lineno': int,
-                            'path': str,
-                            'column': int,
-                          },
-                          'watches': {
-                            expr (str): value (str),
-                            expr (str): {
-                              'value': str,
-                              'type_name': str,
-                              'could_evaluate': bool,
-                              'is_optimized_away': bool,
-                              'is_irretrievable': bool,
-			    }
-                          },
-                        }
-                      ]}
-
-    Keyword args:
-        times (int): Minimum number of times this state pattern is expected to
-             be seen. Defaults to 1. Can be 0.
-
-### Description
-Expect to see a given program `state` a certain number of `times`.
-
-For every debugger step the reported state is compared with the expected state.
-To consider the states a match:
-
-* The `SourceLocation` must match in both states. Omitted fields in the
-`SourceLocation` dictionary are ignored; they always match.
-* Each `expr` in `watches` in the expected state can either be a dictionary
-with the fields shown above, or a string representing its value. In either
-case, the actual value of `expr` in the debugger must match.
-* The function name and inline status are not considered.
-
-### Heuristic
-[TODO]
-
-
----
-## DexExpectStepKind
-    DexExpectStepKind(kind, times)
-
-    Args:
-      kind (str): Expected step kind.
-      times (int): Expected number of encounters.
-
-### Description
-Expect to see a particular step `kind` a number of `times` while stepping
-through the program.
-
-`kind` must be one of:
-
-`FUNC`: The first step into a function which is defined in the test
-directory.</br>
-`FUNC_EXTERNAL`: A step over a function which is not defined in the test
-directory.</br>
-`FUNC_UNKNOWN`: The first step over a function an unknown definition
-location.</br>
-`VERTICAL_FORWARD`: A step onto a line after the previous step line in this
-frame.</br>
-`VERTICAL_BACKWARD`: A step onto a line before the previous step line in
-this frame.</br>
-`HORIZONTAL_FORWARD`: A step forward on the same line as the previous step in
-this frame.</br>
-`HORIZONTAL_BACKWARD`: A step backward on the same line as the previous step
-in this frame.</br>
-`SAME`: A step onto the same line and column as the previous step in this
-frame.</br>
-
-### Heuristic
-[TODO]
-
-
----
-## DexExpectStepOrder
-    DexExpectStepOrder(*order)
-
-    Arg list:
-      order (int): One or more indices.
-
-### Description
-Expect the line every `DexExpectStepOrder` is found on to be stepped on in
-`order`. Each instance must have a set of unique ascending indices.
-
-### Heuristic
-[TODO]
-
-
----
-## DexExpectWatchType
-    DexExpectWatchType(expr, *types [,**from_line=1][,**to_line=Max]
-                        [,**on_line][,**require_in_order=True])
-
-    Args:
-        expr (str): expression to evaluate.
-
-    Arg list:
-        types (str): At least one expected type. NOTE: string type.
-
-    Keyword args:
-        from_line (int): Evaluate the expression from this line. Defaults to 1.
-        to_line (int): Evaluate the expression to this line. Defaults to end of
-            source.
-        on_line (int): Only evaluate the expression on this line. If provided,
-            this overrides from_line and to_line.
-        require_in_order (bool): If False the values can appear in any order.
-
-### Description
-Expect the expression `expr` to evaluate be evaluated and have each evaluation's
-type checked against the list of `types`
-
-### Heuristic
-[TODO]
-
-
----
-## DexExpectWatchValue
-    DexExpectWatchValue(expr, *values [,**from_line=1][,**to_line=Max]
-                        [,**on_line][,**require_in_order=True])
-
-    Args:
-        expr (str): expression to evaluate.
-
-    Arg list:
-        values (str): At least one expected value. NOTE: string type.
-
-    Keyword args:
-        from_line (int): Evaluate the expression from this line. Defaults to 1.
-        to_line (int): Evaluate the expression to this line. Defaults to end of
-            source.
-        on_line (int): Only evaluate the expression on this line. If provided,
-            this overrides from_line and to_line.
-        require_in_order (bool): If False the values can appear in any order.
-
-### Description
-Expect the expression `expr` to evaluate to the list of `values`
-sequentially.
-
-### Heuristic
-[TODO]
-
-
----
-## DexUnreachable
-    DexUnreachable()
-
-### Description
-Expect the source line this is found on will never be stepped on to.
-
-### Heuristic
-[TODO]
-
-
-----
-## DexLimitSteps
-    DexLimitSteps([expr, *values][, **from_line=1][,**to_line=Max]
-                  [,**on_line][,**hit_count])
-
-    Args:
-        expr (str): variable or value to compare.
-
-    Arg list:
-        values (str): At least one potential value the expr may evaluate to.
-
-    Keyword args:
-        from_line (int): Define the start of the limited step range.
-        to_line (int): Define the end of the limited step range.
-        on_line (int): Define a range with length 1 starting and ending on the
-                       same line.
-        hit_count (int): If provided, limit the number of times the command
-                         triggers.
-
-### Description
-Define a limited stepping range that may be predicated on a condition. When the
-leading line is stepped on and any condition '(expr) == (values[n])' is true or
-there are no conditions, set a range of temporary breakpoints within the test
-file defined by the range 'from_line' and 'to_line' or 'on_line'. This only
-happens 'hit_count' number of times if the argument is provided.
-
-The condition is only evaluated on the line 'from_line' or 'on_line'. If the
-condition is not true at the start of the range, or that line is never stepped
-onto, the whole range is ignored.
-
-DexLimitSteps commands are useful for reducing the amount of steps gathered in
-large test cases that would normally take much longer to complete.
-
-----
-## DexLabel
-    DexLabel(name [, **on_line])
-
-    Args:
-        name (str): A unique name for this line.
-
-    Keyword args:
-        on_line (int): Specify a line number to label.
-
-### Description
-Name the line this command is found on or 'on_line' if it is provided. Line
-names can be converted to line numbers with the `ref(str)` function. For
-example, `DexExpectWatchValues(..., on_line=ref('my_line_name'))`. Use
-arithmetic operators to get offsets from labels:
-
-    DexExpectWatchValues(..., on_line=ref('my_line_name') + 3)
-    DexExpectWatchValues(..., on_line=ref('my_line_name') - 5)
-
-
-### Heuristic
-This command does not contribute to the heuristic score.
-
-----
-## DexDeclareFile
-    DexDeclareFile(declared_file)
-
-    Args:
-        name (str): A declared file path for which all subsequent commands
-          will have their path attribute set too.
-
-### Description
-Set the path attribute of all commands from this point in the test onwards.
-The new path holds until the end of the test file or until a new DexDeclareFile
-command is encountered. Used in conjunction with .dex files, DexDeclareFile can
-be used to write your dexter commands in a separate test file avoiding inlined
-Dexter commands mixed with test source.
-
-### Heuristic
-This command does not contribute to the heuristic score.
-
----
-## DexWatch
-    DexWatch(*expressions)
-
-    Arg list:
-        expressions (str): `expression` to evaluate on this line.
-
-### Description
-[Deprecated] Evaluate each given `expression` when the debugger steps onto the
-line this command is found on.
-
-### Heuristic
-[Deprecated]
diff --git a/dexter/LICENSE.txt b/dexter/LICENSE.txt
deleted file mode 100644
index fa6ac54..0000000
--- a/dexter/LICENSE.txt
+++ /dev/null
@@ -1,279 +0,0 @@
-==============================================================================
-The LLVM Project is under the Apache License v2.0 with LLVM Exceptions:
-==============================================================================
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-    1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-    2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-    3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-    4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-    5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-    6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-    7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-    8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-    9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-    END OF TERMS AND CONDITIONS
-
-    APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-    Copyright [yyyy] [name of copyright owner]
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
-
-
----- LLVM Exceptions to the Apache 2.0 License ----
-
-As an exception, if, as a result of your compiling your source code, portions
-of this Software are embedded into an Object form of such source code, you
-may redistribute such embedded portions in such Object form without complying
-with the conditions of Sections 4(a), 4(b) and 4(d) of the License.
-
-In addition, if you combine or link compiled forms of this Software with
-software that is licensed under the GPLv2 ("Combined Software") and if a
-court of competent jurisdiction determines that the patent provision (Section
-3), the indemnity provision (Section 9) or other Section of the License
-conflicts with the conditions of the GPLv2, you may retroactively and
-prospectively choose to deem waived or otherwise exclude such Section(s) of
-the License, but only in their entirety and only with respect to the Combined
-Software.
-
-==============================================================================
-Software from third parties included in the LLVM Project:
-==============================================================================
-The LLVM Project contains third party software which is under different license
-terms. All such code will be identified clearly using at least one of two
-mechanisms:
-1) It will be in a separate directory tree with its own `LICENSE.txt` or
-   `LICENSE` file at the top containing the specific license and restrictions
-   which apply to that software, or
-2) It will contain specific license and restriction terms at the top of every
-   file.
-
-==============================================================================
-Legacy LLVM License (https://llvm.org/docs/DeveloperPolicy.html#legacy):
-==============================================================================
-University of Illinois/NCSA
-Open Source License
-
-Copyright (c) 2003-2019 University of Illinois at Urbana-Champaign.
-All rights reserved.
-
-Developed by:
-
-    LLVM Team
-
-    University of Illinois at Urbana-Champaign
-
-    http://llvm.org
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal with
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-of the Software, and to permit persons to whom the Software is furnished to do
-so, subject to the following conditions:
-
-    * Redistributions of source code must retain the above copyright notice,
-      this list of conditions and the following disclaimers.
-
-    * Redistributions in binary form must reproduce the above copyright notice,
-      this list of conditions and the following disclaimers in the
-      documentation and/or other materials provided with the distribution.
-
-    * Neither the names of the LLVM Team, University of Illinois at
-      Urbana-Champaign, nor the names of its contributors may be used to
-      endorse or promote products derived from this Software without specific
-      prior written permission.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
-SOFTWARE.
-
diff --git a/dexter/README.md b/dexter/README.md
deleted file mode 100644
index 1da6fa1..0000000
--- a/dexter/README.md
+++ /dev/null
@@ -1,304 +0,0 @@
-# DExTer (Debugging Experience Tester)
-
-## Introduction
-
-DExTer is a suite of tools used to evaluate the "User Debugging Experience". DExTer drives an external debugger, running on small test programs, and collects information on the behavior at each debugger step to provide quantitative values that indicate the quality of the debugging experience.
-
-## Supported Debuggers
-
-DExTer currently supports the Visual Studio 2015 and Visual Studio 2017 debuggers via the [DTE interface](https://docs.microsoft.com/en-us/dotnet/api/envdte.dte), and LLDB via its [Python interface](https://lldb.llvm.org/python-reference.html). GDB is not currently supported.
-
-The following command evaluates your environment, listing the available and compatible debuggers:
-
-    dexter.py list-debuggers
-
-## Dependencies
-[TODO] Add a requirements.txt or an install.py and document it here.
-
-### Python 3.6
-
-DExTer requires python version 3.6 or greater.
-
-### pywin32 python package
-
-This is required to access the DTE interface for the Visual Studio debuggers.
-
-    <python-executable> -m pip install pywin32
-
-### clang
-
-DExTer is current compatible with 'clang' and 'clang-cl' compiler drivers.  The compiler must be available for DExTer, for example the following command should successfully build a runnable executable.
-
-     <compiler-executable> tests/nostdlib/fibonacci/test.cpp
-
-## Running a test case
-
-The following DExTer commands build the test.cpp from the tests/nostdlib/fibonacci directory and quietly runs it on the Visual Studio debugger, reporting the debug experience heuristic.  The first command builds with no optimizations (/Od) and scores 1.0000.  The second command builds with optimizations (/Ox) and scores 0.2832 which suggests a worse debugging experience.
-
-    dexter.py test --builder clang-cl_vs2015 --debugger vs2017 --cflags="/Od /Zi" --ldflags="/Zi" -- tests/nostdlib/fibonacci
-    fibonacci = (1.0000)
-
-    dexter.py test --builder clang-cl_vs2015 --debugger vs2017 --cflags="/Ox /Zi" --ldflags="/Zi" -- tests/nostdlib/fibonacci
-    fibonacci = (0.2832)
-
-## An example test case
-
-The sample test case (tests/nostdlib/fibonacci) looks like this:
-
-    1.  #ifdef _MSC_VER
-    2.  # define DEX_NOINLINE __declspec(noinline)
-    3.  #else
-    4.  # define DEX_NOINLINE __attribute__((__noinline__))
-    5.  #endif
-    6.
-    7.  DEX_NOINLINE
-    8.  void Fibonacci(int terms, int& total)
-    9.  {
-    0.      int first = 0;
-    11.     int second = 1;
-    12.     for (int i = 0; i < terms; ++i)
-    13.     {
-    14.         int next = first + second; // DexLabel('start')
-    15.         total += first;
-    16.         first = second;
-    17.         second = next;             // DexLabel('end')
-    18.     }
-    19. }
-    20.
-    21. int main()
-    22. {
-    23.     int total = 0;
-    24.     Fibonacci(5, total);
-    25.     return total;
-    26. }
-    27.
-    28. /*
-    29. DexExpectWatchValue('i', '0', '1', '2', '3', '4',
-    30.                     from_line='start', to_line='end')
-    31. DexExpectWatchValue('first', '0', '1', '2', '3', '5',
-    32.                     from_line='start', to_line='end')
-    33. DexExpectWatchValue('second', '1', '2', '3', '5',
-    34                      from_line='start', to_line='end')
-    35. DexExpectWatchValue('total', '0', '1', '2', '4', '7',
-    36.                     from_line='start', to_line='end')
-    37. DexExpectWatchValue('next', '1', '2', '3', '5', '8',
-    38.                     from_line='start', to_line='end')
-    39. DexExpectWatchValue('total', '7', on_line=25)
-    40. DexExpectStepKind('FUNC_EXTERNAL', 0)
-    41. */
-
-[DexLabel][1] is used to give a name to a line number.
-
-The [DexExpectWatchValue][2] command states that an expression, e.g. `i`, should
-have particular values, `'0', '1', '2', '3','4'`, sequentially over the program
-lifetime on particular lines. You can refer to a named line or simply the line
-number (See line 39).
-
-At the end of the test is the following line:
-
-    DexExpectStepKind('FUNC_EXTERNAL', 0)
-
-This [DexExpectStepKind][3] command indicates that we do not expect the debugger
-to step into a file outside of the test directory.
-
-[1]: Commands.md#DexLabel
-[2]: Commands.md#DexExpectWatchValue
-[3]: Commands.md#DexExpectStepKind
-
-## Detailed DExTer reports
-
-Running the command below launches the tests/nostdlib/fibonacci test case in DExTer, using clang-cl as the compiler, Visual Studio 2017 as the debugger, and producing a detailed report:
-
-    $ dexter.py test --builder clang-cl_vs2015 --debugger vs2017 --cflags="/Ox /Zi" --ldflags="/Zi" -v -- tests/nostdlib/fibonacci
-
-The detailed report is enabled by `-v` and shows a breakdown of the information from each debugger step. For example:
-
-    fibonacci = (0.2832)
-
-    ## BEGIN ##
-    [1, "main", "c:\\dexter\\tests\\nostdlib\\fibonacci\\test.cpp", 23, 1, "BREAKPOINT", "FUNC", {}]
-    [2, "main", "c:\\dexter\\tests\\nostdlib\\fibonacci\\test.cpp", 24, 1, "BREAKPOINT", "VERTICAL_FORWARD", {}]
-    [3, "main", "c:\\dexter\\tests\\nostdlib\\fibonacci\\test.cpp", 25, 1, "BREAKPOINT", "VERTICAL_FORWARD", {}]
-    .   [4, "Fibonacci", "c:\\dexter\\tests\\nostdlib\\fibonacci\\test.cpp", 13, 1, "BREAKPOINT", "FUNC", {}]
-    .   [5, "Fibonacci", "c:\\dexter\\tests\\nostdlib\\fibonacci\\test.cpp", 16, 1, "BREAKPOINT", "VERTICAL_FORWARD", {"i": "Variable is optimized away and not available.", "next": "Variable is optimized away and not available.", "second": "Variable is optimized away and not available.", "total": "0", "first": "Variable is optimized away and not available."}]
-    .   [6, "Fibonacci", "c:\\dexter\\tests\\nostdlib\\fibonacci\\test.cpp", 13, 1, "BREAKPOINT", "VERTICAL_BACKWARD", {}]
-    .   [7, "Fibonacci", "c:\\dexter\\tests\\nostdlib\\fibonacci\\test.cpp", 15, 1, "BREAKPOINT", "VERTICAL_FORWARD", {"i": "Variable is optimized away and not available.", "second": "Variable is optimized away and not available.", "total": "0", "first": "Variable is optimized away and not available."}]
-    .   [8, "Fibonacci", "c:\\dexter\\tests\\nostdlib\\fibonacci\\test.cpp", 16, 1, "BREAKPOINT", "VERTICAL_FORWARD", {"i": "Variable is optimized away and not available.", "next": "Variable is optimized away and not available.", "second": "Variable is optimized away and not available.", "total": "0", "first": "Variable is optimized away and not available."}]
-    .   [9, "Fibonacci", "c:\\dexter\\tests\\nostdlib\\fibonacci\\test.cpp", 15, 1, "BREAKPOINT", "VERTICAL_BACKWARD", {"i": "Variable is optimized away and not available.", "second": "1", "total": "0", "first": "0"}]
-    .   [10, "Fibonacci", "c:\\dexter\\tests\\nostdlib\\fibonacci\\test.cpp", 13, 1, "BREAKPOINT", "VERTICAL_BACKWARD", {}]
-    .   [11, "Fibonacci", "c:\\dexter\\tests\\nostdlib\\fibonacci\\test.cpp", 16, 1, "BREAKPOINT", "VERTICAL_FORWARD", {"i": "Variable is optimized away and not available.", "next": "Variable is optimized away and not available.", "second": "Variable is optimized away and not available.", "total": "0", "first": "Variable is optimized away and not available."}]
-    .   [12, "Fibonacci", "c:\\dexter\\tests\\nostdlib\\fibonacci\\test.cpp", 15, 1, "BREAKPOINT", "VERTICAL_BACKWARD", {"i": "Variable is optimized away and not available.", "second": "1", "total": "0", "first": "1"}]
-    .   [13, "Fibonacci", "c:\\dexter\\tests\\nostdlib\\fibonacci\\test.cpp", 13, 1, "BREAKPOINT", "VERTICAL_BACKWARD", {}]
-    .   [14, "Fibonacci", "c:\\dexter\\tests\\nostdlib\\fibonacci\\test.cpp", 16, 1, "BREAKPOINT", "VERTICAL_FORWARD", {"i": "Variable is optimized away and not available.", "next": "Variable is optimized away and not available.", "second": "Variable is optimized away and not available.", "total": "0", "first": "Variable is optimized away and not available."}]
-    .   [15, "Fibonacci", "c:\\dexter\\tests\\nostdlib\\fibonacci\\test.cpp", 15, 1, "BREAKPOINT", "VERTICAL_BACKWARD", {"i": "Variable is optimized away and not available.", "second": "2", "total": "0", "first": "1"}]
-    .   [16, "Fibonacci", "c:\\dexter\\tests\\nostdlib\\fibonacci\\test.cpp", 13, 1, "BREAKPOINT", "VERTICAL_BACKWARD", {}]
-    .   [17, "Fibonacci", "c:\\dexter\\tests\\nostdlib\\fibonacci\\test.cpp", 16, 1, "BREAKPOINT", "VERTICAL_FORWARD", {"i": "Variable is optimized away and not available.", "next": "Variable is optimized away and not available.", "second": "Variable is optimized away and not available.", "total": "0", "first": "Variable is optimized away and not available."}]
-    .   [18, "Fibonacci", "c:\\dexter\\tests\\nostdlib\\fibonacci\\test.cpp", 15, 1, "BREAKPOINT", "VERTICAL_BACKWARD", {"i": "Variable is optimized away and not available.", "second": "3", "total": "0", "first": "2"}]
-    .   [19, "Fibonacci", "c:\\dexter\\tests\\nostdlib\\fibonacci\\test.cpp", 13, 1, "BREAKPOINT", "VERTICAL_BACKWARD", {}]
-    .   [20, "Fibonacci", "c:\\dexter\\tests\\nostdlib\\fibonacci\\test.cpp", 16, 1, "BREAKPOINT", "VERTICAL_FORWARD", {"i": "Variable is optimized away and not available.", "next": "Variable is optimized away and not available.", "second": "Variable is optimized away and not available.", "total": "0", "first": "Variable is optimized away and not available."}]
-    .   [21, "Fibonacci", "c:\\dexter\\tests\\nostdlib\\fibonacci\\test.cpp", 15, 1, "BREAKPOINT", "VERTICAL_BACKWARD", {"i": "Variable is optimized away and not available.", "second": "5", "total": "0", "first": "3"}]
-    .   [22, "Fibonacci", "c:\\dexter\\tests\\nostdlib\\fibonacci\\test.cpp", 13, 1, "BREAKPOINT", "VERTICAL_BACKWARD", {}]
-    .   [23, "Fibonacci", "c:\\dexter\\tests\\nostdlib\\fibonacci\\test.cpp", 16, 1, "BREAKPOINT", "VERTICAL_FORWARD", {"i": "Variable is optimized away and not available.", "next": "Variable is optimized away and not available.", "second": "Variable is optimized away and not available.", "total": "0", "first": "Variable is optimized away and not available."}]
-    .   [24, "Fibonacci", "c:\\dexter\\tests\\nostdlib\\fibonacci\\test.cpp", 20, 1, "BREAKPOINT", "VERTICAL_FORWARD", {}]
-    [25, "main", "c:\\dexter\\tests\\nostdlib\\fibonacci\\test.cpp", 26, 1, "BREAKPOINT", "FUNC", {"total": "7"}]
-    ## END (25 steps) ##
-
-
-    step kind differences [0/1]
-        FUNC_EXTERNAL:
-        0
-
-    test.cpp:15-18 [first] [9/21]
-        expected encountered values:
-        0
-        1
-        2
-        3
-
-        missing values:
-        5 [-6]
-
-        result optimized away:
-        step 5 (Variable is optimized away and not available.) [-3]
-        step 7 (Variable is optimized away and not available.)
-        step 8 (Variable is optimized away and not available.)
-        step 11 (Variable is optimized away and not available.)
-        step 14 (Variable is optimized away and not available.)
-        step 17 (Variable is optimized away and not available.)
-        step 20 (Variable is optimized away and not available.)
-        step 23 (Variable is optimized away and not available.)
-
-    test.cpp:15-18 [i] [15/21]
-        result optimized away:
-        step 5 (Variable is optimized away and not available.) [-3]
-        step 7 (Variable is optimized away and not available.) [-3]
-        step 8 (Variable is optimized away and not available.) [-3]
-        step 9 (Variable is optimized away and not available.) [-3]
-        step 11 (Variable is optimized away and not available.) [-3]
-        step 12 (Variable is optimized away and not available.)
-        step 14 (Variable is optimized away and not available.)
-        step 15 (Variable is optimized away and not available.)
-        step 17 (Variable is optimized away and not available.)
-        step 18 (Variable is optimized away and not available.)
-        step 20 (Variable is optimized away and not available.)
-        step 21 (Variable is optimized away and not available.)
-        step 23 (Variable is optimized away and not available.)
-
-    test.cpp:15-18 [second] [21/21]
-        expected encountered values:
-        1
-        2
-        3
-        5
-
-        result optimized away:
-        step 5 (Variable is optimized away and not available.) [-3]
-        step 7 (Variable is optimized away and not available.) [-3]
-        step 8 (Variable is optimized away and not available.) [-3]
-        step 11 (Variable is optimized away and not available.) [-3]
-        step 14 (Variable is optimized away and not available.) [-3]
-        step 17 (Variable is optimized away and not available.) [-3]
-        step 20 (Variable is optimized away and not available.) [-3]
-        step 23 (Variable is optimized away and not available.)
-
-    test.cpp:15-18 [total] [21/21]
-        expected encountered values:
-        0
-
-        missing values:
-        1 [-6]
-        2 [-6]
-        4 [-6]
-        7 [-3]
-
-    test.cpp:16-18 [next] [15/21]
-        result optimized away:
-        step 5 (Variable is optimized away and not available.) [-3]
-        step 8 (Variable is optimized away and not available.) [-3]
-        step 11 (Variable is optimized away and not available.) [-3]
-        step 14 (Variable is optimized away and not available.) [-3]
-        step 17 (Variable is optimized away and not available.) [-3]
-        step 20 (Variable is optimized away and not available.)
-        step 23 (Variable is optimized away and not available.)
-
-    test.cpp:26 [total] [0/7]
-        expected encountered values:
-        7
-
-The first line
-
-    fibonacci =  (0.2832)
-
-shows a score of 0.2832 suggesting that unexpected behavior has been seen.  This score is on scale of 0.0000 to 1.000, with 0.000 being the worst score possible and 1.000 being the best score possible.  The verbose output shows the reason for any scoring.  For example:
-
-    test.cpp:15-18 [first] [9/21]
-        expected encountered values:
-        0
-        1
-        2
-        3
-
-        missing values:
-        5 [-6]
-
-        result optimized away:
-        step 5 (Variable is optimized away and not available.) [-3]
-        step 7 (Variable is optimized away and not available.)
-        step 8 (Variable is optimized away and not available.)
-        step 11 (Variable is optimized away and not available.)
-        step 14 (Variable is optimized away and not available.)
-        step 17 (Variable is optimized away and not available.)
-        step 20 (Variable is optimized away and not available.)
-        step 23 (Variable is optimized away and not available.)
-
-shows that for `first` the expected values 0, 1, 2 and 3 were seen, 5 was not.  On some steps the variable was reported as being optimized away.
-
-## Writing new test cases
-
-Each test requires a `test.cfg` file.  Currently the contents of this file are not read, but its presence is used to determine the root directory of a test. In the future, configuration variables for the test such as supported language modes may be stored in this file. Use the various [commands](Commands.md) to encode debugging expectations.
-
-## Additional tools
-
-For clang-based compilers, the `clang-opt-bisect` tool can be used to get a breakdown of which LLVM passes may be contributing to debugging experience issues.  For example:
-
-    $ dexter.py clang-opt-bisect tests/nostdlib/fibonacci --builder clang-cl --debugger vs2017 --cflags="/Ox /Zi" --ldflags="/Zi"
-
-    pass 1/211 =  (1.0000)  (0.0000) [Simplify the CFG on function (?Fibonacci@@YAXHAEAH@Z)]
-    pass 2/211 =  (0.7611) (-0.2389) [SROA on function (?Fibonacci@@YAXHAEAH@Z)]
-    pass 3/211 =  (0.7611)  (0.0000) [Early CSE on function (?Fibonacci@@YAXHAEAH@Z)]
-    pass 4/211 =  (0.7611)  (0.0000) [Simplify the CFG on function (main)]
-    pass 5/211 =  (0.7611)  (0.0000) [SROA on function (main)]
-    pass 6/211 =  (0.7611)  (0.0000) [Early CSE on function (main)]
-    pass 7/211 =  (0.7611)  (0.0000) [Infer set function attributes on module (c:\dexter\tests\fibonacci\test.cpp)]
-    pass 8/211 =  (0.7611)  (0.0000) [Interprocedural Sparse Conditional Constant Propagation on module (c:\dexter\tests\fibonacci\test.cpp)]
-    pass 9/211 =  (0.7611)  (0.0000) [Called Value Propagation on module (c:\dexter\tests\fibonacci\test.cpp)]
-    pass 10/211 =  (0.7611)  (0.0000) [Global Variable Optimizer on module (c:\dexter\tests\fibonacci\test.cpp)]
-    pass 11/211 =  (0.7611)  (0.0000) [Promote Memory to Register on function (?Fibonacci@@YAXHAEAH@Z)]
-    pass 12/211 =  (0.7611)  (0.0000) [Promote Memory to Register on function (main)]
-    pass 13/211 =  (0.7611)  (0.0000) [Dead Argument Elimination on module (c:\dexter\tests\fibonacci\test.cpp)]
-    pass 14/211 =  (0.7611)  (0.0000) [Combine redundant instructions on function (?Fibonacci@@YAXHAEAH@Z)]
-    pass 15/211 =  (0.7611)  (0.0000) [Simplify the CFG on function (?Fibonacci@@YAXHAEAH@Z)]a
-    pass 16/211 =  (0.7345) (-0.0265) [Combine redundant instructions on function (main)]
-    pass 17/211 =  (0.7345)  (0.0000) [Simplify the CFG on function (main)]
-    pass 18/211 =  (0.7345)  (0.0000) [Remove unused exception handling info on SCC (?Fibonacci@@YAXHAEAH@Z)]
-    pass 19/211 =  (0.7345)  (0.0000) [Function Integration/Inlining on SCC (?Fibonacci@@YAXHAEAH@Z)]
-    pass 20/211 =  (0.7345)  (0.0000) [Deduce function attributes on SCC (?Fibonacci@@YAXHAEAH@Z)]
-    pass 21/211 =  (0.7345)  (0.0000) [SROA on function (?Fibonacci@@YAXHAEAH@Z)]
-    pass 22/211 =  (0.7345)  (0.0000) [Early CSE w/ MemorySSA on function (?Fibonacci@@YAXHAEAH@Z)]
-    pass 23/211 =  (0.7345)  (0.0000) [Speculatively execute instructions if target has divergent branches on function (?Fibonacci@@YAXHAEAH@Z)]
-    pass 24/211 =  (0.7345)  (0.0000) [Jump Threading on function (?Fibonacci@@YAXHAEAH@Z)]
-    pass 25/211 =  (0.7345)  (0.0000) [Value Propagation on function (?Fibonacci@@YAXHAEAH@Z)]
-    pass 26/211 =  (0.7345)  (0.0000) [Simplify the CFG on function (?Fibonacci@@YAXHAEAH@Z)]
-    pass 27/211 =  (0.7345)  (0.0000) [Combine redundant instructions on function (?Fibonacci@@YAXHAEAH@Z)]
-    pass 28/211 =  (0.7345)  (0.0000) [Tail Call Elimination on function (?Fibonacci@@YAXHAEAH@Z)]
-    pass 29/211 =  (0.7345)  (0.0000) [Simplify the CFG on function (?Fibonacci@@YAXHAEAH@Z)]
-    pass 30/211 =  (0.7345)  (0.0000) [Reassociate expressions on function (?Fibonacci@@YAXHAEAH@Z)]
-    pass 31/211 =  (0.8673)  (0.1327) [Rotate Loops on loop]
-    pass 32/211 =  (0.5575) (-0.3097) [Loop Invariant Code Motion on loop]
-    pass 33/211 =  (0.5575)  (0.0000) [Unswitch loops on loop]
-    pass 34/211 =  (0.5575)  (0.0000) [Simplify the CFG on function (?Fibonacci@@YAXHAEAH@Z)]
-    pass 35/211 =  (0.5575)  (0.0000) [Combine redundant instructions on function (?Fibonacci@@YAXHAEAH@Z)]
-    pass 36/211 =  (0.5575)  (0.0000) [Induction Variable Simplification on loop]
-    pass 37/211 =  (0.5575)  (0.0000) [Recognize loop idioms on loop]
-    <output-snipped>
-
diff --git a/dexter/dex/__init__.py b/dexter/dex/__init__.py
deleted file mode 100644
index d2a290b..0000000
--- a/dexter/dex/__init__.py
+++ /dev/null
@@ -1,8 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-
-__version__ = '1.0.0'
diff --git a/dexter/dex/builder/Builder.py b/dexter/dex/builder/Builder.py
deleted file mode 100644
index 153c768..0000000
--- a/dexter/dex/builder/Builder.py
+++ /dev/null
@@ -1,119 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-"""Deals with the processing execution of shell or batch build scripts."""
-
-import os
-import subprocess
-import unittest
-
-from dex.dextIR import BuilderIR
-from dex.utils import Timer
-from dex.utils.Exceptions import BuildScriptException
-
-
-def _quotify(text):
-    if '"' in text or ' ' not in text:
-        return text
-    return '"{}"'.format(text)
-
-
-def _get_script_environment(source_files, compiler_options,
-                            linker_options, executable_file):
-
-    source_files = [_quotify(f) for f in source_files]
-    object_files = [
-        _quotify('{}.o'.format(os.path.basename(f))) for f in source_files
-    ]
-    source_indexes = ['{:02d}'.format(i + 1) for i in range(len(source_files))]
-
-    env_variables = {}
-    env_variables['SOURCE_INDEXES'] = ' '.join(source_indexes)
-    env_variables['SOURCE_FILES'] = ' '.join(source_files)
-    env_variables['OBJECT_FILES'] = ' '.join(object_files)
-    env_variables['LINKER_OPTIONS'] = linker_options
-
-    for i, _ in enumerate(source_files):
-        index = source_indexes[i]
-        env_variables['SOURCE_FILE_{}'.format(index)] = source_files[i]
-        env_variables['OBJECT_FILE_{}'.format(index)] = object_files[i]
-        env_variables['COMPILER_OPTIONS_{}'.format(index)] = compiler_options[i]
-
-    env_variables['EXECUTABLE_FILE'] = executable_file
-
-    return env_variables
-
-
-def run_external_build_script(context, script_path, source_files,
-                              compiler_options, linker_options,
-                              executable_file):
-    """Build an executable using a builder script.
-
-    The executable is saved to `context.working_directory.path`.
-
-    Returns:
-        ( stdout (str), stderr (str), builder (BuilderIR) )
-    """
-
-    builderIR = BuilderIR(
-        name=context.options.builder,
-        cflags=compiler_options,
-        ldflags=linker_options,
-    )
-    assert len(source_files) == len(compiler_options), (source_files,
-                                                        compiler_options)
-
-    script_environ = _get_script_environment(source_files, compiler_options,
-                                             linker_options, executable_file)
-    env = dict(os.environ)
-    env.update(script_environ)
-    try:
-        with Timer('running build script'):
-            process = subprocess.Popen(
-                [script_path],
-                cwd=context.working_directory.path,
-                env=env,
-                stdout=subprocess.PIPE,
-                stderr=subprocess.PIPE)
-            out, err = process.communicate()
-            returncode = process.returncode
-        out = out.decode('utf-8')
-        err = err.decode('utf-8')
-        if returncode != 0:
-            raise BuildScriptException(
-                '{}: failed with returncode {}.\nstdout:\n{}\n\nstderr:\n{}\n'.
-                format(script_path, returncode, out, err),
-                script_error=err)
-        return out, err, builderIR
-    except OSError as e:
-        raise BuildScriptException('{}: {}'.format(e.strerror, script_path))
-
-
-class TestBuilder(unittest.TestCase):
-    def test_get_script_environment(self):
-        source_files = ['a.a', 'b.b']
-        compiler_options = ['-option1 value1', '-option2 value2']
-        linker_options = '-optionX valueX'
-        executable_file = 'exe.exe'
-        env = _get_script_environment(source_files, compiler_options,
-                                      linker_options, executable_file)
-
-        assert env['SOURCE_FILES'] == 'a.a b.b'
-        assert env['OBJECT_FILES'] == 'a.a.o b.b.o'
-
-        assert env['SOURCE_INDEXES'] == '01 02'
-        assert env['LINKER_OPTIONS'] == '-optionX valueX'
-
-        assert env['SOURCE_FILE_01'] == 'a.a'
-        assert env['SOURCE_FILE_02'] == 'b.b'
-
-        assert env['OBJECT_FILE_01'] == 'a.a.o'
-        assert env['OBJECT_FILE_02'] == 'b.b.o'
-
-        assert env['EXECUTABLE_FILE'] == 'exe.exe'
-
-        assert env['COMPILER_OPTIONS_01'] == '-option1 value1'
-        assert env['COMPILER_OPTIONS_02'] == '-option2 value2'
diff --git a/dexter/dex/builder/ParserOptions.py b/dexter/dex/builder/ParserOptions.py
deleted file mode 100644
index b6677aa..0000000
--- a/dexter/dex/builder/ParserOptions.py
+++ /dev/null
@@ -1,56 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-"""Command line options for subtools that use the builder component."""
-
-import os
-
-from dex.tools import Context
-from dex.utils import is_native_windows
-
-
-def _find_build_scripts():
-    """Finds build scripts in the 'scripts' subdirectory.
-
-    Returns:
-        { script_name (str): directory (str) }
-    """
-    try:
-        return _find_build_scripts.cached
-    except AttributeError:
-        scripts_directory = os.path.join(os.path.dirname(__file__), 'scripts')
-        if is_native_windows():
-            scripts_directory = os.path.join(scripts_directory, 'windows')
-        else:
-            scripts_directory = os.path.join(scripts_directory, 'posix')
-        assert os.path.isdir(scripts_directory), scripts_directory
-        results = {}
-
-        for f in os.listdir(scripts_directory):
-            results[os.path.splitext(f)[0]] = os.path.abspath(
-                os.path.join(scripts_directory, f))
-
-        _find_build_scripts.cached = results
-        return results
-
-
-def add_builder_tool_arguments(parser):
-    parser.add_argument('--binary',
-                        metavar="<file>",
-                        help='provide binary file to override --builder')
-
-    parser.add_argument(
-        '--builder',
-        type=str,
-        choices=sorted(_find_build_scripts().keys()),
-        help='test builder to use')
-    parser.add_argument(
-        '--cflags', type=str, default='', help='compiler flags')
-    parser.add_argument('--ldflags', type=str, default='', help='linker flags')
-
-
-def handle_builder_tool_options(context: Context) -> str:
-    return _find_build_scripts()[context.options.builder]
diff --git a/dexter/dex/builder/__init__.py b/dexter/dex/builder/__init__.py
deleted file mode 100644
index 3bf0ca4..0000000
--- a/dexter/dex/builder/__init__.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-
-from dex.builder.Builder import run_external_build_script
-from dex.builder.ParserOptions import add_builder_tool_arguments
-from dex.builder.ParserOptions import handle_builder_tool_options
diff --git a/dexter/dex/builder/scripts/posix/clang-c.sh b/dexter/dex/builder/scripts/posix/clang-c.sh
deleted file mode 100755
index f69f51c..0000000
--- a/dexter/dex/builder/scripts/posix/clang-c.sh
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/usr/bin/env bash
-set -e
-
-if test -z "$PATHTOCLANG"; then
-  PATHTOCLANG=clang
-fi
-
-for INDEX in $SOURCE_INDEXES
-do
-  CFLAGS=$(eval echo "\$COMPILER_OPTIONS_$INDEX")
-  SRCFILE=$(eval echo "\$SOURCE_FILE_$INDEX")
-  OBJFILE=$(eval echo "\$OBJECT_FILE_$INDEX")
-  $PATHTOCLANG -std=gnu11 -c $CFLAGS $SRCFILE -o $OBJFILE
-done
-
-$PATHTOCLANG $LINKER_OPTIONS $OBJECT_FILES -o $EXECUTABLE_FILE
diff --git a/dexter/dex/builder/scripts/posix/clang.sh b/dexter/dex/builder/scripts/posix/clang.sh
deleted file mode 100755
index 9cf4cdd..0000000
--- a/dexter/dex/builder/scripts/posix/clang.sh
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/usr/bin/env bash
-set -e
-
-if test -z "$PATHTOCLANGPP"; then
-  PATHTOCLANGPP=clang++
-fi
-
-for INDEX in $SOURCE_INDEXES
-do
-  CFLAGS=$(eval echo "\$COMPILER_OPTIONS_$INDEX")
-  SRCFILE=$(eval echo "\$SOURCE_FILE_$INDEX")
-  OBJFILE=$(eval echo "\$OBJECT_FILE_$INDEX")
-  $PATHTOCLANGPP -std=gnu++11 -c $CFLAGS $SRCFILE -o $OBJFILE
-done
-
-$PATHTOCLANGPP $LINKER_OPTIONS $OBJECT_FILES -o $EXECUTABLE_FILE
diff --git a/dexter/dex/builder/scripts/posix/gcc.sh b/dexter/dex/builder/scripts/posix/gcc.sh
deleted file mode 100755
index c18e333..0000000
--- a/dexter/dex/builder/scripts/posix/gcc.sh
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/usr/bin/env bash
-set -e
-
-if test -z "$PATHTOGCC"; then
-  PATHTOGCC=gcc
-fi
-
-for INDEX in $SOURCE_INDEXES
-do
-  CFLAGS=$(eval echo "\$COMPILER_OPTIONS_$INDEX")
-  SRCFILE=$(eval echo "\$SOURCE_FILE_$INDEX")
-  OBJFILE=$(eval echo "\$OBJECT_FILE_$INDEX")
-  $PATHTOGCC -std=gnu++11 -c $CFLAGS $SRCFILE -o $OBJFILE
-done
-
-$PATHTOGCC $LINKER_OPTIONS $OBJECT_FILES -o $EXECUTABLE_FILE
diff --git a/dexter/dex/builder/scripts/windows/clang-cl_vs2015.bat b/dexter/dex/builder/scripts/windows/clang-cl_vs2015.bat
deleted file mode 100644
index ea0d441..0000000
--- a/dexter/dex/builder/scripts/windows/clang-cl_vs2015.bat
+++ /dev/null
@@ -1,23 +0,0 @@
-@echo OFF
-setlocal EnableDelayedExpansion
-
-call "%VS140COMNTOOLS%..\..\VC\bin\amd64\vcvars64.bat"
-
-@echo OFF
-setlocal EnableDelayedExpansion
-
-for %%I in (%SOURCE_INDEXES%) do (
-  %PATHTOCLANGCL% /c !COMPILER_OPTIONS_%%I! !SOURCE_FILE_%%I! /Fo!OBJECT_FILE_%%I!
-  if errorlevel 1 goto :FAIL
-)
-
-%PATHTOCLANGCL% %LINKER_OPTIONS% %OBJECT_FILES% /Fe%EXECUTABLE_FILE%
-if errorlevel 1 goto :FAIL
-goto :END
-
-:FAIL
-echo FAILED
-exit /B 1
-
-:END
-exit /B 0
diff --git a/dexter/dex/builder/scripts/windows/clang.bat b/dexter/dex/builder/scripts/windows/clang.bat
deleted file mode 100644
index 4aa9e28..0000000
--- a/dexter/dex/builder/scripts/windows/clang.bat
+++ /dev/null
@@ -1,17 +0,0 @@
-@setlocal EnableDelayedExpansion
-
-for %%I in (%SOURCE_INDEXES%) do (
-  %PATHTOCLANGPP% -fuse-ld=lld -c !COMPILER_OPTIONS_%%I! !SOURCE_FILE_%%I! -o !OBJECT_FILE_%%I!
-  if errorlevel 1 goto :FAIL
-)
-
-%PATHTOCLANGPP% -fuse-ld=lld %LINKER_OPTIONS% %OBJECT_FILES% -o %EXECUTABLE_FILE%
-if errorlevel 1 goto :FAIL
-goto :END
-
-:FAIL
-echo FAILED
-exit /B 1
-
-:END
-exit /B 0
diff --git a/dexter/dex/command/CommandBase.py b/dexter/dex/command/CommandBase.py
deleted file mode 100644
index 49e9086..0000000
--- a/dexter/dex/command/CommandBase.py
+++ /dev/null
@@ -1,54 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-"""Base class for all DExTer commands, where a command is a specific Python
-function that can be embedded into a comment in the source code under test
-which will then be executed by DExTer during debugging.
-"""
-
-import abc
-from typing import List
-
-class CommandBase(object, metaclass=abc.ABCMeta):
-    def __init__(self):
-        self.path = None
-        self.lineno = None
-        self.raw_text = ''
-
-    def get_label_args(self):
-        return list()
-
-    def has_labels(self):
-        return False
-
-    @abc.abstractstaticmethod
-    def get_name():
-        """This abstract method is usually implemented in subclasses as:
-        return __class__.__name__
-        """
-
-    def get_watches(self) -> List[str]:
-        return []
-
-    @abc.abstractmethod
-    def eval(self):
-        """Evaluate the command.
-
-        This will be called when constructing a Heuristic object to determine
-        the debug score.
-
-        Returns:
-            The logic for handling the result of CommandBase.eval() must be
-            defined in Heuristic.__init__() so a consitent return type between
-            commands is not enforced.
-        """
-
-    @staticmethod
-    def get_subcommands() -> dict:
-        """Returns a dictionary of subcommands in the form {name: command} or
-        None if no subcommands are required.
-        """
-        return None
diff --git a/dexter/dex/command/ParseCommand.py b/dexter/dex/command/ParseCommand.py
deleted file mode 100644
index 85e7a3f..0000000
--- a/dexter/dex/command/ParseCommand.py
+++ /dev/null
@@ -1,471 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-"""Parse a DExTer command. In particular, ensure that only a very limited
-subset of Python is allowed, in order to prevent the possibility of unsafe
-Python code being embedded within DExTer commands.
-"""
-
-import os
-import unittest
-from copy import copy
-from pathlib import PurePath
-from collections import defaultdict, OrderedDict
-
-from dex.utils.Exceptions import CommandParseError
-
-from dex.command.CommandBase import CommandBase
-from dex.command.commands.DexDeclareFile import DexDeclareFile
-from dex.command.commands.DexExpectProgramState import DexExpectProgramState
-from dex.command.commands.DexExpectStepKind import DexExpectStepKind
-from dex.command.commands.DexExpectStepOrder import DexExpectStepOrder
-from dex.command.commands.DexExpectWatchType import DexExpectWatchType
-from dex.command.commands.DexExpectWatchValue import DexExpectWatchValue
-from dex.command.commands.DexLabel import DexLabel
-from dex.command.commands.DexLimitSteps import DexLimitSteps
-from dex.command.commands.DexUnreachable import DexUnreachable
-from dex.command.commands.DexWatch import DexWatch
-from dex.utils import Timer
-from dex.utils.Exceptions import CommandParseError, DebuggerException
-
-def _get_valid_commands():
-    """Return all top level DExTer test commands.
-
-    Returns:
-        { name (str): command (class) }
-    """
-    return {
-      DexDeclareFile.get_name() : DexDeclareFile,
-      DexExpectProgramState.get_name() : DexExpectProgramState,
-      DexExpectStepKind.get_name() : DexExpectStepKind,
-      DexExpectStepOrder.get_name() : DexExpectStepOrder,
-      DexExpectWatchType.get_name() : DexExpectWatchType,
-      DexExpectWatchValue.get_name() : DexExpectWatchValue,
-      DexLabel.get_name() : DexLabel,
-      DexLimitSteps.get_name() : DexLimitSteps,
-      DexUnreachable.get_name() : DexUnreachable,
-      DexWatch.get_name() : DexWatch
-    }
-
-
-def _get_command_name(command_raw: str) -> str:
-    """Return command name by splitting up DExTer command contained in
-    command_raw on the first opening paranthesis and further stripping
-    any potential leading or trailing whitespace.
-    """
-    return command_raw.split('(', 1)[0].rstrip()
-
-
-def _merge_subcommands(command_name: str, valid_commands: dict) -> dict:
-    """Merge valid_commands and command_name's subcommands into a new dict.
-
-    Returns:
-        { name (str): command (class) }
-    """
-    subcommands = valid_commands[command_name].get_subcommands()
-    if subcommands:
-        return { **valid_commands, **subcommands }
-    return valid_commands
-
-
-def _build_command(command_type, labels, raw_text: str, path: str, lineno: str) -> CommandBase:
-    """Build a command object from raw text.
-
-    This function will call eval().
-
-    Raises:
-        Any exception that eval() can raise.
-
-    Returns:
-        A dexter command object.
-    """
-    def label_to_line(label_name: str) -> int:
-        line = labels.get(label_name, None)
-        if line != None:
-            return line
-        raise format_unresolved_label_err(label_name, raw_text, path, lineno)
-
-    valid_commands = _merge_subcommands(
-        command_type.get_name(), {
-            'ref': label_to_line,
-            command_type.get_name(): command_type,
-        })
-
-    # pylint: disable=eval-used
-    command = eval(raw_text, valid_commands)
-    # pylint: enable=eval-used
-    command.raw_text = raw_text
-    command.path = path
-    command.lineno = lineno
-    return command
-
-
-def _search_line_for_cmd_start(line: str, start: int, valid_commands: dict) -> int:
-    """Scan `line` for a string matching any key in `valid_commands`.
-
-    Start searching from `start`.
-    Commands escaped with `\` (E.g. `\DexLabel('a')`) are ignored.
-
-    Returns:
-        int: the index of the first character of the matching string in `line`
-        or -1 if no command is found.
-    """
-    for command in valid_commands:
-        idx = line.find(command, start)
-        if idx != -1:
-            # Ignore escaped '\' commands.
-            if idx > 0 and line[idx - 1] == '\\':
-                continue
-            return idx
-    return -1
-
-
-def _search_line_for_cmd_end(line: str, start: int, paren_balance: int) -> (int, int):
-    """Find the end of a command by looking for balanced parentheses.
-
-    Args:
-        line: String to scan.
-        start: Index into `line` to start looking.
-        paren_balance(int): paren_balance after previous call.
-
-    Note:
-        On the first call `start` should point at the opening parenthesis and
-        `paren_balance` should be set to 0. Subsequent calls should pass in the
-        returned `paren_balance`.
-
-    Returns:
-        ( end,  paren_balance )
-        Where end is 1 + the index of the last char in the command or, if the
-        parentheses are not balanced, the end of the line.
-
-        paren_balance will be 0 when the parentheses are balanced.
-    """
-    for end in range(start, len(line)):
-        ch = line[end]
-        if ch == '(':
-            paren_balance += 1
-        elif ch == ')':
-            paren_balance -=1
-        if paren_balance == 0:
-            break
-    end += 1
-    return (end, paren_balance)
-
-
-class TextPoint():
-    def __init__(self, line, char):
-        self.line = line
-        self.char = char
-
-    def get_lineno(self):
-        return self.line + 1
-
-    def get_column(self):
-        return self.char + 1
-
-
-def format_unresolved_label_err(label: str, src: str, filename: str, lineno) -> CommandParseError:
-    err = CommandParseError()
-    err.src = src
-    err.caret = '' # Don't bother trying to point to the bad label.
-    err.filename = filename
-    err.lineno = lineno
-    err.info = f'Unresolved label: \'{label}\''
-    return err
-
-
-def format_parse_err(msg: str, path: str, lines: list, point: TextPoint) -> CommandParseError:
-    err = CommandParseError()
-    err.filename = path
-    err.src = lines[point.line].rstrip()
-    err.lineno = point.get_lineno()
-    err.info = msg
-    err.caret = '{}<r>^</>'.format(' ' * (point.char))
-    return err
-
-
-def skip_horizontal_whitespace(line, point):
-    for idx, char in enumerate(line[point.char:]):
-        if char not in ' \t':
-            point.char += idx
-            return
-
-
-def add_line_label(labels, label, cmd_path, cmd_lineno):
-    # Enforce unique line labels.
-    if label.eval() in labels:
-        err = CommandParseError()
-        err.info = f'Found duplicate line label: \'{label.eval()}\''
-        err.lineno = cmd_lineno
-        err.filename = cmd_path
-        err.src = label.raw_text
-        # Don't both trying to point to it since we're only printing the raw
-        # command, which isn't much text.
-        err.caret = ''
-        raise err
-    labels[label.eval()] = label.get_line()
-
-
-def _find_all_commands_in_file(path, file_lines, valid_commands, source_root_dir):
-    labels = {} # dict of {name: line}.
-    cmd_path = path
-    declared_files = set()
-    commands = defaultdict(dict)
-    paren_balance = 0
-    region_start = TextPoint(0, 0)
-
-    for region_start.line in range(len(file_lines)):
-        line = file_lines[region_start.line]
-        region_start.char = 0
-
-        # Search this line till we find no more commands.
-        while True:
-            # If parens are currently balanced we can look for a new command.
-            if paren_balance == 0:
-                region_start.char = _search_line_for_cmd_start(line, region_start.char, valid_commands)
-                if region_start.char == -1:
-                    break # Read next line.
-
-                command_name = _get_command_name(line[region_start.char:])
-                cmd_point = copy(region_start)
-                cmd_text_list = [command_name]
-
-                region_start.char += len(command_name) # Start searching for parens after cmd.
-                skip_horizontal_whitespace(line, region_start)
-                if region_start.char >= len(line) or line[region_start.char] != '(':
-                    raise format_parse_err(
-                        "Missing open parenthesis", path, file_lines, region_start)
-
-            end, paren_balance = _search_line_for_cmd_end(line, region_start.char, paren_balance)
-            # Add this text blob to the command.
-            cmd_text_list.append(line[region_start.char:end])
-            # Move parse ptr to end of line or parens.
-            region_start.char = end
-
-            # If the parens are unbalanced start reading the next line in an attempt
-            # to find the end of the command.
-            if paren_balance != 0:
-                break  # Read next line.
-
-            # Parens are balanced, we have a full command to evaluate.
-            raw_text = "".join(cmd_text_list)
-            try:
-                command = _build_command(
-                    valid_commands[command_name],
-                    labels,
-                    raw_text,
-                    cmd_path,
-                    cmd_point.get_lineno(),
-                )
-            except SyntaxError as e:
-                # This err should point to the problem line.
-                err_point = copy(cmd_point)
-                # To e the command start is the absolute start, so use as offset.
-                err_point.line += e.lineno - 1 # e.lineno is a position, not index.
-                err_point.char += e.offset - 1 # e.offset is a position, not index.
-                raise format_parse_err(e.msg, path, file_lines, err_point)
-            except TypeError as e:
-                # This err should always point to the end of the command name.
-                err_point = copy(cmd_point)
-                err_point.char += len(command_name)
-                raise format_parse_err(str(e), path, file_lines, err_point)
-            else:
-                if type(command) is DexLabel:
-                    add_line_label(labels, command, path, cmd_point.get_lineno())
-                elif type(command) is DexDeclareFile:
-                    cmd_path = command.declared_file
-                    if not os.path.isabs(cmd_path):
-                        source_dir = (source_root_dir if source_root_dir else
-                                      os.path.dirname(path))
-                        cmd_path = os.path.join(source_dir, cmd_path)
-                    # TODO: keep stored paths as PurePaths for 'longer'.
-                    cmd_path = str(PurePath(cmd_path))
-                    declared_files.add(cmd_path)
-                assert (path, cmd_point) not in commands[command_name], (
-                    command_name, commands[command_name])
-                commands[command_name][path, cmd_point] = command
-
-    if paren_balance != 0:
-        # This err should always point to the end of the command name.
-        err_point = copy(cmd_point)
-        err_point.char += len(command_name)
-        msg = "Unbalanced parenthesis starting here"
-        raise format_parse_err(msg, path, file_lines, err_point)
-    return dict(commands), declared_files
-
-def _find_all_commands(test_files, source_root_dir):
-    commands = defaultdict(dict)
-    valid_commands = _get_valid_commands()
-    new_source_files = set()
-    for test_file in test_files:
-        with open(test_file) as fp:
-            lines = fp.readlines()
-        file_commands, declared_files = _find_all_commands_in_file(
-            test_file, lines, valid_commands, source_root_dir)
-        for command_name in file_commands:
-            commands[command_name].update(file_commands[command_name])
-        new_source_files |= declared_files
-
-    return dict(commands), new_source_files
-
-def get_command_infos(test_files, source_root_dir):
-  with Timer('parsing commands'):
-      try:
-          commands, new_source_files = _find_all_commands(test_files, source_root_dir)
-          command_infos = OrderedDict()
-          for command_type in commands:
-              for command in commands[command_type].values():
-                  if command_type not in command_infos:
-                      command_infos[command_type] = []
-                  command_infos[command_type].append(command)
-          return OrderedDict(command_infos), new_source_files
-      except CommandParseError as e:
-          msg = 'parser error: <d>{}({}):</> {}\n{}\n{}\n'.format(
-                e.filename, e.lineno, e.info, e.src, e.caret)
-          raise DebuggerException(msg)
-
-class TestParseCommand(unittest.TestCase):
-    class MockCmd(CommandBase):
-        """A mock DExTer command for testing parsing.
-
-        Args:
-            value (str): Unique name for this instance.
-        """
-
-        def __init__(self, *args):
-           self.value = args[0]
-
-        def get_name():
-            return __class__.__name__
-
-        def eval(this):
-            pass
-
-
-    def __init__(self, *args):
-        super().__init__(*args)
-
-        self.valid_commands = {
-            TestParseCommand.MockCmd.get_name() : TestParseCommand.MockCmd
-        }
-
-
-    def _find_all_commands_in_lines(self, lines):
-        """Use DExTer parsing methods to find all the mock commands in lines.
-
-        Returns:
-            { cmd_name: { (path, line): command_obj } }
-        """
-        cmds, declared_files = _find_all_commands_in_file(__file__, lines, self.valid_commands, None)
-        return cmds
-
-
-    def _find_all_mock_values_in_lines(self, lines):
-        """Use DExTer parsing methods to find all mock command values in lines.
-
-        Returns:
-            values (list(str)): MockCmd values found in lines.
-        """
-        cmds = self._find_all_commands_in_lines(lines)
-        mocks = cmds.get(TestParseCommand.MockCmd.get_name(), None)
-        return [v.value for v in mocks.values()] if mocks else []
-
-
-    def test_parse_inline(self):
-        """Commands can be embedded in other text."""
-
-        lines = [
-            'MockCmd("START") Lorem ipsum dolor sit amet, consectetur\n',
-            'adipiscing elit, MockCmd("EMBEDDED") sed doeiusmod tempor,\n',
-            'incididunt ut labore et dolore magna aliqua.\n'
-        ]
-
-        values = self._find_all_mock_values_in_lines(lines)
-
-        self.assertTrue('START' in values)
-        self.assertTrue('EMBEDDED' in values)
-
-
-    def test_parse_multi_line_comment(self):
-        """Multi-line commands can embed comments."""
-
-        lines = [
-            'Lorem ipsum dolor sit amet, consectetur\n',
-            'adipiscing elit, sed doeiusmod tempor,\n',
-            'incididunt ut labore et MockCmd(\n',
-            '    "WITH_COMMENT" # THIS IS A COMMENT\n',
-            ') dolore magna aliqua. Ut enim ad minim\n',
-        ]
-
-        values = self._find_all_mock_values_in_lines(lines)
-
-        self.assertTrue('WITH_COMMENT' in values)
-
-    def test_parse_empty(self):
-        """Empty files are silently ignored."""
-
-        lines = []
-        values = self._find_all_mock_values_in_lines(lines)
-        self.assertTrue(len(values) == 0)
-
-    def test_parse_bad_whitespace(self):
-        """Throw exception when parsing badly formed whitespace."""
-        lines = [
-            'MockCmd\n',
-            '("XFAIL_CMD_LF_PAREN")\n',
-        ]
-
-        with self.assertRaises(CommandParseError):
-            values = self._find_all_mock_values_in_lines(lines)
-
-    def test_parse_good_whitespace(self):
-        """Try to emulate python whitespace rules"""
-
-        lines = [
-            'MockCmd("NONE")\n',
-            'MockCmd    ("SPACE")\n',
-            'MockCmd\t\t("TABS")\n',
-            'MockCmd(    "ARG_SPACE"    )\n',
-            'MockCmd(\t\t"ARG_TABS"\t\t)\n',
-            'MockCmd(\n',
-            '"CMD_PAREN_LF")\n',
-        ]
-
-        values = self._find_all_mock_values_in_lines(lines)
-
-        self.assertTrue('NONE' in values)
-        self.assertTrue('SPACE' in values)
-        self.assertTrue('TABS' in values)
-        self.assertTrue('ARG_SPACE' in values)
-        self.assertTrue('ARG_TABS' in values)
-        self.assertTrue('CMD_PAREN_LF' in values)
-
-
-    def test_parse_share_line(self):
-        """More than one command can appear on one line."""
-
-        lines = [
-            'MockCmd("START") MockCmd("CONSECUTIVE") words '
-                'MockCmd("EMBEDDED") more words\n'
-        ]
-
-        values = self._find_all_mock_values_in_lines(lines)
-
-        self.assertTrue('START' in values)
-        self.assertTrue('CONSECUTIVE' in values)
-        self.assertTrue('EMBEDDED' in values)
-
-
-    def test_parse_escaped(self):
-        """Escaped commands are ignored."""
-
-        lines = [
-            'words \MockCmd("IGNORED") words words words\n'
-        ]
-
-        values = self._find_all_mock_values_in_lines(lines)
-
-        self.assertFalse('IGNORED' in values)
diff --git a/dexter/dex/command/StepValueInfo.py b/dexter/dex/command/StepValueInfo.py
deleted file mode 100644
index afcb9c5..0000000
--- a/dexter/dex/command/StepValueInfo.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-
-
-class StepValueInfo(object):
-    def __init__(self, step_index, watch_info, expected_value):
-        self.step_index = step_index
-        self.watch_info = watch_info
-        self.expected_value = expected_value
-
-    def __str__(self):
-        return '{}:{}: expected value:{}'.format(self.step_index, self.watch_info, self.expected_value)
-
-    def __eq__(self, other):
-        return (self.watch_info.expression == other.watch_info.expression
-                and self.expected_value == other.expected_value)
-
-    def __hash__(self):
-        return hash(self.watch_info.expression, self.expected_value)
diff --git a/dexter/dex/command/__init__.py b/dexter/dex/command/__init__.py
deleted file mode 100644
index 3b1c448..0000000
--- a/dexter/dex/command/__init__.py
+++ /dev/null
@@ -1,9 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-
-from dex.command.ParseCommand import get_command_infos
-from dex.command.StepValueInfo import StepValueInfo
diff --git a/dexter/dex/command/commands/DexDeclareFile.py b/dexter/dex/command/commands/DexDeclareFile.py
deleted file mode 100644
index c40c854..0000000
--- a/dexter/dex/command/commands/DexDeclareFile.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-"""Commmand sets the path for all following commands to 'declared_file'.
-"""
-
-from pathlib import PurePath
-
-from dex.command.CommandBase import CommandBase
-
-
-class DexDeclareFile(CommandBase):
-    def __init__(self, declared_file):
-
-        if not isinstance(declared_file, str):
-            raise TypeError('invalid argument type')
-
-        # Use PurePath to create a cannonical platform path.
-        # TODO: keep paths as PurePath objects for 'longer'
-        self.declared_file = str(PurePath(declared_file))
-        super(DexDeclareFile, self).__init__()
-
-    @staticmethod
-    def get_name():
-        return __class__.__name__
-
-    def eval(self):
-        return self.declared_file
diff --git a/dexter/dex/command/commands/DexExpectProgramState.py b/dexter/dex/command/commands/DexExpectProgramState.py
deleted file mode 100644
index 26f97b6..0000000
--- a/dexter/dex/command/commands/DexExpectProgramState.py
+++ /dev/null
@@ -1,68 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-"""Command for specifying a partial or complete state for the program to enter
-during execution.
-"""
-
-from itertools import chain
-
-from dex.command.CommandBase import CommandBase
-from dex.dextIR import ProgramState, SourceLocation, StackFrame, DextIR
-
-def frame_from_dict(source: dict) -> StackFrame:
-    if 'location' in source:
-        assert isinstance(source['location'], dict)
-        source['location'] = SourceLocation(**source['location'])
-    return StackFrame(**source)
-
-def state_from_dict(source: dict) -> ProgramState:
-    if 'frames' in source:
-        assert isinstance(source['frames'], list)
-        source['frames'] = list(map(frame_from_dict, source['frames']))
-    return ProgramState(**source)
-
-class DexExpectProgramState(CommandBase):
-    """Expect to see a given program `state` a certain numer of `times`.
-
-    DexExpectProgramState(state [,**times])
-
-    See Commands.md for more info.
-    """
-
-    def __init__(self, *args, **kwargs):
-        if len(args) != 1:
-            raise TypeError('expected exactly one unnamed arg')
-
-        self.program_state_text = str(args[0])
-
-        self.expected_program_state = state_from_dict(args[0])
-
-        self.times = kwargs.pop('times', -1)
-        if kwargs:
-            raise TypeError('unexpected named args: {}'.format(
-                ', '.join(kwargs)))
-
-        # Step indices at which the expected program state was encountered.
-        self.encounters = []
-
-        super(DexExpectProgramState, self).__init__()
-
-    @staticmethod
-    def get_name():
-        return __class__.__name__
-
-    def get_watches(self):
-        frame_expects = chain.from_iterable(frame.watches
-            for frame in self.expected_program_state.frames)
-        return set(frame_expects)
-
-    def eval(self, step_collection: DextIR) -> bool:
-        for step in step_collection.steps:
-            if self.expected_program_state.match(step.program_state):
-                self.encounters.append(step.step_index)
-
-        return self.times < 0 < len(self.encounters) or len(self.encounters) == self.times
diff --git a/dexter/dex/command/commands/DexExpectStepKind.py b/dexter/dex/command/commands/DexExpectStepKind.py
deleted file mode 100644
index 6370f5d..0000000
--- a/dexter/dex/command/commands/DexExpectStepKind.py
+++ /dev/null
@@ -1,45 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-"""Command for specifying an expected number of steps of a particular kind."""
-
-from dex.command.CommandBase import CommandBase
-from dex.dextIR.StepIR import StepKind
-
-
-class DexExpectStepKind(CommandBase):
-    """Expect to see a particular step `kind` a number of `times` while stepping
-    through the program.
-
-    DexExpectStepKind(kind, times)
-
-    See Commands.md for more info.
-    """
-
-    def __init__(self, *args):
-        if len(args) != 2:
-            raise TypeError('expected two args')
-
-        try:
-            step_kind = StepKind[args[0]]
-        except KeyError:
-            raise TypeError('expected arg 0 to be one of {}'.format(
-                [kind for kind, _ in StepKind.__members__.items()]))
-
-        self.name = step_kind
-        self.count = args[1]
-
-        super(DexExpectStepKind, self).__init__()
-
-    @staticmethod
-    def get_name():
-        return __class__.__name__
-
-    def eval(self):
-        # DexExpectStepKind eval() implementation is mixed into
-        # Heuristic.__init__()
-        # [TODO] Fix this ^.
-        pass
diff --git a/dexter/dex/command/commands/DexExpectStepOrder.py b/dexter/dex/command/commands/DexExpectStepOrder.py
deleted file mode 100644
index 700dc54..0000000
--- a/dexter/dex/command/commands/DexExpectStepOrder.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-
-from dex.command.CommandBase import CommandBase
-from dex.dextIR import LocIR
-from dex.dextIR import ValueIR
-
-class DexExpectStepOrder(CommandBase):
-    """Expect the line every `DexExpectStepOrder` is found on to be stepped on
-    in `order`. Each instance must have a set of unique ascending indicies.
-
-    DexExpectStepOrder(*order)
-
-    See Commands.md for more info.
-    """
-
-    def __init__(self, *args):
-        if not args:
-            raise TypeError('Need at least one order number')
-
-        self.sequence = [int(x) for x in args]
-        super(DexExpectStepOrder, self).__init__()
-
-    @staticmethod
-    def get_name():
-        return __class__.__name__
-
-    def eval(self, step_info):
-        return {'DexExpectStepOrder': ValueIR(expression=str(step_info.current_location.lineno),
-                      value=str(step_info.step_index), type_name=None,
-                      error_string=None,
-                      could_evaluate=True,
-                      is_optimized_away=True,
-                      is_irretrievable=False)}
diff --git a/dexter/dex/command/commands/DexExpectWatchBase.py b/dexter/dex/command/commands/DexExpectWatchBase.py
deleted file mode 100644
index e892f01..0000000
--- a/dexter/dex/command/commands/DexExpectWatchBase.py
+++ /dev/null
@@ -1,182 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-
-"""DexExpectWatch base class, holds logic for how to build and process expected
- watch commands.
-"""
-
-import abc
-import difflib
-import os
-
-from dex.command.CommandBase import CommandBase
-from dex.command.StepValueInfo import StepValueInfo
-
-
-class DexExpectWatchBase(CommandBase):
-    def __init__(self, *args, **kwargs):
-        if len(args) < 2:
-            raise TypeError('expected at least two args')
-
-        self.expression = args[0]
-        self.values = [str(arg) for arg in args[1:]]
-        try:
-            on_line = kwargs.pop('on_line')
-            self._from_line = on_line
-            self._to_line = on_line
-        except KeyError:
-            self._from_line = kwargs.pop('from_line', 1)
-            self._to_line = kwargs.pop('to_line', 999999)
-        self._require_in_order = kwargs.pop('require_in_order', True)
-        if kwargs:
-            raise TypeError('unexpected named args: {}'.format(
-                ', '.join(kwargs)))
-
-        # Number of times that this watch has been encountered.
-        self.times_encountered = 0
-
-        # We'll pop from this set as we encounter values so anything left at
-        # the end can be considered as not having been seen.
-        self._missing_values = set(self.values)
-
-        self.misordered_watches = []
-
-        # List of StepValueInfos for any watch that is encountered as invalid.
-        self.invalid_watches = []
-
-        # List of StepValueInfo any any watch where we couldn't retrieve its
-        # data.
-        self.irretrievable_watches = []
-
-        # List of StepValueInfos for any watch that is encountered as having
-        # been optimized out.
-        self.optimized_out_watches = []
-
-        # List of StepValueInfos for any watch that is encountered that has an
-        # expected value.
-        self.expected_watches = []
-
-        # List of StepValueInfos for any watch that is encountered that has an
-        # unexpected value.
-        self.unexpected_watches = []
-
-        super(DexExpectWatchBase, self).__init__()
-
-
-    def get_watches(self):
-        return [self.expression]
-
-    @property
-    def line_range(self):
-        return list(range(self._from_line, self._to_line + 1))
-
-    @property
-    def missing_values(self):
-        return sorted(list(self._missing_values))
-
-    @property
-    def encountered_values(self):
-        return sorted(list(set(self.values) - self._missing_values))
-
-    @abc.abstractmethod
-    def _get_expected_field(self, watch):
-        """Return a field from watch that this ExpectWatch command is checking.
-        """
-
-    def _handle_watch(self, step_info):
-        self.times_encountered += 1
-
-        if not step_info.watch_info.could_evaluate:
-            self.invalid_watches.append(step_info)
-            return
-
-        if step_info.watch_info.is_optimized_away:
-            self.optimized_out_watches.append(step_info)
-            return
-
-        if step_info.watch_info.is_irretrievable:
-            self.irretrievable_watches.append(step_info)
-            return
-
-        if step_info.expected_value not in self.values:
-            self.unexpected_watches.append(step_info)
-            return
-
-        self.expected_watches.append(step_info)
-        try:
-            self._missing_values.remove(step_info.expected_value)
-        except KeyError:
-            pass
-
-    def _check_watch_order(self, actual_watches, expected_values):
-        """Use difflib to figure out whether the values are in the expected order
-        or not.
-        """
-        differences = []
-        actual_values = [w.expected_value for w in actual_watches]
-        value_differences = list(difflib.Differ().compare(actual_values,
-                                                          expected_values))
-
-        missing_value = False
-        index = 0
-        for vd in value_differences:
-            kind = vd[0]
-            if kind == '+':
-                # A value that is encountered in the expected list but not in the
-                # actual list.  We'll keep a note that something is wrong and flag
-                # the next value that matches as misordered.
-                missing_value = True
-            elif kind == ' ':
-                # This value is as expected.  It might still be wrong if we've
-                # previously encountered a value that is in the expected list but
-                #  not the actual list.
-                if missing_value:
-                    missing_value = False
-                    differences.append(actual_watches[index])
-                index += 1
-            elif kind == '-':
-                # A value that is encountered in the actual list but not the
-                #  expected list.
-                differences.append(actual_watches[index])
-                index += 1
-            else:
-                assert False, 'unexpected diff:{}'.format(vd)
-
-        return differences
-
-    def eval(self, step_collection):
-        for step in step_collection.steps:
-            loc = step.current_location
-
-            if (loc.path and os.path.exists(loc.path) and
-                os.path.exists(self.path) and
-                os.path.samefile(loc.path, self.path) and
-                loc.lineno in self.line_range):
-                try:
-                    watch = step.program_state.frames[0].watches[self.expression]
-                except KeyError:
-                    pass
-                else:
-                    expected_field = self._get_expected_field(watch)
-                    step_info = StepValueInfo(step.step_index, watch, 
-                                              expected_field)
-                    self._handle_watch(step_info)
-
-        if self._require_in_order:
-            # A list of all watches where the value has changed.
-            value_change_watches = []
-            prev_value = None
-            for watch in self.expected_watches:
-                if watch.expected_value != prev_value:
-                    value_change_watches.append(watch)
-                    prev_value = watch.expected_value
-
-            self.misordered_watches = self._check_watch_order(
-                value_change_watches, [
-                    v for v in self.values if v in
-                    [w.expected_value for w in self.expected_watches]
-                ])
diff --git a/dexter/dex/command/commands/DexExpectWatchType.py b/dexter/dex/command/commands/DexExpectWatchType.py
deleted file mode 100644
index f2336de..0000000
--- a/dexter/dex/command/commands/DexExpectWatchType.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-"""Command for specifying an expected set of types for a particular watch."""
-
-
-from dex.command.commands.DexExpectWatchBase import DexExpectWatchBase
-
-class DexExpectWatchType(DexExpectWatchBase):
-    """Expect the expression `expr` to evaluate be evaluated and have each
-    evaluation's type checked against the list of `types`.
-
-    DexExpectWatchType(expr, *types [,**from_line=1][,**to_line=Max]
-                        [,**on_line])
-
-    See Commands.md for more info.
-    """
-    @staticmethod
-    def get_name():
-        return __class__.__name__
-
-    def _get_expected_field(self, watch):
-        return watch.type_name
diff --git a/dexter/dex/command/commands/DexExpectWatchValue.py b/dexter/dex/command/commands/DexExpectWatchValue.py
deleted file mode 100644
index d6da006..0000000
--- a/dexter/dex/command/commands/DexExpectWatchValue.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-"""Command for specifying an expected set of values for a particular watch."""
-
-
-from dex.command.commands.DexExpectWatchBase import DexExpectWatchBase
-
-class DexExpectWatchValue(DexExpectWatchBase):
-    """Expect the expression `expr` to evaluate to the list of `values`
-    sequentially.
-
-    DexExpectWatchValue(expr, *values [,**from_line=1][,**to_line=Max]
-                        [,**on_line])
-
-    See Commands.md for more info.
-    """
-
-    @staticmethod
-    def get_name():
-        return __class__.__name__
-
-    def _get_expected_field(self, watch):
-        return watch.value
diff --git a/dexter/dex/command/commands/DexLabel.py b/dexter/dex/command/commands/DexLabel.py
deleted file mode 100644
index 9f42d42..0000000
--- a/dexter/dex/command/commands/DexLabel.py
+++ /dev/null
@@ -1,42 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-"""Command used to give a line in a test a named psuedonym. Every DexLabel has
-   a line number and Label string component.
-"""
-
-from dex.command.CommandBase import CommandBase
-
-
-class DexLabel(CommandBase):
-    def __init__(self, label, **kwargs):
-
-        if not isinstance(label, str):
-            raise TypeError('invalid argument type')
-
-        try:
-            self.on_line = kwargs.pop('on_line')
-        except KeyError:
-            # We cannot use self.lineno because it hasn't been set yet.
-            pass
-        if kwargs:
-            raise TypeError(f'unexpected named args: {", ".join(kwargs)}')
-
-        self._label = label
-        super(DexLabel, self).__init__()
-
-    def get_line(self):
-        return getattr(self, 'on_line', self.lineno)
-
-    def get_as_pair(self):
-        return (self._label, self.get_line())
-
-    @staticmethod
-    def get_name():
-        return __class__.__name__
-
-    def eval(self):
-        return self._label
diff --git a/dexter/dex/command/commands/DexLimitSteps.py b/dexter/dex/command/commands/DexLimitSteps.py
deleted file mode 100644
index d779539..0000000
--- a/dexter/dex/command/commands/DexLimitSteps.py
+++ /dev/null
@@ -1,45 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-"""A Command that enables test writers to specify a limited number of break
-points using an start condition and range.
-"""
-
-from dex.command.CommandBase import CommandBase
-
-class DexLimitSteps(CommandBase):
-    def __init__(self, *args, **kwargs):
-        if len(args) == 0:
-            self.expression = None
-            self.values = []
-        elif len(args) == 1:
-            raise TypeError("expected 0 or at least 2 positional arguments")
-        else:
-            self.expression = args[0]
-            self.values = [str(arg) for arg in args[1:]]
-        try:
-            on_line = kwargs.pop('on_line')
-            self.from_line = on_line
-            self.to_line = on_line
-        except KeyError:
-            self.from_line = kwargs.pop('from_line', 1)
-            self.to_line = kwargs.pop('to_line', 999999)
-        self.hit_count = kwargs.pop('hit_count', None)
-        if kwargs:
-            raise TypeError('unexpected named args: {}'.format(
-                ', '.join(kwargs)))
-        super(DexLimitSteps, self).__init__()
-
-    def eval(self):
-        raise NotImplementedError('DexLimitSteps commands cannot be evaled.')
-
-    @staticmethod
-    def get_name():
-        return __class__.__name__
-
-    @staticmethod
-    def get_subcommands() -> dict:
-        return None
diff --git a/dexter/dex/command/commands/DexUnreachable.py b/dexter/dex/command/commands/DexUnreachable.py
deleted file mode 100644
index 152ce02..0000000
--- a/dexter/dex/command/commands/DexUnreachable.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-
-
-from dex.command.CommandBase import CommandBase
-from dex.dextIR import ValueIR
-
-
-class DexUnreachable(CommandBase):
-    """Expect the source line this is found on will never be stepped on to.
-
-    DexUnreachable()
-
-    See Commands.md for more info.
-    """
-
-    def __init(self):
-        super(DexUnreachable, self).__init__()
-        pass
-
-    @staticmethod
-    def get_name():
-        return __class__.__name__
-
-    def eval(self, step_info):
-        # If we're ever called, at all, then we're evaluating a line that has
-        # been marked as unreachable. Which means a failure.
-        vir = ValueIR(expression="Unreachable",
-                      value="True", type_name=None,
-                      error_string=None,
-                      could_evaluate=True,
-                      is_optimized_away=True,
-                      is_irretrievable=False)
-        return {'DexUnreachable' : vir}
diff --git a/dexter/dex/command/commands/DexWatch.py b/dexter/dex/command/commands/DexWatch.py
deleted file mode 100644
index 2dfa3a3..0000000
--- a/dexter/dex/command/commands/DexWatch.py
+++ /dev/null
@@ -1,39 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-"""Command to instruct the debugger to inspect the value of some set of
-expressions on the current source line.
-"""
-
-from dex.command.CommandBase import CommandBase
-
-
-class DexWatch(CommandBase):
-    """[Deprecated] Evaluate each given `expression` when the debugger steps onto the
-    line this command is found on
-
-    DexWatch(*expressions)
-
-    See Commands.md for more info.
-    """
-
-    def __init__(self, *args):
-        if not args:
-            raise TypeError('expected some arguments')
-
-        for arg in args:
-            if not isinstance(arg, str):
-                raise TypeError('invalid argument type')
-
-        self._args = args
-        super(DexWatch, self).__init__()
-
-    @staticmethod
-    def get_name():
-        return __class__.__name__
-
-    def eval(self, debugger):
-        return {arg: debugger.evaluate_expression(arg) for arg in self._args}
diff --git a/dexter/dex/debugger/DebuggerBase.py b/dexter/dex/debugger/DebuggerBase.py
deleted file mode 100644
index c31be77..0000000
--- a/dexter/dex/debugger/DebuggerBase.py
+++ /dev/null
@@ -1,299 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-"""Base class for all debugger interface implementations."""
-
-import abc
-import os
-import sys
-import traceback
-import unittest
-
-from types import SimpleNamespace
-from dex.dextIR import DebuggerIR, FrameIR, LocIR, StepIR, ValueIR
-from dex.utils.Exceptions import DebuggerException
-from dex.utils.Exceptions import NotYetLoadedDebuggerException
-from dex.utils.ReturnCode import ReturnCode
-
-
-class DebuggerBase(object, metaclass=abc.ABCMeta):
-    def __init__(self, context):
-        self.context = context
-        # Note: We can't already read values from options
-        # as DebuggerBase is created before we initialize options
-        # to read potential_debuggers.
-        self.options = self.context.options
-
-        self._interface = None
-        self.has_loaded = False
-        self._loading_error = NotYetLoadedDebuggerException()
-        try:
-            self._interface = self._load_interface()
-            self.has_loaded = True
-            self._loading_error = None
-        except DebuggerException:
-            self._loading_error = sys.exc_info()
-
-    def __enter__(self):
-        try:
-            self._custom_init()
-            self.clear_breakpoints()
-        except DebuggerException:
-            self._loading_error = sys.exc_info()
-        return self
-
-    def __exit__(self, *args):
-        self._custom_exit()
-
-    def _custom_init(self):
-        pass
-
-    def _custom_exit(self):
-        pass
-
-    @property
-    def debugger_info(self):
-        return DebuggerIR(name=self.name, version=self.version)
-
-    @property
-    def is_available(self):
-        return self.has_loaded and self.loading_error is None
-
-    @property
-    def loading_error(self):
-        return (str(self._loading_error[1])
-                if self._loading_error is not None else None)
-
-    @property
-    def loading_error_trace(self):
-        if not self._loading_error:
-            return None
-
-        tb = traceback.format_exception(*self._loading_error)
-
-        if self._loading_error[1].orig_exception is not None:
-            orig_exception = traceback.format_exception(
-                *self._loading_error[1].orig_exception)
-
-            if ''.join(orig_exception) not in ''.join(tb):
-                tb.extend(['\n'])
-                tb.extend(orig_exception)
-
-        tb = ''.join(tb).splitlines(True)
-        return tb
-
-    def _sanitize_function_name(self, name):  # pylint: disable=no-self-use
-        """If the function name returned by the debugger needs any post-
-        processing to make it fit (for example, if it includes a byte offset),
-        do that here.
-        """
-        return name
-
-    @abc.abstractmethod
-    def _load_interface(self):
-        pass
-
-    @classmethod
-    def get_option_name(cls):
-        """Short name that will be used on the command line to specify this
-        debugger.
-        """
-        raise NotImplementedError()
-
-    @classmethod
-    def get_name(cls):
-        """Full name of this debugger."""
-        raise NotImplementedError()
-
-    @property
-    def name(self):
-        return self.__class__.get_name()
-
-    @property
-    def option_name(self):
-        return self.__class__.get_option_name()
-
-    @abc.abstractproperty
-    def version(self):
-        pass
-
-    @abc.abstractmethod
-    def clear_breakpoints(self):
-        pass
-
-    def add_breakpoint(self, file_, line):
-        """Returns a unique opaque breakpoint id.
-
-        The ID type depends on the debugger being used, but will probably be
-        an int.
-        """
-        return self._add_breakpoint(self._external_to_debug_path(file_), line)
-
-    @abc.abstractmethod
-    def _add_breakpoint(self, file_, line):
-        """Returns a unique opaque breakpoint id.
-        """
-        pass
-
-    def add_conditional_breakpoint(self, file_, line, condition):
-        """Returns a unique opaque breakpoint id.
-
-        The ID type depends on the debugger being used, but will probably be
-        an int.
-        """
-        return self._add_conditional_breakpoint(
-            self._external_to_debug_path(file_), line, condition)
-
-    @abc.abstractmethod
-    def _add_conditional_breakpoint(self, file_, line, condition):
-        """Returns a unique opaque breakpoint id.
-        """
-        pass
-
-    @abc.abstractmethod
-    def delete_breakpoint(self, id):
-        """Delete a breakpoint by id.
-
-        Raises a KeyError if no breakpoint with this id exists.
-        """
-        pass
-
-    @abc.abstractmethod
-    def get_triggered_breakpoint_ids(self):
-        """Returns a set of opaque ids for just-triggered breakpoints.
-        """
-        pass
-
-    @abc.abstractmethod
-    def launch(self):
-        pass
-
-    @abc.abstractmethod
-    def step(self):
-        pass
-
-    @abc.abstractmethod
-    def go(self) -> ReturnCode:
-        pass
-
-    def get_step_info(self, watches, step_index):
-        step_info = self._get_step_info(watches, step_index)
-        for frame in step_info.frames:
-            frame.loc.path = self._debug_to_external_path(frame.loc.path)
-        return step_info
-
-    @abc.abstractmethod
-    def _get_step_info(self, watches, step_index):
-        pass
-
-    @abc.abstractproperty
-    def is_running(self):
-        pass
-
-    @abc.abstractproperty
-    def is_finished(self):
-        pass
-
-    @abc.abstractproperty
-    def frames_below_main(self):
-        pass
-
-    @abc.abstractmethod
-    def evaluate_expression(self, expression, frame_idx=0) -> ValueIR:
-        pass
-
-    def _external_to_debug_path(self, path):
-        if not self.options.debugger_use_relative_paths:
-            return path
-        root_dir = self.options.source_root_dir
-        if not root_dir or not path:
-            return path
-        assert path.startswith(root_dir)
-        return path[len(root_dir):].lstrip(os.path.sep)
-
-    def _debug_to_external_path(self, path):
-        if not self.options.debugger_use_relative_paths:
-            return path
-        if not path or not self.options.source_root_dir:
-            return path
-        for file in self.options.source_files:
-            if path.endswith(self._external_to_debug_path(file)):
-                return file
-        return path
-
-class TestDebuggerBase(unittest.TestCase):
-
-    class MockDebugger(DebuggerBase):
-
-        def __init__(self, context, *args):
-            super().__init__(context, *args)
-            self.step_info = None
-            self.breakpoint_file = None
-
-        def _add_breakpoint(self, file, line):
-            self.breakpoint_file = file
-
-        def _get_step_info(self, watches, step_index):
-            return self.step_info
-
-    def __init__(self, *args):
-        super().__init__(*args)
-        TestDebuggerBase.MockDebugger.__abstractmethods__ = set()
-        self.options = SimpleNamespace(source_root_dir = '', source_files = [])
-        context = SimpleNamespace(options = self.options)
-        self.dbg = TestDebuggerBase.MockDebugger(context)
-
-    def _new_step(self, paths):
-        frames = [
-            FrameIR(
-                function=None,
-                is_inlined=False,
-                loc=LocIR(path=path, lineno=0, column=0)) for path in paths
-        ]
-        return StepIR(step_index=0, stop_reason=None, frames=frames)
-
-    def _step_paths(self, step):
-        return [frame.loc.path for frame in step.frames]
-
-    def test_add_breakpoint_no_source_root_dir(self):
-        self.options.debugger_use_relative_paths = True
-        self.options.source_root_dir = ''
-        self.dbg.add_breakpoint('/root/some_file', 12)
-        self.assertEqual('/root/some_file', self.dbg.breakpoint_file)
-
-    def test_add_breakpoint_with_source_root_dir(self):
-        self.options.debugger_use_relative_paths = True
-        self.options.source_root_dir = '/my_root'
-        self.dbg.add_breakpoint('/my_root/some_file', 12)
-        self.assertEqual('some_file', self.dbg.breakpoint_file)
-
-    def test_add_breakpoint_with_source_root_dir_slash_suffix(self):
-        self.options.debugger_use_relative_paths = True
-        self.options.source_root_dir = '/my_root/'
-        self.dbg.add_breakpoint('/my_root/some_file', 12)
-        self.assertEqual('some_file', self.dbg.breakpoint_file)
-
-    def test_get_step_info_no_source_root_dir(self):
-        self.options.debugger_use_relative_paths = True
-        self.dbg.step_info = self._new_step(['/root/some_file'])
-        self.assertEqual(['/root/some_file'],
-            self._step_paths(self.dbg.get_step_info([], 0)))
-
-    def test_get_step_info_no_frames(self):
-        self.options.debugger_use_relative_paths = True
-        self.options.source_root_dir = '/my_root'
-        self.dbg.step_info = self._new_step([])
-        self.assertEqual([],
-            self._step_paths(self.dbg.get_step_info([], 0)))
-
-    def test_get_step_info(self):
-        self.options.debugger_use_relative_paths = True
-        self.options.source_root_dir = '/my_root'
-        self.options.source_files = ['/my_root/some_file']
-        self.dbg.step_info = self._new_step(
-            [None, '/other/file', '/dbg/some_file'])
-        self.assertEqual([None, '/other/file', '/my_root/some_file'],
-            self._step_paths(self.dbg.get_step_info([], 0)))
diff --git a/dexter/dex/debugger/DebuggerControllers/ConditionalController.py b/dexter/dex/debugger/DebuggerControllers/ConditionalController.py
deleted file mode 100644
index 0c20ecf..0000000
--- a/dexter/dex/debugger/DebuggerControllers/ConditionalController.py
+++ /dev/null
@@ -1,164 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-"""Conditional Controller Class for DExTer.-"""
-
-
-import os
-import time
-from collections import defaultdict
-from itertools import chain
-
-from dex.debugger.DebuggerControllers.ControllerHelpers import in_source_file, update_step_watches
-from dex.debugger.DebuggerControllers.DebuggerControllerBase import DebuggerControllerBase
-from dex.debugger.DebuggerBase import DebuggerBase
-from dex.utils.Exceptions import DebuggerException
-
-
-class BreakpointRange:
-    """A range of breakpoints and a set of conditions.
-
-    The leading breakpoint (on line `range_from`) is always active.
-
-    When the leading breakpoint is hit the trailing range should be activated
-    when `expression` evaluates to any value in `values`. If there are no
-    conditions (`expression` is None) then the trailing breakpoint range should
-    always be activated upon hitting the leading breakpoint.
-
-    Args:
-       expression: None for no conditions, or a str expression to compare
-       against `values`.
-
-       hit_count: None for no limit, or int to set the number of times the
-                  leading breakpoint is triggered before it is removed.
-    """
-
-    def __init__(self, expression: str, path: str, range_from: int, range_to: int,
-                 values: list, hit_count: int):
-        self.expression = expression
-        self.path = path
-        self.range_from = range_from
-        self.range_to = range_to
-        self.conditional_values = values
-        self.max_hit_count = hit_count
-        self.current_hit_count = 0
-
-    def has_conditions(self):
-        return self.expression != None
-
-    def get_conditional_expression_list(self):
-        conditional_list = []
-        for value in self.conditional_values:
-            # (<expression>) == (<value>)
-            conditional_expression = '({}) == ({})'.format(self.expression, value)
-            conditional_list.append(conditional_expression)
-        return conditional_list
-
-    def add_hit(self):
-        self.current_hit_count += 1
-
-    def should_be_removed(self):
-        if self.max_hit_count == None:
-            return False
-        return self.current_hit_count >= self.max_hit_count
-
-
-class ConditionalController(DebuggerControllerBase):
-    def __init__(self, context, step_collection):
-      self.context = context
-      self.step_collection = step_collection
-      self._bp_ranges = None
-      self._build_bp_ranges()
-      self._watches = set()
-      self._step_index = 0
-      self._pause_between_steps = context.options.pause_between_steps
-      self._max_steps = context.options.max_steps
-      # Map {id: BreakpointRange}
-      self._leading_bp_handles = {}
-
-    def _build_bp_ranges(self):
-        commands = self.step_collection.commands
-        self._bp_ranges = []
-        try:
-            limit_commands = commands['DexLimitSteps']
-            for lc in limit_commands:
-                bpr = BreakpointRange(
-                  lc.expression,
-                  lc.path,
-                  lc.from_line,
-                  lc.to_line,
-                  lc.values,
-                  lc.hit_count)
-                self._bp_ranges.append(bpr)
-        except KeyError:
-            raise DebuggerException('Missing DexLimitSteps commands, cannot conditionally step.')
-
-    def _set_leading_bps(self):
-        # Set a leading breakpoint for each BreakpointRange, building a
-        # map of {leading bp id: BreakpointRange}.
-        for bpr in self._bp_ranges:
-            if bpr.has_conditions():
-                # Add a conditional breakpoint for each condition.
-                for cond_expr in bpr.get_conditional_expression_list():
-                    id = self.debugger.add_conditional_breakpoint(bpr.path,
-                                                                  bpr.range_from,
-                                                                  cond_expr)
-                    self._leading_bp_handles[id] = bpr
-            else:
-                # Add an unconditional breakpoint.
-                id = self.debugger.add_breakpoint(bpr.path, bpr.range_from)
-                self._leading_bp_handles[id] = bpr
-
-    def _run_debugger_custom(self):
-        # TODO: Add conditional and unconditional breakpoint support to dbgeng.
-        if self.debugger.get_name() == 'dbgeng':
-            raise DebuggerException('DexLimitSteps commands are not supported by dbgeng')
-
-        self.step_collection.clear_steps()
-        self._set_leading_bps()
-
-        for command_obj in chain.from_iterable(self.step_collection.commands.values()):
-            self._watches.update(command_obj.get_watches())
-
-        self.debugger.launch()
-        time.sleep(self._pause_between_steps)
-        while not self.debugger.is_finished:
-            while self.debugger.is_running:
-                pass
-
-            step_info = self.debugger.get_step_info(self._watches, self._step_index)
-            if step_info.current_frame:
-                self._step_index += 1
-                update_step_watches(step_info, self._watches, self.step_collection.commands)
-                self.step_collection.new_step(self.context, step_info)
-
-            bp_to_delete = []
-            for bp_id in self.debugger.get_triggered_breakpoint_ids():
-                try:
-                    # See if this is one of our leading breakpoints.
-                    bpr = self._leading_bp_handles[bp_id]
-                except KeyError:
-                    # This is a trailing bp. Mark it for removal.
-                    bp_to_delete.append(bp_id)
-                    continue
-
-                bpr.add_hit()
-                if bpr.should_be_removed():
-                    bp_to_delete.append(bp_id)
-                    del self._leading_bp_handles[bp_id]
-                # Add a range of trailing breakpoints covering the lines
-                # requested in the DexLimitSteps command. Ignore first line as
-                # that's covered by the leading bp we just hit and include the
-                # final line.
-                for line in range(bpr.range_from + 1, bpr.range_to + 1):
-                    self.debugger.add_breakpoint(bpr.path, line)
-
-            # Remove any trailing or expired leading breakpoints we just hit.
-            for bp_id in bp_to_delete:
-                self.debugger.delete_breakpoint(bp_id)
-
-            self.debugger.go()
-            time.sleep(self._pause_between_steps)
diff --git a/dexter/dex/debugger/DebuggerControllers/ControllerHelpers.py b/dexter/dex/debugger/DebuggerControllers/ControllerHelpers.py
deleted file mode 100644
index a8e0722..0000000
--- a/dexter/dex/debugger/DebuggerControllers/ControllerHelpers.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-
-import os
-from itertools import chain
-
-def in_source_file(source_files, step_info):
-    if not step_info.current_frame:
-        return False
-    if not step_info.current_location.path:
-        return False
-    if not os.path.exists(step_info.current_location.path):
-        return False
-    return any(os.path.samefile(step_info.current_location.path, f) \
-               for f in source_files)
-
-def update_step_watches(step_info, watches, commands):
-    watch_cmds = ['DexUnreachable', 'DexExpectStepOrder']
-    towatch = chain.from_iterable(commands[x]
-                                  for x in watch_cmds
-                                  if x in commands)
-    try:
-        # Iterate over all watches of the types named in watch_cmds
-        for watch in towatch:
-            loc = step_info.current_location
-            if (loc.path != None
-                    and os.path.exists(loc.path)
-                    and os.path.samefile(watch.path, loc.path)
-                    and watch.lineno == loc.lineno):
-                result = watch.eval(step_info)
-                step_info.watches.update(result)
-                break
-    except KeyError:
-        pass
diff --git a/dexter/dex/debugger/DebuggerControllers/DebuggerControllerBase.py b/dexter/dex/debugger/DebuggerControllers/DebuggerControllerBase.py
deleted file mode 100644
index 87b13fc..0000000
--- a/dexter/dex/debugger/DebuggerControllers/DebuggerControllerBase.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-"""Abstract Base class for controlling debuggers."""
-
-import abc
-
-class DebuggerControllerBase(object, metaclass=abc.ABCMeta):
-    @abc.abstractclassmethod
-    def _run_debugger_custom(self):
-        """Specify your own implementation of run_debugger_custom in your own
-        controller.
-        """
-        pass
-
-    def run_debugger(self, debugger):
-        """Responsible for correctly launching and tearing down the debugger.
-        """
-        self.debugger = debugger
-        with self.debugger:
-            self._run_debugger_custom()
-        # We may need to pickle this debugger controller after running the
-        # debugger. Debuggers are not picklable objects, so set to None.
-        self.debugger = None
diff --git a/dexter/dex/debugger/DebuggerControllers/DefaultController.py b/dexter/dex/debugger/DebuggerControllers/DefaultController.py
deleted file mode 100644
index c41a3ef..0000000
--- a/dexter/dex/debugger/DebuggerControllers/DefaultController.py
+++ /dev/null
@@ -1,66 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-"""Default class for controlling debuggers."""
-
-from itertools import chain
-import os
-import time
-
-from dex.debugger.DebuggerControllers.DebuggerControllerBase import DebuggerControllerBase
-from dex.debugger.DebuggerControllers.ControllerHelpers import in_source_file, update_step_watches
-from dex.utils.Exceptions import DebuggerException, LoadDebuggerException
-
-class DefaultController(DebuggerControllerBase):
-    def __init__(self, context, step_collection):
-        self.context = context
-        self.step_collection = step_collection
-        self.source_files = self.context.options.source_files
-        self.watches = set()
-        self.step_index = 0
-
-    def _break_point_all_lines(self):
-        for s in self.context.options.source_files:
-            with open(s, 'r') as fp:
-                num_lines = len(fp.readlines())
-            for line in range(1, num_lines + 1):
-                try:
-                   self.debugger.add_breakpoint(s, line)
-                except DebuggerException:
-                   raise LoadDebuggerException(DebuggerException.msg)
-
-    def _run_debugger_custom(self):
-        self.step_collection.debugger = self.debugger.debugger_info
-        self._break_point_all_lines()
-        self.debugger.launch()
-
-        for command_obj in chain.from_iterable(self.step_collection.commands.values()):
-            self.watches.update(command_obj.get_watches())
-
-        max_steps = self.context.options.max_steps
-        for _ in range(max_steps):
-            while self.debugger.is_running:
-                pass
-
-            if self.debugger.is_finished:
-                break
-
-            self.step_index += 1
-            step_info = self.debugger.get_step_info(self.watches, self.step_index)
-
-            if step_info.current_frame:
-                update_step_watches(step_info, self.watches, self.step_collection.commands)
-                self.step_collection.new_step(self.context, step_info)
-
-            if in_source_file(self.source_files, step_info):
-                self.debugger.step()
-            else:
-                self.debugger.go()
-
-            time.sleep(self.context.options.pause_between_steps)
-        else:
-            raise DebuggerException(
-                'maximum number of steps reached ({})'.format(max_steps))
diff --git a/dexter/dex/debugger/Debuggers.py b/dexter/dex/debugger/Debuggers.py
deleted file mode 100644
index fbfa629..0000000
--- a/dexter/dex/debugger/Debuggers.py
+++ /dev/null
@@ -1,293 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-"""Discover potential/available debugger interfaces."""
-
-from collections import OrderedDict
-import os
-import pickle
-import subprocess
-import sys
-from tempfile import NamedTemporaryFile
-
-from dex.command import get_command_infos
-from dex.dextIR import DextIR
-from dex.utils import get_root_directory, Timer
-from dex.utils.Environment import is_native_windows
-from dex.utils.Exceptions import ToolArgumentError
-from dex.utils.Warning import warn
-from dex.utils.Exceptions import DebuggerException
-
-from dex.debugger.DebuggerControllers.DefaultController import DefaultController
-
-from dex.debugger.dbgeng.dbgeng import DbgEng
-from dex.debugger.lldb.LLDB import LLDB
-from dex.debugger.visualstudio.VisualStudio2015 import VisualStudio2015
-from dex.debugger.visualstudio.VisualStudio2017 import VisualStudio2017
-from dex.debugger.visualstudio.VisualStudio2019 import VisualStudio2019
-
-
-def _get_potential_debuggers():  # noqa
-    """Return a dict of the supported debuggers.
-    Returns:
-        { name (str): debugger (class) }
-    """
-    return {
-        DbgEng.get_option_name(): DbgEng,
-        LLDB.get_option_name(): LLDB,
-        VisualStudio2015.get_option_name(): VisualStudio2015,
-        VisualStudio2017.get_option_name(): VisualStudio2017,
-        VisualStudio2019.get_option_name(): VisualStudio2019
-    }
-
-
-def _warn_meaningless_option(context, option):
-    if hasattr(context.options, 'list_debuggers'):
-        return
-
-    warn(context,
-         'option <y>"{}"</> is meaningless with this debugger'.format(option),
-         '--debugger={}'.format(context.options.debugger))
-
-
-def add_debugger_tool_base_arguments(parser, defaults):
-    defaults.lldb_executable = 'lldb.exe' if is_native_windows() else 'lldb'
-    parser.add_argument(
-        '--lldb-executable',
-        type=str,
-        metavar='<file>',
-        default=None,
-        display_default=defaults.lldb_executable,
-        help='location of LLDB executable')
-
-
-def add_debugger_tool_arguments(parser, context, defaults):
-    debuggers = Debuggers(context)
-    potential_debuggers = sorted(debuggers.potential_debuggers().keys())
-
-    add_debugger_tool_base_arguments(parser, defaults)
-
-    parser.add_argument(
-        '--debugger',
-        type=str,
-        choices=potential_debuggers,
-        required=True,
-        help='debugger to use')
-    parser.add_argument(
-        '--max-steps',
-        metavar='<int>',
-        type=int,
-        default=1000,
-        help='maximum number of program steps allowed')
-    parser.add_argument(
-        '--pause-between-steps',
-        metavar='<seconds>',
-        type=float,
-        default=0.0,
-        help='number of seconds to pause between steps')
-    defaults.show_debugger = False
-    parser.add_argument(
-        '--show-debugger',
-        action='store_true',
-        default=None,
-        help='show the debugger')
-    defaults.arch = 'x86_64'
-    parser.add_argument(
-        '--arch',
-        type=str,
-        metavar='<architecture>',
-        default=None,
-        display_default=defaults.arch,
-        help='target architecture')
-    defaults.source_root_dir = ''
-    parser.add_argument(
-        '--source-root-dir',
-        type=str,
-        metavar='<directory>',
-        default=None,
-        help='source root directory')
-    parser.add_argument(
-        '--debugger-use-relative-paths',
-        action='store_true',
-        default=False,
-        help='pass the debugger paths relative to --source-root-dir')
-
-def handle_debugger_tool_base_options(context, defaults):  # noqa
-    options = context.options
-
-    if options.lldb_executable is None:
-        options.lldb_executable = defaults.lldb_executable
-    else:
-        if getattr(options, 'debugger', 'lldb') != 'lldb':
-            _warn_meaningless_option(context, '--lldb-executable')
-
-        options.lldb_executable = os.path.abspath(options.lldb_executable)
-        if not os.path.isfile(options.lldb_executable):
-            raise ToolArgumentError('<d>could not find</> <r>"{}"</>'.format(
-                options.lldb_executable))
-
-
-def handle_debugger_tool_options(context, defaults):  # noqa
-    options = context.options
-
-    handle_debugger_tool_base_options(context, defaults)
-
-    if options.arch is None:
-        options.arch = defaults.arch
-    else:
-        if options.debugger != 'lldb':
-            _warn_meaningless_option(context, '--arch')
-
-    if options.show_debugger is None:
-        options.show_debugger = defaults.show_debugger
-    else:
-        if options.debugger == 'lldb':
-            _warn_meaningless_option(context, '--show-debugger')
-
-    if options.source_root_dir != None:
-        if not os.path.isabs(options.source_root_dir):
-            raise ToolArgumentError(f'<d>--source-root-dir: expected absolute path, got</> <r>"{options.source_root_dir}"</>')
-        if not os.path.isdir(options.source_root_dir):
-            raise ToolArgumentError(f'<d>--source-root-dir: could not find directory</> <r>"{options.source_root_dir}"</>')
-
-    if options.debugger_use_relative_paths:
-        if not options.source_root_dir:
-            raise ToolArgumentError(f'<d>--debugger-relative-paths</> <r>requires --source-root-dir</>')
-
-def run_debugger_subprocess(debugger_controller, working_dir_path):
-    with NamedTemporaryFile(
-            dir=working_dir_path, delete=False, mode='wb') as fp:
-        pickle.dump(debugger_controller, fp, protocol=pickle.HIGHEST_PROTOCOL)
-        controller_path = fp.name
-
-    dexter_py = os.path.basename(sys.argv[0])
-    if not os.path.isfile(dexter_py):
-        dexter_py = os.path.join(get_root_directory(), '..', dexter_py)
-    assert os.path.isfile(dexter_py)
-
-    with NamedTemporaryFile(dir=working_dir_path) as fp:
-        args = [
-            sys.executable,
-            dexter_py,
-            'run-debugger-internal-',
-            controller_path,
-            '--working-directory={}'.format(working_dir_path),
-            '--unittest=off',
-            '--indent-timer-level={}'.format(Timer.indent + 2)
-        ]
-        try:
-            with Timer('running external debugger process'):
-                subprocess.check_call(args)
-        except subprocess.CalledProcessError as e:
-            raise DebuggerException(e)
-
-    with open(controller_path, 'rb') as fp:
-        debugger_controller = pickle.load(fp)
-
-    return debugger_controller
-
-
-class Debuggers(object):
-    @classmethod
-    def potential_debuggers(cls):
-        try:
-            return cls._potential_debuggers
-        except AttributeError:
-            cls._potential_debuggers = _get_potential_debuggers()
-            return cls._potential_debuggers
-
-    def __init__(self, context):
-        self.context = context
-
-    def load(self, key):
-        with Timer('load {}'.format(key)):
-            return Debuggers.potential_debuggers()[key](self.context)
-
-    def _populate_debugger_cache(self):
-        debuggers = []
-        for key in sorted(Debuggers.potential_debuggers()):
-            debugger = self.load(key)
-
-            class LoadedDebugger(object):
-                pass
-
-            LoadedDebugger.option_name = key
-            LoadedDebugger.full_name = '[{}]'.format(debugger.name)
-            LoadedDebugger.is_available = debugger.is_available
-
-            if LoadedDebugger.is_available:
-                try:
-                    LoadedDebugger.version = debugger.version.splitlines()
-                except AttributeError:
-                    LoadedDebugger.version = ['']
-            else:
-                try:
-                    LoadedDebugger.error = debugger.loading_error.splitlines()
-                except AttributeError:
-                    LoadedDebugger.error = ['']
-
-                try:
-                    LoadedDebugger.error_trace = debugger.loading_error_trace
-                except AttributeError:
-                    LoadedDebugger.error_trace = None
-
-            debuggers.append(LoadedDebugger)
-        return debuggers
-
-    def list(self):
-        debuggers = self._populate_debugger_cache()
-
-        max_o_len = max(len(d.option_name) for d in debuggers)
-        max_n_len = max(len(d.full_name) for d in debuggers)
-
-        msgs = []
-
-        for d in debuggers:
-            # Option name, right padded with spaces for alignment
-            option_name = (
-                '{{name: <{}}}'.format(max_o_len).format(name=d.option_name))
-
-            # Full name, right padded with spaces for alignment
-            full_name = ('{{name: <{}}}'.format(max_n_len)
-                         .format(name=d.full_name))
-
-            if d.is_available:
-                name = '<b>{} {}</>'.format(option_name, full_name)
-
-                # If the debugger is available, show the first line of the
-                #  version info.
-                available = '<g>YES</>'
-                info = '<b>({})</>'.format(d.version[0])
-            else:
-                name = '<y>{} {}</>'.format(option_name, full_name)
-
-                # If the debugger is not available, show the first line of the
-                # error reason.
-                available = '<r>NO</> '
-                info = '<y>({})</>'.format(d.error[0])
-
-            msg = '{} {} {}'.format(name, available, info)
-
-            if self.context.options.verbose:
-                # If verbose mode and there was more version or error output
-                # than could be displayed in a single line, display the whole
-                # lot slightly indented.
-                verbose_info = None
-                if d.is_available:
-                    if d.version[1:]:
-                        verbose_info = d.version + ['\n']
-                else:
-                    # Some of list elems may contain multiple lines, so make
-                    # sure each elem is a line of its own.
-                    verbose_info = d.error_trace
-
-                if verbose_info:
-                    verbose_info = '\n'.join('        {}'.format(l.rstrip())
-                                             for l in verbose_info) + '\n'
-                    msg = '{}\n\n{}'.format(msg, verbose_info)
-
-            msgs.append(msg)
-        self.context.o.auto('\n{}\n\n'.format('\n'.join(msgs)))
diff --git a/dexter/dex/debugger/__init__.py b/dexter/dex/debugger/__init__.py
deleted file mode 100644
index 394f9f0..0000000
--- a/dexter/dex/debugger/__init__.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-
-from dex.debugger.Debuggers import Debuggers
-from dex.debugger.DebuggerControllers.DebuggerControllerBase import DebuggerControllerBase
-from dex.debugger.DebuggerControllers.DefaultController import DefaultController
diff --git a/dexter/dex/debugger/dbgeng/README.md b/dexter/dex/debugger/dbgeng/README.md
deleted file mode 100644
index 208e628..0000000
--- a/dexter/dex/debugger/dbgeng/README.md
+++ /dev/null
@@ -1,56 +0,0 @@
-# Debugger Engine backend
-
-This directory contains the Dexter backend for the Windows Debugger Engine
-(DbgEng), which powers tools such as WinDbg and CDB.
-
-## Overview
-
-DbgEng is available as a collection of unregistered COM-"like" objects that
-one accesses by calling DebugCreate in DbgEng.dll. The unregistered nature
-means normal COM tooling can't access them; as a result, this backend uses
-ctypes to describe the COM objects and call their methods.
-
-This is obviously not a huge amount of fun; on the other hand, COM has
-maintained ABI compatible interfaces for decades, and nothing is for free.
-
-The dexter backend follows the same formula as others; it creates a process
-and breaks on "main", then steps through the program, observing states and
-stack frames along the way.
-
-## Implementation details
-
-This backend uses a mixture of both APIs for accessing information, and the
-direct command-string interface to DbgEng for performing some actions. We
-have to use the DbgEng stepping interface, or we would effectively be
-building a new debugger, but certain things (like enabling source-line
-stepping) only seem to be possible from the command interface.
-
-Each segment of debugger responsibility has its own COM object: Client,
-Control, Symbols, SymbolGroups, Breakpoint, SystemObjects. In this python
-wrapper, each COM object gets a python object wrapping it. COM methods
-that are relevant to our interests have a python method that wraps the COM
-one and performs data marshalling. Some additional helper methods are added
-to the python objects to extract data.
-
-The majority of the work occurs in setup.py and probe_process.py. The
-former contains routines to launch a process and attach the debugger to
-it, while the latter extracts as much information as possible from a
-stopped process, returning a list of stack frames with associated variable
-information.
-
-## Sharp edges
-
-On process startup, we set a breakpoint on main and then continue running
-to it. This has the potential to never complete -- although of course,
-there's no guarantee that the debuggee will ever do anything anyway.
-
-There doesn't appear to be a way to instruct DbgEng to "step into" a
-function call, thus after reaching main, we scan the module for all
-functions with line numbers in the source directory, and put breakpoints
-on them. An alternative implementation would be putting breakpoints on
-every known line number.
-
-Finally, it's unclear whether arbitrary expressions can be evaluated in
-arbitrary stack frames, although this isn't something that Dexter currently
-supports.
- 
diff --git a/dexter/dex/debugger/dbgeng/__init__.py b/dexter/dex/debugger/dbgeng/__init__.py
deleted file mode 100644
index 3c458f9..0000000
--- a/dexter/dex/debugger/dbgeng/__init__.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-
-from . import dbgeng
-
-import platform
-if platform.system() == 'Windows':
-  from . import breakpoint
-  from . import control
-  from . import probe_process
-  from . import setup
-  from . import symbols
-  from . import symgroup
-  from . import sysobjs
-  from . import utils
diff --git a/dexter/dex/debugger/dbgeng/breakpoint.py b/dexter/dex/debugger/dbgeng/breakpoint.py
deleted file mode 100644
index c966d8c..0000000
--- a/dexter/dex/debugger/dbgeng/breakpoint.py
+++ /dev/null
@@ -1,88 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-
-from ctypes import *
-from enum import *
-from functools import partial
-
-from .utils import *
-
-class BreakpointTypes(IntEnum):
-  DEBUG_BREAKPOINT_CODE =   0
-  DEBUG_BREAKPOINT_DATA =   1
-  DEBUG_BREAKPOINT_TIME =   2
-  DEBUG_BREAKPOINT_INLINE = 3
-
-class BreakpointFlags(IntFlag):
-  DEBUG_BREAKPOINT_GO_ONLY =    0x00000001
-  DEBUG_BREAKPOINT_DEFERRED =   0x00000002
-  DEBUG_BREAKPOINT_ENABLED =    0x00000004
-  DEBUG_BREAKPOINT_ADDER_ONLY = 0x00000008
-  DEBUG_BREAKPOINT_ONE_SHOT =   0x00000010
-
-DebugBreakpoint2IID = IID(0x1b278d20, 0x79f2, 0x426e, IID_Data4_Type(0xa3, 0xf9, 0xc1, 0xdd, 0xf3, 0x75, 0xd4, 0x8e))
-
-class DebugBreakpoint2(Structure):
-  pass
-
-class DebugBreakpoint2Vtbl(Structure):
-  wrp = partial(WINFUNCTYPE, c_long, POINTER(DebugBreakpoint2))
-  idb_setoffset = wrp(c_ulonglong)
-  idb_setflags = wrp(c_ulong)
-  _fields_ = [
-      ("QueryInterface", c_void_p),
-      ("AddRef", c_void_p),
-      ("Release", c_void_p),
-      ("GetId", c_void_p),
-      ("GetType", c_void_p),
-      ("GetAdder", c_void_p),
-      ("GetFlags", c_void_p),
-      ("AddFlags", c_void_p),
-      ("RemoveFlags", c_void_p),
-      ("SetFlags", idb_setflags),
-      ("GetOffset", c_void_p),
-      ("SetOffset", idb_setoffset),
-      ("GetDataParameters", c_void_p),
-      ("SetDataParameters", c_void_p),
-      ("GetPassCount", c_void_p),
-      ("SetPassCount", c_void_p),
-      ("GetCurrentPassCount", c_void_p),
-      ("GetMatchThreadId", c_void_p),
-      ("SetMatchThreadId", c_void_p),
-      ("GetCommand", c_void_p),
-      ("SetCommand", c_void_p),
-      ("GetOffsetExpression", c_void_p),
-      ("SetOffsetExpression", c_void_p),
-      ("GetParameters", c_void_p),
-      ("GetCommandWide", c_void_p),
-      ("SetCommandWide", c_void_p),
-      ("GetOffsetExpressionWide", c_void_p),
-      ("SetOffsetExpressionWide", c_void_p)
-    ]
-
-DebugBreakpoint2._fields_ = [("lpVtbl", POINTER(DebugBreakpoint2Vtbl))]
-
-class Breakpoint(object):
-  def __init__(self, breakpoint):
-    self.breakpoint = breakpoint.contents
-    self.vt = self.breakpoint.lpVtbl.contents
-
-  def SetFlags(self, flags):
-    res = self.vt.SetFlags(self.breakpoint, flags)
-    aborter(res, "Breakpoint SetFlags")
-
-  def SetOffset(self, offs):
-    res = self.vt.SetOffset(self.breakpoint, offs)
-    aborter(res, "Breakpoint SetOffset")
-
-  def RemoveFlags(self, flags):
-    res = self.vt.RemoveFlags(self.breakpoint, flags)
-    aborter(res, "Breakpoint RemoveFlags")
-
-  def die(self):
-    self.breakpoint = None
-    self.vt = None
diff --git a/dexter/dex/debugger/dbgeng/client.py b/dexter/dex/debugger/dbgeng/client.py
deleted file mode 100644
index 22d4652..0000000
--- a/dexter/dex/debugger/dbgeng/client.py
+++ /dev/null
@@ -1,211 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-
-from ctypes import *
-from enum import *
-from functools import partial
-
-from .utils import *
-from . import control
-from . import symbols
-from . import sysobjs
-
-class DebugAttach(IntFlag):
-  DEBUG_ATTACH_DEFAULT =                      0
-  DEBUG_ATTACH_NONINVASIVE =                  1
-  DEBUG_ATTACH_EXISTING =                     2
-  DEBUG_ATTACH_NONINVASIVE_NO_SUSPEND =       4
-  DEBUG_ATTACH_INVASIVE_NO_INITIAL_BREAK =    8
-  DEBUG_ATTACH_INVASIVE_RESUME_PROCESS =   0x10
-  DEBUG_ATTACH_NONINVASIVE_ALLOW_PARTIAL = 0x20
-
-# UUID for DebugClient7 interface.
-DebugClient7IID = IID(0x13586be3, 0x542e, 0x481e, IID_Data4_Type(0xb1, 0xf2, 0x84, 0x97, 0xba, 0x74, 0xf9, 0xa9 ))
-
-class DEBUG_CREATE_PROCESS_OPTIONS(Structure):
-  _fields_ = [
-    ("CreateFlags", c_ulong),
-    ("EngCreateFlags", c_ulong),
-    ("VerifierFlags", c_ulong),
-    ("Reserved", c_ulong)
-  ]
-
-class IDebugClient7(Structure):
-  pass
-
-class IDebugClient7Vtbl(Structure):
-  wrp = partial(WINFUNCTYPE, c_long, POINTER(IDebugClient7))
-  idc_queryinterface = wrp(POINTER(IID), POINTER(c_void_p))
-  idc_attachprocess = wrp(c_longlong, c_long, c_long)
-  idc_detachprocesses = wrp()
-  idc_terminateprocesses = wrp()
-  idc_createprocessandattach2 = wrp(c_ulonglong, c_char_p, c_void_p, c_ulong, c_char_p, c_char_p, c_ulong, c_ulong)
-  _fields_ = [
-      ("QueryInterface", idc_queryinterface),
-      ("AddRef", c_void_p),
-      ("Release", c_void_p),
-      ("AttachKernel", c_void_p),
-      ("GetKernelConnectionOptions", c_void_p),
-      ("SetKernelConnectionOptions", c_void_p),
-      ("StartProcessServer", c_void_p),
-      ("ConnectProcessServer", c_void_p),
-      ("DisconnectProcessServer", c_void_p),
-      ("GetRunningProcessSystemIds", c_void_p),
-      ("GetRunningProcessSystemIdsByExecutableName", c_void_p),
-      ("GetRunningProcessDescription", c_void_p),
-      ("AttachProcess", idc_attachprocess),
-      ("CreateProcess", c_void_p),
-      ("CreateProcessAndAttach", c_void_p),
-      ("GetProcessOptions", c_void_p),
-      ("AddProcessOptions", c_void_p),
-      ("RemoveProcessOptions", c_void_p),
-      ("SetProcessOptions", c_void_p),
-      ("OpenDumpFile", c_void_p),
-      ("WriteDumpFile", c_void_p),
-      ("ConnectSession", c_void_p),
-      ("StartServer", c_void_p),
-      ("OutputServers", c_void_p),
-      ("TerminateProcesses", idc_terminateprocesses),
-      ("DetachProcesses", idc_detachprocesses),
-      ("EndSession", c_void_p),
-      ("GetExitCode", c_void_p),
-      ("DispatchCallbacks", c_void_p),
-      ("ExitDispatch", c_void_p),
-      ("CreateClient", c_void_p),
-      ("GetInputCallbacks", c_void_p),
-      ("SetInputCallbacks", c_void_p),
-      ("GetOutputCallbacks", c_void_p),
-      ("SetOutputCallbacks", c_void_p),
-      ("GetOutputMask", c_void_p),
-      ("SetOutputMask", c_void_p),
-      ("GetOtherOutputMask", c_void_p),
-      ("SetOtherOutputMask", c_void_p),
-      ("GetOutputWidth", c_void_p),
-      ("SetOutputWidth", c_void_p),
-      ("GetOutputLinePrefix", c_void_p),
-      ("SetOutputLinePrefix", c_void_p),
-      ("GetIdentity", c_void_p),
-      ("OutputIdentity", c_void_p),
-      ("GetEventCallbacks", c_void_p),
-      ("SetEventCallbacks", c_void_p),
-      ("FlushCallbacks", c_void_p),
-      ("WriteDumpFile2", c_void_p),
-      ("AddDumpInformationFile", c_void_p),
-      ("EndProcessServer", c_void_p),
-      ("WaitForProcessServerEnd", c_void_p),
-      ("IsKernelDebuggerEnabled", c_void_p),
-      ("TerminateCurrentProcess", c_void_p),
-      ("DetachCurrentProcess", c_void_p),
-      ("AbandonCurrentProcess", c_void_p),
-      ("GetRunningProcessSystemIdByExecutableNameWide", c_void_p),
-      ("GetRunningProcessDescriptionWide", c_void_p),
-      ("CreateProcessWide", c_void_p),
-      ("CreateProcessAndAttachWide", c_void_p),
-      ("OpenDumpFileWide", c_void_p),
-      ("WriteDumpFileWide", c_void_p),
-      ("AddDumpInformationFileWide", c_void_p),
-      ("GetNumberDumpFiles", c_void_p),
-      ("GetDumpFile", c_void_p),
-      ("GetDumpFileWide", c_void_p),
-      ("AttachKernelWide", c_void_p),
-      ("GetKernelConnectionOptionsWide", c_void_p),
-      ("SetKernelConnectionOptionsWide", c_void_p),
-      ("StartProcessServerWide", c_void_p),
-      ("ConnectProcessServerWide", c_void_p),
-      ("StartServerWide", c_void_p),
-      ("OutputServerWide", c_void_p),
-      ("GetOutputCallbacksWide", c_void_p),
-      ("SetOutputCallbacksWide", c_void_p),
-      ("GetOutputLinePrefixWide", c_void_p),
-      ("SetOutputLinePrefixWide", c_void_p),
-      ("GetIdentityWide", c_void_p),
-      ("OutputIdentityWide", c_void_p),
-      ("GetEventCallbacksWide", c_void_p),
-      ("SetEventCallbacksWide", c_void_p),
-      ("CreateProcess2", c_void_p),
-      ("CreateProcess2Wide", c_void_p),
-      ("CreateProcessAndAttach2", idc_createprocessandattach2),
-      ("CreateProcessAndAttach2Wide", c_void_p),
-      ("PushOutputLinePrefix", c_void_p),
-      ("PushOutputLinePrefixWide", c_void_p),
-      ("PopOutputLinePrefix", c_void_p),
-      ("GetNumberInputCallbacks", c_void_p),
-      ("GetNumberOutputCallbacks", c_void_p),
-      ("GetNumberEventCallbacks", c_void_p),
-      ("GetQuitLockString", c_void_p),
-      ("SetQuitLockString", c_void_p),
-      ("GetQuitLockStringWide", c_void_p),
-      ("SetQuitLockStringWide", c_void_p),
-      ("SetEventContextCallbacks", c_void_p),
-      ("SetClientContext", c_void_p),
-    ]
-
-IDebugClient7._fields_ = [("lpVtbl", POINTER(IDebugClient7Vtbl))]
-
-class Client(object):
-  def __init__(self):
-    DbgEng = WinDLL("DbgEng")
-    DbgEng.DebugCreate.argtypes = [POINTER(IID), POINTER(POINTER(IDebugClient7))]
-    DbgEng.DebugCreate.restype = c_ulong
-
-    # Call DebugCreate to create a new debug client
-    ptr = POINTER(IDebugClient7)()
-    res = DbgEng.DebugCreate(byref(DebugClient7IID), ptr)
-    aborter(res, "DebugCreate")
-    self.client = ptr.contents
-    self.vt = vt = self.client.lpVtbl.contents
-
-    def QI(iface, ptr):
-      return vt.QueryInterface(self.client, byref(iface), byref(ptr))
-
-    # Query for a control object
-    ptr = c_void_p()
-    res = QI(control.DebugControl7IID, ptr)
-    aborter(res, "QueryInterface control")
-    self.control_ptr = cast(ptr, POINTER(control.IDebugControl7))
-    self.Control = control.Control(self.control_ptr)
-
-    # Query for a SystemObjects object
-    ptr = c_void_p()
-    res = QI(sysobjs.DebugSystemObjects4IID, ptr)
-    aborter(res, "QueryInterface sysobjects")
-    self.sysobjects_ptr = cast(ptr, POINTER(sysobjs.IDebugSystemObjects4))
-    self.SysObjects = sysobjs.SysObjects(self.sysobjects_ptr)
-
-    # Query for a Symbols object
-    ptr = c_void_p()
-    res = QI(symbols.DebugSymbols5IID, ptr)
-    aborter(res, "QueryInterface debugsymbosl5")
-    self.symbols_ptr = cast(ptr, POINTER(symbols.IDebugSymbols5))
-    self.Symbols = symbols.Symbols(self.symbols_ptr)
-
-  def AttachProcess(self, pid):
-    # Zero process-server id means no process-server.
-    res = self.vt.AttachProcess(self.client, 0, pid, DebugAttach.DEBUG_ATTACH_DEFAULT)
-    aborter(res, "AttachProcess")
-    return
-
-  def DetachProcesses(self):
-    res = self.vt.DetachProcesses(self.client)
-    aborter(res, "DetachProcesses")
-    return
-
-  def TerminateProcesses(self):
-    res = self.vt.TerminateProcesses(self.client)
-    aborter(res, "TerminateProcesses")
-    return
-
-  def CreateProcessAndAttach2(self, cmdline):
-    options = DEBUG_CREATE_PROCESS_OPTIONS()
-    options.CreateFlags = 0x2 # DEBUG_ONLY_THIS_PROCESS
-    options.EngCreateFlags  = 0
-    options.VerifierFlags = 0
-    options.Reserved = 0
-    attach_flags = 0
-    res = self.vt.CreateProcessAndAttach2(self.client, 0, cmdline.encode("ascii"), byref(options), sizeof(options), None, None, 0, attach_flags)
-    aborter(res, "CreateProcessAndAttach2")
-    return
diff --git a/dexter/dex/debugger/dbgeng/control.py b/dexter/dex/debugger/dbgeng/control.py
deleted file mode 100644
index 5f23e2d..0000000
--- a/dexter/dex/debugger/dbgeng/control.py
+++ /dev/null
@@ -1,411 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-
-from ctypes import *
-from functools import partial
-
-from .utils import *
-from .breakpoint import *
-
-class DEBUG_STACK_FRAME_EX(Structure):
-  _fields_ = [
-      ("InstructionOffset", c_ulonglong),
-      ("ReturnOffset", c_ulonglong),
-      ("FrameOffset", c_ulonglong),
-      ("StackOffset", c_ulonglong),
-      ("FuncTableEntry", c_ulonglong),
-      ("Params", c_ulonglong * 4),
-      ("Reserved", c_ulonglong * 6),
-      ("Virtual", c_bool),
-      ("FrameNumber", c_ulong),
-      ("InlineFrameContext", c_ulong),
-      ("Reserved1", c_ulong)
-    ]
-PDEBUG_STACK_FRAME_EX = POINTER(DEBUG_STACK_FRAME_EX)
-
-class DEBUG_VALUE_U(Union):
-  _fields_ = [
-      ("I8", c_byte),
-      ("I16", c_short),
-      ("I32", c_int),
-      ("I64", c_long),
-      ("F32", c_float),
-      ("F64", c_double),
-      ("RawBytes", c_ubyte * 24) # Force length to 24b.
-    ]
-
-class DEBUG_VALUE(Structure):
-  _fields_ = [
-      ("U", DEBUG_VALUE_U),
-      ("TailOfRawBytes", c_ulong),
-      ("Type", c_ulong)
-    ]
-PDEBUG_VALUE = POINTER(DEBUG_VALUE)
-
-class DebugValueType(IntEnum):
-  DEBUG_VALUE_INVALID      = 0
-  DEBUG_VALUE_INT8         = 1
-  DEBUG_VALUE_INT16        = 2
-  DEBUG_VALUE_INT32        = 3
-  DEBUG_VALUE_INT64        = 4
-  DEBUG_VALUE_FLOAT32      = 5
-  DEBUG_VALUE_FLOAT64      = 6
-  DEBUG_VALUE_FLOAT80      = 7
-  DEBUG_VALUE_FLOAT82      = 8
-  DEBUG_VALUE_FLOAT128     = 9
-  DEBUG_VALUE_VECTOR64     = 10
-  DEBUG_VALUE_VECTOR128    = 11
-  DEBUG_VALUE_TYPES        = 12
-
-# UUID for DebugControl7 interface.
-DebugControl7IID = IID(0xb86fb3b1, 0x80d4, 0x475b, IID_Data4_Type(0xae, 0xa3, 0xcf, 0x06, 0x53, 0x9c, 0xf6, 0x3a))
-
-class IDebugControl7(Structure):
-  pass
-
-class IDebugControl7Vtbl(Structure):
-  wrp = partial(WINFUNCTYPE, c_long, POINTER(IDebugControl7))
-  idc_getnumbereventfilters = wrp(c_ulong_p, c_ulong_p, c_ulong_p)
-  idc_setexceptionfiltersecondcommand = wrp(c_ulong, c_char_p)
-  idc_waitforevent = wrp(c_long, c_long)
-  idc_execute = wrp(c_long, c_char_p, c_long)
-  idc_setexpressionsyntax = wrp(c_ulong)
-  idc_addbreakpoint2 = wrp(c_ulong, c_ulong, POINTER(POINTER(DebugBreakpoint2)))
-  idc_setexecutionstatus = wrp(c_ulong)
-  idc_getexecutionstatus = wrp(c_ulong_p)
-  idc_getstacktraceex = wrp(c_ulonglong, c_ulonglong, c_ulonglong, PDEBUG_STACK_FRAME_EX, c_ulong, c_ulong_p)
-  idc_evaluate = wrp(c_char_p, c_ulong, PDEBUG_VALUE, c_ulong_p)
-  idc_setengineoptions = wrp(c_ulong)
-  _fields_ = [
-      ("QueryInterface", c_void_p),
-      ("AddRef", c_void_p),
-      ("Release", c_void_p),
-      ("GetInterrupt", c_void_p),
-      ("SetInterrupt", c_void_p),
-      ("GetInterruptTimeout", c_void_p),
-      ("SetInterruptTimeout", c_void_p),
-      ("GetLogFile", c_void_p),
-      ("OpenLogFile", c_void_p),
-      ("CloseLogFile", c_void_p),
-      ("GetLogMask", c_void_p),
-      ("SetLogMask", c_void_p),
-      ("Input", c_void_p),
-      ("ReturnInput", c_void_p),
-      ("Output", c_void_p),
-      ("OutputVaList", c_void_p),
-      ("ControlledOutput", c_void_p),
-      ("ControlledOutputVaList", c_void_p),
-      ("OutputPrompt", c_void_p),
-      ("OutputPromptVaList", c_void_p),
-      ("GetPromptText", c_void_p),
-      ("OutputCurrentState", c_void_p),
-      ("OutputVersionInformation", c_void_p),
-      ("GetNotifyEventHandle", c_void_p),
-      ("SetNotifyEventHandle", c_void_p),
-      ("Assemble", c_void_p),
-      ("Disassemble", c_void_p),
-      ("GetDisassembleEffectiveOffset", c_void_p),
-      ("OutputDisassembly", c_void_p),
-      ("OutputDisassemblyLines", c_void_p),
-      ("GetNearInstruction", c_void_p),
-      ("GetStackTrace", c_void_p),
-      ("GetReturnOffset", c_void_p),
-      ("OutputStackTrace", c_void_p),
-      ("GetDebuggeeType", c_void_p),
-      ("GetActualProcessorType", c_void_p),
-      ("GetExecutingProcessorType", c_void_p),
-      ("GetNumberPossibleExecutingProcessorTypes", c_void_p),
-      ("GetPossibleExecutingProcessorTypes", c_void_p),
-      ("GetNumberProcessors", c_void_p),
-      ("GetSystemVersion", c_void_p),
-      ("GetPageSize", c_void_p),
-      ("IsPointer64Bit", c_void_p),
-      ("ReadBugCheckData", c_void_p),
-      ("GetNumberSupportedProcessorTypes", c_void_p),
-      ("GetSupportedProcessorTypes", c_void_p),
-      ("GetProcessorTypeNames", c_void_p),
-      ("GetEffectiveProcessorType", c_void_p),
-      ("SetEffectiveProcessorType", c_void_p),
-      ("GetExecutionStatus", idc_getexecutionstatus),
-      ("SetExecutionStatus", idc_setexecutionstatus),
-      ("GetCodeLevel", c_void_p),
-      ("SetCodeLevel", c_void_p),
-      ("GetEngineOptions", c_void_p),
-      ("AddEngineOptions", c_void_p),
-      ("RemoveEngineOptions", c_void_p),
-      ("SetEngineOptions", idc_setengineoptions),
-      ("GetSystemErrorControl", c_void_p),
-      ("SetSystemErrorControl", c_void_p),
-      ("GetTextMacro", c_void_p),
-      ("SetTextMacro", c_void_p),
-      ("GetRadix", c_void_p),
-      ("SetRadix", c_void_p),
-      ("Evaluate", idc_evaluate),
-      ("CoerceValue", c_void_p),
-      ("CoerceValues", c_void_p),
-      ("Execute", idc_execute),
-      ("ExecuteCommandFile", c_void_p),
-      ("GetNumberBreakpoints", c_void_p),
-      ("GetBreakpointByIndex", c_void_p),
-      ("GetBreakpointById", c_void_p),
-      ("GetBreakpointParameters", c_void_p),
-      ("AddBreakpoint", c_void_p),
-      ("RemoveBreakpoint", c_void_p),
-      ("AddExtension", c_void_p),
-      ("RemoveExtension", c_void_p),
-      ("GetExtensionByPath", c_void_p),
-      ("CallExtension", c_void_p),
-      ("GetExtensionFunction", c_void_p),
-      ("GetWindbgExtensionApis32", c_void_p),
-      ("GetWindbgExtensionApis64", c_void_p),
-      ("GetNumberEventFilters", idc_getnumbereventfilters),
-      ("GetEventFilterText", c_void_p),
-      ("GetEventFilterCommand", c_void_p),
-      ("SetEventFilterCommand", c_void_p),
-      ("GetSpecificFilterParameters", c_void_p),
-      ("SetSpecificFilterParameters", c_void_p),
-      ("GetSpecificFilterArgument", c_void_p),
-      ("SetSpecificFilterArgument", c_void_p),
-      ("GetExceptionFilterParameters", c_void_p),
-      ("SetExceptionFilterParameters", c_void_p),
-      ("GetExceptionFilterSecondCommand", c_void_p),
-      ("SetExceptionFilterSecondCommand", idc_setexceptionfiltersecondcommand),
-      ("WaitForEvent", idc_waitforevent),
-      ("GetLastEventInformation", c_void_p),
-      ("GetCurrentTimeDate", c_void_p),
-      ("GetCurrentSystemUpTime", c_void_p),
-      ("GetDumpFormatFlags", c_void_p),
-      ("GetNumberTextReplacements", c_void_p),
-      ("GetTextReplacement", c_void_p),
-      ("SetTextReplacement", c_void_p),
-      ("RemoveTextReplacements", c_void_p),
-      ("OutputTextReplacements", c_void_p),
-      ("GetAssemblyOptions", c_void_p),
-      ("AddAssemblyOptions", c_void_p),
-      ("RemoveAssemblyOptions", c_void_p),
-      ("SetAssemblyOptions", c_void_p),
-      ("GetExpressionSyntax", c_void_p),
-      ("SetExpressionSyntax", idc_setexpressionsyntax),
-      ("SetExpressionSyntaxByName", c_void_p),
-      ("GetNumberExpressionSyntaxes", c_void_p),
-      ("GetExpressionSyntaxNames", c_void_p),
-      ("GetNumberEvents", c_void_p),
-      ("GetEventIndexDescription", c_void_p),
-      ("GetCurrentEventIndex", c_void_p),
-      ("SetNextEventIndex", c_void_p),
-      ("GetLogFileWide", c_void_p),
-      ("OpenLogFileWide", c_void_p),
-      ("InputWide", c_void_p),
-      ("ReturnInputWide", c_void_p),
-      ("OutputWide", c_void_p),
-      ("OutputVaListWide", c_void_p),
-      ("ControlledOutputWide", c_void_p),
-      ("ControlledOutputVaListWide", c_void_p),
-      ("OutputPromptWide", c_void_p),
-      ("OutputPromptVaListWide", c_void_p),
-      ("GetPromptTextWide", c_void_p),
-      ("AssembleWide", c_void_p),
-      ("DisassembleWide", c_void_p),
-      ("GetProcessrTypeNamesWide", c_void_p),
-      ("GetTextMacroWide", c_void_p),
-      ("SetTextMacroWide", c_void_p),
-      ("EvaluateWide", c_void_p),
-      ("ExecuteWide", c_void_p),
-      ("ExecuteCommandFileWide", c_void_p),
-      ("GetBreakpointByIndex2", c_void_p),
-      ("GetBreakpointById2", c_void_p),
-      ("AddBreakpoint2", idc_addbreakpoint2),
-      ("RemoveBreakpoint2", c_void_p),
-      ("AddExtensionWide", c_void_p),
-      ("GetExtensionByPathWide", c_void_p),
-      ("CallExtensionWide", c_void_p),
-      ("GetExtensionFunctionWide", c_void_p),
-      ("GetEventFilterTextWide", c_void_p),
-      ("GetEventfilterCommandWide", c_void_p),
-      ("SetEventFilterCommandWide", c_void_p),
-      ("GetSpecificFilterArgumentWide", c_void_p),
-      ("SetSpecificFilterArgumentWide", c_void_p),
-      ("GetExceptionFilterSecondCommandWide", c_void_p),
-      ("SetExceptionFilterSecondCommandWider", c_void_p),
-      ("GetLastEventInformationWide", c_void_p),
-      ("GetTextReplacementWide", c_void_p),
-      ("SetTextReplacementWide", c_void_p),
-      ("SetExpressionSyntaxByNameWide", c_void_p),
-      ("GetExpressionSyntaxNamesWide", c_void_p),
-      ("GetEventIndexDescriptionWide", c_void_p),
-      ("GetLogFile2", c_void_p),
-      ("OpenLogFile2", c_void_p),
-      ("GetLogFile2Wide", c_void_p),
-      ("OpenLogFile2Wide", c_void_p),
-      ("GetSystemVersionValues", c_void_p),
-      ("GetSystemVersionString", c_void_p),
-      ("GetSystemVersionStringWide", c_void_p),
-      ("GetContextStackTrace", c_void_p),
-      ("OutputContextStackTrace", c_void_p),
-      ("GetStoredEventInformation", c_void_p),
-      ("GetManagedStatus", c_void_p),
-      ("GetManagedStatusWide", c_void_p),
-      ("ResetManagedStatus", c_void_p),
-      ("GetStackTraceEx", idc_getstacktraceex),
-      ("OutputStackTraceEx", c_void_p),
-      ("GetContextStackTraceEx", c_void_p),
-      ("OutputContextStackTraceEx", c_void_p),
-      ("GetBreakpointByGuid", c_void_p),
-      ("GetExecutionStatusEx", c_void_p),
-      ("GetSynchronizationStatus", c_void_p),
-      ("GetDebuggeeType2", c_void_p)
-    ]
-
-IDebugControl7._fields_ = [("lpVtbl", POINTER(IDebugControl7Vtbl))]
-
-class DebugStatus(IntEnum):
-  DEBUG_STATUS_NO_CHANGE =            0
-  DEBUG_STATUS_GO =                   1
-  DEBUG_STATUS_GO_HANDLED =           2
-  DEBUG_STATUS_GO_NOT_HANDLED =       3
-  DEBUG_STATUS_STEP_OVER =            4
-  DEBUG_STATUS_STEP_INTO =            5
-  DEBUG_STATUS_BREAK =                6
-  DEBUG_STATUS_NO_DEBUGGEE =          7
-  DEBUG_STATUS_STEP_BRANCH =          8
-  DEBUG_STATUS_IGNORE_EVENT =         9
-  DEBUG_STATUS_RESTART_REQUESTED =   10
-  DEBUG_STATUS_REVERSE_GO =          11
-  DEBUG_STATUS_REVERSE_STEP_BRANCH = 12
-  DEBUG_STATUS_REVERSE_STEP_OVER =   13
-  DEBUG_STATUS_REVERSE_STEP_INTO =   14
-  DEBUG_STATUS_OUT_OF_SYNC =         15
-  DEBUG_STATUS_WAIT_INPUT =          16
-  DEBUG_STATUS_TIMEOUT =             17
-
-class DebugSyntax(IntEnum):
-  DEBUG_EXPR_MASM = 0
-  DEBUG_EXPR_CPLUSPLUS = 1
-
-class Control(object):
-  def __init__(self, control):
-    self.ptr = control
-    self.control = control.contents
-    self.vt = self.control.lpVtbl.contents
-    # Keep a handy ulong for passing into C methods.
-    self.ulong = c_ulong()
-
-  def GetExecutionStatus(self, doprint=False):
-    ret = self.vt.GetExecutionStatus(self.control, byref(self.ulong))
-    aborter(ret, "GetExecutionStatus")
-    status = DebugStatus(self.ulong.value)
-    if doprint:
-      print("Execution status: {}".format(status))
-    return status
-
-  def SetExecutionStatus(self, status):
-    assert isinstance(status, DebugStatus)
-    res = self.vt.SetExecutionStatus(self.control, status.value)
-    aborter(res, "SetExecutionStatus")
-
-  def WaitForEvent(self, timeout=100):
-    # No flags are taken by WaitForEvent, hence 0
-    ret = self.vt.WaitForEvent(self.control, 0, timeout)
-    aborter(ret, "WaitforEvent", ignore=[S_FALSE])
-    return ret
-
-  def GetNumberEventFilters(self):
-    specific_events = c_ulong()
-    specific_exceptions = c_ulong()
-    arbitrary_exceptions = c_ulong()
-    res = self.vt.GetNumberEventFilters(self.control, byref(specific_events),
-                                    byref(specific_exceptions),
-                                    byref(arbitrary_exceptions))
-    aborter(res, "GetNumberEventFilters")
-    return (specific_events.value, specific_exceptions.value,
-            arbitrary_exceptions.value)
-
-  def SetExceptionFilterSecondCommand(self, index, command):
-    buf = create_string_buffer(command.encode('ascii'))
-    res = self.vt.SetExceptionFilterSecondCommand(self.control, index, buf)
-    aborter(res, "SetExceptionFilterSecondCommand")
-    return
-
-  def AddBreakpoint2(self, offset=None, enabled=None):
-    breakpoint = POINTER(DebugBreakpoint2)()
-    res = self.vt.AddBreakpoint2(self.control, BreakpointTypes.DEBUG_BREAKPOINT_CODE, DEBUG_ANY_ID, byref(breakpoint))
-    aborter(res, "Add breakpoint 2")
-    bp = Breakpoint(breakpoint)
-
-    if offset is not None:
-      bp.SetOffset(offset)
-    if enabled is not None and enabled:
-      bp.SetFlags(BreakpointFlags.DEBUG_BREAKPOINT_ENABLED)
-
-    return bp
-
-  def RemoveBreakpoint(self, bp):
-    res = self.vt.RemoveBreakpoint2(self.control, bp.breakpoint)
-    aborter(res, "RemoveBreakpoint2")
-    bp.die()
-
-  def GetStackTraceEx(self):
-    # XXX -- I can't find a way to query for how many stack frames there _are_
-    # in  advance. Guess 128 for now.
-    num_frames_buffer = 128
-
-    frames = (DEBUG_STACK_FRAME_EX * num_frames_buffer)()
-    numframes = c_ulong()
-
-    # First three args are frame/stack/IP offsets -- leave them as zero to
-    # default to the current instruction.
-    res = self.vt.GetStackTraceEx(self.control, 0, 0, 0, frames, num_frames_buffer, byref(numframes))
-    aborter(res, "GetStackTraceEx")
-    return frames, numframes.value
-
-  def Execute(self, command):
-    # First zero is DEBUG_OUTCTL_*, which we leave as a default, second
-    # zero is DEBUG_EXECUTE_* flags, of which we set none.
-    res = self.vt.Execute(self.control, 0, command.encode('ascii'), 0)
-    aborter(res, "Client execute")
-
-  def SetExpressionSyntax(self, cpp=True):
-    if cpp:
-      syntax = DebugSyntax.DEBUG_EXPR_CPLUSPLUS
-    else:
-      syntax = DebugSyntax.DEBUG_EXPR_MASM
-
-    res = self.vt.SetExpressionSyntax(self.control, syntax)
-    aborter(res, "SetExpressionSyntax")
-
-  def Evaluate(self, expr):
-    ptr = DEBUG_VALUE()
-    res = self.vt.Evaluate(self.control, expr.encode("ascii"), DebugValueType.DEBUG_VALUE_INVALID, byref(ptr), None)
-    aborter(res, "Evaluate", ignore=[E_INTERNALEXCEPTION, E_FAIL])
-    if res != 0:
-      return None
-
-    val_type = DebugValueType(ptr.Type)
-
-    # Here's a map from debug value types to fields. Unclear what happens
-    # with unsigned values, as DbgEng doesn't present any unsigned fields.
-
-    extract_map = {
-      DebugValueType.DEBUG_VALUE_INT8    : ("I8", "char"),
-      DebugValueType.DEBUG_VALUE_INT16   : ("I16", "short"),
-      DebugValueType.DEBUG_VALUE_INT32   : ("I32", "int"),
-      DebugValueType.DEBUG_VALUE_INT64   : ("I64", "long"),
-      DebugValueType.DEBUG_VALUE_FLOAT32 : ("F32", "float"),
-      DebugValueType.DEBUG_VALUE_FLOAT64 : ("F64", "double")
-    } # And everything else is invalid.
-
-    if val_type not in extract_map:
-      raise Exception("Unexpected debug value type {} when evalutaing".format(val_type))
-
-    # Also produce a type name...
-
-    return getattr(ptr.U, extract_map[val_type][0]), extract_map[val_type][1]
-
-  def SetEngineOptions(self, opt):
-    res = self.vt.SetEngineOptions(self.control, opt)
-    aborter(res, "SetEngineOptions")
-    return
diff --git a/dexter/dex/debugger/dbgeng/dbgeng.py b/dexter/dex/debugger/dbgeng/dbgeng.py
deleted file mode 100644
index c95aa54..0000000
--- a/dexter/dex/debugger/dbgeng/dbgeng.py
+++ /dev/null
@@ -1,179 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-
-import sys
-import os
-import platform
-
-from dex.debugger.DebuggerBase import DebuggerBase
-from dex.dextIR import FrameIR, LocIR, StepIR, StopReason, ValueIR
-from dex.dextIR import ProgramState, StackFrame, SourceLocation
-from dex.utils.Exceptions import DebuggerException, LoadDebuggerException
-from dex.utils.ReturnCode import ReturnCode
-
-if platform.system() == "Windows":
-  # Don't load on linux; _load_interface will croak before any names are used.
-  from . import setup
-  from . import probe_process
-  from . import breakpoint
-
-class DbgEng(DebuggerBase):
-    def __init__(self, context, *args):
-        self.breakpoints = []
-        self.running = False
-        self.finished = False
-        self.step_info = None
-        super(DbgEng, self).__init__(context, *args)
-
-    def _custom_init(self):
-        try:
-          res = setup.setup_everything(self.context.options.executable)
-          self.client = res
-          self.running = True
-        except Exception as e:
-          raise Exception('Failed to start debuggee: {}'.format(e))
-
-    def _custom_exit(self):
-        setup.cleanup(self.client)
-
-    def _load_interface(self):
-        arch = platform.architecture()[0]
-        machine = platform.machine()
-        if arch == '32bit' and machine == 'AMD64':
-          # This python process is 32 bits, but is sitting on a 64 bit machine.
-          # Bad things may happen, don't support it.
-          raise LoadDebuggerException('Can\'t run Dexter dbgeng on 32 bit python in a 64 bit environment')
-
-        if platform.system() != 'Windows':
-          raise LoadDebuggerException('DbgEng supports Windows only')
-
-        # Otherwise, everything was imported earlier
-
-    @classmethod
-    def get_name(cls):
-        return 'dbgeng'
-
-    @classmethod
-    def get_option_name(cls):
-        return 'dbgeng'
-
-    @property
-    def frames_below_main(self):
-        return []
-
-    @property
-    def version(self):
-        # I don't believe there's a well defined DbgEng version, outside of the
-        # version of Windows being used.
-        return "1"
-
-    def clear_breakpoints(self):
-        for x in self.breakpoints:
-            x.RemoveFlags(breakpoint.BreakpointFlags.DEBUG_BREAKPOINT_ENABLED)
-            self.client.Control.RemoveBreakpoint(x)
-
-    def _add_breakpoint(self, file_, line):
-        # Breakpoint setting/deleting is not supported by dbgeng at this moment
-        # but is something that should be considered in the future.
-        # TODO: this method is called in the DefaultController but has no effect.
-        pass
-
-    def _add_conditional_breakpoint(self, file_, line, condition):
-        # breakpoint setting/deleting is not supported by dbgeng at this moment
-        # but is something that should be considered in the future.
-        raise NotImplementedError('add_conditional_breakpoint is not yet implemented by dbgeng')
-
-    def get_triggered_breakpoint_ids(self):
-      raise NotImplementedError('get_triggered_breakpoint_ids is not yet implemented by dbgeng')
-
-    def delete_breakpoint(self, id):
-        # breakpoint setting/deleting is not supported by dbgeng at this moment
-        # but is something that should be considered in the future.
-        raise NotImplementedError('delete_conditional_breakpoint is not yet implemented by dbgeng')
-
-    def launch(self):
-        # We are, by this point, already launched.
-        self.step_info = probe_process.probe_state(self.client)
-
-    def step(self):
-        res = setup.step_once(self.client)
-        if not res:
-          self.finished = True
-        self.step_info = res
-
-    def go(self):
-        # FIXME: running freely doesn't seem to reliably stop when back in a
-        # relevant source file -- this is likely to be a problem when setting
-        # breakpoints. Until that's fixed, single step instead of running
-        # freely. This isn't very efficient, but at least makes progress.
-        self.step()
-
-    def _get_step_info(self, watches, step_index):
-        frames = self.step_info
-        state_frames = []
-
-        # For now assume the base function is the... function, ignoring
-        # inlining.
-        dex_frames = []
-        for i, x in enumerate(frames):
-          # XXX Might be able to get columns out through
-          # GetSourceEntriesByOffset, not a priority now
-          loc = LocIR(path=x.source_file, lineno=x.line_no, column=0)
-          new_frame = FrameIR(function=x.function_name, is_inlined=False, loc=loc)
-          dex_frames.append(new_frame)
-
-          state_frame = StackFrame(function=new_frame.function,
-                                   is_inlined=new_frame.is_inlined,
-                                   location=SourceLocation(path=x.source_file,
-                                                           lineno=x.line_no,
-                                                           column=0),
-                                   watches={})
-          for expr in map(
-              lambda watch, idx=i: self.evaluate_expression(watch, idx),
-              watches):
-              state_frame.watches[expr.expression] = expr
-          state_frames.append(state_frame)
-
-        return StepIR(
-            step_index=step_index, frames=dex_frames,
-            stop_reason=StopReason.STEP,
-            program_state=ProgramState(state_frames))
-
-    @property
-    def is_running(self):
-        return False # We're never free-running
-
-    @property
-    def is_finished(self):
-        return self.finished
-
-    def evaluate_expression(self, expression, frame_idx=0):
-        # XXX: cdb insists on using '->' to examine fields of structures,
-        # as it appears to reserve '.' for other purposes.
-        fixed_expr = expression.replace('.', '->')
-
-        orig_scope_idx = self.client.Symbols.GetCurrentScopeFrameIndex()
-        self.client.Symbols.SetScopeFrameByIndex(frame_idx)
-
-        res = self.client.Control.Evaluate(fixed_expr)
-        if res is not None:
-          result, typename = self.client.Control.Evaluate(fixed_expr)
-          could_eval = True
-        else:
-          result, typename = (None, None)
-          could_eval = False
-
-        self.client.Symbols.SetScopeFrameByIndex(orig_scope_idx)
-
-        return ValueIR(
-            expression=expression,
-            value=str(result),
-            type_name=typename,
-            error_string="",
-            could_evaluate=could_eval,
-            is_optimized_away=False,
-            is_irretrievable=not could_eval)
diff --git a/dexter/dex/debugger/dbgeng/probe_process.py b/dexter/dex/debugger/dbgeng/probe_process.py
deleted file mode 100644
index 8bd7f60..0000000
--- a/dexter/dex/debugger/dbgeng/probe_process.py
+++ /dev/null
@@ -1,80 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-
-import os
-
-from .utils import *
-
-class Frame(object):
-  def __init__(self, frame, idx, Symbols):
-    # Store some base information about the frame
-    self.ip = frame.InstructionOffset
-    self.scope_idx = idx
-    self.virtual = frame.Virtual
-    self.inline_frame_context = frame.InlineFrameContext
-    self.func_tbl_entry = frame.FuncTableEntry
-
-    # Fetch the module/symbol we're in, with displacement. Useful for debugging.
-    self.descr = Symbols.GetNearNameByOffset(self.ip)
-    split = self.descr.split('!')[0]
-    self.module = split[0]
-    self.symbol = split[1]
-
-    # Fetch symbol group for this scope.
-    prevscope = Symbols.GetCurrentScopeFrameIndex()
-    if Symbols.SetScopeFrameByIndex(idx):
-      symgroup = Symbols.GetScopeSymbolGroup2()
-      Symbols.SetScopeFrameByIndex(prevscope)
-      self.symgroup = symgroup
-    else:
-      self.symgroup = None
-
-    # Fetch the name according to the line-table, using inlining context.
-    name = Symbols.GetNameByInlineContext(self.ip, self.inline_frame_context)
-    self.function_name = name.split('!')[-1]
-
-    try:
-      tup = Symbols.GetLineByInlineContext(self.ip, self.inline_frame_context)
-      self.source_file, self.line_no = tup
-    except WinError as e:
-      # Fall back to trying to use a non-inlining-aware line number
-      # XXX - this is not inlining aware
-      sym = Symbols.GetLineByOffset(self.ip)
-      if sym is not None:
-        self.source_file, self.line_no = sym
-      else:
-        self.source_file = None
-        self.line_no = None
-        self.basename = None
-
-    if self.source_file is not None:
-      self.basename = os.path.basename(self.source_file)
-    else:
-      self.basename = None
-
-
-
-  def __str__(self):
-    return '{}:{}({}) {}'.format(self.basename, self.line, self.descr, self.function_name)
-
-def main_on_stack(Symbols, frames):
-  module_name = Symbols.get_exefile_module_name()
-  main_name = "{}!main".format(module_name)
-  for x in frames:
-    if main_name in x.descr: # Could be less hard coded...
-      return True
-  return False
-
-def probe_state(Client):
-  # Fetch the state of the program -- represented by the stack frames.
-  frames, numframes = Client.Control.GetStackTraceEx()
-
-  the_frames = [Frame(frames[x], x, Client.Symbols) for x in range(numframes)]
-  if not main_on_stack(Client.Symbols, the_frames):
-    return None
-
-  return the_frames
diff --git a/dexter/dex/debugger/dbgeng/setup.py b/dexter/dex/debugger/dbgeng/setup.py
deleted file mode 100644
index 26360f6..0000000
--- a/dexter/dex/debugger/dbgeng/setup.py
+++ /dev/null
@@ -1,145 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-
-from ctypes import *
-
-from . import client
-from . import control
-from . import symbols
-from .probe_process import probe_state
-from .utils import *
-
-class STARTUPINFOA(Structure):
-  _fields_ = [
-      ('cb', c_ulong),
-      ('lpReserved', c_char_p),
-      ('lpDesktop', c_char_p),
-      ('lpTitle', c_char_p),
-      ('dwX', c_ulong),
-      ('dwY', c_ulong),
-      ('dwXSize', c_ulong),
-      ('dwYSize', c_ulong),
-      ('dwXCountChars', c_ulong),
-      ('dwYCountChars', c_ulong),
-      ('dwFillAttribute', c_ulong),
-      ('wShowWindow', c_ushort),
-      ('cbReserved2', c_ushort),
-      ('lpReserved2', c_char_p),
-      ('hStdInput', c_void_p),
-      ('hStdOutput', c_void_p),
-      ('hStdError', c_void_p)
-    ]
-
-class PROCESS_INFORMATION(Structure):
-  _fields_ = [
-      ('hProcess', c_void_p),
-      ('hThread', c_void_p),
-      ('dwProcessId', c_ulong),
-      ('dwThreadId', c_ulong)
-    ]
-
-def fetch_local_function_syms(Symbols, prefix):
-  syms = Symbols.get_all_functions()
-
-  def is_sym_in_src_dir(sym):
-    name, data = sym
-    symdata = Symbols.GetLineByOffset(data.Offset)
-    if symdata is not None:
-      srcfile, line = symdata
-      if prefix in srcfile:
-        return True
-    return False
-   
-  syms = [x for x in syms if is_sym_in_src_dir(x)]
-  return syms
-
-def break_on_all_but_main(Control, Symbols, main_offset):
-  mainfile, _ = Symbols.GetLineByOffset(main_offset)
-  prefix = '\\'.join(mainfile.split('\\')[:-1])
-
-  for name, rec in fetch_local_function_syms(Symbols, prefix):
-    if name == "main":
-      continue
-    bp = Control.AddBreakpoint2(offset=rec.Offset, enabled=True)
-
-  # All breakpoints are currently discarded: we just sys.exit for cleanup
-  return
-
-def setup_everything(binfile):
-  from . import client
-  from . import symbols
-  Client = client.Client()
-
-  Client.Control.SetEngineOptions(0x20) # DEBUG_ENGOPT_INITIAL_BREAK
-
-  Client.CreateProcessAndAttach2(binfile)
-
-  # Load lines as well as general symbols
-  sym_opts = Client.Symbols.GetSymbolOptions()
-  sym_opts |= symbols.SymbolOptionFlags.SYMOPT_LOAD_LINES
-  Client.Symbols.SetSymbolOptions(sym_opts)
-
-  # Need to enter the debugger engine to let it attach properly.
-  res = Client.Control.WaitForEvent(timeout=1000)
-  if res == S_FALSE:
-    # The debugee apparently didn't do anything at all. Rather than risk
-    # hanging, bail out at this point.
-    client.TerminateProcesses()
-    raise Exception("Debuggee did not start in a timely manner")
-
-  # Enable line stepping.
-  Client.Control.Execute("l+t")
-  # Enable C++ expression interpretation.
-  Client.Control.SetExpressionSyntax(cpp=True)
-
-  # We've requested to break into the process at the earliest opportunity,
-  # and WaitForEvent'ing means we should have reached that break state.
-  # Now set a breakpoint on the main symbol, and "go" until we reach it.
-  module_name = Client.Symbols.get_exefile_module_name()
-  offset = Client.Symbols.GetOffsetByName("{}!main".format(module_name))
-  breakpoint = Client.Control.AddBreakpoint2(offset=offset, enabled=True)
-  Client.Control.SetExecutionStatus(control.DebugStatus.DEBUG_STATUS_GO)
-
-  # Problem: there is no guarantee that the client will ever reach main,
-  # something else exciting could happen in that time, the host system may
-  # be very loaded, and similar. Wait for some period, say, five seconds, and
-  # abort afterwards: this is a trade-off between spurious timeouts and
-  # completely hanging in the case of a environmental/programming error.
-  res = Client.Control.WaitForEvent(timeout=5000)
-  if res == S_FALSE:
-    client.TerminateProcesses()
-    raise Exception("Debuggee did not reach main function in a timely manner")
-
-  break_on_all_but_main(Client.Control, Client.Symbols, offset)
-
-  # Set the default action on all exceptions to be "quit and detach". If we
-  # don't, dbgeng will merrily spin at the exception site forever.
-  filts = Client.Control.GetNumberEventFilters()
-  for x in range(filts[0], filts[0] + filts[1]):
-    Client.Control.SetExceptionFilterSecondCommand(x, "qd")
-
-  return Client
-
-def step_once(client):
-  client.Control.Execute("p")
-  try:
-    client.Control.WaitForEvent()
-  except Exception as e:
-    if client.Control.GetExecutionStatus() == control.DebugStatus.DEBUG_STATUS_NO_DEBUGGEE:
-      return None # Debuggee has gone away, likely due to an exception.
-    raise e
-  # Could assert here that we're in the "break" state
-  client.Control.GetExecutionStatus()
-  return probe_state(client)
-
-def main_loop(client):
-  res = True
-  while res is not None:
-    res = step_once(client)
-
-def cleanup(client):
-  client.TerminateProcesses()
diff --git a/dexter/dex/debugger/dbgeng/symbols.py b/dexter/dex/debugger/dbgeng/symbols.py
deleted file mode 100644
index bc998fa..0000000
--- a/dexter/dex/debugger/dbgeng/symbols.py
+++ /dev/null
@@ -1,499 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-
-from collections import namedtuple
-from ctypes import *
-from enum import *
-from functools import reduce, partial
-
-from .symgroup import SymbolGroup, IDebugSymbolGroup2
-from .utils import *
-
-class SymbolOptionFlags(IntFlag):
-  SYMOPT_CASE_INSENSITIVE          = 0x00000001
-  SYMOPT_UNDNAME                   = 0x00000002
-  SYMOPT_DEFERRED_LOADS            = 0x00000004
-  SYMOPT_NO_CPP                    = 0x00000008
-  SYMOPT_LOAD_LINES                = 0x00000010
-  SYMOPT_OMAP_FIND_NEAREST         = 0x00000020
-  SYMOPT_LOAD_ANYTHING             = 0x00000040
-  SYMOPT_IGNORE_CVREC              = 0x00000080
-  SYMOPT_NO_UNQUALIFIED_LOADS      = 0x00000100
-  SYMOPT_FAIL_CRITICAL_ERRORS      = 0x00000200
-  SYMOPT_EXACT_SYMBOLS             = 0x00000400
-  SYMOPT_ALLOW_ABSOLUTE_SYMBOLS    = 0x00000800
-  SYMOPT_IGNORE_NT_SYMPATH         = 0x00001000
-  SYMOPT_INCLUDE_32BIT_MODULES     = 0x00002000
-  SYMOPT_PUBLICS_ONLY              = 0x00004000
-  SYMOPT_NO_PUBLICS                = 0x00008000
-  SYMOPT_AUTO_PUBLICS              = 0x00010000
-  SYMOPT_NO_IMAGE_SEARCH           = 0x00020000
-  SYMOPT_SECURE                    = 0x00040000
-  SYMOPT_NO_PROMPTS                = 0x00080000
-  SYMOPT_DEBUG                     = 0x80000000
-
-class ScopeGroupFlags(IntFlag):
-  DEBUG_SCOPE_GROUP_ARGUMENTS    = 0x00000001
-  DEBUG_SCOPE_GROUP_LOCALS       = 0x00000002
-  DEBUG_SCOPE_GROUP_ALL          = 0x00000003
-  DEBUG_SCOPE_GROUP_BY_DATAMODEL = 0x00000004
-
-class DebugModuleNames(IntEnum):
-  DEBUG_MODNAME_IMAGE        = 0x00000000
-  DEBUG_MODNAME_MODULE       = 0x00000001
-  DEBUG_MODNAME_LOADED_IMAGE = 0x00000002
-  DEBUG_MODNAME_SYMBOL_FILE  = 0x00000003
-  DEBUG_MODNAME_MAPPED_IMAGE = 0x00000004
-
-class DebugModuleFlags(IntFlag):
-  DEBUG_MODULE_LOADED            = 0x00000000
-  DEBUG_MODULE_UNLOADED          = 0x00000001
-  DEBUG_MODULE_USER_MODE         = 0x00000002
-  DEBUG_MODULE_EXE_MODULE        = 0x00000004
-  DEBUG_MODULE_EXPLICIT          = 0x00000008
-  DEBUG_MODULE_SECONDARY         = 0x00000010
-  DEBUG_MODULE_SYNTHETIC         = 0x00000020
-  DEBUG_MODULE_SYM_BAD_CHECKSUM  = 0x00010000
-
-class DEBUG_MODULE_PARAMETERS(Structure):
-  _fields_ = [
-      ("Base", c_ulonglong),
-      ("Size", c_ulong),
-      ("TimeDateStamp", c_ulong),
-      ("Checksum", c_ulong),
-      ("Flags", c_ulong),
-      ("SymbolType", c_ulong),
-      ("ImageNameSize", c_ulong),
-      ("ModuleNameSize", c_ulong),
-      ("LoadedImageNameSize", c_ulong),
-      ("SymbolFileNameSize", c_ulong),
-      ("MappedImageNameSize", c_ulong),
-      ("Reserved", c_ulonglong * 2)
-    ]
-PDEBUG_MODULE_PARAMETERS = POINTER(DEBUG_MODULE_PARAMETERS)
-
-class DEBUG_MODULE_AND_ID(Structure):
-  _fields_ = [
-      ("ModuleBase", c_ulonglong),
-      ("Id", c_ulonglong)
-    ]
-PDEBUG_MODULE_AND_ID = POINTER(DEBUG_MODULE_AND_ID)
-
-class DEBUG_SYMBOL_ENTRY(Structure):
-  _fields_ = [
-      ("ModuleBase", c_ulonglong),
-      ("Offset", c_ulonglong),
-      ("Id", c_ulonglong),
-      ("Arg64", c_ulonglong),
-      ("Size", c_ulong),
-      ("Flags", c_ulong),
-      ("TypeId", c_ulong),
-      ("NameSize", c_ulong),
-      ("Token", c_ulong),
-      ("Tag", c_ulong),
-      ("Arg32", c_ulong),
-      ("Reserved", c_ulong)
-    ]
-PDEBUG_SYMBOL_ENTRY = POINTER(DEBUG_SYMBOL_ENTRY)
-
-# UUID for DebugSymbols5 interface.
-DebugSymbols5IID = IID(0xc65fa83e, 0x1e69, 0x475e, IID_Data4_Type(0x8e, 0x0e, 0xb5, 0xd7, 0x9e, 0x9c, 0xc1, 0x7e))
-
-class IDebugSymbols5(Structure):
-  pass
-
-class IDebugSymbols5Vtbl(Structure):
-  wrp = partial(WINFUNCTYPE, c_long, POINTER(IDebugSymbols5))
-  ids_getsymboloptions = wrp(c_ulong_p)
-  ids_setsymboloptions = wrp(c_ulong)
-  ids_getmoduleparameters = wrp(c_ulong, c_ulong64_p, c_ulong, PDEBUG_MODULE_PARAMETERS)
-  ids_getmodulenamestring = wrp(c_ulong, c_ulong, c_ulonglong, c_char_p, c_ulong, c_ulong_p)
-  ids_getoffsetbyname = wrp(c_char_p, c_ulong64_p)
-  ids_getlinebyoffset = wrp(c_ulonglong, c_ulong_p, c_char_p, c_ulong, c_ulong_p, c_ulong64_p)
-  ids_getsymbolentriesbyname = wrp(c_char_p, c_ulong, PDEBUG_MODULE_AND_ID, c_ulong, c_ulong_p)
-  ids_getsymbolentrystring = wrp(PDEBUG_MODULE_AND_ID, c_ulong, c_char_p, c_ulong, c_ulong_p)
-  ids_getsymbolentryinformation = wrp(PDEBUG_MODULE_AND_ID, PDEBUG_SYMBOL_ENTRY)
-  ids_getcurrentscopeframeindex = wrp(c_ulong_p)
-  ids_getnearnamebyoffset = wrp(c_ulonglong, c_long, c_char_p, c_ulong, c_ulong_p, c_ulong64_p)
-  ids_setscopeframebyindex = wrp(c_ulong)
-  ids_getscopesymbolgroup2 = wrp(c_ulong, POINTER(IDebugSymbolGroup2), POINTER(POINTER(IDebugSymbolGroup2)))
-  ids_getnamebyinlinecontext = wrp(c_ulonglong, c_ulong, c_char_p, c_ulong, c_ulong_p, c_ulong64_p)
-  ids_getlinebyinlinecontext = wrp(c_ulonglong, c_ulong, c_ulong_p, c_char_p, c_ulong, c_ulong_p, c_ulong64_p)
-  _fields_ = [
-      ("QueryInterface", c_void_p),
-      ("AddRef", c_void_p),
-      ("Release", c_void_p),
-      ("GetSymbolOptions", ids_getsymboloptions),
-      ("AddSymbolOptions", c_void_p),
-      ("RemoveSymbolOptions", c_void_p),
-      ("SetSymbolOptions", ids_setsymboloptions),
-      ("GetNameByOffset", c_void_p),
-      ("GetOffsetByName", ids_getoffsetbyname),
-      ("GetNearNameByOffset", ids_getnearnamebyoffset),
-      ("GetLineByOffset", ids_getlinebyoffset),
-      ("GetOffsetByLine", c_void_p),
-      ("GetNumberModules", c_void_p),
-      ("GetModuleByIndex", c_void_p),
-      ("GetModuleByModuleName", c_void_p),
-      ("GetModuleByOffset", c_void_p),
-      ("GetModuleNames", c_void_p),
-      ("GetModuleParameters", ids_getmoduleparameters),
-      ("GetSymbolModule", c_void_p),
-      ("GetTypeName", c_void_p),
-      ("GetTypeId", c_void_p),
-      ("GetTypeSize", c_void_p),
-      ("GetFieldOffset", c_void_p),
-      ("GetSymbolTypeId", c_void_p),
-      ("GetOffsetTypeId", c_void_p),
-      ("ReadTypedDataVirtual", c_void_p),
-      ("WriteTypedDataVirtual", c_void_p),
-      ("OutputTypedDataVirtual", c_void_p),
-      ("ReadTypedDataPhysical", c_void_p),
-      ("WriteTypedDataPhysical", c_void_p),
-      ("OutputTypedDataPhysical", c_void_p),
-      ("GetScope", c_void_p),
-      ("SetScope", c_void_p),
-      ("ResetScope", c_void_p),
-      ("GetScopeSymbolGroup", c_void_p),
-      ("CreateSymbolGroup", c_void_p),
-      ("StartSymbolMatch", c_void_p),
-      ("GetNextSymbolMatch", c_void_p),
-      ("EndSymbolMatch", c_void_p),
-      ("Reload", c_void_p),
-      ("GetSymbolPath", c_void_p),
-      ("SetSymbolPath", c_void_p),
-      ("AppendSymbolPath", c_void_p),
-      ("GetImagePath", c_void_p),
-      ("SetImagePath", c_void_p),
-      ("AppendImagePath", c_void_p),
-      ("GetSourcePath", c_void_p),
-      ("GetSourcePathElement", c_void_p),
-      ("SetSourcePath", c_void_p),
-      ("AppendSourcePath", c_void_p),
-      ("FindSourceFile", c_void_p),
-      ("GetSourceFileLineOffsets", c_void_p),
-      ("GetModuleVersionInformation", c_void_p),
-      ("GetModuleNameString", ids_getmodulenamestring),
-      ("GetConstantName", c_void_p),
-      ("GetFieldName", c_void_p),
-      ("GetTypeOptions", c_void_p),
-      ("AddTypeOptions", c_void_p),
-      ("RemoveTypeOptions", c_void_p),
-      ("SetTypeOptions", c_void_p),
-      ("GetNameByOffsetWide", c_void_p),
-      ("GetOffsetByNameWide", c_void_p),
-      ("GetNearNameByOffsetWide", c_void_p),
-      ("GetLineByOffsetWide", c_void_p),
-      ("GetOffsetByLineWide", c_void_p),
-      ("GetModuleByModuleNameWide", c_void_p),
-      ("GetSymbolModuleWide", c_void_p),
-      ("GetTypeNameWide", c_void_p),
-      ("GetTypeIdWide", c_void_p),
-      ("GetFieldOffsetWide", c_void_p),
-      ("GetSymbolTypeIdWide", c_void_p),
-      ("GetScopeSymbolGroup2", ids_getscopesymbolgroup2),
-      ("CreateSymbolGroup2", c_void_p),
-      ("StartSymbolMatchWide", c_void_p),
-      ("GetNextSymbolMatchWide", c_void_p),
-      ("ReloadWide", c_void_p),
-      ("GetSymbolPathWide", c_void_p),
-      ("SetSymbolPathWide", c_void_p),
-      ("AppendSymbolPathWide", c_void_p),
-      ("GetImagePathWide", c_void_p),
-      ("SetImagePathWide", c_void_p),
-      ("AppendImagePathWide", c_void_p),
-      ("GetSourcePathWide", c_void_p),
-      ("GetSourcePathElementWide", c_void_p),
-      ("SetSourcePathWide", c_void_p),
-      ("AppendSourcePathWide", c_void_p),
-      ("FindSourceFileWide", c_void_p),
-      ("GetSourceFileLineOffsetsWide", c_void_p),
-      ("GetModuleVersionInformationWide", c_void_p),
-      ("GetModuleNameStringWide", c_void_p),
-      ("GetConstantNameWide", c_void_p),
-      ("GetFieldNameWide", c_void_p),
-      ("IsManagedModule", c_void_p),
-      ("GetModuleByModuleName2", c_void_p),
-      ("GetModuleByModuleName2Wide", c_void_p),
-      ("GetModuleByOffset2", c_void_p),
-      ("AddSyntheticModule", c_void_p),
-      ("AddSyntheticModuleWide", c_void_p),
-      ("RemoveSyntheticModule", c_void_p),
-      ("GetCurrentScopeFrameIndex", ids_getcurrentscopeframeindex),
-      ("SetScopeFrameByIndex", ids_setscopeframebyindex),
-      ("SetScopeFromJitDebugInfo", c_void_p),
-      ("SetScopeFromStoredEvent", c_void_p),
-      ("OutputSymbolByOffset", c_void_p),
-      ("GetFunctionEntryByOffset", c_void_p),
-      ("GetFieldTypeAndOffset", c_void_p),
-      ("GetFieldTypeAndOffsetWide", c_void_p),
-      ("AddSyntheticSymbol", c_void_p),
-      ("AddSyntheticSymbolWide", c_void_p),
-      ("RemoveSyntheticSymbol", c_void_p),
-      ("GetSymbolEntriesByOffset", c_void_p),
-      ("GetSymbolEntriesByName", ids_getsymbolentriesbyname),
-      ("GetSymbolEntriesByNameWide", c_void_p),
-      ("GetSymbolEntryByToken", c_void_p),
-      ("GetSymbolEntryInformation", ids_getsymbolentryinformation),
-      ("GetSymbolEntryString", ids_getsymbolentrystring),
-      ("GetSymbolEntryStringWide", c_void_p),
-      ("GetSymbolEntryOffsetRegions", c_void_p),
-      ("GetSymbolEntryBySymbolEntry", c_void_p),
-      ("GetSourceEntriesByOffset", c_void_p),
-      ("GetSourceEntriesByLine", c_void_p),
-      ("GetSourceEntriesByLineWide", c_void_p),
-      ("GetSourceEntryString", c_void_p),
-      ("GetSourceEntryStringWide", c_void_p),
-      ("GetSourceEntryOffsetRegions", c_void_p),
-      ("GetsourceEntryBySourceEntry", c_void_p),
-      ("GetScopeEx", c_void_p),
-      ("SetScopeEx", c_void_p),
-      ("GetNameByInlineContext", ids_getnamebyinlinecontext),
-      ("GetNameByInlineContextWide", c_void_p),
-      ("GetLineByInlineContext", ids_getlinebyinlinecontext),
-      ("GetLineByInlineContextWide", c_void_p),
-      ("OutputSymbolByInlineContext", c_void_p),
-      ("GetCurrentScopeFrameIndexEx", c_void_p),
-      ("SetScopeFrameByIndexEx", c_void_p)
-    ]
-
-IDebugSymbols5._fields_ = [("lpVtbl", POINTER(IDebugSymbols5Vtbl))]
-
-SymbolId = namedtuple("SymbolId", ["ModuleBase", "Id"])
-SymbolEntry = namedtuple("SymbolEntry", ["ModuleBase", "Offset", "Id", "Arg64", "Size", "Flags", "TypeId", "NameSize", "Token", "Tag", "Arg32"])
-DebugModuleParams = namedtuple("DebugModuleParams", ["Base", "Size", "TimeDateStamp", "Checksum", "Flags", "SymbolType", "ImageNameSize", "ModuleNameSize", "LoadedImageNameSize", "SymbolFileNameSize", "MappedImageNameSize"])
-
-class SymTags(IntEnum):
-  Null = 0
-  Exe = 1
-  SymTagFunction = 5
-
-def make_debug_module_params(cdata):
-  fieldvalues = map(lambda y: getattr(cdata, y), DebugModuleParams._fields)
-  return DebugModuleParams(*fieldvalues)
-
-class Symbols(object):
-  def __init__(self, symbols):
-    self.ptr = symbols
-    self.symbols = symbols.contents
-    self.vt = self.symbols.lpVtbl.contents
-    # Keep some handy ulongs for passing into C methods.
-    self.ulong = c_ulong()
-    self.ulong64 = c_ulonglong()
-
-  def GetCurrentScopeFrameIndex(self):
-    res = self.vt.GetCurrentScopeFrameIndex(self.symbols, byref(self.ulong))
-    aborter(res, "GetCurrentScopeFrameIndex")
-    return self.ulong.value
-
-  def SetScopeFrameByIndex(self, idx):
-    res = self.vt.SetScopeFrameByIndex(self.symbols, idx)
-    aborter(res, "SetScopeFrameByIndex", ignore=[E_EINVAL])
-    return res != E_EINVAL
-
-  def GetOffsetByName(self, name):
-    res = self.vt.GetOffsetByName(self.symbols, name.encode("ascii"), byref(self.ulong64))
-    aborter(res, "GetOffsetByName {}".format(name))
-    return self.ulong64.value
-
-  def GetNearNameByOffset(self, addr):
-    ptr = create_string_buffer(256)
-    pulong = c_ulong()
-    disp = c_ulonglong()
-    # Zero arg -> "delta" indicating how many symbols to skip
-    res = self.vt.GetNearNameByOffset(self.symbols, addr, 0, ptr, 255, byref(pulong), byref(disp))
-    if res == E_NOINTERFACE:
-      return "{noname}"
-    aborter(res, "GetNearNameByOffset")
-    ptr[255] = '\0'.encode("ascii")
-    return '{}+{}'.format(string_at(ptr).decode("ascii"), disp.value)
-
-  def GetModuleByModuleName2(self, name):
-    # First zero arg -> module index to search from, second zero arg ->
-    # DEBUG_GETMOD_* flags, none of which we use.
-    res = self.vt.GetModuleByModuleName2(self.symbols, name, 0, 0, None, byref(self.ulong64))
-    aborter(res, "GetModuleByModuleName2")
-    return self.ulong64.value
-
-  def GetScopeSymbolGroup2(self):
-    retptr = POINTER(IDebugSymbolGroup2)()
-    res = self.vt.GetScopeSymbolGroup2(self.symbols, ScopeGroupFlags.DEBUG_SCOPE_GROUP_ALL, None, retptr)
-    aborter(res, "GetScopeSymbolGroup2")
-    return SymbolGroup(retptr)
-
-  def GetSymbolEntryString(self, idx, module):
-    symid = DEBUG_MODULE_AND_ID()
-    symid.ModuleBase = module
-    symid.Id = idx
-    ptr = create_string_buffer(1024)
-    # Zero arg is the string index -- symbols can have multiple names, for now
-    # only support the first one.
-    res = self.vt.GetSymbolEntryString(self.symbols, symid, 0, ptr, 1023, byref(self.ulong))
-    aborter(res, "GetSymbolEntryString")
-    return string_at(ptr).decode("ascii")
-
-  def GetSymbolEntryInformation(self, module, theid):
-    symid = DEBUG_MODULE_AND_ID()
-    symentry = DEBUG_SYMBOL_ENTRY()
-    symid.ModuleBase = module
-    symid.Id = theid
-    res = self.vt.GetSymbolEntryInformation(self.symbols, symid, symentry)
-    aborter(res, "GetSymbolEntryInformation")
-    # Fetch fields into SymbolEntry object
-    fields = map(lambda x: getattr(symentry, x), SymbolEntry._fields)
-    return SymbolEntry(*fields)
-
-  def GetSymbolEntriesByName(self, symstr):
-    # Initial query to find number of symbol entries
-    res = self.vt.GetSymbolEntriesByName(self.symbols, symstr.encode("ascii"), 0, None, 0, byref(self.ulong))
-    aborter(res, "GetSymbolEntriesByName")
-
-    # Build a buffer and query for 'length' entries
-    length = self.ulong.value
-    symrecs = (DEBUG_MODULE_AND_ID * length)()
-    # Zero arg -> flags, of which there are none defined.
-    res = self.vt.GetSymbolEntriesByName(self.symbols, symstr.encode("ascii"), 0, symrecs, length, byref(self.ulong))
-    aborter(res, "GetSymbolEntriesByName")
-
-    # Extract 'length' number of SymbolIds
-    length = self.ulong.value
-    def extract(x):
-      sym = symrecs[x]
-      return SymbolId(sym.ModuleBase, sym.Id)
-    return [extract(x) for x in range(length)]
-
-  def GetSymbolPath(self):
-    # Query for length of buffer to allocate
-    res = self.vt.GetSymbolPath(self.symbols, None, 0, byref(self.ulong))
-    aborter(res, "GetSymbolPath", ignore=[S_FALSE])
-
-    # Fetch 'length' length symbol path string
-    length = self.ulong.value
-    arr = create_string_buffer(length)
-    res = self.vt.GetSymbolPath(self.symbols, arr, length, byref(self.ulong))
-    aborter(res, "GetSymbolPath")
-
-    return string_at(arr).decode("ascii")
-
-  def GetSourcePath(self):
-    # Query for length of buffer to allocate
-    res = self.vt.GetSourcePath(self.symbols, None, 0, byref(self.ulong))
-    aborter(res, "GetSourcePath", ignore=[S_FALSE])
-
-    # Fetch a string of len 'length'
-    length = self.ulong.value
-    arr = create_string_buffer(length)
-    res = self.vt.GetSourcePath(self.symbols, arr, length, byref(self.ulong))
-    aborter(res, "GetSourcePath")
-
-    return string_at(arr).decode("ascii")
-
-  def SetSourcePath(self, string):
-    res = self.vt.SetSourcePath(self.symbols, string.encode("ascii"))
-    aborter(res, "SetSourcePath")
-    return
-
-  def GetModuleParameters(self, base):
-    self.ulong64.value = base
-    params = DEBUG_MODULE_PARAMETERS()
-    # Fetch one module params struct, starting at idx zero
-    res = self.vt.GetModuleParameters(self.symbols, 1, byref(self.ulong64), 0, byref(params))
-    aborter(res, "GetModuleParameters")
-    return make_debug_module_params(params)
-
-  def GetSymbolOptions(self):
-    res = self.vt.GetSymbolOptions(self.symbols, byref(self.ulong))
-    aborter(res, "GetSymbolOptions")
-    return SymbolOptionFlags(self.ulong.value)
-
-  def SetSymbolOptions(self, opts):
-    assert isinstance(opts, SymbolOptionFlags)
-    res = self.vt.SetSymbolOptions(self.symbols, opts.value)
-    aborter(res, "SetSymbolOptions")
-    return
-
-  def GetLineByOffset(self, offs):
-    # Initial query for filename buffer size
-    res = self.vt.GetLineByOffset(self.symbols, offs, None, None, 0, byref(self.ulong), None)
-    if res == E_FAIL:
-      return None # Sometimes we just can't get line numbers, of course
-    aborter(res, "GetLineByOffset", ignore=[S_FALSE])
-
-    # Allocate filename buffer and query for line number too
-    filenamelen = self.ulong.value
-    text = create_string_buffer(filenamelen)
-    line = c_ulong()
-    res = self.vt.GetLineByOffset(self.symbols, offs, byref(line), text, filenamelen, byref(self.ulong), None)
-    aborter(res, "GetLineByOffset")
-
-    return string_at(text).decode("ascii"), line.value
-
-  def GetModuleNameString(self, whichname, base):
-    # Initial query for name string length
-    res = self.vt.GetModuleNameString(self.symbols, whichname, DEBUG_ANY_ID, base, None, 0, byref(self.ulong))
-    aborter(res, "GetModuleNameString", ignore=[S_FALSE])
-
-    module_name_len = self.ulong.value
-    module_name = (c_char * module_name_len)()
-    res = self.vt.GetModuleNameString(self.symbols, whichname, DEBUG_ANY_ID, base, module_name, module_name_len, None)
-    aborter(res, "GetModuleNameString")
-
-    return string_at(module_name).decode("ascii")
-
-  def GetNameByInlineContext(self, pc, ctx):
-    # None args -> ignore output name size and displacement
-    buf = create_string_buffer(256)
-    res = self.vt.GetNameByInlineContext(self.symbols, pc, ctx, buf, 255, None, None)
-    aborter(res, "GetNameByInlineContext")
-    return string_at(buf).decode("ascii")
-
-  def GetLineByInlineContext(self, pc, ctx):
-    # None args -> ignore output filename size and displacement
-    buf = create_string_buffer(256)
-    res = self.vt.GetLineByInlineContext(self.symbols, pc, ctx, byref(self.ulong), buf, 255, None, None)
-    aborter(res, "GetLineByInlineContext")
-    return string_at(buf).decode("ascii"), self.ulong.value
-
-  def get_all_symbols(self):
-    main_module_name = self.get_exefile_module_name()
-    idnumbers = self.GetSymbolEntriesByName("{}!*".format(main_module_name))
-    lst = []
-    for symid in idnumbers:
-      s = self.GetSymbolEntryString(symid.Id, symid.ModuleBase)
-      symentry = self.GetSymbolEntryInformation(symid.ModuleBase, symid.Id)
-      lst.append((s, symentry))
-    return lst
-
-  def get_all_functions(self):
-    syms = self.get_all_symbols()
-    return [x for x in syms if x[1].Tag == SymTags.SymTagFunction]
-
-  def get_all_modules(self):
-    params = DEBUG_MODULE_PARAMETERS()
-    idx = 0
-    res = 0
-    all_modules = []
-    while res != E_EINVAL:
-      res = self.vt.GetModuleParameters(self.symbols, 1, None, idx, byref(params))
-      aborter(res, "GetModuleParameters", ignore=[E_EINVAL])
-      all_modules.append(make_debug_module_params(params))
-      idx += 1
-    return all_modules
-
-  def get_exefile_module(self):
-    all_modules = self.get_all_modules()
-    reduce_func = lambda x, y: y if y.Flags & DebugModuleFlags.DEBUG_MODULE_EXE_MODULE else x
-    main_module = reduce(reduce_func, all_modules, None)
-    if main_module is None:
-      raise Exception("Couldn't find the exefile module")
-    return main_module
-
-  def get_module_name(self, base):
-    return self.GetModuleNameString(DebugModuleNames.DEBUG_MODNAME_MODULE, base)
-
-  def get_exefile_module_name(self):
-    return self.get_module_name(self.get_exefile_module().Base)
diff --git a/dexter/dex/debugger/dbgeng/symgroup.py b/dexter/dex/debugger/dbgeng/symgroup.py
deleted file mode 100644
index 2775af3..0000000
--- a/dexter/dex/debugger/dbgeng/symgroup.py
+++ /dev/null
@@ -1,98 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-
-from collections import namedtuple
-from ctypes import *
-from functools import partial
-
-from .utils import *
-
-Symbol = namedtuple("Symbol", ["num", "name", "type", "value"])
-
-class IDebugSymbolGroup2(Structure):
-  pass
-
-class IDebugSymbolGroup2Vtbl(Structure):
-  wrp = partial(WINFUNCTYPE, c_long, POINTER(IDebugSymbolGroup2))
-  ids_getnumbersymbols = wrp(c_ulong_p)
-  ids_getsymbolname = wrp(c_ulong, c_char_p, c_ulong, c_ulong_p)
-  ids_getsymboltypename = wrp(c_ulong, c_char_p, c_ulong, c_ulong_p)
-  ids_getsymbolvaluetext = wrp(c_ulong, c_char_p, c_ulong, c_ulong_p)
-  _fields_ = [
-      ("QueryInterface", c_void_p),
-      ("AddRef", c_void_p),
-      ("Release", c_void_p),
-      ("GetNumberSymbols", ids_getnumbersymbols),
-      ("AddSymbol", c_void_p),
-      ("RemoveSymbolByName", c_void_p),
-      ("RemoveSymbolByIndex", c_void_p),
-      ("GetSymbolName", ids_getsymbolname),
-      ("GetSymbolParameters", c_void_p),
-      ("ExpandSymbol", c_void_p),
-      ("OutputSymbols", c_void_p),
-      ("WriteSymbol", c_void_p),
-      ("OutputAsType", c_void_p),
-      ("AddSymbolWide", c_void_p),
-      ("RemoveSymbolByNameWide", c_void_p),
-      ("GetSymbolNameWide", c_void_p),
-      ("WritesymbolWide", c_void_p),
-      ("OutputAsTypeWide", c_void_p),
-      ("GetSymbolTypeName", ids_getsymboltypename),
-      ("GetSymbolTypeNameWide", c_void_p),
-      ("GetSymbolSize", c_void_p),
-      ("GetSymbolOffset", c_void_p),
-      ("GetSymbolRegister", c_void_p),
-      ("GetSymbolValueText", ids_getsymbolvaluetext),
-      ("GetSymbolValueTextWide", c_void_p),
-      ("GetSymbolEntryInformation", c_void_p)
-    ]
-
-IDebugSymbolGroup2._fields_ = [("lpVtbl", POINTER(IDebugSymbolGroup2Vtbl))]
-
-class SymbolGroup(object):
-  def __init__(self, symgroup):
-    self.symgroup = symgroup.contents
-    self.vt = self.symgroup.lpVtbl.contents
-    self.ulong = c_ulong()
-
-  def GetNumberSymbols(self):
-    res = self.vt.GetNumberSymbols(self.symgroup, byref(self.ulong))
-    aborter(res, "GetNumberSymbols")
-    return self.ulong.value
-
-  def GetSymbolName(self, idx):
-    buf = create_string_buffer(256)
-    res = self.vt.GetSymbolName(self.symgroup, idx, buf, 255, byref(self.ulong))
-    aborter(res, "GetSymbolName")
-    thelen = self.ulong.value
-    return string_at(buf).decode("ascii")
-
-  def GetSymbolTypeName(self, idx):
-    buf = create_string_buffer(256)
-    res = self.vt.GetSymbolTypeName(self.symgroup, idx, buf, 255, byref(self.ulong))
-    aborter(res, "GetSymbolTypeName")
-    thelen = self.ulong.value
-    return string_at(buf).decode("ascii")
-
-  def GetSymbolValueText(self, idx, handleserror=False):
-    buf = create_string_buffer(256)
-    res = self.vt.GetSymbolValueText(self.symgroup, idx, buf, 255, byref(self.ulong))
-    if res != 0 and handleserror:
-      return None
-    aborter(res, "GetSymbolTypeName")
-    thelen = self.ulong.value
-    return string_at(buf).decode("ascii")
-
-  def get_symbol(self, idx):
-    name = self.GetSymbolName(idx)
-    thetype = self.GetSymbolTypeName(idx)
-    value = self.GetSymbolValueText(idx)
-    return Symbol(idx, name, thetype, value)
-
-  def get_all_symbols(self):
-    num_syms = self.GetNumberSymbols()
-    return list(map(self.get_symbol, list(range(num_syms))))
diff --git a/dexter/dex/debugger/dbgeng/sysobjs.py b/dexter/dex/debugger/dbgeng/sysobjs.py
deleted file mode 100644
index 0e9844a..0000000
--- a/dexter/dex/debugger/dbgeng/sysobjs.py
+++ /dev/null
@@ -1,200 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-
-from ctypes import *
-from functools import partial
-
-from .utils import *
-
-# UUID For SystemObjects4 interface.
-DebugSystemObjects4IID = IID(0x489468e6, 0x7d0f, 0x4af5, IID_Data4_Type(0x87, 0xab, 0x25, 0x20, 0x74, 0x54, 0xd5, 0x53))
-
-class IDebugSystemObjects4(Structure):
-  pass
-
-class IDebugSystemObjects4Vtbl(Structure):
-  wrp = partial(WINFUNCTYPE, c_long, POINTER(IDebugSystemObjects4))
-  ids_getnumberprocesses = wrp(POINTER(c_ulong))
-  ids_getprocessidsbyindex = wrp(c_ulong, c_ulong, c_ulong_p, c_ulong_p)
-  ids_setcurrentprocessid = wrp(c_ulong)
-  ids_getnumberthreads = wrp(c_ulong_p)
-  ids_getthreadidsbyindex = wrp(c_ulong, c_ulong, c_ulong_p, c_ulong_p)
-  ids_setcurrentthreadid = wrp(c_ulong)
-  _fields_ = [
-      ("QueryInterface", c_void_p),
-      ("AddRef", c_void_p),
-      ("Release", c_void_p),
-      ("GetEventThread", c_void_p),
-      ("GetEventProcess", c_void_p),
-      ("GetCurrentThreadId", c_void_p),
-      ("SetCurrentThreadId", ids_setcurrentthreadid),
-      ("GetCurrentProcessId", c_void_p),
-      ("SetCurrentProcessId", ids_setcurrentprocessid),
-      ("GetNumberThreads", ids_getnumberthreads),
-      ("GetTotalNumberThreads", c_void_p),
-      ("GetThreadIdsByIndex", ids_getthreadidsbyindex),
-      ("GetThreadIdByProcessor", c_void_p),
-      ("GetCurrentThreadDataOffset", c_void_p),
-      ("GetThreadIdByDataOffset", c_void_p),
-      ("GetCurrentThreadTeb", c_void_p),
-      ("GetThreadIdByTeb", c_void_p),
-      ("GetCurrentThreadSystemId", c_void_p),
-      ("GetThreadIdBySystemId", c_void_p),
-      ("GetCurrentThreadHandle", c_void_p),
-      ("GetThreadIdByHandle", c_void_p),
-      ("GetNumberProcesses", ids_getnumberprocesses),
-      ("GetProcessIdsByIndex", ids_getprocessidsbyindex),
-      ("GetCurrentProcessDataOffset", c_void_p),
-      ("GetProcessIdByDataOffset", c_void_p),
-      ("GetCurrentProcessPeb", c_void_p),
-      ("GetProcessIdByPeb", c_void_p),
-      ("GetCurrentProcessSystemId", c_void_p),
-      ("GetProcessIdBySystemId", c_void_p),
-      ("GetCurrentProcessHandle", c_void_p),
-      ("GetProcessIdByHandle", c_void_p),
-      ("GetCurrentProcessExecutableName", c_void_p),
-      ("GetCurrentProcessUpTime", c_void_p),
-      ("GetImplicitThreadDataOffset", c_void_p),
-      ("SetImplicitThreadDataOffset", c_void_p),
-      ("GetImplicitProcessDataOffset", c_void_p),
-      ("SetImplicitProcessDataOffset", c_void_p),
-      ("GetEventSystem", c_void_p),
-      ("GetCurrentSystemId", c_void_p),
-      ("SetCurrentSystemId", c_void_p),
-      ("GetNumberSystems", c_void_p),
-      ("GetSystemIdsByIndex", c_void_p),
-      ("GetTotalNumberThreadsAndProcesses", c_void_p),
-      ("GetCurrentSystemServer", c_void_p),
-      ("GetSystemByServer", c_void_p),
-      ("GetCurrentSystemServerName", c_void_p),
-      ("GetCurrentProcessExecutableNameWide", c_void_p),
-      ("GetCurrentSystemServerNameWide", c_void_p)
-    ]
-
-IDebugSystemObjects4._fields_ = [("lpVtbl", POINTER(IDebugSystemObjects4Vtbl))]
-
-class SysObjects(object):
-  def __init__(self, sysobjects):
-    self.ptr = sysobjects
-    self.sysobjects = sysobjects.contents
-    self.vt = self.sysobjects.lpVtbl.contents
-    # Keep a handy ulong for passing into C methods.
-    self.ulong = c_ulong()
-
-  def GetNumberSystems(self):
-    res = self.vt.GetNumberSystems(self.sysobjects, byref(self.ulong))
-    aborter(res, "GetNumberSystems")
-    return self.ulong.value
-
-  def GetNumberProcesses(self):
-    res = self.vt.GetNumberProcesses(self.sysobjects, byref(self.ulong))
-    aborter(res, "GetNumberProcesses")
-    return self.ulong.value
-
-  def GetNumberThreads(self):
-    res = self.vt.GetNumberThreads(self.sysobjects, byref(self.ulong))
-    aborter(res, "GetNumberThreads")
-    return self.ulong.value
-
-  def GetTotalNumberThreadsAndProcesses(self):
-    tthreads = c_ulong()
-    tprocs = c_ulong()
-    pulong3 = c_ulong()
-    res = self.vt.GetTotalNumberThreadsAndProcesses(self.sysobjects, byref(tthreads), byref(tprocs), byref(pulong3), byref(pulong3), byref(pulong3))
-    aborter(res, "GettotalNumberThreadsAndProcesses")
-    return tthreads.value, tprocs.value
-
-  def GetCurrentProcessId(self):
-    res = self.vt.GetCurrentProcessId(self.sysobjects, byref(self.ulong))
-    aborter(res, "GetCurrentProcessId")
-    return self.ulong.value
-
-  def SetCurrentProcessId(self, sysid):
-    res = self.vt.SetCurrentProcessId(self.sysobjects, sysid)
-    aborter(res, "SetCurrentProcessId")
-    return
-
-  def GetCurrentThreadId(self):
-    res = self.vt.GetCurrentThreadId(self.sysobjects, byref(self.ulong))
-    aborter(res, "GetCurrentThreadId")
-    return self.ulong.value
-
-  def SetCurrentThreadId(self, sysid):
-    res = self.vt.SetCurrentThreadId(self.sysobjects, sysid)
-    aborter(res, "SetCurrentThreadId")
-    return
-
-  def GetProcessIdsByIndex(self):
-    num_processes = self.GetNumberProcesses()
-    if num_processes == 0:
-      return []
-    engineids = (c_ulong * num_processes)()
-    pids = (c_ulong * num_processes)()
-    for x in range(num_processes):
-      engineids[x] = DEBUG_ANY_ID
-      pids[x] = DEBUG_ANY_ID
-    res = self.vt.GetProcessIdsByIndex(self.sysobjects, 0, num_processes, engineids, pids)
-    aborter(res, "GetProcessIdsByIndex")
-    return list(zip(engineids, pids))
-
-  def GetThreadIdsByIndex(self):
-    num_threads = self.GetNumberThreads()
-    if num_threads == 0:
-      return []
-    engineids = (c_ulong * num_threads)()
-    tids = (c_ulong * num_threads)()
-    for x in range(num_threads):
-      engineids[x] = DEBUG_ANY_ID
-      tids[x] = DEBUG_ANY_ID
-    # Zero -> start index
-    res = self.vt.GetThreadIdsByIndex(self.sysobjects, 0, num_threads, engineids, tids)
-    aborter(res, "GetThreadIdsByIndex")
-    return list(zip(engineids, tids))
-
-  def GetCurThreadHandle(self):
-    pulong64 = c_ulonglong()
-    res = self.vt.GetCurrentThreadHandle(self.sysobjects, byref(pulong64))
-    aborter(res, "GetCurrentThreadHandle")
-    return pulong64.value
-
-  def set_current_thread(self, pid, tid):
-    proc_sys_id = -1
-    for x in self.GetProcessIdsByIndex():
-      sysid, procid = x
-      if procid == pid:
-        proc_sys_id = sysid
-
-    if proc_sys_id == -1:
-      raise Exception("Couldn't find designated PID {}".format(pid))
-
-    self.SetCurrentProcessId(proc_sys_id)
-
-    thread_sys_id = -1
-    for x in self.GetThreadIdsByIndex():
-      sysid, threadid = x
-      if threadid == tid:
-        thread_sys_id = sysid
-
-    if thread_sys_id == -1:
-      raise Exception("Couldn't find designated TID {}".format(tid))
-
-    self.SetCurrentThreadId(thread_sys_id)
-    return
-
-  def print_current_procs_threads(self):
-    procs = []
-    for x in self.GetProcessIdsByIndex():
-      sysid, procid = x
-      procs.append(procid)
-
-    threads = []
-    for x in self.GetThreadIdsByIndex():
-      sysid, threadid = x
-      threads.append(threadid)
-
-    print("Current processes: {}".format(procs))
-    print("Current threads: {}".format(threads))
diff --git a/dexter/dex/debugger/dbgeng/utils.py b/dexter/dex/debugger/dbgeng/utils.py
deleted file mode 100644
index 0c9197a..0000000
--- a/dexter/dex/debugger/dbgeng/utils.py
+++ /dev/null
@@ -1,47 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-
-from ctypes import *
-
-# Error codes are negative when received by python, but are typically
-# represented by unsigned hex elsewhere. Subtract 2^32 from the unsigned
-# hex to produce negative error codes.
-E_NOINTERFACE = 0x80004002 - 0x100000000
-E_FAIL = 0x80004005 - 0x100000000
-E_EINVAL = 0x80070057 - 0x100000000
-E_INTERNALEXCEPTION = 0x80040205 - 0x100000000
-S_FALSE = 1
-
-# This doesn't fit into any convenient category
-DEBUG_ANY_ID = 0xFFFFFFFF
-
-class WinError(Exception):
-  def __init__(self, msg, hstatus):
-    self.hstatus = hstatus
-    super(WinError, self).__init__(msg)
-
-def aborter(res, msg, ignore=[]):
-  if res != 0 and res not in ignore:
-    # Convert a negative error code to a positive unsigned one, which is
-    # now NTSTATUSes appear in documentation.
-    if res < 0:
-      res += 0x100000000
-    msg = '{:08X} : {}'.format(res, msg)
-    raise WinError(msg, res)
-
-IID_Data4_Type = c_ubyte * 8
-
-class IID(Structure):
-  _fields_ = [
-      ("Data1", c_uint),
-      ("Data2", c_ushort),
-      ("Data3", c_ushort),
-      ("Data4", IID_Data4_Type)
-  ]
-
-c_ulong_p = POINTER(c_ulong)
-c_ulong64_p = POINTER(c_ulonglong)
diff --git a/dexter/dex/debugger/lldb/LLDB.py b/dexter/dex/debugger/lldb/LLDB.py
deleted file mode 100644
index e8e8939..0000000
--- a/dexter/dex/debugger/lldb/LLDB.py
+++ /dev/null
@@ -1,305 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-"""Interface for communicating with the LLDB debugger via its python interface.
-"""
-
-import imp
-import os
-from subprocess import CalledProcessError, check_output, STDOUT
-import sys
-
-from dex.debugger.DebuggerBase import DebuggerBase
-from dex.dextIR import FrameIR, LocIR, StepIR, StopReason, ValueIR
-from dex.dextIR import StackFrame, SourceLocation, ProgramState
-from dex.utils.Exceptions import DebuggerException, LoadDebuggerException
-from dex.utils.ReturnCode import ReturnCode
-
-
-class LLDB(DebuggerBase):
-    def __init__(self, context, *args):
-        self.lldb_executable = context.options.lldb_executable
-        self._debugger = None
-        self._target = None
-        self._process = None
-        self._thread = None
-        # Map {id (int): condition (str)} for breakpoints which have a
-        # condition. See get_triggered_breakpoint_ids usage for more info.
-        self._breakpoint_conditions = {}
-        super(LLDB, self).__init__(context, *args)
-
-    def _custom_init(self):
-        self._debugger = self._interface.SBDebugger.Create()
-        self._debugger.SetAsync(False)
-        self._target = self._debugger.CreateTargetWithFileAndArch(
-            self.context.options.executable, self.context.options.arch)
-        if not self._target:
-            raise LoadDebuggerException(
-                'could not create target for executable "{}" with arch:{}'.
-                format(self.context.options.executable,
-                       self.context.options.arch))
-
-    def _custom_exit(self):
-        if getattr(self, '_process', None):
-            self._process.Kill()
-        if getattr(self, '_debugger', None) and getattr(self, '_target', None):
-            self._debugger.DeleteTarget(self._target)
-
-    def _translate_stop_reason(self, reason):
-        if reason == self._interface.eStopReasonNone:
-            return None
-        if reason == self._interface.eStopReasonBreakpoint:
-            return StopReason.BREAKPOINT
-        if reason == self._interface.eStopReasonPlanComplete:
-            return StopReason.STEP
-        if reason == self._interface.eStopReasonThreadExiting:
-            return StopReason.PROGRAM_EXIT
-        if reason == self._interface.eStopReasonException:
-            return StopReason.ERROR
-        return StopReason.OTHER
-
-    def _load_interface(self):
-        try:
-            args = [self.lldb_executable, '-P']
-            pythonpath = check_output(
-                args, stderr=STDOUT).rstrip().decode('utf-8')
-        except CalledProcessError as e:
-            raise LoadDebuggerException(str(e), sys.exc_info())
-        except OSError as e:
-            raise LoadDebuggerException(
-                '{} ["{}"]'.format(e.strerror, self.lldb_executable),
-                sys.exc_info())
-
-        if not os.path.isdir(pythonpath):
-            raise LoadDebuggerException(
-                'path "{}" does not exist [result of {}]'.format(
-                    pythonpath, args), sys.exc_info())
-
-        try:
-            module_info = imp.find_module('lldb', [pythonpath])
-            return imp.load_module('lldb', *module_info)
-        except ImportError as e:
-            msg = str(e)
-            if msg.endswith('not a valid Win32 application.'):
-                msg = '{} [Are you mixing 32-bit and 64-bit binaries?]'.format(
-                    msg)
-            raise LoadDebuggerException(msg, sys.exc_info())
-
-    @classmethod
-    def get_name(cls):
-        return 'lldb'
-
-    @classmethod
-    def get_option_name(cls):
-        return 'lldb'
-
-    @property
-    def version(self):
-        try:
-            return self._interface.SBDebugger_GetVersionString()
-        except AttributeError:
-            return None
-
-    def clear_breakpoints(self):
-        self._target.DeleteAllBreakpoints()
-
-    def _add_breakpoint(self, file_, line):
-        return self._add_conditional_breakpoint(file_, line, None)
-
-    def _add_conditional_breakpoint(self, file_, line, condition):
-        bp = self._target.BreakpointCreateByLocation(file_, line)
-        if not bp:
-            raise DebuggerException(
-                  'could not add breakpoint [{}:{}]'.format(file_, line))
-        id = bp.GetID()
-        if condition:
-            bp.SetCondition(condition)
-            assert id not in self._breakpoint_conditions
-            self._breakpoint_conditions[id] = condition
-        return id
-
-    def _evaulate_breakpoint_condition(self, id):
-        """Evaluate the breakpoint condition and return the result.
-
-        Returns True if a conditional breakpoint with the specified id cannot
-        be found (i.e. assume it is an unconditional breakpoint).
-        """
-        try:
-            condition = self._breakpoint_conditions[id]
-        except KeyError:
-            # This must be an unconditional breakpoint.
-            return True
-        valueIR = self.evaluate_expression(condition)
-        return valueIR.type_name == 'bool' and valueIR.value == 'true'
-
-    def get_triggered_breakpoint_ids(self):
-        # Breakpoints can only have been triggered if we've hit one.
-        stop_reason = self._translate_stop_reason(self._thread.GetStopReason())
-        if stop_reason != StopReason.BREAKPOINT:
-            return []
-        breakpoint_ids = set()
-        # When the stop reason is eStopReasonBreakpoint, GetStopReasonDataCount
-        # counts all breakpoints associated with the location that lldb has
-        # stopped at, regardless of their condition. I.e. Even if we have two
-        # breakpoints at the same source location that have mutually exclusive
-        # conditions, both will be counted by GetStopReasonDataCount when
-        # either condition is true. Check each breakpoint condition manually to
-        # filter the list down to breakpoints that have caused this stop.
-        #
-        # Breakpoints have two data parts: Breakpoint ID, Location ID. We're
-        # only interested in the Breakpoint ID so we skip every other item.
-        for i in range(0, self._thread.GetStopReasonDataCount(), 2):
-            id = self._thread.GetStopReasonDataAtIndex(i)
-            if self._evaulate_breakpoint_condition(id):
-                breakpoint_ids.add(id)
-        return breakpoint_ids
-
-    def delete_breakpoint(self, id):
-        bp = self._target.FindBreakpointByID(id)
-        if not bp:
-            # The ID is not valid.
-            raise KeyError
-        try:
-            del self._breakpoint_conditions[id]
-        except KeyError:
-            # This must be an unconditional breakpoint.
-            pass
-        self._target.BreakpointDelete(id)
-
-    def launch(self):
-        self._process = self._target.LaunchSimple(None, None, os.getcwd())
-        if not self._process or self._process.GetNumThreads() == 0:
-            raise DebuggerException('could not launch process')
-        if self._process.GetNumThreads() != 1:
-            raise DebuggerException('multiple threads not supported')
-        self._thread = self._process.GetThreadAtIndex(0)
-        assert self._thread, (self._process, self._thread)
-
-    def step(self):
-        self._thread.StepInto()
-
-    def go(self) -> ReturnCode:
-        self._process.Continue()
-        return ReturnCode.OK
-
-    def _get_step_info(self, watches, step_index):
-        frames = []
-        state_frames = []
-
-        for i in range(0, self._thread.GetNumFrames()):
-            sb_frame = self._thread.GetFrameAtIndex(i)
-            sb_line = sb_frame.GetLineEntry()
-            sb_filespec = sb_line.GetFileSpec()
-
-            try:
-                path = os.path.join(sb_filespec.GetDirectory(),
-                                    sb_filespec.GetFilename())
-            except (AttributeError, TypeError):
-                path = None
-
-            function = self._sanitize_function_name(sb_frame.GetFunctionName())
-
-            loc_dict = {
-                'path': path,
-                'lineno': sb_line.GetLine(),
-                'column': sb_line.GetColumn()
-            }
-            loc = LocIR(**loc_dict)
-
-            frame = FrameIR(
-                function=function, is_inlined=sb_frame.IsInlined(), loc=loc)
-
-            if any(
-                    name in (frame.function or '')  # pylint: disable=no-member
-                    for name in self.frames_below_main):
-                break
-
-            frames.append(frame)
-
-            state_frame = StackFrame(function=frame.function,
-                                     is_inlined=frame.is_inlined,
-                                     location=SourceLocation(**loc_dict),
-                                     watches={})
-            for expr in map(
-                lambda watch, idx=i: self.evaluate_expression(watch, idx),
-                watches):
-                state_frame.watches[expr.expression] = expr
-            state_frames.append(state_frame)
-
-        if len(frames) == 1 and frames[0].function is None:
-            frames = []
-            state_frames = []
-
-        reason = self._translate_stop_reason(self._thread.GetStopReason())
-
-        return StepIR(
-            step_index=step_index, frames=frames, stop_reason=reason,
-            program_state=ProgramState(state_frames))
-
-    @property
-    def is_running(self):
-        # We're not running in async mode so this is always False.
-        return False
-
-    @property
-    def is_finished(self):
-        return not self._thread.GetFrameAtIndex(0)
-
-    @property
-    def frames_below_main(self):
-        return ['__scrt_common_main_seh', '__libc_start_main']
-
-    def evaluate_expression(self, expression, frame_idx=0) -> ValueIR:
-        result = self._thread.GetFrameAtIndex(frame_idx
-            ).EvaluateExpression(expression)
-        error_string = str(result.error)
-
-        value = result.value
-        could_evaluate = not any(s in error_string for s in [
-            "Can't run the expression locally",
-            "use of undeclared identifier",
-            "no member named",
-            "Couldn't lookup symbols",
-            "reference to local variable",
-            "invalid use of 'this' outside of a non-static member function",
-        ])
-
-        is_optimized_away = any(s in error_string for s in [
-            'value may have been optimized out',
-        ])
-
-        is_irretrievable = any(s in error_string for s in [
-            "couldn't get the value of variable",
-            "couldn't read its memory",
-            "couldn't read from memory",
-            "Cannot access memory at address",
-            "invalid address (fault address:",
-        ])
-
-        if could_evaluate and not is_irretrievable and not is_optimized_away:
-            assert error_string == 'success', (error_string, expression, value)
-            # assert result.value is not None, (result.value, expression)
-
-        if error_string == 'success':
-            error_string = None
-
-        # attempt to find expression as a variable, if found, take the variable
-        # obj's type information as it's 'usually' more accurate.
-        var_result = self._thread.GetFrameAtIndex(frame_idx).FindVariable(expression)
-        if str(var_result.error) == 'success':
-            type_name = var_result.type.GetDisplayTypeName()
-        else:
-            type_name = result.type.GetDisplayTypeName()
-
-        return ValueIR(
-            expression=expression,
-            value=value,
-            type_name=type_name,
-            error_string=error_string,
-            could_evaluate=could_evaluate,
-            is_optimized_away=is_optimized_away,
-            is_irretrievable=is_irretrievable,
-        )
diff --git a/dexter/dex/debugger/lldb/__init__.py b/dexter/dex/debugger/lldb/__init__.py
deleted file mode 100644
index 1282f2d..0000000
--- a/dexter/dex/debugger/lldb/__init__.py
+++ /dev/null
@@ -1,8 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-
-from dex.debugger.lldb.LLDB import LLDB
diff --git a/dexter/dex/debugger/visualstudio/VisualStudio.py b/dexter/dex/debugger/visualstudio/VisualStudio.py
deleted file mode 100644
index b4558e2..0000000
--- a/dexter/dex/debugger/visualstudio/VisualStudio.py
+++ /dev/null
@@ -1,329 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-"""Interface for communicating with the Visual Studio debugger via DTE."""
-
-import abc
-import imp
-import os
-import sys
-from pathlib import PurePath
-from collections import namedtuple
-from collections import defaultdict
-
-from dex.debugger.DebuggerBase import DebuggerBase
-from dex.dextIR import FrameIR, LocIR, StepIR, StopReason, ValueIR
-from dex.dextIR import StackFrame, SourceLocation, ProgramState
-from dex.utils.Exceptions import Error, LoadDebuggerException
-from dex.utils.ReturnCode import ReturnCode
-
-
-def _load_com_module():
-    try:
-        module_info = imp.find_module(
-            'ComInterface',
-            [os.path.join(os.path.dirname(__file__), 'windows')])
-        return imp.load_module('ComInterface', *module_info)
-    except ImportError as e:
-        raise LoadDebuggerException(e, sys.exc_info())
-
-
-# VSBreakpoint(path: PurePath, line: int, col: int, cond: str).  This is enough
-# info to identify breakpoint equivalence in visual studio based on the
-# properties we set through dexter currently.
-VSBreakpoint = namedtuple('VSBreakpoint', 'path, line, col, cond')
-
-class VisualStudio(DebuggerBase, metaclass=abc.ABCMeta):  # pylint: disable=abstract-method
-
-    # Constants for results of Debugger.CurrentMode
-    # (https://msdn.microsoft.com/en-us/library/envdte.debugger.currentmode.aspx)
-    dbgDesignMode = 1
-    dbgBreakMode = 2
-    dbgRunMode = 3
-
-    def __init__(self, *args):
-        self.com_module = None
-        self._debugger = None
-        self._solution = None
-        self._fn_step = None
-        self._fn_go = None
-        # The next available unique breakpoint id. Use self._get_next_id().
-        self._next_bp_id = 0
-        # VisualStudio appears to common identical breakpoints. That is, if you
-        # ask for a breakpoint that already exists the Breakpoints list will
-        # not grow. DebuggerBase requires all breakpoints have a unique id,
-        # even for duplicates, so we'll need to do some bookkeeping.  Map
-        # {VSBreakpoint: list(id)} where id is the unique dexter-side id for
-        # the requested breakpoint.
-        self._vs_to_dex_ids = defaultdict(list)
-        # Map {id: VSBreakpoint} where id is unique and VSBreakpoint identifies
-        # a breakpoint in Visual Studio. There may be many ids mapped to a
-        # single VSBreakpoint. Use self._vs_to_dex_ids to find (dexter)
-        # breakpoints mapped to the same visual studio breakpoint.
-        self._dex_id_to_vs = {}
-
-        super(VisualStudio, self).__init__(*args)
-
-    def _custom_init(self):
-        try:
-            self._debugger = self._interface.Debugger
-            self._debugger.HexDisplayMode = False
-
-            self._interface.MainWindow.Visible = (
-                self.context.options.show_debugger)
-
-            self._solution = self._interface.Solution
-            self._solution.Create(self.context.working_directory.path,
-                                  'DexterSolution')
-
-            try:
-                self._solution.AddFromFile(self._project_file)
-            except OSError:
-                raise LoadDebuggerException(
-                    'could not debug the specified executable', sys.exc_info())
-
-            self._fn_step = self._debugger.StepInto
-            self._fn_go = self._debugger.Go
-
-        except AttributeError as e:
-            raise LoadDebuggerException(str(e), sys.exc_info())
-
-    def _custom_exit(self):
-        if self._interface:
-            self._interface.Quit()
-
-    @property
-    def _project_file(self):
-        return self.context.options.executable
-
-    @abc.abstractproperty
-    def _dte_version(self):
-        pass
-
-    @property
-    def _location(self):
-        #TODO: Find a better way of determining path, line and column info
-        # that doesn't require reading break points. This method requires
-        # all lines to have a break point on them.
-        bp = self._debugger.BreakpointLastHit
-        return {
-            'path': getattr(bp, 'File', None),
-            'lineno': getattr(bp, 'FileLine', None),
-            'column': getattr(bp, 'FileColumn', None)
-        }
-
-    @property
-    def _mode(self):
-        return self._debugger.CurrentMode
-
-    def _load_interface(self):
-        self.com_module = _load_com_module()
-        return self.com_module.DTE(self._dte_version)
-
-    @property
-    def version(self):
-        try:
-            return self._interface.Version
-        except AttributeError:
-            return None
-
-    def clear_breakpoints(self):
-        for bp in self._debugger.Breakpoints:
-            bp.Delete()
-        self._vs_to_dex_ids.clear()
-        self._dex_id_to_vs.clear()
-
-    def _add_breakpoint(self, file_, line):
-        return self._add_conditional_breakpoint(file_, line, '')
-
-    def _get_next_id(self):
-        # "Generate" a new unique id for the breakpoint.
-        id = self._next_bp_id
-        self._next_bp_id += 1
-        return id
-
-    def _add_conditional_breakpoint(self, file_, line, condition):
-        col = 1
-        vsbp = VSBreakpoint(PurePath(file_), line, col, condition)
-        new_id = self._get_next_id()
-
-        # Do we have an exact matching breakpoint already?
-        if vsbp in self._vs_to_dex_ids:
-            self._vs_to_dex_ids[vsbp].append(new_id)
-            self._dex_id_to_vs[new_id] = vsbp
-            return new_id
-
-        # Breakpoint doesn't exist already. Add it now.
-        count_before = self._debugger.Breakpoints.Count
-        self._debugger.Breakpoints.Add('', file_, line, col, condition)
-        # Our internal representation of VS says that the breakpoint doesn't
-        # already exist so we do not expect this operation to fail here.
-        assert count_before < self._debugger.Breakpoints.Count
-        # We've added a new breakpoint, record its id.
-        self._vs_to_dex_ids[vsbp].append(new_id)
-        self._dex_id_to_vs[new_id] = vsbp
-        return new_id
-
-    def get_triggered_breakpoint_ids(self):
-        """Returns a set of opaque ids for just-triggered breakpoints.
-        """
-        bps_hit = self._debugger.AllBreakpointsLastHit
-        bp_id_list = []
-        # Intuitively, AllBreakpointsLastHit breakpoints are the last hit
-        # _bound_ breakpoints. A bound breakpoint's parent holds the info of
-        # the breakpoint the user requested. Our internal state tracks the user
-        # requested breakpoints so we look at the Parent of these triggered
-        # breakpoints to determine which have been hit.
-        for bp in bps_hit:
-            # All bound breakpoints should have the user-defined breakpoint as
-            # a parent.
-            assert bp.Parent
-            vsbp = VSBreakpoint(PurePath(bp.Parent.File), bp.Parent.FileLine,
-                                bp.Parent.FileColumn, bp.Parent.Condition)
-            try:
-                ids = self._vs_to_dex_ids[vsbp]
-            except KeyError:
-                pass
-            else:
-                bp_id_list += ids
-        return set(bp_id_list)
-
-    def delete_breakpoint(self, id):
-        """Delete a breakpoint by id.
-
-        Raises a KeyError if no breakpoint with this id exists.
-        """
-        vsbp = self._dex_id_to_vs[id]
-
-        # Remove our id from the associated list of dex ids.
-        self._vs_to_dex_ids[vsbp].remove(id)
-        del self._dex_id_to_vs[id]
-
-        # Bail if there are other uses of this vsbp.
-        if len(self._vs_to_dex_ids[vsbp]) > 0:
-            return
-        # Otherwise find and delete it.
-        for bp in self._debugger.Breakpoints:
-            # We're looking at the user-set breakpoints so there shouild be no
-            # Parent.
-            assert bp.Parent == None
-            this_vsbp = VSBreakpoint(PurePath(bp.File), bp.FileLine,
-                                     bp.FileColumn, bp.Condition)
-            if vsbp == this_vsbp:
-                bp.Delete()
-                break
-
-    def launch(self):
-        self._fn_go()
-
-    def step(self):
-        self._fn_step()
-
-    def go(self) -> ReturnCode:
-        self._fn_go()
-        return ReturnCode.OK
-
-    def set_current_stack_frame(self, idx: int = 0):
-        thread = self._debugger.CurrentThread
-        stack_frames = thread.StackFrames
-        try:
-            stack_frame = stack_frames[idx]
-            self._debugger.CurrentStackFrame = stack_frame.raw
-        except IndexError:
-            raise Error('attempted to access stack frame {} out of {}'
-                .format(idx, len(stack_frames)))
-
-    def _get_step_info(self, watches, step_index):
-        thread = self._debugger.CurrentThread
-        stackframes = thread.StackFrames
-
-        frames = []
-        state_frames = []
-
-
-        for idx, sf in enumerate(stackframes):
-            frame = FrameIR(
-                function=self._sanitize_function_name(sf.FunctionName),
-                is_inlined=sf.FunctionName.startswith('[Inline Frame]'),
-                loc=LocIR(path=None, lineno=None, column=None))
-
-            fname = frame.function or ''  # pylint: disable=no-member
-            if any(name in fname for name in self.frames_below_main):
-                break
-
-
-            state_frame = StackFrame(function=frame.function,
-                                     is_inlined=frame.is_inlined,
-                                     watches={})
-
-            for watch in watches:
-                state_frame.watches[watch] = self.evaluate_expression(
-                    watch, idx)
-
-
-            state_frames.append(state_frame)
-            frames.append(frame)
-
-        loc = LocIR(**self._location)
-        if frames:
-            frames[0].loc = loc
-            state_frames[0].location = SourceLocation(**self._location)
-
-        reason = StopReason.BREAKPOINT
-        if loc.path is None:  # pylint: disable=no-member
-            reason = StopReason.STEP
-
-        program_state = ProgramState(frames=state_frames)
-
-        return StepIR(
-            step_index=step_index, frames=frames, stop_reason=reason,
-            program_state=program_state)
-
-    @property
-    def is_running(self):
-        return self._mode == VisualStudio.dbgRunMode
-
-    @property
-    def is_finished(self):
-        return self._mode == VisualStudio.dbgDesignMode
-
-    @property
-    def frames_below_main(self):
-        return [
-            '[Inline Frame] invoke_main', '__scrt_common_main_seh',
-            '__tmainCRTStartup', 'mainCRTStartup'
-        ]
-
-    def evaluate_expression(self, expression, frame_idx=0) -> ValueIR:
-        self.set_current_stack_frame(frame_idx)
-        result = self._debugger.GetExpression(expression)
-        self.set_current_stack_frame(0)
-        value = result.Value
-
-        is_optimized_away = any(s in value for s in [
-            'Variable is optimized away and not available',
-            'Value is not available, possibly due to optimization',
-        ])
-
-        is_irretrievable = any(s in value for s in [
-            '???',
-            '<Unable to read memory>',
-        ])
-
-        # an optimized away value is still counted as being able to be
-        # evaluated.
-        could_evaluate = (result.IsValidValue or is_optimized_away
-                          or is_irretrievable)
-
-        return ValueIR(
-            expression=expression,
-            value=value,
-            type_name=result.Type,
-            error_string=None,
-            is_optimized_away=is_optimized_away,
-            could_evaluate=could_evaluate,
-            is_irretrievable=is_irretrievable,
-        )
diff --git a/dexter/dex/debugger/visualstudio/VisualStudio2015.py b/dexter/dex/debugger/visualstudio/VisualStudio2015.py
deleted file mode 100644
index af6edcd..0000000
--- a/dexter/dex/debugger/visualstudio/VisualStudio2015.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-"""Specializations for the Visual Studio 2015 interface."""
-
-from dex.debugger.visualstudio.VisualStudio import VisualStudio
-
-
-class VisualStudio2015(VisualStudio):
-    @classmethod
-    def get_name(cls):
-        return 'Visual Studio 2015'
-
-    @classmethod
-    def get_option_name(cls):
-        return 'vs2015'
-
-    @property
-    def _dte_version(self):
-        return 'VisualStudio.DTE.14.0'
diff --git a/dexter/dex/debugger/visualstudio/VisualStudio2017.py b/dexter/dex/debugger/visualstudio/VisualStudio2017.py
deleted file mode 100644
index f2f7575..0000000
--- a/dexter/dex/debugger/visualstudio/VisualStudio2017.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-"""Specializations for the Visual Studio 2017 interface."""
-
-from dex.debugger.visualstudio.VisualStudio import VisualStudio
-
-
-class VisualStudio2017(VisualStudio):
-    @classmethod
-    def get_name(cls):
-        return 'Visual Studio 2017'
-
-    @classmethod
-    def get_option_name(cls):
-        return 'vs2017'
-
-    @property
-    def _dte_version(self):
-        return 'VisualStudio.DTE.15.0'
diff --git a/dexter/dex/debugger/visualstudio/VisualStudio2019.py b/dexter/dex/debugger/visualstudio/VisualStudio2019.py
deleted file mode 100644
index 9ebe0a0..0000000
--- a/dexter/dex/debugger/visualstudio/VisualStudio2019.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-"""Specializations for the Visual Studio 2019 interface."""
-
-from dex.debugger.visualstudio.VisualStudio import VisualStudio
-
-
-class VisualStudio2019(VisualStudio):
-    @classmethod
-    def get_name(cls):
-        return 'Visual Studio 2019'
-
-    @classmethod
-    def get_option_name(cls):
-        return 'vs2019'
-
-    @property
-    def _dte_version(self):
-        return 'VisualStudio.DTE.16.0'
diff --git a/dexter/dex/debugger/visualstudio/__init__.py b/dexter/dex/debugger/visualstudio/__init__.py
deleted file mode 100644
index 35fefac..0000000
--- a/dexter/dex/debugger/visualstudio/__init__.py
+++ /dev/null
@@ -1,9 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-
-from dex.debugger.visualstudio.VisualStudio2015 import VisualStudio2015
-from dex.debugger.visualstudio.VisualStudio2017 import VisualStudio2017
diff --git a/dexter/dex/debugger/visualstudio/windows/ComInterface.py b/dexter/dex/debugger/visualstudio/windows/ComInterface.py
deleted file mode 100644
index 0bce5b5..0000000
--- a/dexter/dex/debugger/visualstudio/windows/ComInterface.py
+++ /dev/null
@@ -1,119 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-"""Communication via the Windows COM interface."""
-
-import inspect
-import time
-import sys
-
-# pylint: disable=import-error
-import win32com.client as com
-import win32api
-# pylint: enable=import-error
-
-from dex.utils.Exceptions import LoadDebuggerException
-
-_com_error = com.pywintypes.com_error  # pylint: disable=no-member
-
-
-def get_file_version(file_):
-    try:
-        info = win32api.GetFileVersionInfo(file_, '\\')
-        ms = info['FileVersionMS']
-        ls = info['FileVersionLS']
-        return '.'.join(
-            str(s) for s in [
-                win32api.HIWORD(ms),
-                win32api.LOWORD(ms),
-                win32api.HIWORD(ls),
-                win32api.LOWORD(ls)
-            ])
-    except com.pywintypes.error:  # pylint: disable=no-member
-        return 'no versioninfo present'
-
-
-def _handle_com_error(e):
-    exc = sys.exc_info()
-    msg = win32api.FormatMessage(e.hresult)
-    try:
-        msg = msg.decode('CP1251')
-    except AttributeError:
-        pass
-    msg = msg.strip()
-    return msg, exc
-
-
-class ComObject(object):
-    """Wrap a raw Windows COM object in a class that implements auto-retry of
-    failed calls.
-    """
-
-    def __init__(self, raw):
-        assert not isinstance(raw, ComObject), raw
-        self.__dict__['raw'] = raw
-
-    def __str__(self):
-        return self._call(self.raw.__str__)
-
-    def __getattr__(self, key):
-        if key in self.__dict__:
-            return self.__dict__[key]
-        return self._call(self.raw.__getattr__, key)
-
-    def __setattr__(self, key, val):
-        if key in self.__dict__:
-            self.__dict__[key] = val
-        self._call(self.raw.__setattr__, key, val)
-
-    def __getitem__(self, key):
-        return self._call(self.raw.__getitem__, key)
-
-    def __setitem__(self, key, val):
-        self._call(self.raw.__setitem__, key, val)
-
-    def __call__(self, *args):
-        return self._call(self.raw, *args)
-
-    @classmethod
-    def _call(cls, fn, *args):
-        """COM calls tend to randomly fail due to thread sync issues.
-        The Microsoft recommended solution is to set up a message filter object
-        to automatically retry failed calls, but this seems prohibitively hard
-        from python, so this is a custom solution to do the same thing.
-        All COM accesses should go through this function.
-        """
-        ex = AssertionError("this should never be raised!")
-
-        assert (inspect.isfunction(fn) or inspect.ismethod(fn)
-                or inspect.isbuiltin(fn)), (fn, type(fn))
-        retries = ([0] * 50) + ([1] * 5)
-        for r in retries:
-            try:
-                try:
-                    result = fn(*args)
-                    if inspect.ismethod(result) or 'win32com' in str(
-                            result.__class__):
-                        result = ComObject(result)
-                    return result
-                except _com_error as e:
-                    msg, _ = _handle_com_error(e)
-                    e = WindowsError(msg)  # pylint: disable=undefined-variable
-                    raise e
-            except (AttributeError, TypeError, OSError) as e:
-                ex = e
-                time.sleep(r)
-        raise ex
-
-
-class DTE(ComObject):
-    def __init__(self, class_string):
-        try:
-            super(DTE, self).__init__(com.DispatchEx(class_string))
-        except _com_error as e:
-            msg, exc = _handle_com_error(e)
-            raise LoadDebuggerException(
-                '{} [{}]'.format(msg, class_string), orig_exception=exc)
diff --git a/dexter/dex/debugger/visualstudio/windows/__init__.py b/dexter/dex/debugger/visualstudio/windows/__init__.py
deleted file mode 100644
index 1194aff..0000000
--- a/dexter/dex/debugger/visualstudio/windows/__init__.py
+++ /dev/null
@@ -1,6 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
diff --git a/dexter/dex/dextIR/BuilderIR.py b/dexter/dex/dextIR/BuilderIR.py
deleted file mode 100644
index b94a1fb..0000000
--- a/dexter/dex/dextIR/BuilderIR.py
+++ /dev/null
@@ -1,16 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-
-
-class BuilderIR:
-    """Data class which represents the compiler related options passed to Dexter
-    """
-
-    def __init__(self, name: str, cflags: str, ldflags: str):
-        self.name = name
-        self.cflags = cflags
-        self.ldflags = ldflags
diff --git a/dexter/dex/dextIR/DebuggerIR.py b/dexter/dex/dextIR/DebuggerIR.py
deleted file mode 100644
index 5956db6..0000000
--- a/dexter/dex/dextIR/DebuggerIR.py
+++ /dev/null
@@ -1,14 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-
-
-class DebuggerIR:
-    """Data class which represents a debugger."""
-
-    def __init__(self, name: str, version: str):
-        self.name = name
-        self.version = version
diff --git a/dexter/dex/dextIR/DextIR.py b/dexter/dex/dextIR/DextIR.py
deleted file mode 100644
index b82c2ba..0000000
--- a/dexter/dex/dextIR/DextIR.py
+++ /dev/null
@@ -1,133 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-from collections import OrderedDict
-import os
-from typing import List
-
-from dex.dextIR.BuilderIR import BuilderIR
-from dex.dextIR.DebuggerIR import DebuggerIR
-from dex.dextIR.StepIR import StepIR, StepKind
-
-
-def _step_kind_func(context, step):
-    if (step.current_location.path is None or
-        not os.path.exists(step.current_location.path)):
-        return StepKind.FUNC_UNKNOWN
-
-    if any(os.path.samefile(step.current_location.path, f)
-           for f in context.options.source_files):
-        return StepKind.FUNC
-
-    return StepKind.FUNC_EXTERNAL
-
-
-class DextIR:
-    """A full Dexter test report.
-
-    This is composed of all the other *IR classes. They are used together to
-    record Dexter inputs and the resultant debugger steps, providing a single
-    high level access container.
-
-    The Heuristic class works with dexter commands and the generated DextIR to
-    determine the debugging score for a given test.
-
-    Args:
-        commands: { name (str), commands (list[CommandIR])
-    """
-
-    def __init__(self,
-                 dexter_version: str,
-                 executable_path: str,
-                 source_paths: List[str],
-                 builder: BuilderIR = None,
-                 debugger: DebuggerIR = None,
-                 commands: OrderedDict = None):
-        self.dexter_version = dexter_version
-        self.executable_path = executable_path
-        self.source_paths = source_paths
-        self.builder = builder
-        self.debugger = debugger
-        self.commands = commands
-        self.steps: List[StepIR] = []
-
-    def __str__(self):
-        colors = 'rgby'
-        st = '## BEGIN ##\n'
-        color_idx = 0
-        for step in self.steps:
-            if step.step_kind in (StepKind.FUNC, StepKind.FUNC_EXTERNAL,
-                                  StepKind.FUNC_UNKNOWN):
-                color_idx += 1
-
-            color = colors[color_idx % len(colors)]
-            st += '<{}>{}</>\n'.format(color, step)
-        st += '## END ({} step{}) ##\n'.format(
-            self.num_steps, '' if self.num_steps == 1 else 's')
-        return st
-
-    @property
-    def num_steps(self):
-        return len(self.steps)
-
-    def _get_prev_step_in_this_frame(self, step):
-        """Find the most recent step in the same frame as `step`.
-
-        Returns:
-            StepIR or None if there is no previous step in this frame.
-        """
-        return next((s for s in reversed(self.steps)
-            if s.current_function == step.current_function
-            and s.num_frames == step.num_frames), None)
-
-    def _get_new_step_kind(self, context, step):
-        if step.current_function is None:
-            return StepKind.UNKNOWN
-
-        if len(self.steps) == 0:
-            return _step_kind_func(context, step)
-
-        prev_step = self.steps[-1]
-
-        if prev_step.current_function is None:
-            return StepKind.UNKNOWN
-
-        if prev_step.num_frames < step.num_frames:
-            return _step_kind_func(context, step)
-
-        if prev_step.num_frames > step.num_frames:
-            frame_step = self._get_prev_step_in_this_frame(step)
-            prev_step = frame_step if frame_step is not None else prev_step
-
-        # If we're missing line numbers to compare then the step kind has to be UNKNOWN.
-        if prev_step.current_location.lineno is None or step.current_location.lineno is None:
-            return StepKind.UNKNOWN
-
-        # We're in the same func as prev step, check lineo.
-        if prev_step.current_location.lineno > step.current_location.lineno:
-            return StepKind.VERTICAL_BACKWARD
-
-        if prev_step.current_location.lineno < step.current_location.lineno:
-            return StepKind.VERTICAL_FORWARD
-
-        # We're on the same line as prev step, check column.
-        if prev_step.current_location.column > step.current_location.column:
-            return StepKind.HORIZONTAL_BACKWARD
-
-        if prev_step.current_location.column < step.current_location.column:
-            return StepKind.HORIZONTAL_FORWARD
-
-        # This step is in exactly the same location as the prev step.
-        return StepKind.SAME
-
-    def new_step(self, context, step):
-        assert isinstance(step, StepIR), type(step)
-        step.step_kind = self._get_new_step_kind(context, step)
-        self.steps.append(step)
-        return step
-
-    def clear_steps(self):
-        self.steps.clear()
diff --git a/dexter/dex/dextIR/FrameIR.py b/dexter/dex/dextIR/FrameIR.py
deleted file mode 100644
index a2c0523..0000000
--- a/dexter/dex/dextIR/FrameIR.py
+++ /dev/null
@@ -1,16 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-from dex.dextIR.LocIR import LocIR
-
-
-class FrameIR:
-    """Data class which represents a frame in the call stack"""
-
-    def __init__(self, function: str, is_inlined: bool, loc: LocIR):
-        self.function = function
-        self.is_inlined = is_inlined
-        self.loc = loc
diff --git a/dexter/dex/dextIR/LocIR.py b/dexter/dex/dextIR/LocIR.py
deleted file mode 100644
index 52a56a8..0000000
--- a/dexter/dex/dextIR/LocIR.py
+++ /dev/null
@@ -1,45 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-import os
-
-
-class LocIR:
-    """Data class which represents a source location."""
-
-    def __init__(self, path: str, lineno: int, column: int):
-        if path:
-            path = os.path.normcase(path)
-        self.path = path
-        self.lineno = lineno
-        self.column = column
-
-    def __str__(self):
-        return '{}({}:{})'.format(self.path, self.lineno, self.column)
-
-    def __eq__(self, rhs):
-        return (os.path.exists(self.path) and os.path.exists(rhs.path)
-                and os.path.samefile(self.path, rhs.path)
-                and self.lineno == rhs.lineno
-                and self.column == rhs.column)
-
-    def __lt__(self, rhs):
-        if self.path != rhs.path:
-            return False
-
-        if self.lineno == rhs.lineno:
-            return self.column < rhs.column
-
-        return self.lineno < rhs.lineno
-
-    def __gt__(self, rhs):
-        if self.path != rhs.path:
-            return False
-
-        if self.lineno == rhs.lineno:
-            return self.column > rhs.column
-
-        return self.lineno > rhs.lineno
diff --git a/dexter/dex/dextIR/ProgramState.py b/dexter/dex/dextIR/ProgramState.py
deleted file mode 100644
index 4f05189..0000000
--- a/dexter/dex/dextIR/ProgramState.py
+++ /dev/null
@@ -1,117 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-"""Set of data classes for representing the complete debug program state at a
-fixed point in execution.
-"""
-
-import os
-
-from collections import OrderedDict
-from typing import List
-
-class SourceLocation:
-    def __init__(self, path: str = None, lineno: int = None, column: int = None):
-        if path:
-            path = os.path.normcase(path)
-        self.path = path
-        self.lineno = lineno
-        self.column = column
-
-    def __str__(self):
-        return '{}({}:{})'.format(self.path, self.lineno, self.column)
-
-    def match(self, other) -> bool:
-        """Returns true iff all the properties that appear in `self` have the
-        same value in `other`, but not necessarily vice versa.
-        """
-        if not other or not isinstance(other, SourceLocation):
-            return False
-
-        if self.path and (self.path != other.path):
-            return False
-
-        if self.lineno and (self.lineno != other.lineno):
-            return False
-
-        if self.column and (self.column != other.column):
-            return False
-
-        return True
-
-
-class StackFrame:
-    def __init__(self,
-                 function: str = None,
-                 is_inlined: bool = None,
-                 location: SourceLocation = None,
-                 watches: OrderedDict = None):
-        if watches is None:
-            watches = {}
-
-        self.function = function
-        self.is_inlined = is_inlined
-        self.location = location
-        self.watches = watches
-
-    def __str__(self):
-        return '{}{}: {} | {}'.format(
-            self.function,
-            ' (inlined)' if self.is_inlined else '',
-            self.location,
-            {k: str(self.watches[k]) for k in self.watches})
-
-    def match(self, other) -> bool:
-        """Returns true iff all the properties that appear in `self` have the
-        same value in `other`, but not necessarily vice versa.
-        """
-        if not other or not isinstance(other, StackFrame):
-            return False
-
-        if self.location and not self.location.match(other.location):
-            return False
-
-        if self.watches:
-            for name in iter(self.watches):
-                try:
-                    if isinstance(self.watches[name], dict):
-                        for attr in iter(self.watches[name]):
-                            if (getattr(other.watches[name], attr, None) !=
-                                    self.watches[name][attr]):
-                                return False
-                    else:
-                        if other.watches[name].value != self.watches[name]:
-                            return False
-                except KeyError:
-                    return False
-
-        return True
-
-class ProgramState:
-    def __init__(self, frames: List[StackFrame] = None):
-        self.frames = frames
-
-    def __str__(self):
-        return '\n'.join(map(
-            lambda enum: 'Frame {}: {}'.format(enum[0], enum[1]),
-            enumerate(self.frames)))
-
-    def match(self, other) -> bool:
-        """Returns true iff all the properties that appear in `self` have the
-        same value in `other`, but not necessarily vice versa.
-        """
-        if not other or not isinstance(other, ProgramState):
-            return False
-
-        if self.frames:
-            for idx, frame in enumerate(self.frames):
-                try:
-                    if not frame.match(other.frames[idx]):
-                        return False
-                except (IndexError, KeyError):
-                    return False
-
-        return True
diff --git a/dexter/dex/dextIR/StepIR.py b/dexter/dex/dextIR/StepIR.py
deleted file mode 100644
index 8111968..0000000
--- a/dexter/dex/dextIR/StepIR.py
+++ /dev/null
@@ -1,103 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-"""Classes which are used to represent debugger steps."""
-
-import json
-
-from collections import OrderedDict
-from typing import List
-from enum import Enum
-from dex.dextIR.FrameIR import FrameIR
-from dex.dextIR.LocIR import LocIR
-from dex.dextIR.ProgramState import ProgramState
-
-
-class StopReason(Enum):
-    BREAKPOINT = 0
-    STEP = 1
-    PROGRAM_EXIT = 2
-    ERROR = 3
-    OTHER = 4
-
-
-class StepKind(Enum):
-    FUNC = 0
-    FUNC_EXTERNAL = 1
-    FUNC_UNKNOWN = 2
-    VERTICAL_FORWARD = 3
-    SAME = 4
-    VERTICAL_BACKWARD = 5
-    UNKNOWN = 6
-    HORIZONTAL_FORWARD = 7
-    HORIZONTAL_BACKWARD = 8
-
-
-class StepIR:
-    """A debugger step.
-
-    Args:
-        watches (OrderedDict): { expression (str), result (ValueIR) }
-    """
-
-    def __init__(self,
-                 step_index: int,
-                 stop_reason: StopReason,
-                 frames: List[FrameIR],
-                 step_kind: StepKind = None,
-                 watches: OrderedDict = None,
-                 program_state: ProgramState = None):
-        self.step_index = step_index
-        self.step_kind = step_kind
-        self.stop_reason = stop_reason
-        self.program_state = program_state
-
-        if frames is None:
-            frames = []
-        self.frames = frames
-
-        if watches is None:
-            watches = {}
-        self.watches = watches
-
-    def __str__(self):
-        try:
-            frame = self.current_frame
-            frame_info = (frame.function, frame.loc.path, frame.loc.lineno,
-                          frame.loc.column)
-        except AttributeError:
-            frame_info = (None, None, None, None)
-
-        step_info = (self.step_index, ) + frame_info + (
-            str(self.stop_reason), str(self.step_kind),
-                                    [w for w in self.watches])
-
-        return '{}{}'.format('.   ' * (self.num_frames - 1),
-                             json.dumps(step_info))
-
-    @property
-    def num_frames(self):
-        return len(self.frames)
-
-    @property
-    def current_frame(self):
-        if not len(self.frames):
-            return None
-        return self.frames[0]
-
-    @property
-    def current_function(self):
-        try:
-            return self.current_frame.function
-        except AttributeError:
-            return None
-
-    @property
-    def current_location(self):
-        try:
-            return self.current_frame.loc
-        except AttributeError:
-            return LocIR(path=None, lineno=None, column=None)
diff --git a/dexter/dex/dextIR/ValueIR.py b/dexter/dex/dextIR/ValueIR.py
deleted file mode 100644
index 9d532ac..0000000
--- a/dexter/dex/dextIR/ValueIR.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-
-
-class ValueIR:
-    """Data class to store the result of an expression evaluation."""
-
-    def __init__(self,
-                 expression: str,
-                 value: str,
-                 type_name: str,
-                 could_evaluate: bool,
-                 error_string: str = None,
-                 is_optimized_away: bool = False,
-                 is_irretrievable: bool = False):
-        self.expression = expression
-        self.value = value
-        self.type_name = type_name
-        self.could_evaluate = could_evaluate
-        self.error_string = error_string
-        self.is_optimized_away = is_optimized_away
-        self.is_irretrievable = is_irretrievable
-
-    def __str__(self):
-        prefix = '"{}": '.format(self.expression)
-        if self.error_string is not None:
-            return prefix + self.error_string
-        if self.value is not None:
-            return prefix + '({}) {}'.format(self.type_name, self.value)
-        return (prefix +
-                'could_evaluate: {}; irretrievable: {}; optimized_away: {};'
-                    .format(self.could_evaluate, self.is_irretrievable,
-                            self.is_optimized_away))
-
diff --git a/dexter/dex/dextIR/__init__.py b/dexter/dex/dextIR/__init__.py
deleted file mode 100644
index 463a2c1..0000000
--- a/dexter/dex/dextIR/__init__.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-"""dextIR: DExTer Intermediate Representation of DExTer's debugger trace output.
-"""
-
-from dex.dextIR.BuilderIR import BuilderIR
-from dex.dextIR.DextIR import DextIR
-from dex.dextIR.DebuggerIR import DebuggerIR
-from dex.dextIR.FrameIR import FrameIR
-from dex.dextIR.LocIR import LocIR
-from dex.dextIR.StepIR import StepIR, StepKind, StopReason
-from dex.dextIR.ValueIR import ValueIR
-from dex.dextIR.ProgramState import ProgramState, SourceLocation, StackFrame
diff --git a/dexter/dex/heuristic/Heuristic.py b/dexter/dex/heuristic/Heuristic.py
deleted file mode 100644
index 205b767..0000000
--- a/dexter/dex/heuristic/Heuristic.py
+++ /dev/null
@@ -1,497 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-"""Calculate a 'score' based on some dextIR.
-Assign penalties based on different commands to decrease the score.
-1.000 would be a perfect score.
-0.000 is the worst theoretical score possible.
-"""
-
-from collections import defaultdict, namedtuple, Counter
-import difflib
-import os
-from itertools import groupby
-from dex.command.StepValueInfo import StepValueInfo
-
-
-PenaltyCommand = namedtuple('PenaltyCommand', ['pen_dict', 'max_penalty'])
-# 'meta' field used in different ways by different things
-PenaltyInstance = namedtuple('PenaltyInstance', ['meta', 'the_penalty'])
-
-
-def add_heuristic_tool_arguments(parser):
-    parser.add_argument(
-        '--penalty-variable-optimized',
-        type=int,
-        default=3,
-        help='set the penalty multiplier for each'
-        ' occurrence of a variable that was optimized'
-        ' away',
-        metavar='<int>')
-    parser.add_argument(
-        '--penalty-misordered-values',
-        type=int,
-        default=3,
-        help='set the penalty multiplier for each'
-        ' occurrence of a misordered value.',
-        metavar='<int>')
-    parser.add_argument(
-        '--penalty-irretrievable',
-        type=int,
-        default=4,
-        help='set the penalty multiplier for each'
-        " occurrence of a variable that couldn't"
-        ' be retrieved',
-        metavar='<int>')
-    parser.add_argument(
-        '--penalty-not-evaluatable',
-        type=int,
-        default=5,
-        help='set the penalty multiplier for each'
-        " occurrence of a variable that couldn't"
-        ' be evaluated',
-        metavar='<int>')
-    parser.add_argument(
-        '--penalty-missing-values',
-        type=int,
-        default=6,
-        help='set the penalty multiplier for each missing'
-        ' value',
-        metavar='<int>')
-    parser.add_argument(
-        '--penalty-incorrect-values',
-        type=int,
-        default=7,
-        help='set the penalty multiplier for each'
-        ' occurrence of an unexpected value.',
-        metavar='<int>')
-    parser.add_argument(
-        '--penalty-unreachable',
-        type=int,
-        default=4,  # XXX XXX XXX selected by random
-        help='set the penalty for each line stepped onto that should'
-        ' have been unreachable.',
-        metavar='<int>')
-    parser.add_argument(
-        '--penalty-misordered-steps',
-        type=int,
-        default=2,  # XXX XXX XXX selected by random
-        help='set the penalty for differences in the order of steps'
-        ' the program was expected to observe.',
-        metavar='<int>')
-    parser.add_argument(
-        '--penalty-missing-step',
-        type=int,
-        default=4,  # XXX XXX XXX selected by random
-        help='set the penalty for the program skipping over a step.',
-        metavar='<int>')
-    parser.add_argument(
-        '--penalty-incorrect-program-state',
-        type=int,
-        default=4,  # XXX XXX XXX selected by random
-        help='set the penalty for the program never entering an expected state'
-        ' or entering an unexpected state.',
-        metavar='<int>')
-
-
-class Heuristic(object):
-    def __init__(self, context, steps):
-        self.context = context
-        self.penalties = {}
-
-        worst_penalty = max([
-            self.penalty_variable_optimized, self.penalty_irretrievable,
-            self.penalty_not_evaluatable, self.penalty_incorrect_values,
-            self.penalty_missing_values, self.penalty_unreachable,
-            self.penalty_missing_step, self.penalty_misordered_steps
-        ])
-
-        # Get DexExpectWatchType results.
-        try:
-            for command in steps.commands['DexExpectWatchType']:
-                command.eval(steps)
-                maximum_possible_penalty = min(3, len(
-                    command.values)) * worst_penalty
-                name, p = self._calculate_expect_watch_penalties(
-                    command, maximum_possible_penalty)
-                name = name + ' ExpectType'
-                self.penalties[name] = PenaltyCommand(p,
-                                                      maximum_possible_penalty)
-        except KeyError:
-            pass
-
-        # Get DexExpectWatchValue results.
-        try:
-            for command in steps.commands['DexExpectWatchValue']:
-                command.eval(steps)
-                maximum_possible_penalty = min(3, len(
-                    command.values)) * worst_penalty
-                name, p = self._calculate_expect_watch_penalties(
-                    command, maximum_possible_penalty)
-                name = name + ' ExpectValue'
-                self.penalties[name] = PenaltyCommand(p,
-                                                      maximum_possible_penalty)
-        except KeyError:
-            pass
-
-        try:
-            penalties = defaultdict(list)
-            maximum_possible_penalty_all = 0
-            for expect_state in steps.commands['DexExpectProgramState']:
-                success = expect_state.eval(steps)
-                p = 0 if success else self.penalty_incorrect_program_state
-
-                meta = 'expected {}: {}'.format(
-                    '{} times'.format(expect_state.times)
-                        if expect_state.times >= 0 else 'at least once',
-                    expect_state.program_state_text)
-
-                if success:
-                    meta = '<g>{}</>'.format(meta)
-
-                maximum_possible_penalty = self.penalty_incorrect_program_state
-                maximum_possible_penalty_all += maximum_possible_penalty
-                name = expect_state.program_state_text
-                penalties[meta] = [PenaltyInstance('{} times'.format(
-                    len(expect_state.encounters)), p)]
-            self.penalties['expected program states'] = PenaltyCommand(
-                penalties, maximum_possible_penalty_all)
-        except KeyError:
-            pass
-
-        # Get the total number of each step kind.
-        step_kind_counts = defaultdict(int)
-        for step in getattr(steps, 'steps'):
-            step_kind_counts[step.step_kind] += 1
-
-        # Get DexExpectStepKind results.
-        penalties = defaultdict(list)
-        maximum_possible_penalty_all = 0
-        try:
-            for command in steps.commands['DexExpectStepKind']:
-                command.eval()
-                # Cap the penalty at 2 * expected count or else 1
-                maximum_possible_penalty = max(command.count * 2, 1)
-                p = abs(command.count - step_kind_counts[command.name])
-                actual_penalty = min(p, maximum_possible_penalty)
-                key = ('{}'.format(command.name)
-                       if actual_penalty else '<g>{}</>'.format(command.name))
-                penalties[key] = [PenaltyInstance(p, actual_penalty)]
-                maximum_possible_penalty_all += maximum_possible_penalty
-            self.penalties['step kind differences'] = PenaltyCommand(
-                penalties, maximum_possible_penalty_all)
-        except KeyError:
-            pass
-
-        if 'DexUnreachable' in steps.commands:
-            cmds = steps.commands['DexUnreachable']
-            unreach_count = 0
-
-            # Find steps with unreachable in them
-            ureachs = [
-                s for s in steps.steps if 'DexUnreachable' in s.watches.keys()
-            ]
-
-            # There's no need to match up cmds with the actual watches
-            upen = self.penalty_unreachable
-
-            count = upen * len(ureachs)
-            if count != 0:
-                d = dict()
-                for x in ureachs:
-                    msg = 'line {} reached'.format(x.current_location.lineno)
-                    d[msg] = [PenaltyInstance(upen, upen)]
-            else:
-                d = {
-                    '<g>No unreachable lines seen</>': [PenaltyInstance(0, 0)]
-                }
-            total = PenaltyCommand(d, len(cmds) * upen)
-
-            self.penalties['unreachable lines'] = total
-
-        if 'DexExpectStepOrder' in steps.commands:
-            cmds = steps.commands['DexExpectStepOrder']
-
-            # Form a list of which line/cmd we _should_ have seen
-            cmd_num_lst = [(x, c.lineno) for c in cmds
-                                         for x in c.sequence]
-            # Order them by the sequence number
-            cmd_num_lst.sort(key=lambda t: t[0])
-            # Strip out sequence key
-            cmd_num_lst = [y for x, y in cmd_num_lst]
-
-            # Now do the same, but for the actually observed lines/cmds
-            ss = steps.steps
-            deso = [s for s in ss if 'DexExpectStepOrder' in s.watches.keys()]
-            deso = [s.watches['DexExpectStepOrder'] for s in deso]
-            # We rely on the steps remaining in order here
-            order_list = [int(x.expression) for x in deso]
-
-            # First off, check to see whether or not there are missing items
-            expected = Counter(cmd_num_lst)
-            seen = Counter(order_list)
-
-            unseen_line_dict = dict()
-            skipped_line_dict = dict()
-
-            mispen = self.penalty_missing_step
-            num_missing = 0
-            num_repeats = 0
-            for k, v in expected.items():
-                if k not in seen:
-                    msg = 'Line {} not seen'.format(k)
-                    unseen_line_dict[msg] = [PenaltyInstance(mispen, mispen)]
-                    num_missing += v
-                elif v > seen[k]:
-                    msg = 'Line {} skipped at least once'.format(k)
-                    skipped_line_dict[msg] = [PenaltyInstance(mispen, mispen)]
-                    num_missing += v - seen[k]
-                elif v < seen[k]:
-                    # Don't penalise unexpected extra sightings of a line
-                    # for now
-                    num_repeats = seen[k] - v
-                    pass
-
-            if len(unseen_line_dict) == 0:
-                pi = PenaltyInstance(0, 0)
-                unseen_line_dict['<g>All lines were seen</>'] = [pi]
-
-            if len(skipped_line_dict) == 0:
-                pi = PenaltyInstance(0, 0)
-                skipped_line_dict['<g>No lines were skipped</>'] = [pi]
-
-            total = PenaltyCommand(unseen_line_dict, len(expected) * mispen)
-            self.penalties['Unseen lines'] = total
-            total = PenaltyCommand(skipped_line_dict, len(expected) * mispen)
-            self.penalties['Skipped lines'] = total
-
-            ordpen = self.penalty_misordered_steps
-            cmd_num_lst = [str(x) for x in cmd_num_lst]
-            order_list = [str(x) for x in order_list]
-            lst = list(difflib.Differ().compare(cmd_num_lst, order_list))
-            diff_detail = Counter(l[0] for l in lst)
-
-            assert '?' not in diff_detail
-
-            # Diffs are hard to interpret; there are many algorithms for
-            # condensing them. Ignore all that, and just print out the changed
-            # sequences, it's up to the user to interpret what's going on.
-
-            def filt_lines(s, seg, e, key):
-                lst = [s]
-                for x in seg:
-                    if x[0] == key:
-                        lst.append(int(x[2:]))
-                lst.append(e)
-                return lst
-
-            diff_msgs = dict()
-
-            def reportdiff(start_idx, segment, end_idx):
-                msg = 'Order mismatch, expected linenos {}, saw {}'
-                expected_linenos = filt_lines(start_idx, segment, end_idx, '-')
-                seen_linenos = filt_lines(start_idx, segment, end_idx, '+')
-                msg = msg.format(expected_linenos, seen_linenos)
-                diff_msgs[msg] = [PenaltyInstance(ordpen, ordpen)]
-
-            # Group by changed segments.
-            start_expt_step = 0
-            end_expt_step = 0
-            to_print_lst = []
-            for k, subit in groupby(lst, lambda x: x[0] == ' '):
-                if k:  # Whitespace group
-                    nochanged = [x for x in subit]
-                    end_expt_step = int(nochanged[0][2:])
-                    if len(to_print_lst) > 0:
-                        reportdiff(start_expt_step, to_print_lst,
-                                   end_expt_step)
-                    start_expt_step = int(nochanged[-1][2:])
-                    to_print_lst = []
-                else:  # Diff group, save for printing
-                    to_print_lst = [x for x in subit]
-
-            # If there was a dangling different step, print that too.
-            if len(to_print_lst) > 0:
-                reportdiff(start_expt_step, to_print_lst, '[End]')
-
-            if len(diff_msgs) == 0:
-                diff_msgs['<g>No lines misordered</>'] = [
-                    PenaltyInstance(0, 0)
-                ]
-            total = PenaltyCommand(diff_msgs, len(cmd_num_lst) * ordpen)
-            self.penalties['Misordered lines'] = total
-
-        return
-
-    def _calculate_expect_watch_penalties(self, c, maximum_possible_penalty):
-        penalties = defaultdict(list)
-
-        if c.line_range[0] == c.line_range[-1]:
-            line_range = str(c.line_range[0])
-        else:
-            line_range = '{}-{}'.format(c.line_range[0], c.line_range[-1])
-
-        name = '{}:{} [{}]'.format(
-            os.path.basename(c.path), line_range, c.expression)
-
-        num_actual_watches = len(c.expected_watches) + len(
-            c.unexpected_watches)
-
-        penalty_available = maximum_possible_penalty
-
-        # Only penalize for missing values if we have actually seen a watch
-        # that's returned us an actual value at some point, or if we've not
-        # encountered the value at all.
-        if num_actual_watches or c.times_encountered == 0:
-            for v in c.missing_values:
-                current_penalty = min(penalty_available,
-                                      self.penalty_missing_values)
-                penalty_available -= current_penalty
-                penalties['missing values'].append(
-                    PenaltyInstance(v, current_penalty))
-
-        for v in c.encountered_values:
-            penalties['<g>expected encountered watches</>'].append(
-                PenaltyInstance(v, 0))
-
-        penalty_descriptions = [
-            (self.penalty_not_evaluatable, c.invalid_watches,
-             'could not evaluate'),
-            (self.penalty_variable_optimized, c.optimized_out_watches,
-             'result optimized away'),
-            (self.penalty_misordered_values, c.misordered_watches,
-             'misordered result'),
-            (self.penalty_irretrievable, c.irretrievable_watches,
-             'result could not be retrieved'),
-            (self.penalty_incorrect_values, c.unexpected_watches,
-             'unexpected result'),
-        ]
-
-        for penalty_score, watches, description in penalty_descriptions:
-            # We only penalize the encountered issue for each missing value per
-            # command but we still want to record each one, so set the penalty
-            # to 0 after the threshold is passed.
-            times_to_penalize = len(c.missing_values)
-
-            for w in watches:
-                times_to_penalize -= 1
-                penalty_score = min(penalty_available, penalty_score)
-                penalty_available -= penalty_score
-                penalties[description].append(
-                    PenaltyInstance(w, penalty_score))
-                if not times_to_penalize:
-                    penalty_score = 0
-
-        return name, penalties
-
-    @property
-    def penalty(self):
-        result = 0
-
-        maximum_allowed_penalty = 0
-        for name, pen_cmd in self.penalties.items():
-            maximum_allowed_penalty += pen_cmd.max_penalty
-            value = pen_cmd.pen_dict
-            for category, inst_list in value.items():
-                result += sum(x.the_penalty for x in inst_list)
-        return min(result, maximum_allowed_penalty)
-
-    @property
-    def max_penalty(self):
-        return sum(p_cat.max_penalty for p_cat in self.penalties.values())
-
-    @property
-    def score(self):
-        try:
-            return 1.0 - (self.penalty / float(self.max_penalty))
-        except ZeroDivisionError:
-            return float('nan')
-
-    @property
-    def summary_string(self):
-        score = self.score
-        isnan = score != score  # pylint: disable=comparison-with-itself
-        color = 'g'
-        if score < 0.25 or isnan:
-            color = 'r'
-        elif score < 0.75:
-            color = 'y'
-
-        return '<{}>({:.4f})</>'.format(color, score)
-
-    @property
-    def verbose_output(self):  # noqa
-        string = ''
-        string += ('\n')
-        for command in sorted(self.penalties):
-            pen_cmd = self.penalties[command]
-            maximum_possible_penalty = pen_cmd.max_penalty
-            total_penalty = 0
-            lines = []
-            for category in sorted(pen_cmd.pen_dict):
-                lines.append('    <r>{}</>:\n'.format(category))
-
-                for result, penalty in pen_cmd.pen_dict[category]:
-                    if isinstance(result, StepValueInfo):
-                        text = 'step {}'.format(result.step_index)
-                        if result.expected_value:
-                            text += ' ({})'.format(result.expected_value)
-                    else:
-                        text = str(result)
-                    if penalty:
-                        assert penalty > 0, penalty
-                        total_penalty += penalty
-                        text += ' <r>[-{}]</>'.format(penalty)
-                    lines.append('      {}\n'.format(text))
-
-                lines.append('\n')
-
-            string += ('  <b>{}</> <y>[{}/{}]</>\n'.format(
-                command, total_penalty, maximum_possible_penalty))
-            for line in lines:
-                string += (line)
-        string += ('\n')
-        return string
-
-    @property
-    def penalty_variable_optimized(self):
-        return self.context.options.penalty_variable_optimized
-
-    @property
-    def penalty_irretrievable(self):
-        return self.context.options.penalty_irretrievable
-
-    @property
-    def penalty_not_evaluatable(self):
-        return self.context.options.penalty_not_evaluatable
-
-    @property
-    def penalty_incorrect_values(self):
-        return self.context.options.penalty_incorrect_values
-
-    @property
-    def penalty_missing_values(self):
-        return self.context.options.penalty_missing_values
-
-    @property
-    def penalty_misordered_values(self):
-        return self.context.options.penalty_misordered_values
-
-    @property
-    def penalty_unreachable(self):
-        return self.context.options.penalty_unreachable
-
-    @property
-    def penalty_missing_step(self):
-        return self.context.options.penalty_missing_step
-
-    @property
-    def penalty_misordered_steps(self):
-        return self.context.options.penalty_misordered_steps
-
-    @property
-    def penalty_incorrect_program_state(self):
-        return self.context.options.penalty_incorrect_program_state
diff --git a/dexter/dex/heuristic/__init__.py b/dexter/dex/heuristic/__init__.py
deleted file mode 100644
index 2a143f6..0000000
--- a/dexter/dex/heuristic/__init__.py
+++ /dev/null
@@ -1,8 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-
-from dex.heuristic.Heuristic import Heuristic, StepValueInfo
diff --git a/dexter/dex/tools/Main.py b/dexter/dex/tools/Main.py
deleted file mode 100644
index 78fb4f7..0000000
--- a/dexter/dex/tools/Main.py
+++ /dev/null
@@ -1,207 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-"""This is the main entry point.
-It implements some functionality common to all subtools such as command line
-parsing and running the unit-testing harnesses, before calling the reequested
-subtool.
-"""
-
-import imp
-import os
-import sys
-
-from dex.utils import PrettyOutput, Timer
-from dex.utils import ExtArgParse as argparse
-from dex.utils import get_root_directory
-from dex.utils.Exceptions import Error, ToolArgumentError
-from dex.utils.UnitTests import unit_tests_ok
-from dex.utils.Version import version
-from dex.utils import WorkingDirectory
-from dex.utils.ReturnCode import ReturnCode
-
-
-def _output_bug_report_message(context):
-    """ In the event of a catastrophic failure, print bug report request to the
-        user.
-    """
-    context.o.red(
-        '\n\n'
-        '<g>****************************************</>\n'
-        '<b>****************************************</>\n'
-        '****************************************\n'
-        '**                                    **\n'
-        '** <y>This is a bug in <a>DExTer</>.</>           **\n'
-        '**                                    **\n'
-        '**                  <y>Please report it.</> **\n'
-        '**                                    **\n'
-        '****************************************\n'
-        '<b>****************************************</>\n'
-        '<g>****************************************</>\n'
-        '\n'
-        '<b>system:</>\n'
-        '<d>{}</>\n\n'
-        '<b>version:</>\n'
-        '<d>{}</>\n\n'
-        '<b>args:</>\n'
-        '<d>{}</>\n'
-        '\n'.format(sys.platform, version('DExTer'),
-                    [sys.executable] + sys.argv),
-        stream=PrettyOutput.stderr)
-
-
-def get_tools_directory():
-    """ Returns directory path where DExTer tool imports can be
-        found.
-    """
-    tools_directory = os.path.join(get_root_directory(), 'tools')
-    assert os.path.isdir(tools_directory), tools_directory
-    return tools_directory
-
-
-def get_tool_names():
-    """ Returns a list of expected DExTer Tools
-    """
-    return [
-        'clang-opt-bisect', 'help', 'list-debuggers', 'no-tool-',
-        'run-debugger-internal-', 'test', 'view'
-    ]
-
-
-def _set_auto_highlights(context):
-    """Flag some strings for auto-highlighting.
-    """
-    context.o.auto_reds.extend([
-        r'[Ee]rror\:',
-        r'[Ee]xception\:',
-        r'un(expected|recognized) argument',
-    ])
-    context.o.auto_yellows.extend([
-        r'[Ww]arning\:',
-        r'\(did you mean ',
-        r'During handling of the above exception, another exception',
-    ])
-
-
-def _get_options_and_args(context):
-    """ get the options and arguments from the commandline
-    """
-    parser = argparse.ExtArgumentParser(context, add_help=False)
-    parser.add_argument('tool', default=None, nargs='?')
-    options, args = parser.parse_known_args(sys.argv[1:])
-
-    return options, args
-
-
-def _get_tool_name(options):
-    """ get the name of the dexter tool (if passed) specified on the command
-        line, otherwise return 'no_tool_'.
-    """
-    tool_name = options.tool
-    if tool_name is None:
-        tool_name = 'no_tool_'
-    else:
-        _is_valid_tool_name(tool_name)
-    return tool_name
-
-
-def _is_valid_tool_name(tool_name):
-    """ check tool name matches a tool directory within the dexter tools
-        directory.
-    """
-    valid_tools = get_tool_names()
-    if tool_name not in valid_tools:
-        raise Error('invalid tool "{}" (choose from {})'.format(
-            tool_name,
-            ', '.join([t for t in valid_tools if not t.endswith('-')])))
-
-
-def _import_tool_module(tool_name):
-    """ Imports the python module at the tool directory specificed by
-        tool_name.
-    """
-    # format tool argument to reflect tool directory form.
-    tool_name = tool_name.replace('-', '_')
-
-    tools_directory = get_tools_directory()
-    module_info = imp.find_module(tool_name, [tools_directory])
-
-    return imp.load_module(tool_name, *module_info)
-
-
-def tool_main(context, tool, args):
-    with Timer(tool.name):
-        options, defaults = tool.parse_command_line(args)
-        Timer.display = options.time_report
-        Timer.indent = options.indent_timer_level
-        Timer.fn = context.o.blue
-        context.options = options
-        context.version = version(tool.name)
-
-        if options.version:
-            context.o.green('{}\n'.format(context.version))
-            return ReturnCode.OK
-
-        if (options.unittest != 'off' and not unit_tests_ok(context)):
-            raise Error('<d>unit test failures</>')
-
-        if options.colortest:
-            context.o.colortest()
-            return ReturnCode.OK
-
-        try:
-            tool.handle_base_options(defaults)
-        except ToolArgumentError as e:
-            raise Error(e)
-
-        dir_ = context.options.working_directory
-        with WorkingDirectory(context, dir=dir_) as context.working_directory:
-            return_code = tool.go()
-
-        return return_code
-
-
-class Context(object):
-    """Context encapsulates globally useful objects and data; passed to many
-    Dexter functions.
-    """
-
-    def __init__(self):
-        self.o: PrettyOutput = None
-        self.working_directory: str = None
-        self.options: dict = None
-        self.version: str = None
-        self.root_directory: str = None
-
-
-def main() -> ReturnCode:
-
-    context = Context()
-
-    with PrettyOutput() as context.o:
-        try:
-            context.root_directory = get_root_directory()
-            # Flag some strings for auto-highlighting.
-            _set_auto_highlights(context)
-            options, args = _get_options_and_args(context)
-            # raises 'Error' if command line tool is invalid.
-            tool_name = _get_tool_name(options)
-            module = _import_tool_module(tool_name)
-            return tool_main(context, module.Tool(context), args)
-        except Error as e:
-            context.o.auto(
-                '\nerror: {}\n'.format(str(e)), stream=PrettyOutput.stderr)
-            try:
-                if context.options.error_debug:
-                    raise
-            except AttributeError:
-                pass
-            return ReturnCode._ERROR
-        except (KeyboardInterrupt, SystemExit):
-            raise
-        except:  # noqa
-            _output_bug_report_message(context)
-            raise
diff --git a/dexter/dex/tools/TestToolBase.py b/dexter/dex/tools/TestToolBase.py
deleted file mode 100644
index cfea497..0000000
--- a/dexter/dex/tools/TestToolBase.py
+++ /dev/null
@@ -1,161 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-"""Base class for subtools that do build/run tests."""
-
-import abc
-from datetime import datetime
-import os
-import sys
-
-from dex.builder import add_builder_tool_arguments
-from dex.builder import handle_builder_tool_options
-from dex.debugger.Debuggers import add_debugger_tool_arguments
-from dex.debugger.Debuggers import handle_debugger_tool_options
-from dex.heuristic.Heuristic import add_heuristic_tool_arguments
-from dex.tools.ToolBase import ToolBase
-from dex.utils import get_root_directory, warn
-from dex.utils.Exceptions import Error, ToolArgumentError
-from dex.utils.ReturnCode import ReturnCode
-
-
-class TestToolBase(ToolBase):
-    def __init__(self, *args, **kwargs):
-        super(TestToolBase, self).__init__(*args, **kwargs)
-        self.build_script: str = None
-
-    def add_tool_arguments(self, parser, defaults):
-        parser.description = self.__doc__
-        add_builder_tool_arguments(parser)
-        add_debugger_tool_arguments(parser, self.context, defaults)
-        add_heuristic_tool_arguments(parser)
-
-        parser.add_argument(
-            'test_path',
-            type=str,
-            metavar='<test-path>',
-            nargs='?',
-            default=os.path.abspath(
-                os.path.join(get_root_directory(), '..', 'tests')),
-            help='directory containing test(s)')
-
-        parser.add_argument(
-            '--results-directory',
-            type=str,
-            metavar='<directory>',
-            default=os.path.abspath(
-                os.path.join(get_root_directory(), '..', 'results',
-                             datetime.now().strftime('%Y-%m-%d-%H%M-%S'))),
-            help='directory to save results')
-
-    def handle_options(self, defaults):
-        options = self.context.options
-
-        # We accept either or both of --binary and --builder.
-        if not options.binary and not options.builder:
-            raise Error('expected --builder or --binary')
-
-        # --binary overrides --builder
-        if options.binary:
-            if options.builder:
-                warn(self.context, "overriding --builder with --binary\n")
-
-            options.binary = os.path.abspath(options.binary)
-            if not os.path.isfile(options.binary):
-                raise Error('<d>could not find binary file</> <r>"{}"</>'
-                            .format(options.binary))
-        else:
-            try:
-                self.build_script = handle_builder_tool_options(self.context)
-            except ToolArgumentError as e:
-                raise Error(e)
-
-        try:
-            handle_debugger_tool_options(self.context, defaults)
-        except ToolArgumentError as e:
-            raise Error(e)
-
-        options.test_path = os.path.abspath(options.test_path)
-        options.test_path = os.path.normcase(options.test_path)
-        if not os.path.isfile(options.test_path) and not os.path.isdir(options.test_path):
-            raise Error(
-                '<d>could not find test path</> <r>"{}"</>'.format(
-                    options.test_path))
-
-        options.results_directory = os.path.abspath(options.results_directory)
-        if not os.path.isdir(options.results_directory):
-            try:
-                os.makedirs(options.results_directory, exist_ok=True)
-            except OSError as e:
-                raise Error(
-                    '<d>could not create directory</> <r>"{}"</> <y>({})</>'.
-                    format(options.results_directory, e.strerror))
-
-    def go(self) -> ReturnCode:  # noqa
-        options = self.context.options
-
-        options.executable = os.path.join(
-            self.context.working_directory.path, 'tmp.exe')
-
-        # Test files contain dexter commands.
-        options.test_files = []
-        # Source files are to be compiled by the builder script and may also
-        # contains dexter commands.
-        options.source_files = []
-        if os.path.isdir(options.test_path):
-            subdirs = sorted([
-                r for r, _, f in os.walk(options.test_path)
-                if 'test.cfg' in f
-            ])
-
-            for subdir in subdirs:
-                for f in os.listdir(subdir):
-                    # TODO: read file extensions from the test.cfg file instead so
-                    # that this isn't just limited to C and C++.
-                    file_path = os.path.normcase(os.path.join(subdir, f))
-                    if f.endswith('.cpp'):
-                        options.source_files.append(file_path)
-                    elif f.endswith('.c'):
-                        options.source_files.append(file_path)
-                    elif f.endswith('.dex'):
-                        options.test_files.append(file_path)
-                # Source files can contain dexter commands too.
-                options.test_files = options.test_files + options.source_files
-
-                self._run_test(self._get_test_name(subdir))
-        else:
-            # We're dealing with a direct file path to a test file. If the file is non
-            # .dex, then it must be a source file.
-            if not options.test_path.endswith('.dex'):
-                options.source_files = [options.test_path]
-            options.test_files = [options.test_path]
-            self._run_test(self._get_test_name(options.test_path))
-
-        return self._handle_results()
-
-    @staticmethod
-    def _is_current_directory(test_directory):
-        return test_directory == '.'
-
-    def _get_test_name(self, test_path):
-        """Get the test name from either the test file, or the sub directory
-        path it's stored in.
-        """
-        # test names are distinguished by their relative path from the
-        # specified test path.
-        test_name = os.path.relpath(test_path,
-                                    self.context.options.test_path)
-        if self._is_current_directory(test_name):
-            test_name = os.path.basename(test_path)
-        return test_name
-
-    @abc.abstractmethod
-    def _run_test(self, test_dir):
-        pass
-
-    @abc.abstractmethod
-    def _handle_results(self) -> ReturnCode:
-        pass
diff --git a/dexter/dex/tools/ToolBase.py b/dexter/dex/tools/ToolBase.py
deleted file mode 100644
index eb6ba94..0000000
--- a/dexter/dex/tools/ToolBase.py
+++ /dev/null
@@ -1,135 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-"""Base class for all subtools."""
-
-import abc
-import os
-import tempfile
-
-from dex import __version__
-from dex.utils import ExtArgParse
-from dex.utils import PrettyOutput
-from dex.utils.ReturnCode import ReturnCode
-
-
-class ToolBase(object, metaclass=abc.ABCMeta):
-    def __init__(self, context):
-        self.context = context
-        self.parser = None
-
-    @abc.abstractproperty
-    def name(self):
-        pass
-
-    @abc.abstractmethod
-    def add_tool_arguments(self, parser, defaults):
-        pass
-
-    def parse_command_line(self, args):
-        """Define two parsers: pparser and self.parser.
-        pparser deals with args that need to be parsed prior to any of those of
-        self.parser.  For example, any args which may affect the state of
-        argparse error output.
-        """
-
-        class defaults(object):
-            pass
-
-        pparser = ExtArgParse.ExtArgumentParser(
-            self.context, add_help=False, prog=self.name)
-
-        pparser.add_argument(
-            '--no-color-output',
-            action='store_true',
-            default=False,
-            help='do not use colored output on stdout/stderr')
-        pparser.add_argument(
-            '--time-report',
-            action='store_true',
-            default=False,
-            help='display timing statistics')
-
-        self.parser = ExtArgParse.ExtArgumentParser(
-            self.context, parents=[pparser], prog=self.name)
-        self.parser.add_argument(
-            '-v',
-            '--verbose',
-            action='store_true',
-            default=False,
-            help='enable verbose output')
-        self.parser.add_argument(
-            '-V',
-            '--version',
-            action='store_true',
-            default=False,
-            help='display the DExTer version and exit')
-        self.parser.add_argument(
-            '-w',
-            '--no-warnings',
-            action='store_true',
-            default=False,
-            help='suppress warning output')
-        self.parser.add_argument(
-            '--unittest',
-            type=str,
-            choices=['off', 'show-failures', 'show-all'],
-            default='off',
-            help='run the DExTer codebase unit tests')
-
-        suppress = ExtArgParse.SUPPRESS  # pylint: disable=no-member
-        self.parser.add_argument(
-            '--colortest', action='store_true', default=False, help=suppress)
-        self.parser.add_argument(
-            '--error-debug', action='store_true', default=False, help=suppress)
-        defaults.working_directory = os.path.join(tempfile.gettempdir(),
-                                                  'dexter')
-        self.parser.add_argument(
-            '--indent-timer-level', type=int, default=1, help=suppress)
-        self.parser.add_argument(
-            '--working-directory',
-            type=str,
-            metavar='<file>',
-            default=None,
-            display_default=defaults.working_directory,
-            help='location of working directory')
-        self.parser.add_argument(
-            '--save-temps',
-            action='store_true',
-            default=False,
-            help='save temporary files')
-
-        self.add_tool_arguments(self.parser, defaults)
-
-        # If an error is encountered during pparser, show the full usage text
-        # including self.parser options. Strip the preceding 'usage: ' to avoid
-        # having it appear twice.
-        pparser.usage = self.parser.format_usage().lstrip('usage: ')
-
-        options, args = pparser.parse_known_args(args)
-
-        if options.no_color_output:
-            PrettyOutput.stdout.color_enabled = False
-            PrettyOutput.stderr.color_enabled = False
-
-        options = self.parser.parse_args(args, namespace=options)
-        return options, defaults
-
-    def handle_base_options(self, defaults):
-        self.handle_options(defaults)
-
-        options = self.context.options
-
-        if options.working_directory is None:
-            options.working_directory = defaults.working_directory
-
-    @abc.abstractmethod
-    def handle_options(self, defaults):
-        pass
-
-    @abc.abstractmethod
-    def go(self) -> ReturnCode:
-        pass
diff --git a/dexter/dex/tools/__init__.py b/dexter/dex/tools/__init__.py
deleted file mode 100644
index 76d1261..0000000
--- a/dexter/dex/tools/__init__.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-
-from dex.tools.Main import Context, get_tool_names, get_tools_directory, main, tool_main
-from dex.tools.TestToolBase import TestToolBase
-from dex.tools.ToolBase import ToolBase
diff --git a/dexter/dex/tools/clang_opt_bisect/Tool.py b/dexter/dex/tools/clang_opt_bisect/Tool.py
deleted file mode 100644
index 414f3d1..0000000
--- a/dexter/dex/tools/clang_opt_bisect/Tool.py
+++ /dev/null
@@ -1,314 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-"""Clang opt-bisect tool."""
-
-from collections import defaultdict
-import os
-import csv
-import re
-import pickle
-
-from dex.builder import run_external_build_script
-from dex.command.ParseCommand import get_command_infos
-from dex.debugger.Debuggers import run_debugger_subprocess
-from dex.debugger.DebuggerControllers.DefaultController import DefaultController
-from dex.dextIR.DextIR import DextIR
-from dex.heuristic import Heuristic
-from dex.tools import TestToolBase
-from dex.utils.Exceptions import DebuggerException, Error
-from dex.utils.Exceptions import BuildScriptException, HeuristicException
-from dex.utils.PrettyOutputBase import Stream
-from dex.utils.ReturnCode import ReturnCode
-
-
-class BisectPass(object):
-    def __init__(self, no, description, description_no_loc):
-        self.no = no
-        self.description = description
-        self.description_no_loc = description_no_loc
-
-        self.penalty = 0
-        self.differences = []
-
-
-class Tool(TestToolBase):
-    """Use the LLVM "-opt-bisect-limit=<n>" flag to get information on the
-    contribution of each LLVM pass to the overall DExTer score when using
-    clang.
-
-    Clang is run multiple times, with an increasing value of n, measuring the
-    debugging experience at each value.
-    """
-
-    _re_running_pass = re.compile(
-        r'^BISECT\: running pass \((\d+)\) (.+?)( \(.+\))?$')
-
-    def __init__(self, *args, **kwargs):
-        super(Tool, self).__init__(*args, **kwargs)
-        self._all_bisect_pass_summary = defaultdict(list)
-
-    @property
-    def name(self):
-        return 'DExTer clang opt bisect'
-
-    def _get_bisect_limits(self):
-        options = self.context.options
-
-        max_limit = 999999
-        limits = [max_limit for _ in options.source_files]
-        all_passes = [
-            l for l in self._clang_opt_bisect_build(limits)[1].splitlines()
-            if l.startswith('BISECT: running pass (')
-        ]
-
-        results = []
-        for i, pass_ in enumerate(all_passes[1:]):
-            if pass_.startswith('BISECT: running pass (1)'):
-                results.append(all_passes[i])
-        results.append(all_passes[-1])
-
-        assert len(results) == len(
-            options.source_files), (results, options.source_files)
-
-        limits = [
-            int(Tool._re_running_pass.match(r).group(1)) for r in results
-        ]
-
-        return limits
-
-    def handle_options(self, defaults):
-        options = self.context.options
-        if "clang" not in options.builder.lower():
-            raise Error("--builder %s is not supported by the clang-opt-bisect tool - only 'clang' is "
-                        "supported " % options.builder)
-        super(Tool, self).handle_options(defaults)
-
-    def _init_debugger_controller(self):
-        step_collection = DextIR(
-            executable_path=self.context.options.executable,
-            source_paths=self.context.options.source_files,
-            dexter_version=self.context.version)
-
-        step_collection.commands, new_source_files = get_command_infos(
-            self.context.options.source_files, self.context.options.source_root_dir)
-        self.context.options.source_files.extend(list(new_source_files))
-
-        debugger_controller = DefaultController(self.context, step_collection)
-        return debugger_controller
-
-    def _run_test(self, test_name):  # noqa
-        options = self.context.options
-
-        per_pass_score = []
-        current_bisect_pass_summary = defaultdict(list)
-
-        max_limits = self._get_bisect_limits()
-        overall_limit = sum(max_limits)
-        prev_score = 1.0
-        prev_steps_str = None
-
-        for current_limit in range(overall_limit + 1):
-            # Take the overall limit number and split it across buckets for
-            # each source file.
-            limit_remaining = current_limit
-            file_limits = [0] * len(max_limits)
-            for i, max_limit in enumerate(max_limits):
-                if limit_remaining < max_limit:
-                    file_limits[i] += limit_remaining
-                    break
-                else:
-                    file_limits[i] = max_limit
-                    limit_remaining -= file_limits[i]
-
-            f = [l for l in file_limits if l]
-            current_file_index = len(f) - 1 if f else 0
-
-            _, err, builderIR = self._clang_opt_bisect_build(file_limits)
-            err_lines = err.splitlines()
-            # Find the last line that specified a running pass.
-            for l in err_lines[::-1]:
-                match = Tool._re_running_pass.match(l)
-                if match:
-                    pass_info = match.groups()
-                    break
-            else:
-                pass_info = (0, None, None)
-
-            try:
-                debugger_controller =self._init_debugger_controller()
-                debugger_controller = run_debugger_subprocess(
-                    debugger_controller, self.context.working_directory.path)
-                steps = debugger_controller.step_collection
-            except DebuggerException:
-                steps =  DextIR(
-                    executable_path=self.context.options.executable,
-                    source_paths=self.context.options.source_files,
-                    dexter_version=self.context.version)
-
-            steps.builder = builderIR
-
-            try:
-                heuristic = Heuristic(self.context, steps)
-            except HeuristicException as e:
-                raise Error(e)
-
-            score_difference = heuristic.score - prev_score
-            prev_score = heuristic.score
-
-            isnan = heuristic.score != heuristic.score
-            if isnan or score_difference < 0:
-                color1 = 'r'
-                color2 = 'r'
-            elif score_difference > 0:
-                color1 = 'g'
-                color2 = 'g'
-            else:
-                color1 = 'y'
-                color2 = 'd'
-
-            summary = '<{}>running pass {}/{} on "{}"'.format(
-                color2, pass_info[0], max_limits[current_file_index],
-                test_name)
-            if len(options.source_files) > 1:
-                summary += ' [{}/{}]'.format(current_limit, overall_limit)
-
-            pass_text = ''.join(p for p in pass_info[1:] if p)
-            summary += ': {} <{}>{:+.4f}</> <{}>{}</></>\n'.format(
-                heuristic.summary_string, color1, score_difference, color2,
-                pass_text)
-
-            self.context.o.auto(summary)
-
-            heuristic_verbose_output = heuristic.verbose_output
-
-            if options.verbose:
-                self.context.o.auto(heuristic_verbose_output)
-
-            steps_str = str(steps)
-            steps_changed = steps_str != prev_steps_str
-            prev_steps_str = steps_str
-
-            # If this is the first pass, or something has changed, write a text
-            # file containing verbose information on the current status.
-            if current_limit == 0 or score_difference or steps_changed:
-                file_name = '-'.join(
-                    str(s) for s in [
-                        'status', test_name, '{{:0>{}}}'.format(
-                            len(str(overall_limit))).format(current_limit),
-                        '{:.4f}'.format(heuristic.score).replace(
-                            '.', '_'), pass_info[1]
-                    ] if s is not None)
-
-                file_name = ''.join(
-                    c for c in file_name
-                    if c.isalnum() or c in '()-_./ ').strip().replace(
-                    ' ', '_').replace('/', '_')
-
-                output_text_path = os.path.join(options.results_directory,
-                                                '{}.txt'.format(file_name))
-                with open(output_text_path, 'w') as fp:
-                    self.context.o.auto(summary + '\n', stream=Stream(fp))
-                    self.context.o.auto(str(steps) + '\n', stream=Stream(fp))
-                    self.context.o.auto(
-                        heuristic_verbose_output + '\n', stream=Stream(fp))
-
-                output_dextIR_path = os.path.join(options.results_directory,
-                                                  '{}.dextIR'.format(file_name))
-                with open(output_dextIR_path, 'wb') as fp:
-                    pickle.dump(steps, fp, protocol=pickle.HIGHEST_PROTOCOL)
-
-            per_pass_score.append((test_name, pass_text,
-                                   heuristic.score))
-
-            if pass_info[1]:
-                self._all_bisect_pass_summary[pass_info[1]].append(
-                    score_difference)
-
-                current_bisect_pass_summary[pass_info[1]].append(
-                    score_difference)
-
-        per_pass_score_path = os.path.join(
-            options.results_directory,
-            '{}-per_pass_score.csv'.format(test_name))
-
-        with open(per_pass_score_path, mode='w', newline='') as fp:
-            writer = csv.writer(fp, delimiter=',')
-            writer.writerow(['Source File', 'Pass', 'Score'])
-
-            for path, pass_, score in per_pass_score:
-                writer.writerow([path, pass_, score])
-        self.context.o.blue('wrote "{}"\n'.format(per_pass_score_path))
-
-        pass_summary_path = os.path.join(
-            options.results_directory, '{}-pass-summary.csv'.format(test_name))
-
-        self._write_pass_summary(pass_summary_path,
-                                 current_bisect_pass_summary)
-
-    def _handle_results(self) -> ReturnCode:
-        options = self.context.options
-        pass_summary_path = os.path.join(options.results_directory,
-                                         'overall-pass-summary.csv')
-
-        self._write_pass_summary(pass_summary_path,
-                                 self._all_bisect_pass_summary)
-        return ReturnCode.OK
-
-    def _clang_opt_bisect_build(self, opt_bisect_limits):
-        options = self.context.options
-        compiler_options = [
-            '{} -mllvm -opt-bisect-limit={}'.format(options.cflags,
-                                                    opt_bisect_limit)
-            for opt_bisect_limit in opt_bisect_limits
-        ]
-        linker_options = options.ldflags
-
-        try:
-            return run_external_build_script(
-                self.context,
-                source_files=options.source_files,
-                compiler_options=compiler_options,
-                linker_options=linker_options,
-                script_path=self.build_script,
-                executable_file=options.executable)
-        except BuildScriptException as e:
-            raise Error(e)
-
-    def _write_pass_summary(self, path, pass_summary):
-        # Get a list of tuples.
-        pass_summary_list = list(pass_summary.items())
-
-        for i, item in enumerate(pass_summary_list):
-            # Add elems for the sum, min, and max of the values, as well as
-            # 'interestingness' which is whether any of these values are
-            # non-zero.
-            pass_summary_list[i] += (sum(item[1]), min(item[1]), max(item[1]),
-                                     any(item[1]))
-
-            # Split the pass name into the basic name and kind.
-            pass_summary_list[i] += tuple(item[0].rsplit(' on ', 1))
-
-        # Sort the list by the following columns in order of precedence:
-        #   - Is interesting (True first)
-        #   - Sum (smallest first)
-        #   - Number of times pass ran (largest first)
-        #   - Kind (alphabetically)
-        #   - Name (alphabetically)
-        pass_summary_list.sort(
-            key=lambda tup: (not tup[5], tup[2], -len(tup[1]), tup[7], tup[6]))
-
-        with open(path, mode='w', newline='') as fp:
-            writer = csv.writer(fp, delimiter=',')
-            writer.writerow(
-                ['Pass', 'Kind', 'Sum', 'Min', 'Max', 'Interesting'])
-
-            for (_, vals, sum_, min_, max_, interesting, name,
-                 kind) in pass_summary_list:
-                writer.writerow([name, kind, sum_, min_, max_, interesting] +
-                                vals)
-
-        self.context.o.blue('wrote "{}"\n'.format(path))
diff --git a/dexter/dex/tools/clang_opt_bisect/__init__.py b/dexter/dex/tools/clang_opt_bisect/__init__.py
deleted file mode 100644
index b933e69..0000000
--- a/dexter/dex/tools/clang_opt_bisect/__init__.py
+++ /dev/null
@@ -1,8 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-
-from dex.tools.clang_opt_bisect.Tool import Tool
diff --git a/dexter/dex/tools/help/Tool.py b/dexter/dex/tools/help/Tool.py
deleted file mode 100644
index 2b35af4..0000000
--- a/dexter/dex/tools/help/Tool.py
+++ /dev/null
@@ -1,61 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-"""Help tool."""
-
-import imp
-import textwrap
-
-from dex.tools import ToolBase, get_tool_names, get_tools_directory, tool_main
-from dex.utils.ReturnCode import ReturnCode
-
-
-class Tool(ToolBase):
-    """Provides help info on subtools."""
-
-    @property
-    def name(self):
-        return 'DExTer help'
-
-    @property
-    def _visible_tool_names(self):
-        return [t for t in get_tool_names() if not t.endswith('-')]
-
-    def add_tool_arguments(self, parser, defaults):
-        parser.description = Tool.__doc__
-        parser.add_argument(
-            'tool',
-            choices=self._visible_tool_names,
-            nargs='?',
-            help='name of subtool')
-
-    def handle_options(self, defaults):
-        pass
-
-    @property
-    def _default_text(self):
-        s = '\n<b>The following subtools are available:</>\n\n'
-        tools_directory = get_tools_directory()
-        for tool_name in sorted(self._visible_tool_names):
-            internal_name = tool_name.replace('-', '_')
-            module_info = imp.find_module(internal_name, [tools_directory])
-            tool_doc = imp.load_module(internal_name,
-                                       *module_info).Tool.__doc__
-            tool_doc = tool_doc.strip() if tool_doc else ''
-            tool_doc = textwrap.fill(' '.join(tool_doc.split()), 80)
-            s += '<g>{}</>\n{}\n\n'.format(tool_name, tool_doc)
-        return s
-
-    def go(self) -> ReturnCode:
-        if self.context.options.tool is None:
-            self.context.o.auto(self._default_text)
-            return ReturnCode.OK
-
-        tool_name = self.context.options.tool.replace('-', '_')
-        tools_directory = get_tools_directory()
-        module_info = imp.find_module(tool_name, [tools_directory])
-        module = imp.load_module(tool_name, *module_info)
-        return tool_main(self.context, module.Tool(self.context), ['--help'])
diff --git a/dexter/dex/tools/help/__init__.py b/dexter/dex/tools/help/__init__.py
deleted file mode 100644
index 351e8fe..0000000
--- a/dexter/dex/tools/help/__init__.py
+++ /dev/null
@@ -1,8 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-
-from dex.tools.help.Tool import Tool
diff --git a/dexter/dex/tools/list_debuggers/Tool.py b/dexter/dex/tools/list_debuggers/Tool.py
deleted file mode 100644
index 5ef5d65..0000000
--- a/dexter/dex/tools/list_debuggers/Tool.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-"""List debuggers tool."""
-
-from dex.debugger.Debuggers import add_debugger_tool_base_arguments
-from dex.debugger.Debuggers import handle_debugger_tool_base_options
-from dex.debugger.Debuggers import Debuggers
-from dex.tools import ToolBase
-from dex.utils import Timer
-from dex.utils.Exceptions import DebuggerException, Error
-from dex.utils.ReturnCode import ReturnCode
-
-
-class Tool(ToolBase):
-    """List all of the potential debuggers that DExTer knows about and whether
-    there is currently a valid interface available for them.
-    """
-
-    @property
-    def name(self):
-        return 'DExTer list debuggers'
-
-    def add_tool_arguments(self, parser, defaults):
-        parser.description = Tool.__doc__
-        add_debugger_tool_base_arguments(parser, defaults)
-
-    def handle_options(self, defaults):
-        handle_debugger_tool_base_options(self.context, defaults)
-
-    def go(self) -> ReturnCode:
-        with Timer('list debuggers'):
-            try:
-                Debuggers(self.context).list()
-            except DebuggerException as e:
-                raise Error(e)
-        return ReturnCode.OK
diff --git a/dexter/dex/tools/list_debuggers/__init__.py b/dexter/dex/tools/list_debuggers/__init__.py
deleted file mode 100644
index 9574102..0000000
--- a/dexter/dex/tools/list_debuggers/__init__.py
+++ /dev/null
@@ -1,8 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-
-from dex.tools.list_debuggers.Tool import Tool
diff --git a/dexter/dex/tools/no_tool_/Tool.py b/dexter/dex/tools/no_tool_/Tool.py
deleted file mode 100644
index 3d73189..0000000
--- a/dexter/dex/tools/no_tool_/Tool.py
+++ /dev/null
@@ -1,49 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-"""This is a special subtool that is run when no subtool is specified.
-It just provides a welcome message and simple usage instructions.
-"""
-
-from dex.tools import ToolBase, get_tool_names
-from dex.utils.Exceptions import Error
-from dex.utils.ReturnCode import ReturnCode
-
-
-# This is a special "tool" that is run when no subtool has been specified on
-# the command line. Its only job is to provide useful usage info.
-class Tool(ToolBase):
-    """Welcome to DExTer (Debugging Experience Tester).
-    Please choose a subtool from the list below.  Use 'dexter.py help' for more
-    information.
-    """
-
-    @property
-    def name(self):
-        return 'DExTer'
-
-    def add_tool_arguments(self, parser, defaults):
-        parser.description = Tool.__doc__
-        parser.add_argument(
-            'subtool',
-            choices=[t for t in get_tool_names() if not t.endswith('-')],
-            nargs='?',
-            help='name of subtool')
-        parser.add_argument(
-            'subtool_options',
-            metavar='subtool-options',
-            nargs='*',
-            help='subtool specific options')
-
-    def handle_options(self, defaults):
-        if not self.context.options.subtool:
-            raise Error('<d>no subtool specified</>\n\n{}\n'.format(
-                self.parser.format_help()))
-
-    def go(self) -> ReturnCode:
-        # This fn is never called because not specifying a subtool raises an
-        # exception.
-        return ReturnCode._ERROR
diff --git a/dexter/dex/tools/no_tool_/__init__.py b/dexter/dex/tools/no_tool_/__init__.py
deleted file mode 100644
index 0e355f8..0000000
--- a/dexter/dex/tools/no_tool_/__init__.py
+++ /dev/null
@@ -1,8 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-
-from dex.tools.no_tool_.Tool import Tool
diff --git a/dexter/dex/tools/run_debugger_internal_/Tool.py b/dexter/dex/tools/run_debugger_internal_/Tool.py
deleted file mode 100644
index c4536c4..0000000
--- a/dexter/dex/tools/run_debugger_internal_/Tool.py
+++ /dev/null
@@ -1,62 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-"""This is an internal subtool used to sandbox the communication with a
-debugger into a separate process so that any crashes inside the debugger will
-not bring down the entire DExTer tool.
-"""
-
-import pickle
-
-from dex.debugger import Debuggers
-from dex.tools import ToolBase
-from dex.utils import Timer
-from dex.utils.Exceptions import DebuggerException, Error
-from dex.utils.ReturnCode import ReturnCode
-
-class Tool(ToolBase):
-    def __init__(self, *args, **kwargs):
-        self.controller_path = None
-        self.debugger_controller = None
-        self.options = None
-        super(Tool, self).__init__(*args, **kwargs)
-
-    @property
-    def name(self):
-        return 'DExTer run debugger internal'
-
-    def add_tool_arguments(self, parser, defaults):
-        parser.add_argument(
-            'controller_path',
-            type=str,
-            help='pickled debugger controller file')
-
-    def handle_options(self, defaults):
-        with open(self.context.options.controller_path, 'rb') as fp:
-            self.debugger_controller = pickle.load(fp)
-        self.controller_path = self.context.options.controller_path   
-        self.context = self.debugger_controller.context
-        self.options = self.context.options
-        Timer.display = self.options.time_report
-
-    def go(self) -> ReturnCode:
-        with Timer('loading debugger'):
-            debugger = Debuggers(self.context).load(self.options.debugger)
-
-        with Timer('running debugger'):
-            if not debugger.is_available:
-                msg = '<d>could not load {}</> ({})\n'.format(
-                    debugger.name, debugger.loading_error)
-                if self.options.verbose:
-                    msg = '{}\n    {}'.format(
-                        msg, '    '.join(debugger.loading_error_trace))
-                raise Error(msg)
-
-        self.debugger_controller.run_debugger(debugger)
-
-        with open(self.controller_path, 'wb') as fp:
-            pickle.dump(self.debugger_controller, fp)
-        return ReturnCode.OK
diff --git a/dexter/dex/tools/run_debugger_internal_/__init__.py b/dexter/dex/tools/run_debugger_internal_/__init__.py
deleted file mode 100644
index db3f98b..0000000
--- a/dexter/dex/tools/run_debugger_internal_/__init__.py
+++ /dev/null
@@ -1,8 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-
-from dex.tools.run_debugger_internal_.Tool import Tool
diff --git a/dexter/dex/tools/test/Tool.py b/dexter/dex/tools/test/Tool.py
deleted file mode 100644
index 1456d6e..0000000
--- a/dexter/dex/tools/test/Tool.py
+++ /dev/null
@@ -1,286 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-"""Test tool."""
-
-import math
-import os
-import csv
-import pickle
-import shutil
-
-from dex.builder import run_external_build_script
-from dex.command.ParseCommand import get_command_infos
-from dex.debugger.Debuggers import run_debugger_subprocess
-from dex.debugger.DebuggerControllers.DefaultController import DefaultController
-from dex.debugger.DebuggerControllers.ConditionalController import ConditionalController
-from dex.dextIR.DextIR import DextIR
-from dex.heuristic import Heuristic
-from dex.tools import TestToolBase
-from dex.utils.Exceptions import DebuggerException
-from dex.utils.Exceptions import BuildScriptException, HeuristicException
-from dex.utils.PrettyOutputBase import Stream
-from dex.utils.ReturnCode import ReturnCode
-from dex.dextIR import BuilderIR
-
-
-class TestCase(object):
-    def __init__(self, context, name, heuristic, error):
-        self.context = context
-        self.name = name
-        self.heuristic = heuristic
-        self.error = error
-
-    @property
-    def penalty(self):
-        try:
-            return self.heuristic.penalty
-        except AttributeError:
-            return float('nan')
-
-    @property
-    def max_penalty(self):
-        try:
-            return self.heuristic.max_penalty
-        except AttributeError:
-            return float('nan')
-
-    @property
-    def score(self):
-        try:
-            return self.heuristic.score
-        except AttributeError:
-            return float('nan')
-
-    def __str__(self):
-        if self.error and self.context.options.verbose:
-            verbose_error = str(self.error)
-        else:
-            verbose_error = ''
-
-        if self.error:
-            script_error = (' : {}'.format(
-                self.error.script_error.splitlines()[0]) if getattr(
-                    self.error, 'script_error', None) else '')
-
-            error = ' [{}{}]'.format(
-                str(self.error).splitlines()[0], script_error)
-        else:
-            error = ''
-
-        try:
-            summary = self.heuristic.summary_string
-        except AttributeError:
-            summary = '<r>nan/nan (nan)</>'
-        return '{}: {}{}\n{}'.format(self.name, summary, error, verbose_error)
-
-
-class Tool(TestToolBase):
-    """Run the specified DExTer test(s) with the specified compiler and linker
-    options and produce a dextIR file as well as printing out the debugging
-    experience score calculated by the DExTer heuristic.
-    """
-
-    def __init__(self, *args, **kwargs):
-        super(Tool, self).__init__(*args, **kwargs)
-        self._test_cases = []
-
-    @property
-    def name(self):
-        return 'DExTer test'
-
-    def add_tool_arguments(self, parser, defaults):
-        parser.add_argument('--fail-lt',
-                            type=float,
-                            default=0.0, # By default TEST always succeeds.
-                            help='exit with status FAIL(2) if the test result'
-                                ' is less than this value.',
-                            metavar='<float>')
-        parser.add_argument('--calculate-average',
-                            action="store_true",
-                            help='calculate the average score of every test run')
-        super(Tool, self).add_tool_arguments(parser, defaults)
-
-    def _build_test_case(self):
-        """Build an executable from the test source with the given --builder
-        script and flags (--cflags, --ldflags) in the working directory.
-        Or, if the --binary option has been given, copy the executable provided
-        into the working directory and rename it to match the --builder output.
-        """
-
-        options = self.context.options
-        if options.binary:
-            # Copy user's binary into the tmp working directory
-            shutil.copy(options.binary, options.executable)
-            builderIR = BuilderIR(
-                name='binary',
-                cflags=[options.binary],
-                ldflags='')
-        else:
-            options = self.context.options
-            compiler_options = [options.cflags for _ in options.source_files]
-            linker_options = options.ldflags
-            _, _, builderIR = run_external_build_script(
-                self.context,
-                script_path=self.build_script,
-                source_files=options.source_files,
-                compiler_options=compiler_options,
-                linker_options=linker_options,
-                executable_file=options.executable)
-        return builderIR
-
-    def _init_debugger_controller(self):
-        step_collection = DextIR(
-            executable_path=self.context.options.executable,
-            source_paths=self.context.options.source_files,
-            dexter_version=self.context.version)
-
-        step_collection.commands, new_source_files = get_command_infos(
-            self.context.options.test_files, self.context.options.source_root_dir)
-
-        self.context.options.source_files.extend(list(new_source_files))
-
-        if 'DexLimitSteps' in step_collection.commands:
-            debugger_controller = ConditionalController(self.context, step_collection)
-        else:
-            debugger_controller = DefaultController(self.context, step_collection)
-
-        return debugger_controller
-
-    def _get_steps(self, builderIR):
-        """Generate a list of debugger steps from a test case.
-        """
-        debugger_controller = self._init_debugger_controller()
-        debugger_controller = run_debugger_subprocess(
-            debugger_controller, self.context.working_directory.path)
-        steps = debugger_controller.step_collection
-        steps.builder = builderIR
-        return steps
-
-    def _get_results_basename(self, test_name):
-        def splitall(x):
-            while len(x) > 0:
-              x, y = os.path.split(x)
-              yield y
-        all_components = reversed([x for x in splitall(test_name)])
-        return '_'.join(all_components)
-
-    def _get_results_path(self, test_name):
-        """Returns the path to the test results directory for the test denoted
-        by test_name.
-        """
-        return os.path.join(self.context.options.results_directory,
-                            self._get_results_basename(test_name))
-
-    def _get_results_text_path(self, test_name):
-        """Returns path results .txt file for test denoted by test_name.
-        """
-        test_results_path = self._get_results_path(test_name)
-        return '{}.txt'.format(test_results_path)
-
-    def _get_results_pickle_path(self, test_name):
-        """Returns path results .dextIR file for test denoted by test_name.
-        """
-        test_results_path = self._get_results_path(test_name)
-        return '{}.dextIR'.format(test_results_path)
-
-    def _record_steps(self, test_name, steps):
-        """Write out the set of steps out to the test's .txt and .json
-        results file.
-        """
-        output_text_path = self._get_results_text_path(test_name)
-        with open(output_text_path, 'w') as fp:
-            self.context.o.auto(str(steps), stream=Stream(fp))
-
-        output_dextIR_path = self._get_results_pickle_path(test_name)
-        with open(output_dextIR_path, 'wb') as fp:
-            pickle.dump(steps, fp, protocol=pickle.HIGHEST_PROTOCOL)
-
-    def _record_score(self, test_name, heuristic):
-        """Write out the test's heuristic score to the results .txt file.
-        """
-        output_text_path = self._get_results_text_path(test_name)
-        with open(output_text_path, 'a') as fp:
-            self.context.o.auto(heuristic.verbose_output, stream=Stream(fp))
-
-    def _record_test_and_display(self, test_case):
-        """Output test case to o stream and record test case internally for
-        handling later.
-        """
-        self.context.o.auto(test_case)
-        self._test_cases.append(test_case)
-
-    def _record_failed_test(self, test_name, exception):
-        """Instantiate a failed test case with failure exception and
-        store internally.
-        """
-        test_case = TestCase(self.context, test_name, None, exception)
-        self._record_test_and_display(test_case)
-
-    def _record_successful_test(self, test_name, steps, heuristic):
-        """Instantiate a successful test run, store test for handling later.
-        Display verbose output for test case if required.
-        """
-        test_case = TestCase(self.context, test_name, heuristic, None)
-        self._record_test_and_display(test_case)
-        if self.context.options.verbose:
-            self.context.o.auto('\n{}\n'.format(steps))
-            self.context.o.auto(heuristic.verbose_output)
-
-    def _run_test(self, test_name):
-        """Attempt to run test files specified in options.source_files. Store
-        result internally in self._test_cases.
-        """
-        try:
-            builderIR = self._build_test_case()
-            steps = self._get_steps(builderIR)
-            self._record_steps(test_name, steps)
-            heuristic_score = Heuristic(self.context, steps)
-            self._record_score(test_name, heuristic_score)
-        except (BuildScriptException, DebuggerException,
-                HeuristicException) as e:
-            self._record_failed_test(test_name, e)
-            return
-
-        self._record_successful_test(test_name, steps, heuristic_score)
-        return
-
-    def _handle_results(self) -> ReturnCode:
-        return_code = ReturnCode.OK
-        options = self.context.options
-
-        if not options.verbose:
-            self.context.o.auto('\n')
-
-        if options.calculate_average:
-            # Calculate and print the average score
-            score_sum = 0.0
-            num_tests = 0
-            for test_case in self._test_cases:
-                score = test_case.score
-                if not test_case.error and not math.isnan(score):
-                    score_sum += test_case.score
-                    num_tests += 1
-
-            if num_tests != 0:
-                print("@avg: ({:.4f})".format(score_sum/num_tests))
-
-        summary_path = os.path.join(options.results_directory, 'summary.csv')
-        with open(summary_path, mode='w', newline='') as fp:
-            writer = csv.writer(fp, delimiter=',')
-            writer.writerow(['Test Case', 'Score', 'Error'])
-
-            for test_case in self._test_cases:
-                if (test_case.score < options.fail_lt or
-                        test_case.error is not None):
-                    return_code = ReturnCode.FAIL
-
-                writer.writerow([
-                    test_case.name, '{:.4f}'.format(test_case.score),
-                    test_case.error
-                ])
-
-        return return_code
diff --git a/dexter/dex/tools/test/__init__.py b/dexter/dex/tools/test/__init__.py
deleted file mode 100644
index 01ead3a..0000000
--- a/dexter/dex/tools/test/__init__.py
+++ /dev/null
@@ -1,8 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-
-from dex.tools.test.Tool import Tool
diff --git a/dexter/dex/tools/view/Tool.py b/dexter/dex/tools/view/Tool.py
deleted file mode 100644
index ad7d530..0000000
--- a/dexter/dex/tools/view/Tool.py
+++ /dev/null
@@ -1,59 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-"""View tool."""
-
-import os
-
-import pickle
-from dex.heuristic import Heuristic
-from dex.heuristic.Heuristic import add_heuristic_tool_arguments
-from dex.tools import ToolBase
-from dex.utils.Exceptions import Error, HeuristicException
-from dex.utils.ReturnCode import ReturnCode
-
-
-class Tool(ToolBase):
-    """Given a dextIR file, display the information in a human-readable form.
-    """
-
-    @property
-    def name(self):
-        return 'DExTer view'
-
-    def add_tool_arguments(self, parser, defaults):
-        add_heuristic_tool_arguments(parser)
-        parser.add_argument(
-            'input_path',
-            metavar='dextIR-file',
-            type=str,
-            default=None,
-            help='dexter dextIR file to view')
-        parser.description = Tool.__doc__
-
-    def handle_options(self, defaults):
-        options = self.context.options
-
-        options.input_path = os.path.abspath(options.input_path)
-        if not os.path.isfile(options.input_path):
-            raise Error('<d>could not find dextIR file</> <r>"{}"</>'.format(
-                options.input_path))
-
-    def go(self) -> ReturnCode:
-        options = self.context.options
-
-        with open(options.input_path, 'rb') as fp:
-            steps = pickle.load(fp)
-
-        try:
-            heuristic = Heuristic(self.context, steps)
-        except HeuristicException as e:
-            raise Error('could not apply heuristic: {}'.format(e))
-
-        self.context.o.auto('{}\n\n{}\n\n{}\n\n'.format(
-            heuristic.summary_string, steps, heuristic.verbose_output))
-
-        return ReturnCode.OK
diff --git a/dexter/dex/tools/view/__init__.py b/dexter/dex/tools/view/__init__.py
deleted file mode 100644
index 1868fca..0000000
--- a/dexter/dex/tools/view/__init__.py
+++ /dev/null
@@ -1,8 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-
-from dex.tools.view.Tool import Tool
diff --git a/dexter/dex/utils/Environment.py b/dexter/dex/utils/Environment.py
deleted file mode 100644
index d2df252..0000000
--- a/dexter/dex/utils/Environment.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-"""Utility functions for querying the current environment."""
-
-import os
-
-
-def is_native_windows():
-    return os.name == 'nt'
-
-
-def has_pywin32():
-    try:
-        import win32com.client  # pylint:disable=unused-variable
-        import win32api  # pylint:disable=unused-variable
-        return True
-    except ImportError:
-        return False
diff --git a/dexter/dex/utils/Exceptions.py b/dexter/dex/utils/Exceptions.py
deleted file mode 100644
index 39c0c2f..0000000
--- a/dexter/dex/utils/Exceptions.py
+++ /dev/null
@@ -1,72 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-"""Provides Dexter-specific exception types."""
-
-
-class Dexception(Exception):
-    """All dexter-specific exceptions derive from this."""
-    pass
-
-
-class Error(Dexception):
-    """Error.  Prints 'error: <message>' without a traceback."""
-    pass
-
-
-class DebuggerException(Dexception):
-    """Any error from using the debugger."""
-
-    def __init__(self, msg, orig_exception=None):
-        super(DebuggerException, self).__init__(msg)
-        self.msg = msg
-        self.orig_exception = orig_exception
-
-    def __str__(self):
-        return str(self.msg)
-
-
-class LoadDebuggerException(DebuggerException):
-    """If specified debugger cannot be loaded."""
-    pass
-
-
-class NotYetLoadedDebuggerException(LoadDebuggerException):
-    """If specified debugger has not yet been attempted to load."""
-
-    def __init__(self):
-        super(NotYetLoadedDebuggerException,
-              self).__init__('not loaded', orig_exception=None)
-
-
-class CommandParseError(Dexception):
-    """If a command instruction cannot be successfully parsed."""
-
-    def __init__(self, *args, **kwargs):
-        super(CommandParseError, self).__init__(*args, **kwargs)
-        self.filename = None
-        self.lineno = None
-        self.info = None
-        self.src = None
-        self.caret = None
-
-
-class ToolArgumentError(Dexception):
-    """If a tool argument is invalid."""
-    pass
-
-
-class BuildScriptException(Dexception):
-    """If there is an error in a build script file."""
-
-    def __init__(self, *args, **kwargs):
-        self.script_error = kwargs.pop('script_error', None)
-        super(BuildScriptException, self).__init__(*args, **kwargs)
-
-
-class HeuristicException(Dexception):
-    """If there was a problem with the heuristic."""
-    pass
diff --git a/dexter/dex/utils/ExtArgParse.py b/dexter/dex/utils/ExtArgParse.py
deleted file mode 100644
index 9fa08fb..0000000
--- a/dexter/dex/utils/ExtArgParse.py
+++ /dev/null
@@ -1,148 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-"""Extended Argument Parser. Extends the argparse module with some extra
-functionality, to hopefully aid user-friendliness.
-"""
-
-import argparse
-import difflib
-import unittest
-
-from dex.utils import PrettyOutput
-from dex.utils.Exceptions import Error
-
-# re-export all of argparse
-for argitem in argparse.__all__:
-    vars()[argitem] = getattr(argparse, argitem)
-
-
-def _did_you_mean(val, possibles):
-    close_matches = difflib.get_close_matches(val, possibles)
-    did_you_mean = ''
-    if close_matches:
-        did_you_mean = 'did you mean {}?'.format(' or '.join(
-            "<y>'{}'</>".format(c) for c in close_matches[:2]))
-    return did_you_mean
-
-
-def _colorize(message):
-    lines = message.splitlines()
-    for i, line in enumerate(lines):
-        lines[i] = lines[i].replace('usage:', '<g>usage:</>')
-        if line.endswith(':'):
-            lines[i] = '<g>{}</>'.format(line)
-    return '\n'.join(lines)
-
-
-class ExtArgumentParser(argparse.ArgumentParser):
-    def error(self, message):
-        """Use the Dexception Error mechanism (including auto-colored output).
-        """
-        raise Error('{}\n\n{}'.format(message, self.format_usage()))
-
-    # pylint: disable=redefined-builtin
-    def _print_message(self, message, file=None):
-        if message:
-            if file and file.name == '<stdout>':
-                file = PrettyOutput.stdout
-            else:
-                file = PrettyOutput.stderr
-
-            self.context.o.auto(message, file)
-
-    # pylint: enable=redefined-builtin
-
-    def format_usage(self):
-        return _colorize(super(ExtArgumentParser, self).format_usage())
-
-    def format_help(self):
-        return _colorize(super(ExtArgumentParser, self).format_help() + '\n\n')
-
-    @property
-    def _valid_visible_options(self):
-        """A list of all non-suppressed command line flags."""
-        return [
-            item for sublist in vars(self)['_actions']
-            for item in sublist.option_strings
-            if sublist.help != argparse.SUPPRESS
-        ]
-
-    def parse_args(self, args=None, namespace=None):
-        """Add 'did you mean' output to errors."""
-        args, argv = self.parse_known_args(args, namespace)
-        if argv:
-            errors = []
-            for arg in argv:
-                if arg in self._valid_visible_options:
-                    error = "unexpected argument: <y>'{}'</>".format(arg)
-                else:
-                    error = "unrecognized argument: <y>'{}'</>".format(arg)
-                    dym = _did_you_mean(arg, self._valid_visible_options)
-                    if dym:
-                        error += '  ({})'.format(dym)
-                errors.append(error)
-            self.error('\n       '.join(errors))
-
-        return args
-
-    def add_argument(self, *args, **kwargs):
-        """Automatically add the default value to help text."""
-        if 'default' in kwargs:
-            default = kwargs['default']
-            if default is None:
-                default = kwargs.pop('display_default', None)
-
-            if (default and isinstance(default, (str, int, float))
-                    and default != argparse.SUPPRESS):
-                assert (
-                    'choices' not in kwargs or default in kwargs['choices']), (
-                        "default value '{}' is not one of allowed choices: {}".
-                        format(default, kwargs['choices']))
-                if 'help' in kwargs and kwargs['help'] != argparse.SUPPRESS:
-                    assert isinstance(kwargs['help'], str), type(kwargs['help'])
-                    kwargs['help'] = ('{} (default:{})'.format(
-                        kwargs['help'], default))
-
-        super(ExtArgumentParser, self).add_argument(*args, **kwargs)
-
-    def __init__(self, context, *args, **kwargs):
-        self.context = context
-        super(ExtArgumentParser, self).__init__(*args, **kwargs)
-
-
-class TestExtArgumentParser(unittest.TestCase):
-    def test_did_you_mean(self):
-        parser = ExtArgumentParser(None)
-        parser.add_argument('--foo')
-        parser.add_argument('--qoo', help=argparse.SUPPRESS)
-        parser.add_argument('jam', nargs='?')
-
-        parser.parse_args(['--foo', '0'])
-
-        expected = (r"^unrecognized argument\: <y>'\-\-doo'</>\s+"
-                    r"\(did you mean <y>'\-\-foo'</>\?\)\n"
-                    r"\s*<g>usage:</>")
-        with self.assertRaisesRegex(Error, expected):
-            parser.parse_args(['--doo'])
-
-        parser.add_argument('--noo')
-
-        expected = (r"^unrecognized argument\: <y>'\-\-doo'</>\s+"
-                    r"\(did you mean <y>'\-\-noo'</> or <y>'\-\-foo'</>\?\)\n"
-                    r"\s*<g>usage:</>")
-        with self.assertRaisesRegex(Error, expected):
-            parser.parse_args(['--doo'])
-
-        expected = (r"^unrecognized argument\: <y>'\-\-bar'</>\n"
-                    r"\s*<g>usage:</>")
-        with self.assertRaisesRegex(Error, expected):
-            parser.parse_args(['--bar'])
-
-        expected = (r"^unexpected argument\: <y>'\-\-foo'</>\n"
-                    r"\s*<g>usage:</>")
-        with self.assertRaisesRegex(Error, expected):
-            parser.parse_args(['--', 'x', '--foo'])
diff --git a/dexter/dex/utils/PrettyOutputBase.py b/dexter/dex/utils/PrettyOutputBase.py
deleted file mode 100644
index d21db89..0000000
--- a/dexter/dex/utils/PrettyOutputBase.py
+++ /dev/null
@@ -1,392 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-"""Provides formatted/colored console output on both Windows and Linux.
-
-Do not use this module directly, but instead use via the appropriate platform-
-specific module.
-"""
-
-import abc
-import re
-import sys
-import threading
-import unittest
-
-from io import StringIO
-
-from dex.utils.Exceptions import Error
-
-
-class _NullLock(object):
-    def __enter__(self):
-        return None
-
-    def __exit__(self, *params):
-        pass
-
-
-_lock = threading.Lock()
-_null_lock = _NullLock()
-
-
-class PreserveAutoColors(object):
-    def __init__(self, pretty_output):
-        self.pretty_output = pretty_output
-        self.orig_values = {}
-        self.properties = [
-            'auto_reds', 'auto_yellows', 'auto_greens', 'auto_blues'
-        ]
-
-    def __enter__(self):
-        for p in self.properties:
-            self.orig_values[p] = getattr(self.pretty_output, p)[:]
-        return self
-
-    def __exit__(self, *args):
-        for p in self.properties:
-            setattr(self.pretty_output, p, self.orig_values[p])
-
-
-class Stream(object):
-    def __init__(self, py_, os_=None):
-        self.py = py_
-        self.os = os_
-        self.orig_color = None
-        self.color_enabled = self.py.isatty()
-
-
-class PrettyOutputBase(object, metaclass=abc.ABCMeta):
-    stdout = Stream(sys.stdout)
-    stderr = Stream(sys.stderr)
-
-    def __init__(self):
-        self.auto_reds = []
-        self.auto_yellows = []
-        self.auto_greens = []
-        self.auto_blues = []
-        self._stack = []
-
-    def __enter__(self):
-        return self
-
-    def __exit__(self, *args):
-        pass
-
-    def _set_valid_stream(self, stream):
-        if stream is None:
-            return self.__class__.stdout
-        return stream
-
-    def _write(self, text, stream):
-        text = str(text)
-
-        # Users can embed color control tags in their output
-        # (e.g. <r>hello</> <y>world</> would write the word 'hello' in red and
-        # 'world' in yellow).
-        # This function parses these tags using a very simple recursive
-        # descent.
-        colors = {
-            'r': self.red,
-            'y': self.yellow,
-            'g': self.green,
-            'b': self.blue,
-            'd': self.default,
-            'a': self.auto,
-        }
-
-        # Find all tags (whether open or close)
-        tags = [
-            t for t in re.finditer('<([{}/])>'.format(''.join(colors)), text)
-        ]
-
-        if not tags:
-            # No tags.  Just write the text to the current stream and return.
-            # 'unmangling' any tags that have been mangled so that they won't
-            # render as colors (for example in error output from this
-            # function).
-            stream = self._set_valid_stream(stream)
-            stream.py.write(text.replace(r'\>', '>'))
-            return
-
-        open_tags = [i for i in tags if i.group(1) != '/']
-        close_tags = [i for i in tags if i.group(1) == '/']
-
-        if (len(open_tags) != len(close_tags)
-                or any(o.start() >= c.start()
-                       for (o, c) in zip(open_tags, close_tags))):
-            raise Error('open/close tag mismatch in "{}"'.format(
-                text.rstrip()).replace('>', r'\>'))
-
-        open_tag = open_tags.pop(0)
-
-        # We know that the tags balance correctly, so figure out where the
-        # corresponding close tag is to the current open tag.
-        tag_nesting = 1
-        close_tag = None
-        for tag in tags[1:]:
-            if tag.group(1) == '/':
-                tag_nesting -= 1
-            else:
-                tag_nesting += 1
-            if tag_nesting == 0:
-                close_tag = tag
-                break
-        else:
-            assert False, text
-
-        # Use the method on the top of the stack for text prior to the open
-        # tag.
-        before = text[:open_tag.start()]
-        if before:
-            self._stack[-1](before, lock=_null_lock, stream=stream)
-
-        # Use the specified color for the tag itself.
-        color = open_tag.group(1)
-        within = text[open_tag.end():close_tag.start()]
-        if within:
-            colors[color](within, lock=_null_lock, stream=stream)
-
-        # Use the method on the top of the stack for text after the close tag.
-        after = text[close_tag.end():]
-        if after:
-            self._stack[-1](after, lock=_null_lock, stream=stream)
-
-    def flush(self, stream):
-        stream = self._set_valid_stream(stream)
-        stream.py.flush()
-
-    def auto(self, text, stream=None, lock=_lock):
-        text = str(text)
-        stream = self._set_valid_stream(stream)
-        lines = text.splitlines(True)
-
-        with lock:
-            for line in lines:
-                # This is just being cute for the sake of cuteness, but why
-                # not?
-                line = line.replace('DExTer', '<r>D<y>E<g>x<b>T</></>e</>r</>')
-
-                # Apply the appropriate color method if the expression matches
-                # any of
-                # the patterns we have set up.
-                for fn, regexs in ((self.red, self.auto_reds),
-                                   (self.yellow, self.auto_yellows),
-                                   (self.green,
-                                    self.auto_greens), (self.blue,
-                                                        self.auto_blues)):
-                    if any(re.search(regex, line) for regex in regexs):
-                        fn(line, stream=stream, lock=_null_lock)
-                        break
-                else:
-                    self.default(line, stream=stream, lock=_null_lock)
-
-    def _call_color_impl(self, fn, impl, text, *args, **kwargs):
-        try:
-            self._stack.append(fn)
-            return impl(text, *args, **kwargs)
-        finally:
-            fn = self._stack.pop()
-
-    @abc.abstractmethod
-    def red_impl(self, text, stream=None, **kwargs):
-        pass
-
-    def red(self, *args, **kwargs):
-        return self._call_color_impl(self.red, self.red_impl, *args, **kwargs)
-
-    @abc.abstractmethod
-    def yellow_impl(self, text, stream=None, **kwargs):
-        pass
-
-    def yellow(self, *args, **kwargs):
-        return self._call_color_impl(self.yellow, self.yellow_impl, *args,
-                                     **kwargs)
-
-    @abc.abstractmethod
-    def green_impl(self, text, stream=None, **kwargs):
-        pass
-
-    def green(self, *args, **kwargs):
-        return self._call_color_impl(self.green, self.green_impl, *args,
-                                     **kwargs)
-
-    @abc.abstractmethod
-    def blue_impl(self, text, stream=None, **kwargs):
-        pass
-
-    def blue(self, *args, **kwargs):
-        return self._call_color_impl(self.blue, self.blue_impl, *args,
-                                     **kwargs)
-
-    @abc.abstractmethod
-    def default_impl(self, text, stream=None, **kwargs):
-        pass
-
-    def default(self, *args, **kwargs):
-        return self._call_color_impl(self.default, self.default_impl, *args,
-                                     **kwargs)
-
-    def colortest(self):
-        from itertools import combinations, permutations
-
-        fns = ((self.red, 'rrr'), (self.yellow, 'yyy'), (self.green, 'ggg'),
-               (self.blue, 'bbb'), (self.default, 'ddd'))
-
-        for l in range(1, len(fns) + 1):
-            for comb in combinations(fns, l):
-                for perm in permutations(comb):
-                    for stream in (None, self.__class__.stderr):
-                        perm[0][0]('stdout '
-                                   if stream is None else 'stderr ', stream)
-                        for fn, string in perm:
-                            fn(string, stream)
-                        self.default('\n', stream)
-
-        tests = [
-            (self.auto, 'default1<r>red2</>default3'),
-            (self.red, 'red1<r>red2</>red3'),
-            (self.blue, 'blue1<r>red2</>blue3'),
-            (self.red, 'red1<y>yellow2</>red3'),
-            (self.auto, 'default1<y>yellow2<r>red3</></>'),
-            (self.auto, 'default1<g>green2<r>red3</></>'),
-            (self.auto, 'default1<g>green2<r>red3</>green4</>default5'),
-            (self.auto, 'default1<g>green2</>default3<g>green4</>default5'),
-            (self.auto, '<r>red1<g>green2</>red3<g>green4</>red5</>'),
-            (self.auto, '<r>red1<y><g>green2</>yellow3</>green4</>default5'),
-            (self.auto, '<r><y><g><b><d>default1</></><r></></></>red2</>'),
-            (self.auto, '<r>red1</>default2<r>red3</><g>green4</>default5'),
-            (self.blue, '<r>red1</>blue2<r><r>red3</><g><g>green</></></>'),
-            (self.blue, '<r>r<r>r<y>y<r><r><r><r>r</></></></></></></>b'),
-        ]
-
-        for fn, text in tests:
-            for stream in (None, self.__class__.stderr):
-                stream_name = 'stdout' if stream is None else 'stderr'
-                fn('{} {}\n'.format(stream_name, text), stream)
-
-
-class TestPrettyOutput(unittest.TestCase):
-    class MockPrettyOutput(PrettyOutputBase):
-        def red_impl(self, text, stream=None, **kwargs):
-            self._write('[R]{}[/R]'.format(text), stream)
-
-        def yellow_impl(self, text, stream=None, **kwargs):
-            self._write('[Y]{}[/Y]'.format(text), stream)
-
-        def green_impl(self, text, stream=None, **kwargs):
-            self._write('[G]{}[/G]'.format(text), stream)
-
-        def blue_impl(self, text, stream=None, **kwargs):
-            self._write('[B]{}[/B]'.format(text), stream)
-
-        def default_impl(self, text, stream=None, **kwargs):
-            self._write('[D]{}[/D]'.format(text), stream)
-
-    def test_red(self):
-        with TestPrettyOutput.MockPrettyOutput() as o:
-            stream = Stream(StringIO())
-            o.red('hello', stream)
-            self.assertEqual(stream.py.getvalue(), '[R]hello[/R]')
-
-    def test_yellow(self):
-        with TestPrettyOutput.MockPrettyOutput() as o:
-            stream = Stream(StringIO())
-            o.yellow('hello', stream)
-            self.assertEqual(stream.py.getvalue(), '[Y]hello[/Y]')
-
-    def test_green(self):
-        with TestPrettyOutput.MockPrettyOutput() as o:
-            stream = Stream(StringIO())
-            o.green('hello', stream)
-            self.assertEqual(stream.py.getvalue(), '[G]hello[/G]')
-
-    def test_blue(self):
-        with TestPrettyOutput.MockPrettyOutput() as o:
-            stream = Stream(StringIO())
-            o.blue('hello', stream)
-            self.assertEqual(stream.py.getvalue(), '[B]hello[/B]')
-
-    def test_default(self):
-        with TestPrettyOutput.MockPrettyOutput() as o:
-            stream = Stream(StringIO())
-            o.default('hello', stream)
-            self.assertEqual(stream.py.getvalue(), '[D]hello[/D]')
-
-    def test_auto(self):
-        with TestPrettyOutput.MockPrettyOutput() as o:
-            stream = Stream(StringIO())
-            o.auto_reds.append('foo')
-            o.auto('bar\n', stream)
-            o.auto('foo\n', stream)
-            o.auto('baz\n', stream)
-            self.assertEqual(stream.py.getvalue(),
-                             '[D]bar\n[/D][R]foo\n[/R][D]baz\n[/D]')
-
-            stream = Stream(StringIO())
-            o.auto('bar\nfoo\nbaz\n', stream)
-            self.assertEqual(stream.py.getvalue(),
-                             '[D]bar\n[/D][R]foo\n[/R][D]baz\n[/D]')
-
-            stream = Stream(StringIO())
-            o.auto('barfoobaz\nbardoobaz\n', stream)
-            self.assertEqual(stream.py.getvalue(),
-                             '[R]barfoobaz\n[/R][D]bardoobaz\n[/D]')
-
-            o.auto_greens.append('doo')
-            stream = Stream(StringIO())
-            o.auto('barfoobaz\nbardoobaz\n', stream)
-            self.assertEqual(stream.py.getvalue(),
-                             '[R]barfoobaz\n[/R][G]bardoobaz\n[/G]')
-
-    def test_PreserveAutoColors(self):
-        with TestPrettyOutput.MockPrettyOutput() as o:
-            o.auto_reds.append('foo')
-            with PreserveAutoColors(o):
-                o.auto_greens.append('bar')
-                stream = Stream(StringIO())
-                o.auto('foo\nbar\nbaz\n', stream)
-                self.assertEqual(stream.py.getvalue(),
-                                 '[R]foo\n[/R][G]bar\n[/G][D]baz\n[/D]')
-
-            stream = Stream(StringIO())
-            o.auto('foo\nbar\nbaz\n', stream)
-            self.assertEqual(stream.py.getvalue(),
-                             '[R]foo\n[/R][D]bar\n[/D][D]baz\n[/D]')
-
-            stream = Stream(StringIO())
-            o.yellow('<a>foo</>bar<a>baz</>', stream)
-            self.assertEqual(
-                stream.py.getvalue(),
-                '[Y][Y][/Y][R]foo[/R][Y][Y]bar[/Y][D]baz[/D][Y][/Y][/Y][/Y]')
-
-    def test_tags(self):
-        with TestPrettyOutput.MockPrettyOutput() as o:
-            stream = Stream(StringIO())
-            o.auto('<r>hi</>', stream)
-            self.assertEqual(stream.py.getvalue(),
-                             '[D][D][/D][R]hi[/R][D][/D][/D]')
-
-            stream = Stream(StringIO())
-            o.auto('<r><y>a</>b</>c', stream)
-            self.assertEqual(
-                stream.py.getvalue(),
-                '[D][D][/D][R][R][/R][Y]a[/Y][R]b[/R][/R][D]c[/D][/D]')
-
-            with self.assertRaisesRegex(Error, 'tag mismatch'):
-                o.auto('<r>hi', stream)
-
-            with self.assertRaisesRegex(Error, 'tag mismatch'):
-                o.auto('hi</>', stream)
-
-            with self.assertRaisesRegex(Error, 'tag mismatch'):
-                o.auto('<r><y>hi</>', stream)
-
-            with self.assertRaisesRegex(Error, 'tag mismatch'):
-                o.auto('<r><y>hi</><r></>', stream)
-
-            with self.assertRaisesRegex(Error, 'tag mismatch'):
-                o.auto('</>hi<r>', stream)
diff --git a/dexter/dex/utils/ReturnCode.py b/dexter/dex/utils/ReturnCode.py
deleted file mode 100644
index 487d225..0000000
--- a/dexter/dex/utils/ReturnCode.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-
-from enum import Enum
-
-
-class ReturnCode(Enum):
-   """Used to indicate whole program success status."""
-
-   OK = 0
-   _ERROR = 1        # Unhandled exceptions result in exit(1) by default.
-                     # Usage of _ERROR is discouraged:
-                     # If the program cannot run, raise an exception.
-                     # If the program runs successfully but the result is
-                     # "failure" based on the inputs, return FAIL
-   FAIL = 2
diff --git a/dexter/dex/utils/RootDirectory.py b/dexter/dex/utils/RootDirectory.py
deleted file mode 100644
index 57f204c..0000000
--- a/dexter/dex/utils/RootDirectory.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-"""Utility functions related to DExTer's directory layout."""
-
-import os
-
-
-def get_root_directory():
-    root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
-    assert os.path.basename(root) == 'dex', root
-    return root
diff --git a/dexter/dex/utils/Timer.py b/dexter/dex/utils/Timer.py
deleted file mode 100644
index 63726f1..0000000
--- a/dexter/dex/utils/Timer.py
+++ /dev/null
@@ -1,50 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-"""RAII-style timer class to be used with a 'with' statement to get wall clock
-time for the contained code.
-"""
-
-import sys
-import time
-
-
-def _indent(indent):
-    return '| ' * indent
-
-
-class Timer(object):
-    fn = sys.stdout.write
-    display = False
-    indent = 0
-
-    def __init__(self, name=None):
-        self.name = name
-        self.start = self.now
-
-    def __enter__(self):
-        Timer.indent += 1
-        if Timer.display and self.name:
-            indent = _indent(Timer.indent - 1) + ' _'
-            Timer.fn('{}\n'.format(_indent(Timer.indent - 1)))
-            Timer.fn('{} start {}\n'.format(indent, self.name))
-        return self
-
-    def __exit__(self, *args):
-        if Timer.display and self.name:
-            indent = _indent(Timer.indent - 1) + '|_'
-            Timer.fn('{} {} time taken: {:0.1f}s\n'.format(
-                indent, self.name, self.elapsed))
-            Timer.fn('{}\n'.format(_indent(Timer.indent - 1)))
-        Timer.indent -= 1
-
-    @property
-    def elapsed(self):
-        return self.now - self.start
-
-    @property
-    def now(self):
-        return time.time()
diff --git a/dexter/dex/utils/UnitTests.py b/dexter/dex/utils/UnitTests.py
deleted file mode 100644
index cfddce5..0000000
--- a/dexter/dex/utils/UnitTests.py
+++ /dev/null
@@ -1,64 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-"""Unit test harness."""
-
-from fnmatch import fnmatch
-import os
-import unittest
-
-from io import StringIO
-
-from dex.utils import is_native_windows, has_pywin32
-from dex.utils import PreserveAutoColors, PrettyOutput
-from dex.utils import Timer
-
-
-class DexTestLoader(unittest.TestLoader):
-    def _match_path(self, path, full_path, pattern):
-        """Don't try to import platform-specific modules for the wrong platform
-        during test discovery.
-        """
-        d = os.path.basename(os.path.dirname(full_path))
-        if is_native_windows():
-            if d == 'posix':
-                return False
-            if d == 'windows':
-                return has_pywin32()
-        else:
-            if d == 'windows':
-                return False
-            elif d == 'dbgeng':
-                return False
-        return fnmatch(path, pattern)
-
-
-def unit_tests_ok(context):
-    unittest.TestCase.maxDiff = None  # remove size limit from diff output.
-
-    with Timer('unit tests'):
-        suite = DexTestLoader().discover(
-            context.root_directory, pattern='*.py')
-        stream = StringIO()
-        result = unittest.TextTestRunner(verbosity=2, stream=stream).run(suite)
-
-        ok = result.wasSuccessful()
-        if not ok or context.options.unittest == 'show-all':
-            with PreserveAutoColors(context.o):
-                context.o.auto_reds.extend(
-                    [r'FAIL(ED|\:)', r'\.\.\.\s(FAIL|ERROR)$'])
-                context.o.auto_greens.extend([r'^OK$', r'\.\.\.\sok$'])
-                context.o.auto_blues.extend([r'^Ran \d+ test'])
-                context.o.default('\n')
-                for line in stream.getvalue().splitlines(True):
-                    context.o.auto(line, stream=PrettyOutput.stderr)
-
-        return ok
-
-
-class TestUnitTests(unittest.TestCase):
-    def test_sanity(self):
-        self.assertEqual(1, 1)
diff --git a/dexter/dex/utils/Version.py b/dexter/dex/utils/Version.py
deleted file mode 100644
index 1a257fa..0000000
--- a/dexter/dex/utils/Version.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-"""DExTer version output."""
-
-import os
-from subprocess import CalledProcessError, check_output, STDOUT
-import sys
-
-from dex import __version__
-
-
-def _git_version():
-    dir_ = os.path.dirname(__file__)
-    try:
-        branch = (check_output(
-            ['git', 'rev-parse', '--abbrev-ref', 'HEAD'],
-            stderr=STDOUT,
-            cwd=dir_).rstrip().decode('utf-8'))
-        hash_ = check_output(
-            ['git', 'rev-parse', 'HEAD'], stderr=STDOUT,
-            cwd=dir_).rstrip().decode('utf-8')
-        repo = check_output(
-            ['git', 'remote', 'get-url', 'origin'], stderr=STDOUT,
-            cwd=dir_).rstrip().decode('utf-8')
-        return '[{} {}] ({})'.format(branch, hash_, repo)
-    except (OSError, CalledProcessError):
-        pass
-    return None
-
-
-def version(name):
-    lines = []
-    lines.append(' '.join(
-        [s for s in [name, __version__, _git_version()] if s]))
-    lines.append('  using Python {}'.format(sys.version))
-    return '\n'.join(lines)
diff --git a/dexter/dex/utils/Warning.py b/dexter/dex/utils/Warning.py
deleted file mode 100644
index 402861a..0000000
--- a/dexter/dex/utils/Warning.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-"""Utility functions for producing command line warnings."""
-
-
-def warn(context, msg, flag=None):
-    if context.options.no_warnings:
-        return
-
-    msg = msg.rstrip()
-    if flag:
-        msg = '{} <y>[{}]</>'.format(msg, flag)
-
-    context.o.auto('warning: <d>{}</>\n'.format(msg))
diff --git a/dexter/dex/utils/WorkingDirectory.py b/dexter/dex/utils/WorkingDirectory.py
deleted file mode 100644
index 04f9b64..0000000
--- a/dexter/dex/utils/WorkingDirectory.py
+++ /dev/null
@@ -1,46 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-"""Create/set a temporary working directory for some operations."""
-
-import os
-import shutil
-import tempfile
-import time
-
-from dex.utils.Exceptions import Error
-from dex.utils.Warning import warn
-
-class WorkingDirectory(object):
-    def __init__(self, context, *args, **kwargs):
-        self.context = context
-        self.orig_cwd = os.getcwd()
-
-        dir_ = kwargs.get('dir', None)
-        if dir_ and not os.path.isdir(dir_):
-            os.makedirs(dir_, exist_ok=True)
-        self.path = tempfile.mkdtemp(*args, **kwargs)
-
-    def __enter__(self):
-        os.chdir(self.path)
-        return self
-
-    def __exit__(self, *args):
-        os.chdir(self.orig_cwd)
-        if self.context.options.save_temps:
-            self.context.o.blue('"{}" left in place [--save-temps]\n'.format(
-                self.path))
-            return
-
-        for _ in range(100):
-            try:
-                shutil.rmtree(self.path)
-                return
-            except OSError:
-                time.sleep(0.1)
-
-        warn(self.context, '"{}" left in place (couldn\'t delete)\n'.format(self.path))
-        return
diff --git a/dexter/dex/utils/__init__.py b/dexter/dex/utils/__init__.py
deleted file mode 100644
index ac08139..0000000
--- a/dexter/dex/utils/__init__.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-"""Generic non-dexter-specific utility classes and functions."""
-
-import os
-
-from dex.utils.Environment import is_native_windows, has_pywin32
-from dex.utils.PrettyOutputBase import PreserveAutoColors
-from dex.utils.RootDirectory import get_root_directory
-from dex.utils.Timer import Timer
-from dex.utils.Warning import warn
-from dex.utils.WorkingDirectory import WorkingDirectory
-
-if is_native_windows():
-    from dex.utils.windows.PrettyOutput import PrettyOutput
-else:
-    from dex.utils.posix.PrettyOutput import PrettyOutput
diff --git a/dexter/dex/utils/posix/PrettyOutput.py b/dexter/dex/utils/posix/PrettyOutput.py
deleted file mode 100644
index 82cfed5..0000000
--- a/dexter/dex/utils/posix/PrettyOutput.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-"""Provides POSIX implementation of formatted/colored console output."""
-
-from ..PrettyOutputBase import PrettyOutputBase, _lock
-
-
-class PrettyOutput(PrettyOutputBase):
-    def _color(self, text, color, stream, lock=_lock):
-        """Use ANSI escape codes to provide color on Linux."""
-        stream = self._set_valid_stream(stream)
-        with lock:
-            if stream.color_enabled:
-                text = '\033[{}m{}\033[0m'.format(color, text)
-            self._write(text, stream)
-
-    def red_impl(self, text, stream=None, **kwargs):
-        self._color(text, 91, stream, **kwargs)
-
-    def yellow_impl(self, text, stream=None, **kwargs):
-        self._color(text, 93, stream, **kwargs)
-
-    def green_impl(self, text, stream=None, **kwargs):
-        self._color(text, 92, stream, **kwargs)
-
-    def blue_impl(self, text, stream=None, **kwargs):
-        self._color(text, 96, stream, **kwargs)
-
-    def default_impl(self, text, stream=None, **kwargs):
-        self._color(text, 0, stream, **kwargs)
diff --git a/dexter/dex/utils/posix/__init__.py b/dexter/dex/utils/posix/__init__.py
deleted file mode 100644
index 1194aff..0000000
--- a/dexter/dex/utils/posix/__init__.py
+++ /dev/null
@@ -1,6 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
diff --git a/dexter/dex/utils/windows/PrettyOutput.py b/dexter/dex/utils/windows/PrettyOutput.py
deleted file mode 100644
index 657406a..0000000
--- a/dexter/dex/utils/windows/PrettyOutput.py
+++ /dev/null
@@ -1,83 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-"""Provides Windows implementation of formatted/colored console output."""
-
-import sys
-
-import ctypes
-import ctypes.wintypes
-
-from ..PrettyOutputBase import PrettyOutputBase, Stream, _lock, _null_lock
-
-
-class _CONSOLE_SCREEN_BUFFER_INFO(ctypes.Structure):
-    # pylint: disable=protected-access
-    _fields_ = [('dwSize', ctypes.wintypes._COORD), ('dwCursorPosition',
-                                                     ctypes.wintypes._COORD),
-                ('wAttributes',
-                 ctypes.c_ushort), ('srWindow', ctypes.wintypes._SMALL_RECT),
-                ('dwMaximumWindowSize', ctypes.wintypes._COORD)]
-    # pylint: enable=protected-access
-
-
-class PrettyOutput(PrettyOutputBase):
-
-    stdout = Stream(sys.stdout, ctypes.windll.kernel32.GetStdHandle(-11))
-    stderr = Stream(sys.stderr, ctypes.windll.kernel32.GetStdHandle(-12))
-
-    def __enter__(self):
-        info = _CONSOLE_SCREEN_BUFFER_INFO()
-
-        for s in (PrettyOutput.stdout, PrettyOutput.stderr):
-            ctypes.windll.kernel32.GetConsoleScreenBufferInfo(
-                s.os, ctypes.byref(info))
-            s.orig_color = info.wAttributes
-
-        return self
-
-    def __exit__(self, *args):
-        self._restore_orig_color(PrettyOutput.stdout)
-        self._restore_orig_color(PrettyOutput.stderr)
-
-    def _restore_orig_color(self, stream, lock=_lock):
-        if not stream.color_enabled:
-            return
-
-        with lock:
-            stream = self._set_valid_stream(stream)
-            self.flush(stream)
-            if stream.orig_color:
-                ctypes.windll.kernel32.SetConsoleTextAttribute(
-                    stream.os, stream.orig_color)
-
-    def _color(self, text, color, stream, lock=_lock):
-        stream = self._set_valid_stream(stream)
-        with lock:
-            try:
-                if stream.color_enabled:
-                    ctypes.windll.kernel32.SetConsoleTextAttribute(
-                        stream.os, color)
-                self._write(text, stream)
-            finally:
-                if stream.color_enabled:
-                    self._restore_orig_color(stream, lock=_null_lock)
-
-    def red_impl(self, text, stream=None, **kwargs):
-        self._color(text, 12, stream, **kwargs)
-
-    def yellow_impl(self, text, stream=None, **kwargs):
-        self._color(text, 14, stream, **kwargs)
-
-    def green_impl(self, text, stream=None, **kwargs):
-        self._color(text, 10, stream, **kwargs)
-
-    def blue_impl(self, text, stream=None, **kwargs):
-        self._color(text, 11, stream, **kwargs)
-
-    def default_impl(self, text, stream=None, **kwargs):
-        stream = self._set_valid_stream(stream)
-        self._color(text, stream.orig_color, stream, **kwargs)
diff --git a/dexter/dex/utils/windows/__init__.py b/dexter/dex/utils/windows/__init__.py
deleted file mode 100644
index 1194aff..0000000
--- a/dexter/dex/utils/windows/__init__.py
+++ /dev/null
@@ -1,6 +0,0 @@
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
diff --git a/dexter/dexter.py b/dexter/dexter.py
deleted file mode 100755
index 49ba85d..0000000
--- a/dexter/dexter.py
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/usr/bin/env python
-# DExTer : Debugging Experience Tester
-# ~~~~~~   ~         ~~         ~   ~~
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-"""DExTer entry point. This is the only non-module file."""
-
-import sys
-
-if sys.version_info < (3, 6, 0):
-    sys.stderr.write("You need python 3.6 or later to run DExTer\n")
-    # Equivalent to sys.exit(ReturnCode._ERROR).
-    sys.exit(1)
-
-from dex.tools import main
-
-if __name__ == '__main__':
-    return_code = main()
-    sys.exit(return_code.value)
diff --git a/dexter/feature_tests/Readme.md b/dexter/feature_tests/Readme.md
deleted file mode 100644
index 303aa3c..0000000
--- a/dexter/feature_tests/Readme.md
+++ /dev/null
@@ -1,4 +0,0 @@
-# DExTer feature tests
-
-This directory is home to dexter feature and regression tests to be run with
-llvm-lit.
\ No newline at end of file
diff --git a/dexter/feature_tests/commands/penalty/dex_declare_file.cpp b/dexter/feature_tests/commands/penalty/dex_declare_file.cpp
deleted file mode 100644
index 7860ffd..0000000
--- a/dexter/feature_tests/commands/penalty/dex_declare_file.cpp
+++ /dev/null
@@ -1,17 +0,0 @@
-// Purpose:
-//    Check that \DexDeclareFile causes a DexExpectWatchValue's to generate a
-//    missing value penalty when the declared path is incorrect.
-//
-// UNSUPPORTED: system-darwin
-//
-//
-// RUN: not %dexter_regression_test -- %s | FileCheck %s
-// CHECK: dex_declare_file.cpp
-
-int main() {
-  int result = 0;
-  return result; //DexLabel('return')
-}
-
-// DexDeclareFile('this_file_does_not_exist.cpp')
-// DexExpectWatchValue('result', 0, on_line='return')
diff --git a/dexter/feature_tests/commands/penalty/expect_program_state.cpp b/dexter/feature_tests/commands/penalty/expect_program_state.cpp
deleted file mode 100644
index 2493fd0..0000000
--- a/dexter/feature_tests/commands/penalty/expect_program_state.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-// Purpose:
-//      Check that \DexExpectProgramState correctly applies a penalty when
-//      an expected program state is never found.
-//
-// UNSUPPORTED: system-darwin
-//
-// RUN: not %dexter_regression_test -- %s | FileCheck %s
-// CHECK: expect_program_state.cpp:
-
-int GCD(int lhs, int rhs)
-{
-    if (rhs == 0)   // DexLabel('check')
-        return lhs;
-    return GCD(rhs, lhs % rhs);
-}
-
-int main()
-{
-    return GCD(111, 259);
-}
-
-/*
-DexExpectProgramState({
-    'frames': [
-        {
-            'location': {
-                'lineno': ref('check')
-            },
-            'watches': {
-                'lhs': '0', 'rhs': '0'
-            }
-        },
-    ]
-})
-*/
diff --git a/dexter/feature_tests/commands/penalty/expect_step_kinds.cpp b/dexter/feature_tests/commands/penalty/expect_step_kinds.cpp
deleted file mode 100644
index 2075cd2..0000000
--- a/dexter/feature_tests/commands/penalty/expect_step_kinds.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-// Purpose:
-//      Check that \DexExpectStepKind correctly applies a penalty when
-//      unexpected step kinds are encountered.
-//
-// UNSUPPORTED: system-darwin
-//
-// RUN: not %dexter_regression_test -- %s | FileCheck %s
-// CHECK: expect_step_kinds.cpp:
-
-int abs(int i){
-    return i < 0? i * -1: i;
-}
-
-int main()
-{
-    volatile int x = 2;
-    for (int i = 0; i < x; ++i) {
-        abs(i);
-    }
-    return 0;
-}
-
-// DexExpectStepKind('FUNC', 5)
-// DexExpectStepKind('FUNC_EXTERNAL', 2)
-// DexExpectStepKind('VERTICAL_BACKWARD', 2)
diff --git a/dexter/feature_tests/commands/penalty/expect_step_order.cpp b/dexter/feature_tests/commands/penalty/expect_step_order.cpp
deleted file mode 100644
index dc5f8c6..0000000
--- a/dexter/feature_tests/commands/penalty/expect_step_order.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-// Purpose:
-//      Check that \DexExpectStepOrder correctly applies a penalty for steps
-//      found out of expected order.
-//
-// UNSUPPORTED: system-darwin
-//
-// RUN: not %dexter_regression_test -- %s | FileCheck %s
-// CHECK: expect_step_order.cpp:
-
-int main()
-{
-    volatile int x = 1; // DexExpectStepOrder(3)
-    volatile int y = 1; // DexExpectStepOrder(1)
-    volatile int z = 1; // DexExpectStepOrder(2)
-    return 0;
-}
diff --git a/dexter/feature_tests/commands/penalty/expect_watch_type.cpp b/dexter/feature_tests/commands/penalty/expect_watch_type.cpp
deleted file mode 100644
index d758a0f..0000000
--- a/dexter/feature_tests/commands/penalty/expect_watch_type.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-// Purpose:
-//      Check that \DexExpectWatchType applies penalties when expected
-//      types are not found and unexpected types are.
-//
-// UNSUPPORTED: system-darwin
-//
-//
-// NOTE: This test passes but not in the expected way on Windows.
-// TODO: Reduce this test's coverage and be more specific about
-// expected behaviour.
-//
-// RUN: not %dexter_regression_test -- %s | FileCheck %s
-// CHECK: expect_watch_type.cpp:
-
-template<class T>
-class Doubled {
-public:
-  Doubled(const T & to_double)
-    : m_member(to_double * 2) {}
-
-  T GetVal() {
-    T to_return = m_member; // DexLabel('gv_start')
-    return to_return;       // DexLabel('gv_end')
-  }
-
-  static T static_doubler(const T & to_double) {
-    T result = 0;           // DexLabel('sd_start')
-    result = to_double * 2;
-    return result;          // DexLabel('sd_end')
-  }
-
-private:
-  T m_member;
-};
-
-int main() {
-  auto myInt = Doubled<int>(5); // DexLabel('main_start')
-  auto myDouble = Doubled<double>(5.5);
-  auto staticallyDoubledInt = Doubled<int>::static_doubler(5);
-  auto staticallyDoubledDouble = Doubled<double>::static_doubler(5.5);
-  return int(double(myInt.GetVal())
-         + double(staticallyDoubledInt)
-         + myDouble.GetVal()
-         + staticallyDoubledDouble); // DexLabel('main_end')
-}
-
-
-// DexExpectWatchType('m_member', 'int', 'double', from_line=ref('gv_start'), to_line=ref('gv_end'))
-
-// THIS COMMAND should create a penalty for a missing type 'const double' and unexpected type 'const double &'
-// DexExpectWatchType('to_double', 'const double', 'const int &', from_line=ref('sd_start'), to_line=ref('sd_end'))
-
-// DexExpectWatchType('myInt', 'Doubled<int>', from_line=ref('main_start'), to_line=ref('main_end'))
-// DexExpectWatchType('myDouble', 'Doubled<double>', from_line=ref('main_start'), to_line=ref('main_end'))
-// DexExpectWatchType('staticallyDoubledInt', 'int', from_line=ref('main_start'), to_line=ref('main_end'))
-// DexExpectWatchType('staticallyDoubledDouble', 'double', from_line=ref('main_start'), to_line=ref('main_end'))
-
diff --git a/dexter/feature_tests/commands/penalty/expect_watch_value.cpp b/dexter/feature_tests/commands/penalty/expect_watch_value.cpp
deleted file mode 100644
index b7fe385..0000000
--- a/dexter/feature_tests/commands/penalty/expect_watch_value.cpp
+++ /dev/null
@@ -1,20 +0,0 @@
-// Purpose:
-//      Check that \DexExpectWatchValue correctly applies a penalty when
-//      expected values are not found.
-//
-// UNSUPPORTED: system-darwin
-//
-//
-// RUN: not %dexter_regression_test -- %s | FileCheck %s
-// CHECK: expect_watch_value.cpp:
-
-int main()
-{
-    for (int i = 0; i < 3; ++i)
-        int a = i; // DexLabel('loop')
-    return 0;  // DexLabel('ret')
-}
-
-// DexExpectWatchValue('i', '0', '1', '2', on_line=ref('loop'))
-// DexExpectWatchValue('i', '3', on_line=ref('ret'))
-// ---------------------^ out of scope
diff --git a/dexter/feature_tests/commands/penalty/unreachable.cpp b/dexter/feature_tests/commands/penalty/unreachable.cpp
deleted file mode 100644
index 48f56b7..0000000
--- a/dexter/feature_tests/commands/penalty/unreachable.cpp
+++ /dev/null
@@ -1,15 +0,0 @@
-// Purpose:
-//      Check that \DexUnreachable correctly applies a penalty if the command
-//      line is stepped on.
-//
-// UNSUPPORTED: system-darwin
-//
-//
-// RUN: not %dexter_regression_test -- %s | FileCheck %s
-// CHECK: unreachable.cpp:
-
-int
-main()
-{
-  return 1;  // DexUnreachable()
-}
diff --git a/dexter/feature_tests/commands/perfect/dex_declare_file/dex_and_source/commands.dex b/dexter/feature_tests/commands/perfect/dex_declare_file/dex_and_source/commands.dex
deleted file mode 100644
index bbad7db..0000000
--- a/dexter/feature_tests/commands/perfect/dex_declare_file/dex_and_source/commands.dex
+++ /dev/null
@@ -1,2 +0,0 @@
-DexDeclareFile('test.cpp')
-DexExpectWatchValue('result', 0, on_line=14)
diff --git a/dexter/feature_tests/commands/perfect/dex_declare_file/dex_and_source/lit.local.cfg.py b/dexter/feature_tests/commands/perfect/dex_declare_file/dex_and_source/lit.local.cfg.py
deleted file mode 100644
index 159c376..0000000
--- a/dexter/feature_tests/commands/perfect/dex_declare_file/dex_and_source/lit.local.cfg.py
+++ /dev/null
@@ -1 +0,0 @@
-config.suffixes = ['.cpp']
diff --git a/dexter/feature_tests/commands/perfect/dex_declare_file/dex_and_source/test.cfg b/dexter/feature_tests/commands/perfect/dex_declare_file/dex_and_source/test.cfg
deleted file mode 100644
index e69de29..0000000
--- a/dexter/feature_tests/commands/perfect/dex_declare_file/dex_and_source/test.cfg
+++ /dev/null
diff --git a/dexter/feature_tests/commands/perfect/dex_declare_file/dex_and_source/test.cpp b/dexter/feature_tests/commands/perfect/dex_declare_file/dex_and_source/test.cpp
deleted file mode 100644
index 5f1d50e..0000000
--- a/dexter/feature_tests/commands/perfect/dex_declare_file/dex_and_source/test.cpp
+++ /dev/null
@@ -1,15 +0,0 @@
-// Purpose:
-//    Check that \DexDeclareFile changes the path of all succeeding commands
-//    to the file path it declares. Also check that dexter correctly accepts
-//    files with .dex extensions.
-//
-// UNSUPPORTED: system-darwin
-//
-//
-// RUN: %dexter_regression_test -- %S | FileCheck %s
-// CHECK: dex_and_source
-
-int main() {
-  int result = 0;
-  return result;
-}
diff --git a/dexter/feature_tests/commands/perfect/dex_declare_file/precompiled_binary/commands.dex b/dexter/feature_tests/commands/perfect/dex_declare_file/precompiled_binary/commands.dex
deleted file mode 100644
index 1aec2f8..0000000
--- a/dexter/feature_tests/commands/perfect/dex_declare_file/precompiled_binary/commands.dex
+++ /dev/null
@@ -1,18 +0,0 @@
-# Purpose:
-#    Check that \DexDeclareFile's file declaration can reference source files
-#    in a precompiled binary.
-#
-# UNSUPPORTED: system-darwin
-#
-# RUN: %clang %S/test.cpp -O0 -g -o %t
-# RUN: %dexter_regression_test --binary %t %s | FileCheck %s
-# CHECK: commands.dex
-#
-# test.cpp
-# 1. int main() {
-# 2.   int result = 0;
-# 3.   return result;
-# 4. }
-
-DexDeclareFile('test.cpp')
-DexExpectWatchValue('result', 0, on_line=3)
diff --git a/dexter/feature_tests/commands/perfect/dex_declare_file/precompiled_binary/lit.local.cfg.py b/dexter/feature_tests/commands/perfect/dex_declare_file/precompiled_binary/lit.local.cfg.py
deleted file mode 100644
index e65498f..0000000
--- a/dexter/feature_tests/commands/perfect/dex_declare_file/precompiled_binary/lit.local.cfg.py
+++ /dev/null
@@ -1 +0,0 @@
-config.suffixes = ['.dex']
diff --git a/dexter/feature_tests/commands/perfect/dex_declare_file/precompiled_binary/test.cpp b/dexter/feature_tests/commands/perfect/dex_declare_file/precompiled_binary/test.cpp
deleted file mode 100644
index 4d3cc58..0000000
--- a/dexter/feature_tests/commands/perfect/dex_declare_file/precompiled_binary/test.cpp
+++ /dev/null
@@ -1,4 +0,0 @@
-int main() {
-  int result = 0;
-  return result;
-}
diff --git a/dexter/feature_tests/commands/perfect/dex_declare_file/precompiled_binary_different_dir/dex_commands/commands.dex b/dexter/feature_tests/commands/perfect/dex_declare_file/precompiled_binary_different_dir/dex_commands/commands.dex
deleted file mode 100644
index 964c770..0000000
--- a/dexter/feature_tests/commands/perfect/dex_declare_file/precompiled_binary_different_dir/dex_commands/commands.dex
+++ /dev/null
@@ -1,19 +0,0 @@
-# Purpose:
-#    Check that \DexDeclareFile's file declaration can reference source files
-#    not included in the test directory
-#
-# UNSUPPORTED: system-darwin
-#
-# RUN: %clang %S/../source/test.cpp -O0 -g -o %t
-# RUN: %dexter_regression_test --binary %t %s | FileCheck %s
-# RUN: rm %t
-# CHECK: commands.dex
-#
-# test.cpp
-# 1. int main() {
-# 2.   int result = 0;
-# 3.   return result;
-# 4. }
-
-DexDeclareFile('../source/test.cpp')
-DexExpectWatchValue('result', 0, on_line=3)
diff --git a/dexter/feature_tests/commands/perfect/dex_declare_file/precompiled_binary_different_dir/dex_commands/source_root_dir.dex b/dexter/feature_tests/commands/perfect/dex_declare_file/precompiled_binary_different_dir/dex_commands/source_root_dir.dex
deleted file mode 100644
index 466b827..0000000
--- a/dexter/feature_tests/commands/perfect/dex_declare_file/precompiled_binary_different_dir/dex_commands/source_root_dir.dex
+++ /dev/null
@@ -1,23 +0,0 @@
-## Purpose:
-##    Check that \DexDeclareFile's file declaration can be made relative to the
-##    --source-root-dir path.
-
-# REQUIRES: lldb
-# UNSUPPORTED: system-darwin
-
-# RUN: %clang %S/../source/test.cpp -O0 -g -o %t
-# RUN: %dexter_regression_test --binary %t \
-# RUN:   --source-root-dir="%S/../source" -- %s | FileCheck %s
-# RUN: rm %t
-
-# CHECK: source_root_dir.dex: (1.0000)
-
-## ../source/test.cpp
-## 1. int main() {
-## 2.   int result = 0;
-## 3.   return result;
-## 4. }
-
-## test.cpp is found in ../source, which we set as the source-root-dir.
-DexDeclareFile('test.cpp')
-DexExpectWatchValue('result', 0, on_line=3)
diff --git a/dexter/feature_tests/commands/perfect/dex_declare_file/precompiled_binary_different_dir/lit.local.cfg.py b/dexter/feature_tests/commands/perfect/dex_declare_file/precompiled_binary_different_dir/lit.local.cfg.py
deleted file mode 100644
index e65498f..0000000
--- a/dexter/feature_tests/commands/perfect/dex_declare_file/precompiled_binary_different_dir/lit.local.cfg.py
+++ /dev/null
@@ -1 +0,0 @@
-config.suffixes = ['.dex']
diff --git a/dexter/feature_tests/commands/perfect/dex_declare_file/precompiled_binary_different_dir/source/test.cpp b/dexter/feature_tests/commands/perfect/dex_declare_file/precompiled_binary_different_dir/source/test.cpp
deleted file mode 100644
index 4d3cc58..0000000
--- a/dexter/feature_tests/commands/perfect/dex_declare_file/precompiled_binary_different_dir/source/test.cpp
+++ /dev/null
@@ -1,4 +0,0 @@
-int main() {
-  int result = 0;
-  return result;
-}
diff --git a/dexter/feature_tests/commands/perfect/dex_declare_file/windows_noncanonical_path/lit.local.cfg.py b/dexter/feature_tests/commands/perfect/dex_declare_file/windows_noncanonical_path/lit.local.cfg.py
deleted file mode 100644
index e65498f..0000000
--- a/dexter/feature_tests/commands/perfect/dex_declare_file/windows_noncanonical_path/lit.local.cfg.py
+++ /dev/null
@@ -1 +0,0 @@
-config.suffixes = ['.dex']
diff --git a/dexter/feature_tests/commands/perfect/dex_declare_file/windows_noncanonical_path/source/test file.cpp b/dexter/feature_tests/commands/perfect/dex_declare_file/windows_noncanonical_path/source/test file.cpp
deleted file mode 100644
index f6dcd82..0000000
--- a/dexter/feature_tests/commands/perfect/dex_declare_file/windows_noncanonical_path/source/test file.cpp
+++ /dev/null
@@ -1,4 +0,0 @@
-int main(const int argc, const char * argv[]) {
-  int result = argc;
-  return result;
-}
\ No newline at end of file
diff --git a/dexter/feature_tests/commands/perfect/dex_declare_file/windows_noncanonical_path/test.cfg b/dexter/feature_tests/commands/perfect/dex_declare_file/windows_noncanonical_path/test.cfg
deleted file mode 100644
index e69de29..0000000
--- a/dexter/feature_tests/commands/perfect/dex_declare_file/windows_noncanonical_path/test.cfg
+++ /dev/null
diff --git a/dexter/feature_tests/commands/perfect/dex_declare_file/windows_noncanonical_path/test.dex b/dexter/feature_tests/commands/perfect/dex_declare_file/windows_noncanonical_path/test.dex
deleted file mode 100644
index d9c9b80..0000000
--- a/dexter/feature_tests/commands/perfect/dex_declare_file/windows_noncanonical_path/test.dex
+++ /dev/null
@@ -1,17 +0,0 @@
-# Purpose:
-#    Check that non-canonical paths resolve correctly on Windows.
-#
-# REQUIRES: system-windows
-#
-# RUN: %clang "%S/source/test file.cpp" -O0 -g -o %t
-# RUN: %dexter_regression_test --binary %t %s | FileCheck %s
-# CHECK: test.dex
-#
-# ./source/test file.cpp
-# 1 int main(const int argc, const char * argv[]) {
-# 2 int result = argc;
-# 3 return result;
-# 4 }
-
-DexDeclareFile('./sOuRce\\test filE.cpp')
-DexExpectWatchValue('result', 1, on_line=3)
diff --git a/dexter/feature_tests/commands/perfect/expect_program_state.cpp b/dexter/feature_tests/commands/perfect/expect_program_state.cpp
deleted file mode 100644
index 7aa8b1a..0000000
--- a/dexter/feature_tests/commands/perfect/expect_program_state.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-// Purpose:
-//      Check that \DexExpectWatchValue applies no penalties when expected
-//      program states are found.
-//
-// UNSUPPORTED: system-darwin
-//
-//
-// RUN: %dexter_regression_test -- %s | FileCheck %s
-// CHECK: expect_program_state.cpp:
-
-int GCD(int lhs, int rhs)
-{
-    if (rhs == 0)
-        return lhs; // DexLabel('check')
-    return GCD(rhs, lhs % rhs);
-}
-
-int main()
-{
-    return GCD(111, 259);
-}
-
-/*
-DexExpectProgramState({
-    'frames': [
-        {
-            'location': {
-                'lineno': ref('check')
-            },
-            'watches': {
-                'lhs': '37', 'rhs': '0'
-            }
-        },
-        {
-            'watches': {
-                'lhs': {'value': '111'}, 'rhs': {'value': '37'}
-            }
-        },
-        {
-            'watches': {
-                'lhs': {'value': '259'}, 'rhs': {'value': '111'}
-            }
-        },
-        {
-            'watches': {
-                'lhs': {'value': '111'}, 'rhs': {'value': '259'}
-            }
-        }
-    ]
-})
-*/
diff --git a/dexter/feature_tests/commands/perfect/expect_step_kind/direction.cpp b/dexter/feature_tests/commands/perfect/expect_step_kind/direction.cpp
deleted file mode 100644
index 1f7a96b..0000000
--- a/dexter/feature_tests/commands/perfect/expect_step_kind/direction.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-// Purpose:
-//      Check that \DexExpectStepKind correctly counts 'VERTICAL_BACKWARD' steps
-//      for a trivial test. Expect one 'VERTICAL_BACKWARD' for every step onto
-//      a lesser source line number in the same function. Expect one
-//      'VERTICAL_FORWARD' for every step onto a greater source line number in
-//      the same function.
-//
-// UNSUPPORTED: system-darwin
-//
-// TODO: The dbgeng debugger does not support column step reporting at present.
-// XFAIL: system-windows
-//
-// RUN: %dexter_regression_test -- %s | FileCheck %s
-// CHECK: direction.cpp:
-
-int func(int i) {
-    return i; // step 7, 9, 11
-}
-
-int main()
-{
-    for (int i = 0; i < 2; ++i) { // step 1: FUNC, step 3, 5: VERTICAL_BACKWARD
-        i = i;                    // step 2, 4: VERTICAL_FORWARD
-    }
-    // ---------1           - step 6: VERTICAL_FORWARD
-    // ---------|---------2 - step 8: HORIZONTAL_FORWARD
-    // ----3----|---------| - step 10: HORIZONTAL_BACKWARD
-    return func(func(0) + func(1));
-}
-
-// DexExpectStepKind('VERTICAL_BACKWARD', 2)
-// DexExpectStepKind('VERTICAL_FORWARD', 3)
-// DexExpectStepKind('HORIZONTAL_FORWARD', 1)
-// DexExpectStepKind('HORIZONTAL_BACKWARD', 1)
diff --git a/dexter/feature_tests/commands/perfect/expect_step_kind/func.cpp b/dexter/feature_tests/commands/perfect/expect_step_kind/func.cpp
deleted file mode 100644
index b386dc4..0000000
--- a/dexter/feature_tests/commands/perfect/expect_step_kind/func.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
-// Purpose:
-//      Check that \DexExpectStepKind correctly counts 'FUNC' steps for a
-//      trivial test. Expect one 'FUNC' per call to a function which is defined
-//      in one of the source files in the test directory.
-//
-// UNSUPPORTED: system-darwin
-//
-// RUN: %dexter_regression_test -- %s | FileCheck %s
-// CHECK: func.cpp:
-
-int func(int i) {
-    return i;
-}
-
-int main()
-{
-    func(0);
-    func(1);
-    return 0;
-}
-
-// main, func, func
-// DexExpectStepKind('FUNC', 3)
diff --git a/dexter/feature_tests/commands/perfect/expect_step_kind/func_external.cpp b/dexter/feature_tests/commands/perfect/expect_step_kind/func_external.cpp
deleted file mode 100644
index cbefcb9..0000000
--- a/dexter/feature_tests/commands/perfect/expect_step_kind/func_external.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-// Purpose:
-//      Check that \DexExpectStepKind correctly counts 'FUNC_EXTERNAL' steps
-//      for a trivial test. Expect one 'FUNC_EXTERNAL' per external call.
-//
-// UNSUPPORTED: system-darwin
-//
-// XFAIL:*
-// This fails right now on my linux and windows machine, needs examining as to
-// why.
-//
-// RUN: %dexter_regression_test -- %s | FileCheck %s
-// CHECK: func_external.cpp:
-
-#include <cstdlib>
-
-int func(int i){
-    return abs(i);
-}
-
-int main()
-{
-    func(0);
-    func(1);
-    return 0;
-}
-
-// DexExpectStepKind('FUNC_EXTERNAL', 2)
diff --git a/dexter/feature_tests/commands/perfect/expect_step_kind/recursive.cpp b/dexter/feature_tests/commands/perfect/expect_step_kind/recursive.cpp
deleted file mode 100644
index 0264420..0000000
--- a/dexter/feature_tests/commands/perfect/expect_step_kind/recursive.cpp
+++ /dev/null
@@ -1,24 +0,0 @@
-// Purpose:
-//      Check that \DexExpectStepKind correctly handles recursive calls.
-//      Specifically, ensure recursive calls count towards 'FUNC' and not
-//      'VERTICAL_BACKWARD'.
-//
-// UNSUPPORTED: system-darwin
-//
-// RUN: %dexter_regression_test -- %s | FileCheck %s
-// CHECK: recursive.cpp:
-
-int func(int i) {
-    if (i > 1)
-        return i + func(i - 1);
-    return i;
-}
-
-int main()
-{
-    return func(3);
-}
-
-// main, func, func, func
-// DexExpectStepKind('FUNC', 4)
-// DexExpectStepKind('VERTICAL_BACKWARD', 0)
diff --git a/dexter/feature_tests/commands/perfect/expect_step_kind/small_loop.cpp b/dexter/feature_tests/commands/perfect/expect_step_kind/small_loop.cpp
deleted file mode 100644
index fb19869..0000000
--- a/dexter/feature_tests/commands/perfect/expect_step_kind/small_loop.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
-// Purpose:
-//      Check that \DexExpectStepKind correctly counts function calls in loops
-//      where the last source line in the loop is a call. Expect steps out
-//      of a function to a line before the call to count as 'VERTICAL_BACKWARD'.
-//
-// UNSUPPORTED: system-darwin
-//
-// RUN: %dexter_regression_test -- %s | FileCheck %s
-// CHECK: small_loop.cpp:
-
-int func(int i){
-    return i;
-}
-
-int main()
-{
-    for (int i = 0; i < 2; ++i) {
-        func(i);
-    }
-    return 0;
-}
-
-// DexExpectStepKind('VERTICAL_BACKWARD', 2)
diff --git a/dexter/feature_tests/commands/perfect/expect_step_order.cpp b/dexter/feature_tests/commands/perfect/expect_step_order.cpp
deleted file mode 100644
index cbcb506..0000000
--- a/dexter/feature_tests/commands/perfect/expect_step_order.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-// Purpose:
-//      Check that \DexExpectStepOrder applies no penalty when the expected
-//      order is found.
-//
-// UNSUPPORTED: system-darwin
-//
-// RUN: %dexter_regression_test -- %s | FileCheck %s
-// CHECK: expect_step_order.cpp:
-
-int main()
-{
-  volatile int x = 1; // DexExpectStepOrder(1)
-  volatile int y = 1; // DexExpectStepOrder(2)
-  volatile int z = 1; // DexExpectStepOrder(3)
-  return 0;
-}
diff --git a/dexter/feature_tests/commands/perfect/expect_watch_type.cpp b/dexter/feature_tests/commands/perfect/expect_watch_type.cpp
deleted file mode 100644
index 6719406..0000000
--- a/dexter/feature_tests/commands/perfect/expect_watch_type.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-// Purpose:
-//      Check that \DexExpectWatchType applies no penalties when expected
-//      types are found.
-//
-// UNSUPPORTED: system-darwin
-//
-// TODO: On Windows WITH dbgeng, This test takes a long time to run and doesn't evaluate type values
-// in the same manner as LLDB.
-// XFAIL: system-windows
-//
-// RUN: %dexter_regression_test -- %s | FileCheck %s
-// CHECK: expect_watch_type.cpp:
-
-template<class T>
-class Doubled {
-public:
-  Doubled(const T & to_double)
-    : m_member(to_double * 2) {}
-
-  T GetVal() {
-    T to_return = m_member; // DexLabel('gv_start')
-    return to_return;       // DexLabel('gv_end')
-  }
-
-  static T static_doubler(const T & to_double) {
-    T result = 0;           // DexLabel('sd_start')
-    result = to_double * 2;
-    return result;          // DexLabel('sd_end')
-  }
-
-private:
-  T m_member;
-};
-
-int main() {
-  auto myInt = Doubled<int>(5); // DexLabel('main_start')
-  auto myDouble = Doubled<double>(5.5);
-  auto staticallyDoubledInt = Doubled<int>::static_doubler(5);
-  auto staticallyDoubledDouble = Doubled<double>::static_doubler(5.5);
-  return int(double(myInt.GetVal())
-         + double(staticallyDoubledInt)
-         + myDouble.GetVal()
-         + staticallyDoubledDouble); // DexLabel('main_end')
-}
-
-// DexExpectWatchType('m_member', 'int', 'double', from_line=ref('gv_start'), to_line=ref('gv_end'))
-
-// DexExpectWatchType('to_double', 'const int &', 'const double &', from_line=ref('sd_start'), to_line=ref('sd_end'))
-
-// DexExpectWatchType('myInt', 'Doubled<int>', from_line=ref('main_start'), to_line=ref('main_end'))
-// DexExpectWatchType('myDouble', 'Doubled<double>', from_line=ref('main_start'), to_line=ref('main_end'))
-// DexExpectWatchType('staticallyDoubledInt', 'int', from_line=ref('main_start'), to_line=ref('main_end'))
-// DexExpectWatchType('staticallyDoubledDouble', 'double', from_line=ref('main_start'), to_line=ref('main_end'))
-
diff --git a/dexter/feature_tests/commands/perfect/expect_watch_value.cpp b/dexter/feature_tests/commands/perfect/expect_watch_value.cpp
deleted file mode 100644
index a4877dd..0000000
--- a/dexter/feature_tests/commands/perfect/expect_watch_value.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-// Purpose:
-//      Check that \DexExpectWatchValue applies no penalties when expected
-//      values are found.
-//
-// UNSUPPORTED: system-darwin
-//
-// RUN: %dexter_regression_test -- %s | FileCheck %s
-// CHECK: expect_watch_value.cpp:
-
-unsigned long Factorial(int n) {
-    volatile unsigned long fac = 1; // DexLabel('entry')
-
-    for (int i = 1; i <= n; ++i)
-        fac *= i;                   // DexLabel('loop')
-
-    return fac;                     // DexLabel('ret')
-}
-
-int main()
-{
-    return Factorial(8);
-}
-
-/*
-DexExpectWatchValue('n', '8', on_line=ref('entry'))
-DexExpectWatchValue('i',
-                    '1', '2', '3', '4', '5', '6', '7', '8',
-                    on_line=ref('loop'))
-
-DexExpectWatchValue('fac',
-                    '1', '2', '6', '24', '120', '720', '5040',
-                     on_line=ref('loop'))
-
-DexExpectWatchValue('n', '8', on_line=ref('loop'))
-DexExpectWatchValue('fac', '40320', on_line=ref('ret'))
-DexExpectWatchValue('n', '8', on_line=ref('ret'))
-*/
diff --git a/dexter/feature_tests/commands/perfect/limit_steps/hit_count.cpp b/dexter/feature_tests/commands/perfect/limit_steps/hit_count.cpp
deleted file mode 100644
index e7cd903..0000000
--- a/dexter/feature_tests/commands/perfect/limit_steps/hit_count.cpp
+++ /dev/null
@@ -1,21 +0,0 @@
-// Purpose:
-//      Test that \DexLimitSteps keyword argument hit_count correctly limits
-//      the number of times the command can trigger.
-//
-// REQUIRES: system-linux
-//
-// RUN: %dexter_regression_test -- %s | FileCheck %s
-// CHECK: hit_count.cpp
-
-int a;
-int main() {
-  for (int i = 0; i < 4; i++) {
-    a = i; // DexLabel('check')
-  }
-  return 0;
-}
-
-//// Unconditionally limit dexter's view of the program to 'on_line' and check
-//// for i=0, i=1. The test will fail if dexter sees any other value for test.
-// DexLimitSteps(hit_count=2, on_line=ref('check'))
-// DexExpectWatchValue('i', '0', '1')
diff --git a/dexter/feature_tests/commands/perfect/limit_steps/limit_steps_check_json_step_count.cpp b/dexter/feature_tests/commands/perfect/limit_steps/limit_steps_check_json_step_count.cpp
deleted file mode 100644
index 3c96035..0000000
--- a/dexter/feature_tests/commands/perfect/limit_steps/limit_steps_check_json_step_count.cpp
+++ /dev/null
@@ -1,20 +0,0 @@
-// Purpose:
-//      Check number of step lines are correctly reported in json output.
-//
-// REQUIRES: system-linux
-//
-// RUN: %dexter_regression_test --verbose -- %s | FileCheck %s
-// CHECK: limit_steps_check_json_step_count.cpp
-// CHECK: ## BEGIN ##
-// CHECK-COUNT-3: json_step_count.cpp",
-
-int main() {
-  int result = 0;
-  for(int ix = 0; ix != 10; ++ix) {
-    int index = ix;
-    result += index; // DexLabel('check')
-  }
-}
-
-// DexExpectWatchValue('index', 2, 7, 9, on_line=ref('check'))
-// DexLimitSteps('ix', 2, 7, 9, on_line=ref('check'))
diff --git a/dexter/feature_tests/commands/perfect/limit_steps/limit_steps_expect_loop.cpp b/dexter/feature_tests/commands/perfect/limit_steps/limit_steps_expect_loop.cpp
deleted file mode 100644
index 5dc7cd2..0000000
--- a/dexter/feature_tests/commands/perfect/limit_steps/limit_steps_expect_loop.cpp
+++ /dev/null
@@ -1,20 +0,0 @@
-// Purpose:
-//      Check the DexLimit steps only gathers step info for 2 iterations of a
-//      for loop.
-//
-// REQUIRES: system-linux
-//
-// RUN: %dexter_regression_test -- %s | FileCheck %s
-// CHECK: limit_steps_expect_loop.cpp:
-
-int main(const int argc, const char * argv[]) {
-  unsigned int sum = 1;
-  for(unsigned int ix = 0; ix != 5; ++ix) {
-    unsigned thing_to_add = ix + ix - ix;   // DexLabel('start')
-    sum += ix;                              // DexLabel('end')
-  }
-  return sum;
-}
-
-// DexLimitSteps('ix', 0, 3, from_line=ref('start'), to_line=ref('end'))
-// DexExpectWatchValue('ix', 0, 3, from_line=ref('start'), to_line=ref('end'))
diff --git a/dexter/feature_tests/commands/perfect/limit_steps/limit_steps_expect_value.cpp b/dexter/feature_tests/commands/perfect/limit_steps/limit_steps_expect_value.cpp
deleted file mode 100644
index 0565313..0000000
--- a/dexter/feature_tests/commands/perfect/limit_steps/limit_steps_expect_value.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-// Purpose:
-//      Ensure that limited stepping breaks for all expected values.
-//
-// REQUIRES: system-linux
-//
-// RUN: %dexter_regression_test -- %s | FileCheck %s
-// CHECK: limit_steps_expect_value.cpp
-
-int main() {
-  int i = 0;
-  i = 1;    // DexLabel('from')
-  i = 2;
-  i = 3;
-  return 0; // DexLabel('long_range')
-}
-
-// DexLimitSteps('i', '0', from_line=ref('from'), to_line=ref('long_range'))
-// DexExpectWatchValue('i', 0, 1, 2, 3, from_line=ref('from'), to_line=ref('long_range'))
diff --git a/dexter/feature_tests/commands/perfect/limit_steps/limit_steps_line_mismatch.cpp b/dexter/feature_tests/commands/perfect/limit_steps/limit_steps_line_mismatch.cpp
deleted file mode 100644
index 711c006..0000000
--- a/dexter/feature_tests/commands/perfect/limit_steps/limit_steps_line_mismatch.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-// Purpose:
-//      Check that \DexLimitSteps works even if the opening breakpoint line
-//      doesn't exist. This can happen due to optimisations or label is on an
-//      empty line.
-//
-// FIXME: Windows regression tests run with dbgeng. \DexLimitSteps isn't yet
-// supported with dbgeng.
-//
-// REQUIRES: system-linux
-//
-// RUN: %dexter_regression_test -- %s | FileCheck %s
-// CHECK: limit_steps_line_mismatch.cpp
-
-int main() {
-  int i = 0;
-  for (; i < 2; i++) {
-    // DexLabel('from')
-    int x = i;
-  }
-  int ret = 0;
-  return ret; // DexLabel('to')
-}
-
-// DexLimitSteps('1', '1', from_line=ref('from'), to_line=ref('to'))
-// DexExpectWatchValue('i', 0, 1, 2, from_line=ref('from'), to_line=ref('to'))
diff --git a/dexter/feature_tests/commands/perfect/limit_steps/limit_steps_overlapping_ranges.cpp b/dexter/feature_tests/commands/perfect/limit_steps/limit_steps_overlapping_ranges.cpp
deleted file mode 100644
index 251eef7..0000000
--- a/dexter/feature_tests/commands/perfect/limit_steps/limit_steps_overlapping_ranges.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-// Purpose:
-//      Ensure that multiple overlapping \DexLimitSteps ranges do not interfere.
-//
-// REQUIRES: system-linux
-//
-// RUN: %dexter_regression_test -- %s | FileCheck %s
-// CHECK: limit_steps_overlapping_ranges.cpp
-
-int main() {
-  int val1;
-  int val2;
-  int placeholder;
-  for (int ix = 0; ix != 10; ++ix) {
-    placeholder=val1+val2;   // DexLabel('from')
-    if (ix == 0) {
-      val1 = ix;
-      val2 = ix;             // DexLabel('val1_check')
-      placeholder=val1+val2; // DexLabel('val1_check_to')
-    }
-    else if (ix == 2) {
-      val2 = ix;
-      val1 = ix;             // DexLabel('val2_check')
-      placeholder=val1+val2; // DexLabel('val2_check_to')
-    }
-    placeholder=val1+val2;   // DexLabel('to')
-  }
-  return val1 + val2;
-}
-
-// DexExpectWatchValue('ix', 0, 2, 5, from_line=ref('from'), to_line=ref('to'))
-// DexExpectWatchValue('val1', 0, from_line=ref('val1_check'), to_line=ref('val1_check_to'))
-// DexExpectWatchValue('val2', 2, from_line=ref('val2_check'), to_line=ref('val2_check_to'))
-
-// DexLimitSteps('ix', 5, from_line=ref('from'), to_line=ref('to'))
-// DexLimitSteps('val1', 0, from_line=ref('val1_check'), to_line=ref('val1_check_to'))
-// DexLimitSteps('val2', 2, from_line=ref('val2_check'), to_line=ref('val2_check_to'))
diff --git a/dexter/feature_tests/commands/perfect/limit_steps/limit_steps_same_line_conditional.cpp b/dexter/feature_tests/commands/perfect/limit_steps/limit_steps_same_line_conditional.cpp
deleted file mode 100644
index f71b54a..0000000
--- a/dexter/feature_tests/commands/perfect/limit_steps/limit_steps_same_line_conditional.cpp
+++ /dev/null
@@ -1,26 +0,0 @@
-// Purpose:
-//      Test that LimitStep commands can exist on the same from line.
-//
-// REQUIRES: system-linux
-//
-// RUN: %dexter_regression_test -- %s | FileCheck %s
-// CHECK: limit_steps_same_line_conditional.cpp
-
-int main() {
-  int val1 = 0;
-
-  int placeholder;
-  for(int ix = 0; ix != 4; ++ix) {
-    val1 = ix;
-    placeholder = ix;    // DexLabel('from')
-    placeholder = ix;
-    val1 += 2;           // DexLabel('to')
-    placeholder = ix;    // DexLabel('extended_to')
-  }
-  return val1 + placeholder;
-}
-
-// DexExpectWatchValue('val1', 0, 1, 3, from_line=ref('from'), to_line=ref('extended_to'))
-
-// DexLimitSteps('ix', 0, from_line=ref('from'), to_line=ref('to'))
-// DexLimitSteps('ix', 1, from_line=ref('from'), to_line=ref('extended_to'))
diff --git a/dexter/feature_tests/commands/perfect/limit_steps/unconditional.cpp b/dexter/feature_tests/commands/perfect/limit_steps/unconditional.cpp
deleted file mode 100644
index af3ead4..0000000
--- a/dexter/feature_tests/commands/perfect/limit_steps/unconditional.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-// Purpose:
-//      Test that \DexLimitSteps can be used without a condition (i.e. the
-//      breakpoint range is set any time from_line is stepped on).
-//
-// REQUIRES: system-linux
-//
-// RUN: %dexter_regression_test -- %s | FileCheck %s
-// CHECK: unconditional.cpp
-
-int glob;
-int main() {
-  int test = 0;
-  for (test = 1; test < 4; test++) {
-    glob += test; // DexLabel('from')
-    glob += test; // DexLabel('to')
-  }
-  return test; // test = 4
-}
-
-// DexLimitSteps(from_line=ref('from'), to_line=ref('to'))
-//// Unconditionally limit dexter's view of the program from line 'from' to
-//// 'to'. Check for test=0, 1, 2 so that the test will fail if dexter sees
-//// test=0 or test=4.
-// DexExpectWatchValue('test', 1, 2, 3)
-
diff --git a/dexter/feature_tests/commands/perfect/lit.local.cfg b/dexter/feature_tests/commands/perfect/lit.local.cfg
deleted file mode 100644
index 7d1dd8b..0000000
--- a/dexter/feature_tests/commands/perfect/lit.local.cfg
+++ /dev/null
@@ -1,2 +0,0 @@
-if not 'lldb' in config.available_features:
-    config.unsupported = True
diff --git a/dexter/feature_tests/commands/perfect/unreachable.cpp b/dexter/feature_tests/commands/perfect/unreachable.cpp
deleted file mode 100644
index bcc1b83..0000000
--- a/dexter/feature_tests/commands/perfect/unreachable.cpp
+++ /dev/null
@@ -1,14 +0,0 @@
-// Purpose:
-//    Check that \DexUnreachable has no effect if the command line is never
-//    stepped on.
-//
-// UNSUPPORTED: system-darwin
-//
-// RUN: %dexter_regression_test -- %s | FileCheck %s
-// CHECK: unreachable.cpp:
-
-int main()
-{
-  return 0;
-  return 1; // DexUnreachable()
-}
diff --git a/dexter/feature_tests/lit.local.cfg b/dexter/feature_tests/lit.local.cfg
deleted file mode 100644
index 6eb9f0a..0000000
--- a/dexter/feature_tests/lit.local.cfg
+++ /dev/null
@@ -1,5 +0,0 @@
-if 'dexter' not in config.available_features:
-    config.unsupported = True
-
-config.name = "DExTer feature tests"
-config.suffixes = ['.cpp', '.c', '.test']
diff --git a/dexter/feature_tests/subtools/clang-opt-bisect/clang-opt-bisect.cpp b/dexter/feature_tests/subtools/clang-opt-bisect/clang-opt-bisect.cpp
deleted file mode 100644
index b0e1aab..0000000
--- a/dexter/feature_tests/subtools/clang-opt-bisect/clang-opt-bisect.cpp
+++ /dev/null
@@ -1,17 +0,0 @@
-// Purpose:
-//     Check the `clang-opt-bisect` tool runs with typical input.
-//
-// REQUIRES: system-linux, lldb
-//
-// RUN: true
-// RUN: %dexter_base clang-opt-bisect --debugger 'lldb' --builder 'clang' \
-// RUN:     --cflags "-O0 -g" -- %s \
-// RUN:     | FileCheck %s
-// CHECK: running pass 0
-// CHECK: wrote{{.*}}per_pass_score
-// CHECK: wrote{{.*}}pass-summary
-// CHECK: wrote{{.*}}overall-pass-summary
-
-int main() {
-    return 0;
-}
diff --git a/dexter/feature_tests/subtools/help/help.test b/dexter/feature_tests/subtools/help/help.test
deleted file mode 100644
index fc3f455..0000000
--- a/dexter/feature_tests/subtools/help/help.test
+++ /dev/null
@@ -1,10 +0,0 @@
-Purpose:
-    Check the `help` subtool runs.
-
-RUN: %dexter_base help | FileCheck %s
-CHECK: The following subtools are available:
-CHECK: clang-opt-bisect
-CHECK: help
-CHECK: list-debuggers
-CHECK: test
-CHECK: view
diff --git a/dexter/feature_tests/subtools/list-debuggers/list-debuggers.test b/dexter/feature_tests/subtools/list-debuggers/list-debuggers.test
deleted file mode 100644
index bbc9dd5..0000000
--- a/dexter/feature_tests/subtools/list-debuggers/list-debuggers.test
+++ /dev/null
@@ -1,7 +0,0 @@
-Purpose:
-    Check the `list-debuggers` subtool runs.
-
-RUN: %dexter_base list-debuggers | FileCheck %s
-CHECK: lldb
-CHECK: vs2015
-CHECK: vs2017
diff --git a/dexter/feature_tests/subtools/test/err_bad_label_ref.cpp b/dexter/feature_tests/subtools/test/err_bad_label_ref.cpp
deleted file mode 100644
index 424edaa..0000000
--- a/dexter/feature_tests/subtools/test/err_bad_label_ref.cpp
+++ /dev/null
@@ -1,14 +0,0 @@
-// Purpose:
-//      Check that referencing an undefined label gives a useful error message.
-//
-// RUN: not %dexter_regression_test -v -- %s | FileCheck %s --match-full-lines
-//
-// CHECK: parser error:{{.*}}err_bad_label_ref.cpp(14): Unresolved label: 'label_does_not_exist'
-// CHECK-NEXT: {{Dex}}ExpectWatchValue('result', '0', on_line=ref('label_does_not_exist'))
-
-int main() {
-    int result = 0;
-    return result;
-}
-
-// DexExpectWatchValue('result', '0', on_line=ref('label_does_not_exist'))
diff --git a/dexter/feature_tests/subtools/test/err_duplicate_label.cpp b/dexter/feature_tests/subtools/test/err_duplicate_label.cpp
deleted file mode 100644
index 7da6920..0000000
--- a/dexter/feature_tests/subtools/test/err_duplicate_label.cpp
+++ /dev/null
@@ -1,12 +0,0 @@
-// Purpose:
-//      Check that defining duplicate labels gives a useful error message.
-//
-// RUN: not %dexter_regression_test -v -- %s | FileCheck %s --match-full-lines
-//
-// CHECK: parser error:{{.*}}err_duplicate_label.cpp(11): Found duplicate line label: 'oops'
-// CHECK-NEXT: {{Dex}}Label('oops')
-
-int main() {
-    int result = 0; // DexLabel('oops')
-    return result;  // DexLabel('oops')
-}
diff --git a/dexter/feature_tests/subtools/test/err_label_kwarg.cpp b/dexter/feature_tests/subtools/test/err_label_kwarg.cpp
deleted file mode 100644
index b0bd50a..0000000
--- a/dexter/feature_tests/subtools/test/err_label_kwarg.cpp
+++ /dev/null
@@ -1,8 +0,0 @@
-// Purpose:
-//    Check that bad keyword args in \DexLabel are reported.
-//    Use --binary switch to trick dexter into skipping the build step.
-//
-// RUN: not %dexter_base test --binary %s --debugger 'lldb' -- %s | FileCheck %s
-// CHECK: parser error:{{.*}}err_label_kwarg.cpp(8): unexpected named args: bad_arg
-
-// DexLabel('test', bad_arg=0)
diff --git a/dexter/feature_tests/subtools/test/err_limit_steps_no_values.cpp b/dexter/feature_tests/subtools/test/err_limit_steps_no_values.cpp
deleted file mode 100644
index 17e5994..0000000
--- a/dexter/feature_tests/subtools/test/err_limit_steps_no_values.cpp
+++ /dev/null
@@ -1,10 +0,0 @@
-// Purpose:
-//    Check that specifying an expression without any values to compare against
-//    in a \DexLimitSteps command results in a useful error message.
-//    Use --binary switch to trick dexter into skipping the build step.
-//
-// REQUIRES: system-linux
-// RUN: not %dexter_base test --binary %s --debugger 'lldb' -- %s | FileCheck %s
-// CHECK: parser error:{{.*}}err_limit_steps_no_values.cpp(10): expected 0 or at least 2 positional arguments
-
-// DexLimitSteps('test')
diff --git a/dexter/feature_tests/subtools/test/err_paren.cpp b/dexter/feature_tests/subtools/test/err_paren.cpp
deleted file mode 100644
index feb26a7..0000000
--- a/dexter/feature_tests/subtools/test/err_paren.cpp
+++ /dev/null
@@ -1,22 +0,0 @@
-// Purpose:
-//      Check that parsing bad commands gives a useful error.
-//          - Unbalanced parenthesis
-//      Check directives are in check.txt to prevent dexter reading any embedded
-//      commands.
-//
-// Note: Despite using 'lldb' as the debugger, lldb is not actually required
-//       as the test should finish before lldb would be invoked.
-//
-// RUN: not %dexter_base test --builder 'clang' --debugger 'lldb' \
-// RUN:     --cflags "-O0 -g" -v -- %s \
-// RUN:     | FileCheck %s --match-full-lines --strict-whitespace
-//
-// CHECK:parser error:{{.*}}err_paren.cpp(22): Unbalanced parenthesis starting here
-// CHECK:// {{Dex}}ExpectWatchValue(
-// CHECK:                      ^
-
-int main(){
-    return 0;
-}
-
-// DexExpectWatchValue(
diff --git a/dexter/feature_tests/subtools/test/err_paren_mline.cpp b/dexter/feature_tests/subtools/test/err_paren_mline.cpp
deleted file mode 100644
index 7cbce8d..0000000
--- a/dexter/feature_tests/subtools/test/err_paren_mline.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-// Purpose:
-//      Check that parsing bad commands gives a useful error.
-//          - Unbalanced parenthesis over multiple lines
-//      Check directives are in check.txt to prevent dexter reading any embedded
-//      commands.
-//
-// Note: Despite using 'lldb' as the debugger, lldb is not actually required
-//       as the test should finish before lldb would be invoked.
-//
-// RUN: not %dexter_base test --builder 'clang' --debugger "lldb" \
-// RUN:     --cflags "-O0 -g" -v -- %s \
-// RUN:     | FileCheck %s --match-full-lines --strict-whitespace
-//
-// CHECK:parser error:{{.*}}err_paren_mline.cpp(23): Unbalanced parenthesis starting here
-// CHECK:{{Dex}}ExpectWatchValue(
-// CHECK:                   ^
-
-int main(){
-    return 0;
-}
-
-/*
-DexExpectWatchValue(
-    1
-*/
diff --git a/dexter/feature_tests/subtools/test/err_syntax.cpp b/dexter/feature_tests/subtools/test/err_syntax.cpp
deleted file mode 100644
index a0b8ab7..0000000
--- a/dexter/feature_tests/subtools/test/err_syntax.cpp
+++ /dev/null
@@ -1,21 +0,0 @@
-// Purpose:
-//      Check that parsing bad commands gives a useful error.
-//          - Syntax error (misplaced ',')
-//      Check directives are in check.txt to prevent dexter reading any embedded
-//      commands.
-//
-// Note: Despite using 'lldb' as the debugger, lldb is not actually required
-//       as the test should finish before lldb would be invoked.
-//
-// RUN: not %dexter_base test --builder 'clang' --debugger "lldb" \
-// RUN:     --cflags "-O0 -g" -v -- %s \
-// RUN:     | FileCheck %s --match-full-lines --strict-whitespace
-//
-// CHECK:parser error:{{.*}}err_syntax.cpp(21): invalid syntax
-// CHECK:// {{Dex}}ExpectWatchValue(,'a', 3, 3, 3, 3, on_line=0)
-// CHECK:                       ^
-
-int main(){
-    return 0;
-}
-// DexExpectWatchValue(,'a', 3, 3, 3, 3, on_line=0)
diff --git a/dexter/feature_tests/subtools/test/err_syntax_mline.cpp b/dexter/feature_tests/subtools/test/err_syntax_mline.cpp
deleted file mode 100644
index f47ddf8..0000000
--- a/dexter/feature_tests/subtools/test/err_syntax_mline.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-// Purpose:
-//      Check that parsing bad commands gives a useful error.
-//          - Syntax error (misplaced ',') over multiple lines
-//      Check directives are in check.txt to prevent dexter reading any embedded
-//      commands.
-//
-// Note: Despite using 'lldb' as the debugger, lldb is not actually required
-//       as the test should finish before lldb would be invoked.
-//
-// RUN: not %dexter_base test --builder 'clang' --debugger "lldb" \
-// RUN:     --cflags "-O0 -g" -v -- %s \
-// RUN:     | FileCheck %s --match-full-lines --strict-whitespace
-//
-// CHECK:parser error:{{.*}}err_syntax_mline.cpp(24): invalid syntax
-// CHECK:    ,'a', 3, 3, 3, 3, on_line=0)
-// CHECK:    ^
-
-int main(){
-    return 0;
-}
-
-/*
-DexExpectWatchValue(
-    ,'a', 3, 3, 3, 3, on_line=0)
-*/
diff --git a/dexter/feature_tests/subtools/test/err_type.cpp b/dexter/feature_tests/subtools/test/err_type.cpp
deleted file mode 100644
index d42c5a0..0000000
--- a/dexter/feature_tests/subtools/test/err_type.cpp
+++ /dev/null
@@ -1,21 +0,0 @@
-// Purpose:
-//      Check that parsing bad commands gives a useful error.
-//          - Type error (missing args)
-//      Check directives are in check.txt to prevent dexter reading any embedded
-//      commands.
-//
-// Note: Despite using 'lldb' as the debugger, lldb is not actually required
-//       as the test should finish before lldb would be invoked.
-//
-// RUN: not %dexter_base test --builder 'clang' --debugger "lldb" \
-// RUN:     --cflags "-O0 -g" -v -- %s \
-// RUN:     | FileCheck %s --match-full-lines --strict-whitespace
-//
-// CHECK:parser error:{{.*}}err_type.cpp(21): expected at least two args
-// CHECK:// {{Dex}}ExpectWatchValue()
-// CHECK:                      ^
-
-int main(){
-    return 0;
-}
-// DexExpectWatchValue()
diff --git a/dexter/feature_tests/subtools/test/err_type_mline.cpp b/dexter/feature_tests/subtools/test/err_type_mline.cpp
deleted file mode 100644
index 733c0d4..0000000
--- a/dexter/feature_tests/subtools/test/err_type_mline.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-// Purpose:
-//      Check that parsing bad commands gives a useful error.
-//          - Type error (missing args) over multple lines
-//      Check directives are in check.txt to prevent dexter reading any embedded
-//      commands.
-//
-// Note: Despite using 'lldb' as the debugger, lldb is not actually required
-//       as the test should finish before lldb would be invoked.
-//
-// RUN: not %dexter_base test --builder 'clang' --debugger "lldb" \
-// RUN:     --cflags "-O0 -g" -v -- %s \
-// RUN:     | FileCheck %s --match-full-lines --strict-whitespace
-//
-// CHECK:parser error:{{.*}}err_type_mline.cpp(22): expected at least two args
-// CHECK:{{Dex}}ExpectWatchValue(
-// CHECK:                   ^
-
-int main(){
-    return 0;
-}
-/*
-DexExpectWatchValue(
-    'a'
-)
-*/
diff --git a/dexter/feature_tests/subtools/test/label_another_line.cpp b/dexter/feature_tests/subtools/test/label_another_line.cpp
deleted file mode 100644
index c7cbe7c..0000000
--- a/dexter/feature_tests/subtools/test/label_another_line.cpp
+++ /dev/null
@@ -1,17 +0,0 @@
-// REQUIRES: lldb
-// UNSUPPORTED: system-windows
-//
-// Purpose:
-//    Check that the optional keyword argument 'on_line' makes a \DexLabel label
-//    that line instead of the line the command is found on.
-//
-// RUN: %dexter_regression_test -- %s | FileCheck %s
-// CHECK: label_another_line.cpp: (1.0000)
-
-int main() {
-  int result = 0;
-  return result;
-}
-
-// DexLabel('test', on_line=13)
-// DexExpectWatchValue('result', '0', on_line=ref('test'))
diff --git a/dexter/feature_tests/subtools/test/label_offset.cpp b/dexter/feature_tests/subtools/test/label_offset.cpp
deleted file mode 100644
index cad7d0c..0000000
--- a/dexter/feature_tests/subtools/test/label_offset.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-// REQUIRES: lldb
-// Purpose:
-//      Check that we can use label-relative line numbers.
-//
-// RUN: %dexter_regression_test -v -- %s | FileCheck %s
-//
-// CHECK: label_offset.cpp: (1.0000)
-
-int main() {  // DexLabel('main')
-    int var = 0;
-    var = var;
-    return 0;
-}
-
-/*
-DexExpectWatchValue('var', '0', from_line=ref('main')+2, to_line=ref('main')+3)
-DexExpectProgramState({
-    'frames': [
-        {
-            'location': { 'lineno': ref('main')+2 },
-            'watches': { 'var': '0' }
-        }
-    ]
-})
-*/
diff --git a/dexter/feature_tests/subtools/test/source-root-dir.cpp b/dexter/feature_tests/subtools/test/source-root-dir.cpp
deleted file mode 100644
index d589fbc..0000000
--- a/dexter/feature_tests/subtools/test/source-root-dir.cpp
+++ /dev/null
@@ -1,15 +0,0 @@
-// REQUIRES: lldb
-// UNSUPPORTED: system-windows
-//
-// RUN: %dexter --fail-lt 1.0 -w \
-// RUN:     --builder 'clang' --debugger 'lldb' \
-// RUN:     --cflags "-O0 -glldb -fdebug-prefix-map=%S=/changed" \
-// RUN:     --source-root-dir=%S --debugger-use-relative-paths -- %s
-
-#include <stdio.h>
-int main() {
-  int x = 42;
-  printf("hello world: %d\n", x); // DexLabel('check')
-}
-
-// DexExpectWatchValue('x', 42, on_line=ref('check'))
diff --git a/dexter/feature_tests/subtools/view.cpp b/dexter/feature_tests/subtools/view.cpp
deleted file mode 100644
index a48410a..0000000
--- a/dexter/feature_tests/subtools/view.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-// REQUIRES: lldb
-// Purpose:
-//      Check the `view` subtool works with typical inputs.
-//
-// RUN: %dexter_regression_test --results %t -- %s
-//
-// RUN: %dexter_base view %t/view.cpp.dextIR | FileCheck %s
-// CHECK: ## BEGIN
-// CHECK: ## END
-//
-// # [TODO] This doesn't run if FileCheck fails!
-// RUN: rm -rf %t
-
-int main() {
-    int a = 0;
-    return 0; //DexLabel('ret')
-}
-// DexExpectWatchValue('a', '0', on_line=ref('ret'))
diff --git a/dexter/feature_tests/unittests/run.test b/dexter/feature_tests/unittests/run.test
deleted file mode 100644
index 721732a..0000000
--- a/dexter/feature_tests/unittests/run.test
+++ /dev/null
@@ -1,9 +0,0 @@
-Purpose:
-    Run DExTer unit tests.
-
-# Dexter returns 1 when no subtools are specified.
-RUN: not %dexter_base --unittest=show-all 2>&1 | FileCheck %s
-
-CHECK: Ran {{[0-9]+}} tests
-CHECK-EMPTY:
-CHECK-NEXT: OK
diff --git a/lit.cfg.py b/lit.cfg.py
deleted file mode 100644
index ac46e27..0000000
--- a/lit.cfg.py
+++ /dev/null
@@ -1,186 +0,0 @@
-# -*- Python -*-
-
-import os
-import platform
-import re
-import subprocess
-import sys
-
-import lit.formats
-import lit.util
-
-from lit.llvm import llvm_config
-from lit.llvm.subst import ToolSubst
-
-# Configuration file for the 'lit' test runner.
-
-# name: The name of this test suite.
-config.name = 'debuginfo-tests'
-
-# testFormat: The test format to use to interpret tests.
-#
-# For now we require '&&' between commands, until they get globally killed and
-# the test runner updated.
-config.test_format = lit.formats.ShTest(not llvm_config.use_lit_shell)
-
-# suffixes: A list of file extensions to treat as test files.
-config.suffixes = ['.c', '.cpp', '.m']
-
-# excludes: A list of directories to exclude from the testsuite. The 'Inputs'
-# subdirectories contain auxiliary inputs for various tests in their parent
-# directories.
-config.excludes = ['Inputs']
-
-# test_source_root: The root path where tests are located.
-config.test_source_root = os.path.join(config.debuginfo_tests_src_root)
-
-# test_exec_root: The root path where tests should be run.
-config.test_exec_root = config.debuginfo_tests_obj_root
-
-llvm_config.use_default_substitutions()
-
-tools = [
-    ToolSubst('%test_debuginfo', command=os.path.join(
-        config.debuginfo_tests_src_root, 'llgdb-tests', 'test_debuginfo.pl')),
-    ToolSubst("%llvm_src_root", config.llvm_src_root),
-    ToolSubst("%llvm_tools_dir", config.llvm_tools_dir),
-]
-
-def get_required_attr(config, attr_name):
-  attr_value = getattr(config, attr_name, None)
-  if attr_value == None:
-    lit_config.fatal(
-      "No attribute %r in test configuration! You may need to run "
-      "tests from your build directory or add this attribute "
-      "to lit.site.cfg " % attr_name)
-  return attr_value
-
-# If this is an MSVC environment, the tests at the root of the tree are
-# unsupported. The local win_cdb test suite, however, is supported.
-is_msvc = get_required_attr(config, "is_msvc")
-if is_msvc:
-    config.available_features.add('msvc')
-    # FIXME: We should add some llvm lit utility code to find the Windows SDK
-    # and set up the environment appopriately.
-    win_sdk = 'C:/Program Files (x86)/Windows Kits/10/'
-    arch = 'x64'
-    llvm_config.with_system_environment(['LIB', 'LIBPATH', 'INCLUDE'])
-    # Clear _NT_SYMBOL_PATH to prevent cdb from attempting to load symbols from
-    # the network.
-    llvm_config.with_environment('_NT_SYMBOL_PATH', '')
-    tools.append(ToolSubst('%cdb', '"%s"' % os.path.join(win_sdk, 'Debuggers',
-                                                         arch, 'cdb.exe')))
-
-# clang_src_dir is not used by these tests, but is required by
-# use_clang(), so set it to "".
-if not hasattr(config, 'clang_src_dir'):
-    config.clang_src_dir = ""
-llvm_config.use_clang()
-
-if config.llvm_use_sanitizer:
-    # Propagate path to symbolizer for ASan/MSan.
-    llvm_config.with_system_environment(
-        ['ASAN_SYMBOLIZER_PATH', 'MSAN_SYMBOLIZER_PATH'])
-
-def add_host_triple(clang):
-  return '{} --target={}'.format(clang, config.host_triple)
-
-# The set of arches we can build.
-targets = set(config.targets_to_build)
-# Add aliases to the target set.
-if 'AArch64' in targets:
-  targets.add('arm64')
-if 'ARM' in config.targets_to_build:
-  targets.add('thumbv7')
-
-def can_target_host():
-  # Check if the targets set contains anything that looks like our host arch.
-  # The arch name in the triple and targets set may be spelled differently
-  # (e.g. x86 vs X86).
-  return any(config.host_triple.lower().startswith(x.lower())
-             for x in targets)
-
-# Dexter tests run on the host machine. If the host arch is supported add
-# 'dexter' as an available feature and force the dexter tests to use the host
-# triple.
-if can_target_host():
-  config.available_features.add('dexter')
-  if config.host_triple != config.target_triple:
-    print('Forcing dexter tests to use host triple {}.'.format(config.host_triple))
-  llvm_config.with_environment('PATHTOCLANG',
-                               add_host_triple(llvm_config.config.clang))
-  llvm_config.with_environment('PATHTOCLANGPP',
-                               add_host_triple(llvm_config.use_llvm_tool('clang++')))
-  llvm_config.with_environment('PATHTOCLANGCL',
-                               add_host_triple(llvm_config.use_llvm_tool('clang-cl')))
-else:
-  print('Host triple {} not supported. Skipping dexter tests in the '
-        'debuginfo-tests project.'.format(config.host_triple))
-
-# Check which debuggers are available:
-lldb_path = llvm_config.use_llvm_tool('lldb', search_env='LLDB')
-
-if lldb_path is not None:
-    config.available_features.add('lldb')
-
-# Produce dexter path, lldb path, and combine into the %dexter substitution
-# for running a test.
-dexter_path = os.path.join(config.debuginfo_tests_src_root,
-                           'dexter', 'dexter.py')
-dexter_test_cmd = '"{}" "{}" test'.format(sys.executable, dexter_path)
-if lldb_path is not None:
-  dexter_test_cmd += ' --lldb-executable "{}"'.format(lldb_path)
-tools.append(ToolSubst('%dexter', dexter_test_cmd))
-
-# For testing other bits of dexter that aren't under the "test" subcommand,
-# have a %dexter_base substitution.
-dexter_base_cmd = '"{}" "{}"'.format(sys.executable, dexter_path)
-tools.append(ToolSubst('%dexter_base', dexter_base_cmd))
-
-# Set up commands for DexTer regression tests.
-# Builder, debugger, optimisation level and several other flags differ
-# depending on whether we're running a unix like or windows os.
-if platform.system() == 'Windows': 
-  dexter_regression_test_builder = '--builder clang-cl_vs2015'
-  dexter_regression_test_debugger = '--debugger dbgeng'
-  dexter_regression_test_cflags = '--cflags "/Zi /Od"'
-  dexter_regression_test_ldflags = '--ldflags "/Zi"'
-else:
-  dexter_regression_test_builder = '--builder clang'
-  dexter_regression_test_debugger = "--debugger lldb"
-  dexter_regression_test_cflags = '--cflags "-O0 -glldb"'
-  dexter_regression_test_ldflags = ''
-
-# Typical command would take the form:
-# ./path_to_py/python.exe ./path_to_dex/dexter.py test --fail-lt 1.0 -w --builder clang --debugger lldb --cflags '-O0 -g'
-dexter_regression_test_command = ' '.join(
-  # "python", "dexter.py", test, fail_mode, builder, debugger, cflags, ldflags
-  ['"{}"'.format(sys.executable),
-  '"{}"'.format(dexter_path),
-  'test',
-  '--fail-lt 1.0 -w',
-  dexter_regression_test_builder,
-  dexter_regression_test_debugger,
-  dexter_regression_test_cflags,
-  dexter_regression_test_ldflags])
-
-tools.append(ToolSubst('%dexter_regression_test', dexter_regression_test_command))
-
-tool_dirs = [config.llvm_tools_dir]
-
-llvm_config.add_tool_substitutions(tools, tool_dirs)
-
-lit.util.usePlatformSdkOnDarwin(config, lit_config)
-
-# available_features: REQUIRES/UNSUPPORTED lit commands look at this list.
-if platform.system() == 'Darwin':
-    xcode_lldb_vers = subprocess.check_output(['xcrun', 'lldb', '--version']).decode("utf-8")
-    match = re.search('lldb-(\d+)', xcode_lldb_vers)
-    if match:
-        apple_lldb_vers = int(match.group(1))
-        if apple_lldb_vers < 1000:
-            config.available_features.add('apple-lldb-pre-1000')
-
-llvm_config.feature_config(
-    [('--build-mode', {'Debug|RelWithDebInfo': 'debug-info'})]
-)
diff --git a/lit.site.cfg.py.in b/lit.site.cfg.py.in
deleted file mode 100644
index bd2cadc..0000000
--- a/lit.site.cfg.py.in
+++ /dev/null
@@ -1,37 +0,0 @@
-@LIT_SITE_CFG_IN_HEADER@
-
-import sys
-import lit.util
-
-config.targets_to_build = "@TARGETS_TO_BUILD@".split()
-config.llvm_src_root = "@LLVM_SOURCE_DIR@"
-config.llvm_tools_dir = "@LLVM_TOOLS_DIR@"
-config.llvm_libs_dir = "@LLVM_LIBS_DIR@"
-config.llvm_shlib_dir = "@SHLIBDIR@"
-config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@"
-config.llvm_plugin_ext = "@LLVM_PLUGIN_EXT@"
-config.debuginfo_tests_obj_root = "@DEBUGINFO_TESTS_BINARY_DIR@"
-config.debuginfo_tests_src_root = "@DEBUGINFO_TESTS_SOURCE_DIR@"
-config.host_triple = "@LLVM_HOST_TRIPLE@"
-config.target_triple = "@TARGET_TRIPLE@"
-config.is_msvc = lit.util.pythonize_bool("@MSVC@")
-
-config.mlir_src_root = "@MLIR_SOURCE_DIR@"
-
-config.llvm_use_sanitizer = "@LLVM_USE_SANITIZER@"
-
-# Support substitution of the tools_dir with user parameters. This is
-# used when we can't determine the tool dir at configuration time.
-try:
-    config.llvm_tools_dir = config.llvm_tools_dir % lit_config.params
-    config.llvm_shlib_dir = config.llvm_shlib_dir % lit_config.params
-except KeyError:
-    e = sys.exc_info()[1]
-    key, = e.args
-    lit_config.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key,key))
-
-import lit.llvm
-lit.llvm.initialize(lit_config, config)
-
-# Let the main config do the real work.
-lit_config.load_config(config, "@DEBUGINFO_TESTS_SOURCE_DIR@/lit.cfg.py")
diff --git a/llgdb-tests/apple-accel.cpp b/llgdb-tests/apple-accel.cpp
deleted file mode 100644
index 2705c29..0000000
--- a/llgdb-tests/apple-accel.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
-// REQUIRES: system-darwin
-// Test that clang produces the __apple accelerator tables,
-// e.g., __apple_types, correctly.
-// These sections are going to be retired in DWARF 5, so we hardcode
-// the DWARF version in the tests.
-// RUN: %clang %s %target_itanium_abi_host_triple -gdwarf-2 -O0 -c -g -o %t-ex
-// RUN: llvm-objdump --section-headers %t-ex | FileCheck %s
-// RUN: %clang %s %target_itanium_abi_host_triple -gdwarf-4 -O0 -c -g -o %t-ex
-// RUN: llvm-objdump --section-headers %t-ex | FileCheck %s
-
-// A function in a different section forces the compiler to create the
-// __debug_ranges section.
-__attribute__((section("1,__text_foo"))) void foo() {}
-int main (int argc, char const *argv[]) { return argc; }
-
-// CHECK-DAG: __debug_abbrev
-// CHECK-DAG: __debug_info
-// CHECK-DAG: __debug_str
-// CHECK-DAG: __debug_ranges
-// CHECK-DAG: __apple_names
-// CHECK-DAG: __apple_objc
-// CHECK-DAG: __apple_namespac
-// CHECK-DAG: __apple_types
diff --git a/llgdb-tests/asan-blocks.c b/llgdb-tests/asan-blocks.c
deleted file mode 100644
index 33f44cd..0000000
--- a/llgdb-tests/asan-blocks.c
+++ /dev/null
@@ -1,41 +0,0 @@
-// RUN: %clang -fblocks %target_itanium_abi_host_triple -arch x86_64 %s -o %t.out -g -fsanitize=address
-// RUN: %test_debuginfo %s %t.out
-// FIXME: Remove system-darwin when we build BlocksRuntime everywhere.
-// REQUIRES: !asan, system-darwin
-//           Zorg configures the ASAN stage2 bots to not build the asan
-//           compiler-rt. Only run this test on non-asanified configurations.
-void b();
-struct S {
-  int a[8];
-};
-
-int f(struct S s, unsigned i) {
-  // DEBUGGER: break 17
-  // DEBUGGER: r
-  // DEBUGGER: p s
-  // CHECK: a = ([0] = 0, [1] = 1, [2] = 2, [3] = 3, [4] = 4, [5] = 5, [6] = 6, [7] = 7)
-  return s.a[i];
-}
-
-int main(int argc, const char **argv) {
-  struct S s = {{0, 1, 2, 3, 4, 5, 6, 7}};
-  if (f(s, 4) == 4) {
-    // DEBUGGER: break 27
-    // DEBUGGER: c
-    // DEBUGGER: p s
-    // CHECK: a = ([0] = 0, [1] = 1, [2] = 2, [3] = 3, [4] = 4, [5] = 5, [6] = 6, [7] = 7)
-    b();
-  }
-  return 0;
-}
-
-void c() {}
-
-void b() {
-  // DEBUGGER: break 40
-  // DEBUGGER: c
-  // DEBUGGER: p x
-  // CHECK: 42
-  __block int x = 42;
-  c();
-}
diff --git a/llgdb-tests/asan-deque.cpp b/llgdb-tests/asan-deque.cpp
deleted file mode 100644
index f3f55aa..0000000
--- a/llgdb-tests/asan-deque.cpp
+++ /dev/null
@@ -1,46 +0,0 @@
-// RUN: %clangxx -arch x86_64 %target_itanium_abi_host_triple -O1 -g %s -o %t.out -fsanitize=address
-// RUN: %test_debuginfo %s %t.out
-// REQUIRES: !asan
-//           Zorg configures the ASAN stage2 bots to not build the asan
-//           compiler-rt. Only run this test on non-asanified configurations.
-// UNSUPPORTED: apple-lldb-pre-1000
-#include <deque>
-
-struct A {
-  int a;
-  A(int a) : a(a) {}
-};
-
-using log_t = std::deque<A>;
-
-static void __attribute__((noinline, optnone)) escape(log_t &log) {
-  static volatile log_t *sink;
-  sink = &log;
-}
-
-int main() {
-  log_t log;
-  log.push_back(1234);
-  log.push_back(56789);
-  escape(log);
-  // DEBUGGER: break 25
-  while (!log.empty()) {
-    auto record = log.front();
-    log.pop_front();
-    escape(log);
-    // DEBUGGER: break 30
-  }
-}
-
-// DEBUGGER: r
-
-// (at line 25)
-// DEBUGGER: p log
-// CHECK: 1234
-// CHECK: 56789
-
-// DEBUGGER: c
-
-// (at line 30)
-// DEBUGGER: p log
-// CHECK: 56789
diff --git a/llgdb-tests/asan.c b/llgdb-tests/asan.c
deleted file mode 100644
index 96dffb3..0000000
--- a/llgdb-tests/asan.c
+++ /dev/null
@@ -1,31 +0,0 @@
-// RUN: %clang -fblocks %target_itanium_abi_host_triple -arch x86_64 %s -o %t.out -g -fsanitize=address
-// RUN: %test_debuginfo %s %t.out
-// REQUIRES: !asan
-//           Zorg configures the ASAN stage2 bots to not build the asan
-//           compiler-rt. Only run this test on non-asanified configurations.
-//
-
-struct S {
-  int a[8];
-};
-
-int f(struct S s, unsigned i) {
-  // DEBUGGER: break 14
-  return s.a[i];
-}
-
-int main(int argc, const char **argv) {
-  struct S s = {{0, 1, 2, 3, 4, 5, 6, 7}};
-  if (f(s, 4) == 4)
-    return f(s, 0);
-  return 0;
-}
-
-// DEBUGGER: r
-// DEBUGGER: p s
-// CHECK: a =
-// DEBUGGER: p s.a[0]
-// CHECK: = 0
-// DEBUGGER: p s.a[1]
-// CHECK: = 1
-// DEBUGGER: p s.a[7]
diff --git a/llgdb-tests/block_var.m b/llgdb-tests/block_var.m
deleted file mode 100644
index 7ec786f..0000000
--- a/llgdb-tests/block_var.m
+++ /dev/null
@@ -1,32 +0,0 @@
-// RUN: %clang %target_itanium_abi_host_triple -O0 -g %s -c -o %t.o
-// RUN: %clang %target_itanium_abi_host_triple %t.o -o %t.out -framework Foundation
-// RUN: %test_debuginfo %s %t.out 
-
-// REQUIRES: system-darwin
-
-// DEBUGGER: break 24
-// DEBUGGER: r
-// DEBUGGER: p result
-// CHECK: ${{[0-9]}} = 42
-
-void doBlock(void (^block)(void))
-{
-    block();
-}
-
-int I(int n)
-{
-    __block int result;
-    int i = 2;
-    doBlock(^{
-        result = n;
-    });
-    return result + i; /* Check value of 'result' */
-}
-
-
-int main (int argc, const char * argv[]) {
-  return I(42);
-}
-
-
diff --git a/llgdb-tests/blocks.m b/llgdb-tests/blocks.m
deleted file mode 100644
index 8e5a212..0000000
--- a/llgdb-tests/blocks.m
+++ /dev/null
@@ -1,43 +0,0 @@
-// RUN: %clang %target_itanium_abi_host_triple -O0 -g %s -c -o %t.o
-// RUN: %clang %target_itanium_abi_host_triple %t.o -o %t.out -framework Foundation
-// RUN: %test_debuginfo %s %t.out 
-
-// REQUIRES: system-darwin
-// Radar 9279956
-
-// DEBUGGER: break 31
-// DEBUGGER: r
-// DEBUGGER: p m2
-// CHECK: ${{[0-9]}} = 1
-// DEBUGGER: p dbTransaction
-// CHECK: ${{[0-9]}} = 0
-// DEBUGGER: p master
-// CHECK: ${{[0-9]}} = 0
-
-#include <Cocoa/Cocoa.h>
-
-extern void foo(void(^)(void));
-
-@interface A:NSObject @end
-@implementation A
-- (void) helper {
- int master = 0;
- __block int m2 = 0;
- __block int dbTransaction = 0;
- int (^x)(void) = ^(void) { (void) self; 
-	(void) master; 
-	(void) dbTransaction; 
-	m2++;
-	return m2;
-	};
-  master = x();
-}
-@end
-
-void foo(void(^x)(void)) {}
-
-int main() {
-	A *a = [A alloc];
-	[a helper];
-	return 0;
-}
diff --git a/llgdb-tests/foreach.m b/llgdb-tests/foreach.m
deleted file mode 100644
index 2e3c312..0000000
--- a/llgdb-tests/foreach.m
+++ /dev/null
@@ -1,31 +0,0 @@
-// RUN: %clang %target_itanium_abi_host_triple -O0 -g %s -c -o %t.o
-// RUN: %clang %target_itanium_abi_host_triple %t.o -o %t.out -framework Foundation
-// RUN: %test_debuginfo %s %t.out 
-//
-// REQUIRES: system-darwin
-// Radar 8757124
-
-// DEBUGGER: break 25
-// DEBUGGER: r
-// DEBUGGER: po thing
-// CHECK: aaa
-
-#import <Foundation/Foundation.h>
-
-int main (int argc, const char * argv[]) {
-
-    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-    NSArray *things = [NSArray arrayWithObjects:@"one", @"two", @"three" , nil];
-    for (NSString *thing in things) {
-        NSLog (@"%@", thing);
-    }
-    
-    things = [NSArray arrayWithObjects:@"aaa", @"bbb", @"ccc" , nil];
-    for (NSString *thing in things) {
-        NSLog (@"%@", thing);
-    }
-    [pool release];
-    return 0;
-}
-
-
diff --git a/llgdb-tests/forward-declare-class.cpp b/llgdb-tests/forward-declare-class.cpp
deleted file mode 100644
index 1324200..0000000
--- a/llgdb-tests/forward-declare-class.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-// RUN: %clangxx %target_itanium_abi_host_triple -O0 -g %s -c -o %t.o
-// RUN: %test_debuginfo %s %t.o
-// Radar 9168773
-
-// DEBUGGER: ptype A
-// Work around a gdb bug where it believes that a class is a
-// struct if there aren't any methods - even though it's tagged
-// as a class.
-// CHECK: type = {{struct|class}} A {
-// CHECK-NEXT: {{(public:){0,1}}}
-// CHECK-NEXT: int MyData;
-// CHECK-NEXT: }
-class A;
-class B {
-public:
-  void foo(const A *p);
-};
-
-B iEntry;
-
-class A {
-public:
-  int MyData;
-};
-
-A irp;
-
diff --git a/llgdb-tests/lit.local.cfg b/llgdb-tests/lit.local.cfg
deleted file mode 100644
index 725aa59..0000000
--- a/llgdb-tests/lit.local.cfg
+++ /dev/null
@@ -1,5 +0,0 @@
-# debuginfo-tests are not expected to pass in a cross-compilation setup.
-if 'native' not in config.available_features or config.is_msvc:
-    config.unsupported = True
-
-
diff --git a/llgdb-tests/llgdb.py b/llgdb-tests/llgdb.py
deleted file mode 100755
index 83b5ec6..0000000
--- a/llgdb-tests/llgdb.py
+++ /dev/null
@@ -1,162 +0,0 @@
-#!/usr/bin/env python
-"""
-A gdb-compatible frontend for lldb that implements just enough
-commands to run the tests in the debuginfo-tests repository with lldb.
-"""
-
-# ----------------------------------------------------------------------
-# Auto-detect lldb python module.
-import commands, platform, os,  sys
-try:
-    # Just try for LLDB in case PYTHONPATH is already correctly setup.
-    import lldb
-except ImportError:
-    lldb_python_dirs = list()
-    # lldb is not in the PYTHONPATH, try some defaults for the current platform.
-    platform_system = platform.system()
-    if platform_system == 'Darwin':
-        # On Darwin, try the currently selected Xcode directory
-        xcode_dir = commands.getoutput("xcode-select --print-path")
-        if xcode_dir:
-            lldb_python_dirs.append(os.path.realpath(xcode_dir +
-'/../SharedFrameworks/LLDB.framework/Resources/Python'))
-            lldb_python_dirs.append(xcode_dir +
-'/Library/PrivateFrameworks/LLDB.framework/Resources/Python')
-        lldb_python_dirs.append(
-'/System/Library/PrivateFrameworks/LLDB.framework/Resources/Python')
-    success = False
-    for lldb_python_dir in lldb_python_dirs:
-        if os.path.exists(lldb_python_dir):
-            if not (sys.path.__contains__(lldb_python_dir)):
-                sys.path.append(lldb_python_dir)
-                try:
-                    import lldb
-                except ImportError:
-                    pass
-                else:
-                    print 'imported lldb from: "%s"' % (lldb_python_dir)
-                    success = True
-                    break
-    if not success:
-        print "error: couldn't locate the 'lldb' module, please set PYTHONPATH correctly"
-        sys.exit(1)
-# ----------------------------------------------------------------------
-
-# Command line option handling.
-import argparse
-parser = argparse.ArgumentParser(description=__doc__)
-parser.add_argument('--quiet', '-q', action="store_true", help='ignored')
-parser.add_argument('-batch', action="store_true",
-                    help='exit after processing comand line')
-parser.add_argument('-n', action="store_true", help='ignore .lldb file')
-parser.add_argument('-x', dest='script', type=file, help='execute commands from file')
-parser.add_argument("target", help="the program to debug")
-args = parser.parse_args()
-
-
-# Create a new debugger instance.
-debugger = lldb.SBDebugger.Create()
-debugger.SkipLLDBInitFiles(args.n)
-
-# Make sure to clean up the debugger on exit.
-import atexit
-def on_exit():
-    debugger.Terminate()
-atexit.register(on_exit)
-
-# Don't return from lldb function calls until the process stops.
-debugger.SetAsync(False)
-
-# Create a target from a file and arch.
-arch = os.popen("file "+args.target).read().split()[-1]
-target = debugger.CreateTargetWithFileAndArch(args.target, arch)
-
-if not target:
-    print "Could not create target", args.target
-    sys.exit(1)
-
-if not args.script:
-    print "Interactive mode is not implemented."
-    sys.exit(1)
-
-import re
-for command in args.script:
-    # Strip newline and whitespaces and split into words.
-    cmd = command[:-1].strip().split()
-    if not cmd:
-        continue
-
-    print '> %s'% command[:-1]
-
-    try:
-        if re.match('^r|(run)$', cmd[0]):
-            error = lldb.SBError()
-            launchinfo = lldb.SBLaunchInfo([])
-            launchinfo.SetWorkingDirectory(os.getcwd())
-            process = target.Launch(launchinfo, error)
-            print error
-            if not process or error.fail:
-                state = process.GetState()
-                print "State = %d" % state
-                print """
-ERROR: Could not launch process.
-NOTE: There are several reasons why this may happen:
-  * Root needs to run "DevToolsSecurity --enable".
-  * Older versions of lldb cannot launch more than one process simultaneously.
-"""
-                sys.exit(1)
-
-        elif re.match('^b|(break)$', cmd[0]) and len(cmd) == 2:
-            if re.match('[0-9]+', cmd[1]):
-                # b line
-                mainfile = target.FindFunctions('main')[0].compile_unit.file
-                print target.BreakpointCreateByLocation(mainfile, int(cmd[1]))
-            else:
-                # b file:line
-                file, line = cmd[1].split(':')
-                print target.BreakpointCreateByLocation(file, int(line))
-
-        elif re.match('^ptype$', cmd[0]) and len(cmd) == 2:
-            # GDB's ptype has multiple incarnations depending on its
-            # argument (global variable, function, type).  The definition
-            # here is for looking up the signature of a function and only
-            # if that fails it looks for a type with that name.
-            # Type lookup in LLDB would be "image lookup --type".
-            for elem in target.FindFunctions(cmd[1]):
-                print elem.function.type
-                continue
-            print target.FindFirstType(cmd[1])
-
-        elif re.match('^po$', cmd[0]) and len(cmd) > 1:
-            try:
-                opts = lldb.SBExpressionOptions()
-                opts.SetFetchDynamicValue(True)
-                opts.SetCoerceResultToId(True)
-                print target.EvaluateExpression(' '.join(cmd[1:]), opts)
-            except:
-                # FIXME: This is a fallback path for the lab.llvm.org
-                # buildbot running OS X 10.7; it should be removed.
-                thread = process.GetThreadAtIndex(0)
-                frame = thread.GetFrameAtIndex(0)
-                print frame.EvaluateExpression(' '.join(cmd[1:]))
-
-        elif re.match('^p|(print)$', cmd[0]) and len(cmd) > 1:
-            thread = process.GetThreadAtIndex(0)
-            frame = thread.GetFrameAtIndex(0)
-            print frame.EvaluateExpression(' '.join(cmd[1:]))
-
-        elif re.match('^n|(next)$', cmd[0]):
-            thread = process.GetThreadAtIndex(0)
-            thread.StepOver()
-
-        elif re.match('^q|(quit)$', cmd[0]):
-            sys.exit(0)
-
-        else:
-            print debugger.HandleCommand(' '.join(cmd))
-
-    except SystemExit:
-        raise
-    except:
-        print 'Could not handle the command "%s"' % ' '.join(cmd)
-
diff --git a/llgdb-tests/nested-struct.cpp b/llgdb-tests/nested-struct.cpp
deleted file mode 100644
index 7533e6a..0000000
--- a/llgdb-tests/nested-struct.cpp
+++ /dev/null
@@ -1,21 +0,0 @@
-// RUN: %clangxx %target_itanium_abi_host_triple -O0 -g %s -c -o %t.o
-// RUN: %test_debuginfo %s %t.o
-// Radar 9440721
-// If debug info for my_number() is emitted outside function foo's scope
-// then a debugger may not be able to handle it. At least one version of
-// gdb crashes in such cases.
-
-// DEBUGGER: ptype foo
-// CHECK: int (void)
-
-int foo() {
-  struct Local {
-    static int my_number() {
-      return 42;
-    }
-  };
-
-  int i = 0;
-  i = Local::my_number();
-  return i + 1;
-}
diff --git a/llgdb-tests/nrvo-string.cpp b/llgdb-tests/nrvo-string.cpp
deleted file mode 100644
index 9b805c9..0000000
--- a/llgdb-tests/nrvo-string.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-// This ensures that DW_OP_deref is inserted when necessary, such as when NRVO
-// of a string object occurs in C++.
-//
-// RUN: %clangxx -O0 -fno-exceptions %target_itanium_abi_host_triple %s -o %t.out -g
-// RUN: %test_debuginfo %s %t.out
-// RUN: %clangxx -O1 -fno-exceptions %target_itanium_abi_host_triple %s -o %t.out -g
-// RUN: %test_debuginfo %s %t.out
-//
-// PR34513
-volatile int sideeffect = 0;
-void __attribute__((noinline)) stop() { sideeffect++; }
-
-struct string {
-  string() {}
-  string(int i) : i(i) {}
-  ~string() {}
-  int i = 0;
-};
-string __attribute__((noinline)) get_string() {
-  string unused;
-  string result = 3;
-  // DEBUGGER: break 23
-  stop();
-  return result;
-}
-void some_function(int) {}
-struct string2 {
-  string2() = default;
-  string2(string2 &&other) { i = other.i; }
-  int i;
-};
-string2 __attribute__((noinline)) get_string2() {
-  string2 result;
-  result.i = 5;
-  some_function(result.i);
-  // Test that the debugger can get the value of result after another
-  // function is called.
-  // DEBUGGER: break 39
-  stop();
-  return result;
-}
-int main() {
-  get_string();
-  get_string2();
-}
-
-// DEBUGGER: r
-// DEBUGGER: print result.i
-// CHECK:  = 3
-// DEBUGGER: c
-// DEBUGGER: print result.i
-// CHECK:  = 5
diff --git a/llgdb-tests/safestack.c b/llgdb-tests/safestack.c
deleted file mode 100644
index cf3efc7..0000000
--- a/llgdb-tests/safestack.c
+++ /dev/null
@@ -1,52 +0,0 @@
-// RUN: %clang %target_itanium_abi_host_triple -arch x86_64 %s -o %t.out -g -fsanitize=safe-stack
-// RUN: %test_debuginfo %s %t.out
-// UNSUPPORTED: system-darwin
-// REQUIRES: !asan
-//           Zorg configures the ASAN stage2 bots to not build the
-//           safestack compiler-rt.  Only run this test on
-//           non-asanified configurations.
-
-struct S {
-  int a[8];
-};
-
-int f(struct S s, unsigned i);
-
-int main(int argc, const char **argv) {
-  struct S s = {{0, 1, 2, 3, 4, 5, 6, 7}};
-  // DEBUGGER: break 17
-  f(s, 4);
-  // DEBUGGER: break 19
-  return 0;
-}
-
-int f(struct S s, unsigned i) {
-  // DEBUGGER: break 24
-  return s.a[i];
-}
-
-// DEBUGGER: r
-// DEBUGGER: p s
-// CHECK: a =
-// DEBUGGER: p s.a[0]
-// CHECK: = 0
-// DEBUGGER: p s.a[1]
-// CHECK: = 1
-// DEBUGGER: p s.a[7]
-// CHECK: = 7
-// DEBUGGER: c
-// DEBUGGER: p s
-// CHECK: a =
-// DEBUGGER: p s.a[0]
-// CHECK: = 0
-// DEBUGGER: p s.a[1]
-// CHECK: = 1
-// DEBUGGER: p s.a[7]
-// DEBUGGER: c
-// DEBUGGER: p s
-// CHECK: a =
-// DEBUGGER: p s.a[0]
-// CHECK: = 0
-// DEBUGGER: p s.a[1]
-// CHECK: = 1
-// DEBUGGER: p s.a[7]
diff --git a/llgdb-tests/sret.cpp b/llgdb-tests/sret.cpp
deleted file mode 100644
index 640015f..0000000
--- a/llgdb-tests/sret.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-// RUN: %clangxx %target_itanium_abi_host_triple -O0 -g %s -c -o %t.o
-// RUN: %clangxx %target_itanium_abi_host_triple %t.o -o %t.out
-// RUN: %test_debuginfo %s %t.out
-// Radar 8775834
-// DEBUGGER: break 62
-// DEBUGGER: r
-// DEBUGGER: p a
-// CHECK: ${{[0-9]+}} =
-// LLDB does not print artificial members.
-// CHECK:  {{(_vptr\$A =)?.*}}m_int = 12
-
-class A
-{
-public:
-    A (int i=0);
-    A (const A& rhs);
-    const A&
-    operator= (const A& rhs);
-    virtual ~A() {}
-
-    int get_int();
-
-protected:
-    int m_int;
-};
-
-A::A (int i) :
-    m_int(i)
-{
-}
-
-A::A (const A& rhs) :
-    m_int (rhs.m_int)
-{
-}
-
-const A &
-A::operator =(const A& rhs)
-{
-    m_int = rhs.m_int;
-    return *this;
-}
-
-int A::get_int()
-{
-    return m_int;
-}
-
-class B
-{
-public:
-    B () {}
-
-    A AInstance();
-};
-
-A
-B::AInstance()
-{
-    A a(12);
-    return a;
-}
-
-int main (int argc, char const *argv[])
-{
-    B b;
-    int return_val = b.AInstance().get_int();
-
-    A a(b.AInstance());
-    return return_val;
-}
diff --git a/llgdb-tests/static-member-2.cpp b/llgdb-tests/static-member-2.cpp
deleted file mode 100644
index 4edb2b0..0000000
--- a/llgdb-tests/static-member-2.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-// RUN: %clangxx %target_itanium_abi_host_triple -O0 -g %s -o %t -c
-// RUN: %clangxx %target_itanium_abi_host_triple %t -o %t.out
-// RUN: %test_debuginfo %s %t.out
-
-// FIXME: LLDB finds the wrong symbol for "C". rdar://problem/14933867
-// XFAIL: darwin
-
-// DEBUGGER: delete breakpoints
-// DEBUGGER: break static-member.cpp:33
-// DEBUGGER: r
-// DEBUGGER: ptype C
-// CHECK:      {{struct|class}} C {
-// CHECK:      static const int a;
-// CHECK-NEXT: static int b;
-// CHECK-NEXT: static int c;
-// CHECK-NEXT: int d;
-// CHECK-NEXT: }
-// DEBUGGER: p C::a
-// CHECK: ${{[0-9]}} = 4
-// DEBUGGER: p C::c
-// CHECK: ${{[0-9]}} = 15
-
-// PR14471, PR14734
-
-class C {
-public:
-  const static int a = 4;
-  static int b;
-  static int c;
-  int d;
-};
-
-int C::c = 15;
-const int C::a;
-
-int main() {
-    C instance_C;
-    return C::a;
-}
diff --git a/llgdb-tests/static-member.cpp b/llgdb-tests/static-member.cpp
deleted file mode 100644
index 1d8ad62..0000000
--- a/llgdb-tests/static-member.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-// RUN: %clangxx %target_itanium_abi_host_triple -O0 -g %s -o %t -c
-// RUN: %clangxx %target_itanium_abi_host_triple %t -o %t.out
-// RUN: %test_debuginfo %s %t.out
-
-// DEBUGGER: delete breakpoints
-// DEBUGGER: break static-member.cpp:33
-// DEBUGGER: r
-// DEBUGGER: ptype MyClass
-// CHECK:      {{struct|class}} MyClass {
-// CHECK:      static const int a;
-// CHECK-NEXT: static int b;
-// CHECK-NEXT: static int c;
-// CHECK-NEXT: int d;
-// CHECK-NEXT: }
-// DEBUGGER: p MyClass::a
-// CHECK: ${{[0-9]}} = 4
-// DEBUGGER: p MyClass::c
-// CHECK: ${{[0-9]}} = 15
-
-// PR14471, PR14734
-
-class MyClass {
-public:
-  const static int a = 4;
-  static int b;
-  static int c;
-  int d;
-};
-
-int MyClass::c = 15;
-const int MyClass::a;
-
-int main() {
-    MyClass instance_MyClass;
-    return MyClass::a;
-}
diff --git a/llgdb-tests/test_debuginfo.pl b/llgdb-tests/test_debuginfo.pl
deleted file mode 100755
index 23d2304..0000000
--- a/llgdb-tests/test_debuginfo.pl
+++ /dev/null
@@ -1,81 +0,0 @@
-#!/usr/bin/env perl
-#
-# This script tests debugging information generated by a compiler.
-# Input arguments
-#   - Input source program. Usually this source file is decorated using
-#     special comments to communicate debugger commands.
-#   - Executable file. This file is generated by the compiler.
-#
-# This perl script extracts debugger commands from input source program
-# comments in a script. A debugger is used to load the executable file
-# and run the script generated from source program comments. Finally,
-# the debugger output is checked, using FileCheck, to validate
-# debugging information.
-#
-# On Darwin the default is to use the llgdb.py wrapper script which
-# translates gdb commands into their lldb equivalents.
-
-use File::Basename;
-use Config;
-use Cwd;
-
-my $testcase_file = $ARGV[0];
-my $executable_file = $ARGV[1];
-
-my $input_filename = basename $testcase_file;
-my $output_dir = dirname $executable_file;
-
-my $debugger_script_file = "$output_dir/$input_filename.debugger.script";
-my $output_file = "$output_dir/$input_filename.gdb.output";
-
-my %cmd_map = ();
-# Assume lldb to be the debugger on Darwin.
-my $use_lldb = 0;
-$use_lldb = 1 if ($Config{osname} eq "darwin");
-
-# Extract debugger commands from testcase. They are marked with DEBUGGER:
-# at the beginning of a comment line.
-open(INPUT, $testcase_file);
-open(OUTPUT, ">$debugger_script_file");
-while(<INPUT>) {
-    my($line) = $_;
-    $i = index($line, "DEBUGGER:");
-    if ( $i >= 0) {
-        $l = length("DEBUGGER:");
-        $s = substr($line, $i + $l);
-        print OUTPUT  "$s";
-    }
-}
-print OUTPUT "\n";
-print OUTPUT "quit\n";
-close(INPUT);
-close(OUTPUT);
-
-# setup debugger and debugger options to run a script.
-my $my_debugger = $ENV{'DEBUGGER'};
-if (!$my_debugger) {
-    if ($use_lldb) {
-        my $path = dirname(Cwd::abs_path($0));
-        # At least on darwin, LLDB needs te system python.
-        $my_debugger = "/usr/bin/python $path/llgdb.py";
-    } else {
-        $my_debugger = "gdb";
-    }
-}
-
-# quiet / exit after cmdline / no init file / execute script
-my $debugger_options = "-q -batch -n -x";
-
-# run debugger and capture output.
-system("$my_debugger $debugger_options $debugger_script_file $executable_file > $output_file 2>&1");
-
-# validate output.
-system("FileCheck", "-input-file", "$output_file", "$testcase_file");
-if ($?>>8 == 1) {
-    print "Debugger output was:\n";
-    system("cat", "$output_file");
-    exit 1;
-}
-else {
-    exit 0;
-}
diff --git a/llvm-prettyprinters/gdb/lit.local.cfg b/llvm-prettyprinters/gdb/lit.local.cfg
deleted file mode 100644
index a4200fb..0000000
--- a/llvm-prettyprinters/gdb/lit.local.cfg
+++ /dev/null
@@ -1,13 +0,0 @@
-import lit.util
-
-# debuginfo-tests are not expected to pass in a cross-compilation setup.
-if 'native' not in config.available_features or lit.util.which('gdb') is None:
-    config.unsupported = True
-
-if config.mlir_src_root:
-  config.substitutions.append(("%mlir_src_root", config.mlir_src_root))
-  config.available_features.add('mlir')
-
-config.suffixes = ['.gdb']
-
-
diff --git a/llvm-prettyprinters/gdb/llvm-support.cpp b/llvm-prettyprinters/gdb/llvm-support.cpp
deleted file mode 100644
index 8679628..0000000
--- a/llvm-prettyprinters/gdb/llvm-support.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/ADT/PointerUnion.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/Twine.h"
-#include "llvm/ADT/ilist.h"
-#include "llvm/Support/Error.h"
-
-int Array[] = {1, 2, 3};
-auto IntPtr = reinterpret_cast<int *>(0xabc);
-
-llvm::ArrayRef<int> ArrayRef(Array);
-llvm::MutableArrayRef<int> MutableArrayRef(Array);
-llvm::DenseMap<int, int> DenseMap = {{4, 5}, {6, 7}};
-llvm::StringMap<int> StringMap = {{"foo", 123}, {"bar", 456}};
-llvm::Expected<int> ExpectedValue(8);
-llvm::Expected<int> ExpectedError(llvm::createStringError({}, ""));
-llvm::Optional<int> OptionalValue(9);
-llvm::Optional<int> OptionalNone(llvm::None);
-llvm::SmallVector<int, 5> SmallVector = {10, 11, 12};
-llvm::SmallString<5> SmallString("foo");
-llvm::StringRef StringRef = "bar";
-llvm::Twine Twine = llvm::Twine(SmallString) + StringRef;
-llvm::PointerIntPair<int *, 1> PointerIntPair(IntPtr, 1);
-
-struct alignas(8) Z {};
-llvm::PointerUnion<Z *, int *> PointerUnion(IntPtr);
-
-// No members which instantiate PointerUnionUIntTraits<Z *> (e.g. get<T *>())
-// are called, and this instance will therefore be raw-printed.
-llvm::PointerUnion<Z *, float *> RawPrintingPointerUnion(nullptr);
-
-using IlistTag = llvm::ilist_tag<struct A>;
-using SimpleIlistTag = llvm::ilist_tag<struct B>;
-struct IlistNode : llvm::ilist_node<IlistNode, IlistTag>,
-                   llvm::ilist_node<IlistNode, SimpleIlistTag> {
-  int Value;
-};
-auto Ilist = [] {
-  llvm::ilist<IlistNode, IlistTag> Result;
-  for (int I : {13, 14, 15}) {
-    Result.push_back(new IlistNode);
-    Result.back().Value = I;
-  }
-  return Result;
-}();
-auto SimpleIlist = []() {
-  llvm::simple_ilist<IlistNode, SimpleIlistTag> Result;
-  for (auto &Node : Ilist)
-    Result.push_front(Node);
-  return Result;
-}();
-
-int main() {
-  // Reference symbols that might otherwise be stripped.
-  ArrayRef[0];
-  MutableArrayRef[0];
-  (void)!ExpectedValue;
-  (void)!ExpectedError;
-  *OptionalValue;
-  *OptionalNone;
-  return 0;
-}
diff --git a/llvm-prettyprinters/gdb/llvm-support.gdb b/llvm-prettyprinters/gdb/llvm-support.gdb
deleted file mode 100644
index b07eabf..0000000
--- a/llvm-prettyprinters/gdb/llvm-support.gdb
+++ /dev/null
@@ -1,136 +0,0 @@
-# RUN: gdb -q -batch -n -iex 'source %llvm_src_root/utils/gdb-scripts/prettyprinters.py' -x %s %llvm_tools_dir/check-gdb-llvm-support | FileCheck %s
-# REQUIRES: debug-info
-
-break main
-run
-
-# CHECK: llvm::ArrayRef of length 3 = {1, 2, 3}
-p ArrayRef
-
-# CHECK: llvm::ArrayRef of length 3 = {1, 2, 3}
-p MutableArrayRef
-
-# CHECK: llvm::DenseMap with 2 elements = {
-# CHECK:   [4] = 5,
-# CHECK:   [6] = 7,
-# CHECK: }
-p DenseMap
-
-# CHECK: llvm::Expected = {value = 8}
-p ExpectedValue
-
-# CHECK: llvm::Expected is error
-p ExpectedError
-
-# CHECK: llvm::Optional = {value = 9}
-p OptionalValue
-
-# CHECK: llvm::Optional is not initialized
-p OptionalNone
-
-# CHECK: llvm::SmallVector of Size 3, Capacity 5 = {10, 11, 12}
-p SmallVector
-
-# CHECK: "foo"
-p SmallString
-
-# CHECK: "bar"
-p StringRef
-
-# CHECK: "\"foo\"\"bar\""
-p Twine
-
-# CHECK: llvm::StringMap with 2 elements = {["foo"] = 123, ["bar"] = 456}
-p StringMap
-
-# CHECK: {pointer = 0xabc, value = 1}
-p PointerIntPair
-
-# CHECK: Containing int * = {pointer = 0xabc}
-p PointerUnion
-
-# CHECK: PointerUnionMembers<llvm::PointerUnion<Z*, float*>,
-p RawPrintingPointerUnion
-
-# Switch to print pretty adds newlines to the following statements.
-set print pretty
-
-# CHECK: {
-# CHECK:   [0] = {
-# CHECK:     <llvm::ilist_node<IlistNode, llvm::ilist_tag<A> >> = {
-# CHECK:       prev = [[Ilist_Sentinel:0x.*]] <Ilist>,
-# CHECK:       next = [[Node_14:0x.*]]
-# CHECK:     },
-# CHECK:     <llvm::ilist_node<IlistNode, llvm::ilist_tag<B> >> = {
-# CHECK:       prev = [[Node_14]],
-# CHECK:       next = [[SimpleIlist_Sentinel:0x.*]] <SimpleIlist>
-# CHECK:     },
-# CHECK:     members of IlistNode:
-# CHECK:     Value = 13
-# CHECK:   },
-# CHECK:   [1] = {
-# CHECK:     <llvm::ilist_node<IlistNode, llvm::ilist_tag<A> >> = {
-# CHECK:       prev = [[Node_13:0x.*]],
-# CHECK:       next = [[Node_15:0x.*]]
-# CHECK:     },
-# CHECK:     <llvm::ilist_node<IlistNode, llvm::ilist_tag<B> >> = {
-# CHECK:       prev = [[Node_15]],
-# CHECK:       next = [[Node_13]]
-# CHECK:     },
-# CHECK:     members of IlistNode:
-# CHECK:     Value = 14
-# CHECK:   },
-# CHECK:   [2] = {
-# CHECK:     <llvm::ilist_node<IlistNode, llvm::ilist_tag<A> >> = {
-# CHECK:       prev = [[Node_14]],
-# CHECK:       next = [[Ilist_Sentinel]] <Ilist>
-# CHECK:     },
-# CHECK:     <llvm::ilist_node<IlistNode, llvm::ilist_tag<B> >> = {
-# CHECK:       prev = [[SimpleIlist_Sentinel]] <SimpleIlist>,
-# CHECK:       next = [[Node_14]]
-# CHECK:     },
-# CHECK:     members of IlistNode:
-# CHECK:     Value = 15
-# CHECK:   }
-# CHECK: }
-p Ilist
-
-# CHECK: {
-# CHECK:   [0] = {
-# CHECK:     <llvm::ilist_node<IlistNode, llvm::ilist_tag<A> >> = {
-# CHECK:       prev = [[Node_14]],
-# CHECK:       next = [[Ilist_Sentinel]] <Ilist>
-# CHECK:     },
-# CHECK:     <llvm::ilist_node<IlistNode, llvm::ilist_tag<B> >> = {
-# CHECK:       prev = [[SimpleIlist_Sentinel]] <SimpleIlist>,
-# CHECK:       next = [[Node_14]]
-# CHECK:     },
-# CHECK:     members of IlistNode:
-# CHECK:     Value = 15
-# CHECK:   },
-# CHECK:   [1] = {
-# CHECK:     <llvm::ilist_node<IlistNode, llvm::ilist_tag<A> >> = {
-# CHECK:       prev = [[Node_13]],
-# CHECK:       next = [[Node_15]]
-# CHECK:     },
-# CHECK:     <llvm::ilist_node<IlistNode, llvm::ilist_tag<B> >> = {
-# CHECK:       prev = [[Node_15]],
-# CHECK:       next = [[Node_13]]
-# CHECK:     },
-# CHECK:     members of IlistNode:
-# CHECK:     Value = 14
-# CHECK:   },
-# CHECK:   [2] = {
-# CHECK:     <llvm::ilist_node<IlistNode, llvm::ilist_tag<A> >> = {
-# CHECK:       prev = [[Ilist_Sentinel]] <Ilist>,
-# CHECK:       next = [[Node_14]]
-# CHECK:     },
-# CHECK:     <llvm::ilist_node<IlistNode, llvm::ilist_tag<B> >> = {
-# CHECK:       prev = [[Node_14]],
-# CHECK:       next = [[SimpleIlist_Sentinel]] <SimpleIlist>
-# CHECK:     },
-# CHECK:     members of IlistNode:
-# CHECK:     Value = 13
-# CHECK:   }
-# CHECK: }
-p SimpleIlist
diff --git a/llvm-prettyprinters/gdb/mlir-support.cpp b/llvm-prettyprinters/gdb/mlir-support.cpp
deleted file mode 100644
index 9a65ad3..0000000
--- a/llvm-prettyprinters/gdb/mlir-support.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-#include "mlir/IR/BuiltinAttributes.h"
-#include "mlir/IR/BuiltinTypes.h"
-#include "mlir/IR/Identifier.h"
-#include "mlir/IR/Location.h"
-#include "mlir/IR/MLIRContext.h"
-#include "mlir/IR/OperationSupport.h"
-
-mlir::MLIRContext Context;
-
-auto Identifier = mlir::Identifier::get("foo", &Context);
-mlir::OperationName OperationName("FooOp", &Context);
-mlir::Value Value({reinterpret_cast<void *>(0x8),
-                   mlir::Value::Kind::TrailingOpResult});
-
-mlir::Type Type(nullptr);
-mlir::Type IndexType = mlir::IndexType::get(&Context);
-mlir::Type IntegerType =
-    mlir::IntegerType::get(&Context, 3, mlir::IntegerType::Unsigned);
-mlir::Type FloatType = mlir::Float32Type::get(&Context);
-mlir::Type MemRefType = mlir::MemRefType::get({4, 5}, FloatType);
-mlir::Type UnrankedMemRefType = mlir::UnrankedMemRefType::get(IntegerType, 6);
-mlir::Type VectorType = mlir::VectorType::get({1, 2}, FloatType);
-mlir::Type TupleType =
-    mlir::TupleType::get(&Context, mlir::TypeRange({IndexType, FloatType}));
-
-auto UnknownLoc = mlir::UnknownLoc::get(&Context);
-auto FileLineColLoc = mlir::FileLineColLoc::get(&Context, "file", 7, 8);
-auto OpaqueLoc = mlir::OpaqueLoc::get<uintptr_t>(9, &Context);
-auto NameLoc = mlir::NameLoc::get(Identifier);
-auto CallSiteLoc = mlir::CallSiteLoc::get(FileLineColLoc, OpaqueLoc);
-auto FusedLoc = mlir::FusedLoc::get(&Context, {FileLineColLoc, NameLoc});
-
-mlir::Attribute UnitAttr = mlir::UnitAttr::get(&Context);
-mlir::Attribute FloatAttr = mlir::FloatAttr::get(FloatType, 1.0);
-mlir::Attribute IntegerAttr = mlir::IntegerAttr::get(IntegerType, 10);
-mlir::Attribute TypeAttr = mlir::TypeAttr::get(IndexType);
-mlir::Attribute ArrayAttr = mlir::ArrayAttr::get(&Context, {UnitAttr});
-mlir::Attribute StringAttr = mlir::StringAttr::get(&Context, "foo");
-mlir::Attribute ElementsAttr = mlir::DenseElementsAttr::get(
-    VectorType.cast<mlir::ShapedType>(), llvm::ArrayRef<float>{2.0f, 3.0f});
-
-int main() { return 0; }
diff --git a/llvm-prettyprinters/gdb/mlir-support.gdb b/llvm-prettyprinters/gdb/mlir-support.gdb
deleted file mode 100644
index 2a82412..0000000
--- a/llvm-prettyprinters/gdb/mlir-support.gdb
+++ /dev/null
@@ -1,112 +0,0 @@
-# RUN: gdb -q -batch -n -iex 'source %mlir_src_root/utils/gdb-scripts/prettyprinters.py' -iex 'source %llvm_src_root/utils/gdb-scripts/prettyprinters.py' -x %s %llvm_tools_dir/check-gdb-mlir-support | FileCheck %s
-# REQUIRES: debug-info
-# REQUIRES: mlir
-
-break main
-run
-
-# CHECK: "foo"
-p Identifier
-
-# CHECK: "FooOp"
-p OperationName
-
-# CHECK: 0x8
-# CHECK: TrailingOpResult
-p Value
-
-# CHECK: impl = 0x0
-p Type
-
-# CHECK: cast<mlir::IndexType>
-p IndexType
-
-# CHECK: cast<mlir::IntegerType>
-# CHECK: width = 3
-# CHECK: Unsigned
-p IntegerType
-
-# CHECK: cast<mlir::Float32Type>
-p FloatType
-
-# CHECK: cast<mlir::MemRefType>
-# CHECK: shapeSize = 2
-# CHECK: shapeElements[0] = 4
-# CHECK: shapeElements[1] = 5
-p MemRefType
-
-# CHECK: cast<mlir::UnrankedMemRefType>
-# CHECK: memorySpace = 6
-p UnrankedMemRefType
-
-# CHECK: cast<mlir::VectorType>
-# CHECK: shapeSize = 2
-# CHECK: shapeElements[0] = 1
-# CHECK: shapeElements[1] = 2
-p VectorType
-
-# CHECK: cast<mlir::TupleType>
-# CHECK: numElements = 2
-# CHECK: elements[0]
-# CHECK: mlir::IndexType
-# CHECK: elements[1]
-# CHECK: mlir::Float32Type
-p TupleType
-
-# CHECK: cast<mlir::UnknownLoc>
-p UnknownLoc
-
-# CHECK: cast<mlir::FileLineColLoc>
-# CHECK: filename = "file"
-# CHECK: line = 7
-# CHECK: column = 8
-p FileLineColLoc
-
-# CHECK: cast<mlir::OpaqueLoc>
-# CHECK: underlyingLocation = 9
-p OpaqueLoc
-
-# CHECK: cast<mlir::NameLoc>
-# CHECK: name = "foo"
-# CHECK: mlir::UnknownLoc
-p NameLoc
-
-# CHECK: cast<mlir::CallSiteLoc>
-# CHECK: callee
-# CHECK: mlir::FileLineColLoc
-# CHECK: caller
-# CHECK: mlir::OpaqueLoc
-p CallSiteLoc
-
-# CHECK: cast<mlir::FusedLoc>
-# CHECK: numLocs = 2
-# CHECK: locs[0]
-# CHECK: mlir::FileLineColLoc
-# CHECK: locs[1]
-# CHECK: mlir::NameLoc
-p FusedLoc
-
-# CHECK: cast<mlir::UnitAttr>
-p UnitAttr
-
-# CHECK: cast<mlir::FloatAttr>
-p FloatAttr
-
-# CHECK: cast<mlir::IntegerAttr>
-p IntegerAttr
-
-# CHECK: cast<mlir::TypeAttr>
-# CHECK: mlir::IndexType
-p TypeAttr
-
-# CHECK: cast<mlir::ArrayAttr>
-# CHECK: llvm::ArrayRef of length 1
-# CHECK: mlir::UnitAttr
-p ArrayAttr
-
-# CHECK: cast<mlir::StringAttr>
-# CHECK: value = "foo"
-p StringAttr
-
-# CHECK: cast<mlir::DenseIntOrFPElementsAttr>
-p ElementsAttr
diff --git a/win_cdb-tests/README.txt b/win_cdb-tests/README.txt
deleted file mode 100644
index 4ef69c0..0000000
--- a/win_cdb-tests/README.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-These are debug info integration tests similar to the ones in the parent
-directory, except that these are designed to test compatibility between clang,
-lld, and cdb, the command line debugger that ships as part of the Microsoft
-Windows SDK. The debugger command language that cdb uses is very different from
-gdb and LLDB, so it's useful to be able to write some tests directly in the cdb
-command language.
-
-An example header for a CDB test, of which there are currently none:
-
-// RUN: %clang_cl %s -o %t.exe -fuse-ld=lld -Z7
-// RUN: grep DE[B]UGGER: %s | sed -e 's/.*DE[B]UGGER: //' > %t.script
-// RUN: %cdb -cf %t.script %t.exe | FileCheck %s --check-prefixes=DEBUGGER,CHECK
diff --git a/win_cdb-tests/lit.local.cfg.py b/win_cdb-tests/lit.local.cfg.py
deleted file mode 100644
index e4d61b1..0000000
--- a/win_cdb-tests/lit.local.cfg.py
+++ /dev/null
@@ -1,2 +0,0 @@
-# The win_cdb tests are supported when cmake was run in an MSVC environment.
-config.unsupported = not config.is_msvc