Enable access control service

1. Put the API access control checks in the frontend service to the
access control service;
2. Use casbin as the access control engine;
3. Remove the mesapy-based access control engine as mesapy is no longer
maintained.
diff --git a/.github/workflows/doc.yml b/.github/workflows/doc.yml
index 5e6d3bc..51a043c 100644
--- a/.github/workflows/doc.yml
+++ b/.github/workflows/doc.yml
@@ -16,7 +16,7 @@
 # under the License.
 
 name: Doc-ubuntu-20.04
-on: [push, pull_request, workflow_dispatch]
+on: [push, workflow_dispatch]
 defaults:
   run:
     shell: bash
@@ -25,7 +25,7 @@
     DOC: 1
 
 jobs:
-  sim-debug-unit:
+  doc:
     runs-on: ubuntu-20.04
     container: teaclave/teaclave-build-ubuntu-2004-sgx-2.17.1:0.2.0
     steps:
diff --git a/.github/workflows/ubuntu2004-test.yml b/.github/workflows/ubuntu2004-test.yml
index 54f328b..b2ce6b8 100644
--- a/.github/workflows/ubuntu2004-test.yml
+++ b/.github/workflows/ubuntu2004-test.yml
@@ -107,23 +107,6 @@
           . ~/.cargo/env &&
           cd build &&
           make run-examples
-  sim-debug-cancel:
-    runs-on: ubuntu-20.04
-    container: teaclave/teaclave-build-ubuntu-2004-sgx-2.17.1:0.2.0
-    steps:
-      - uses: actions/checkout@v3
-      - name: Build
-        run: |
-          . cmake/scripts/build_in_ci.sh
-      - name: Run cancel test
-        run: |
-          export AS_SPID="00000000000000000000000000000000" &&
-          export AS_KEY="00000000000000000000000000000000" &&
-          export AS_ALGO="sgx_epid" &&
-          export AS_URL="https://api.trustedservices.intel.com:443" &&
-          . ~/.cargo/env &&
-          cd build &&
-          make run-cancel-test
   sim-debug-libos-example:
     runs-on: ubuntu-20.04
     container: teaclave/teaclave-build-ubuntu-2004-sgx-2.17.1:0.2.0
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 64413f3..979a32e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -27,7 +27,7 @@
 endif()
 find_package(Git)
 find_package(OpenSSL)
-check_exe_dependencies(rustup pypy)
+check_exe_dependencies(rustup)
 pkg_check_modules(INTEL_SGX_SDK QUIET libsgx_urts>=2.17.101.1)
 if(NOT INTEL_SGX_SDK_FOUND)
   message(FATAL_ERROR "Intel SGX SDK (version 2.17.1) is not found or version not matched.")
@@ -47,7 +47,7 @@
 option(DCAP "Turn on/off DCAP attestation" OFF)
 option(GIT_SUBMODULE "Check submodules during build" ON)
 option(EXECUTOR_BUILTIN "Compile with the Builtin executor" ON)
-option(EXECUTOR_MESAPY "Compile with the MesaPy executor" ON)
+option(EXECUTOR_MESAPY "Compile with the MesaPy executor" OFF)
 option(EXECUTOR_WAMR "Compile with the WebAssembly Micro Runtime executor" ON)
 init_submodules()
 
@@ -174,28 +174,12 @@
     ${SGX_APPS_DEPENDS})
 endforeach()
 
-set(MESAPY_OUTPUTS
-  ${TEACLAVE_OUT_DIR}/libpypy-c.a
-  ${TEACLAVE_OUT_DIR}/libffi.a
-  ${TEACLAVE_OUT_DIR}/libsgx_tlibc_ext.a
-  ${TEACLAVE_OUT_DIR}/libsgx_ulibc.a
-  ${TEACLAVE_OUT_DIR}/ffi.o
-)
-
 # WAMR library
 
 set(WAMR_OUTPUTS
   ${TEACLAVE_OUT_DIR}/libvmlib.a
 )
 
-add_custom_command(
-  OUTPUT ${MESAPY_OUTPUTS}
-  COMMAND
-    wget -qN https://github.com/mesatee/mesapy/releases/download/${MESAPY_VERSION}/mesapy-${MESAPY_VERSION}.tar.gz &&
-    tar xzf mesapy-${MESAPY_VERSION}.tar.gz
-  DEPENDS prep
-  WORKING_DIRECTORY ${TEACLAVE_OUT_DIR})
-
 ExternalProject_Add(wamr_teaclave
   SOURCE_DIR ${WAMR_TEACLAVE_ROOT_DIR}
   BINARY_DIR ${WAMR_TEACLAVE_ROOT_DIR}/build
@@ -211,28 +195,10 @@
   WORKING_DIRECTORY ${WAMR_TEACLAVE_ROOT_DIR}/build
   )
 
-add_custom_target(mesapy
-  DEPENDS ${MESAPY_OUTPUTS}
-  )
-
 add_custom_target(wamr
   DEPENDS ${WAMR_TEACLAVE_ROOT_DIR}/CMakeLists.txt ${WAMR_OUTPUTS}
   )
 
-# mesapy components
-add_library(pycomponent STATIC ${PROJECT_SOURCE_DIR}/services/access_control/python/acs_py_enclave.c)
-set_target_properties(pycomponent PROPERTIES ARCHIVE_OUTPUT_DIRECTORY
-                                             ${TEACLAVE_OUT_DIR})
-target_compile_definitions(pycomponent PUBLIC SGX)
-if(NOT EXISTS "/usr/lib/pypy/include/Python.h")
-  message(
-    FATAL_ERROR
-      "pypy development package not found\nFor Ubuntu, please run `apt-get install pypy-dev`"
-  )
-endif()
-target_compile_options(pycomponent PUBLIC -UWITH_THREAD -O2 -fPIC -Wimplicit
-                                          -I/usr/lib/pypy/include)
-
 # std Aware Cargo
 set(DEFAULT_STD_PATH ${TRUSTED_TARGET_DIR}/default_std/sysroot/lib/rustlib/${SGX_LIB_TARGET}/lib)
 set(COV_STD_PATH ${TRUSTED_TARGET_DIR}/cov_std/sysroot/lib/rustlib/${SGX_LIB_TARGET}/lib)
@@ -273,7 +239,7 @@
 
 # sgx_trusted_lib
 list(LENGTH SGX_LIBS SGX_LIB_LEN)
-set(SGX_LIB_DEPENDS prep mesapy pycomponent)
+set(SGX_LIB_DEPENDS prep)
 math(EXPR SGX_LIB_LAST_INDEX "${SGX_LIB_LEN} - 1")
 foreach(_i RANGE ${SGX_LIB_LAST_INDEX})
   list(GET SGX_LIBS ${_i} _pkg_name)
diff --git a/LICENSE b/LICENSE
index a3a6d98..185a65e 100644
--- a/LICENSE
+++ b/LICENSE
@@ -218,4 +218,3 @@
 -----------
 
 common/rusty_leveldb_sgx
-https://github.com/mesatee/mesapy/releases/download/v1.0.0-sgx/mesapy-v1.0.0-sgx.tar.gz
diff --git a/cmake/scripts/sgx_link_sign.sh b/cmake/scripts/sgx_link_sign.sh
index 2b0225b..691d350 100755
--- a/cmake/scripts/sgx_link_sign.sh
+++ b/cmake/scripts/sgx_link_sign.sh
@@ -44,7 +44,7 @@
     exit 0
 fi
 
-TEACLAVE_LINK_FLAGS="-L${TEACLAVE_OUT_DIR} -lpycomponent ffi.o -lpypy-c -lsgx_tlibc_ext -lffi"
+TEACLAVE_LINK_FLAGS="-L${TEACLAVE_OUT_DIR}"
 if [ "$TEACLAVE_EXECUTOR_WAMR" == "ON" ]; then
     TEACLAVE_LINK_FLAGS+=" -lvmlib"
 fi
diff --git a/cmake/scripts/test.sh b/cmake/scripts/test.sh
index fcdc66c..5f0ee1d 100755
--- a/cmake/scripts/test.sh
+++ b/cmake/scripts/test.sh
@@ -115,13 +115,13 @@
   pushd ${TEACLAVE_SERVICE_INSTALL_DIR}
   ./teaclave_authentication_service &
   ./teaclave_storage_service &
-  wait_port 7776 17776 17778 # wait for authentication and storage service
+  ./teaclave_access_control_service &
+  wait_port 7776 17776 17778 17779 # wait for access control, authentication, storage service
   ./teaclave_management_service &
   ./teaclave_scheduler_service &
   wait_port 17777 17780 # wait for management service and scheduler_service
-  ./teaclave_access_control_service &
   ./teaclave_frontend_service &
-  wait_port 17779 7777 # wait for other services
+  wait_port 7777 # wait for other services
   popd
 
   pushd ${TEACLAVE_TEST_INSTALL_DIR}
@@ -185,13 +185,13 @@
   pushd ${TEACLAVE_SERVICE_INSTALL_DIR}
   ./teaclave_authentication_service &
   ./teaclave_storage_service &
-  wait_port 7776 17776 17778 # wait for authentication and storage service
+  ./teaclave_access_control_service &
+  wait_port 7776 17776 17778 17779 # wait for access control, authentication, storage service
   ./teaclave_management_service &
   ./teaclave_scheduler_service &
   wait_port 17777 17780 # wait for management service and scheduler_service
-  ./teaclave_access_control_service &
   ./teaclave_frontend_service &
-  wait_port 17779 7777 # wait for other services
+  wait_port 7777 # wait for other services
 
   start_storage_server
 
@@ -281,13 +281,13 @@
   pushd ${TEACLAVE_SERVICE_INSTALL_DIR}
   ./teaclave_authentication_service &
   ./teaclave_storage_service &
-  wait_port 7776 17776 17778 # wait for authentication and storage service
+  ./teaclave_access_control_service &
+  wait_port 7776 17776 17778 17779 # wait for access control, authentication, storage service
   ./teaclave_management_service &
   ./teaclave_scheduler_service &
   wait_port 17777 17780 # wait for management service and scheduler_service
-  ./teaclave_access_control_service &
   ./teaclave_frontend_service &
-  wait_port 17779 7777 # wait for other services
+  wait_port 7777 # wait for other services
 
   start_storage_server
 
@@ -301,9 +301,6 @@
   # run builtin examples
   builtin_examples
 
-  # run mesapy examples
-  mesapy_examples
-
   # run wasm examples
   wasm_examples
 
@@ -324,13 +321,13 @@
   pushd ${TEACLAVE_SERVICE_INSTALL_DIR}
   ./teaclave_authentication_service &
   ./teaclave_storage_service &
-  wait_port 7776 17776 17778 # wait for authentication and storage service
+  ./teaclave_access_control_service &
+  wait_port 7776 17776 17778 17779 # wait for access control, authentication, storage service
   ./teaclave_management_service &
   ./teaclave_scheduler_service &
   wait_port 17777 17780 # wait for management service and scheduler_service
-  ./teaclave_access_control_service &
   ./teaclave_frontend_service &
-  wait_port 17779 7777 # wait for other services
+  wait_port 7777 # wait for other services
 
   start_storage_server
 
@@ -372,13 +369,13 @@
   pushd ${TEACLAVE_SERVICE_INSTALL_DIR}
   ./teaclave_authentication_service &
   ./teaclave_storage_service &
-  wait_port 7776 17776 17778 # wait for authentication and storage service
+  ./teaclave_access_control_service &
+  wait_port 7776 17776 17778 17779 # wait for access control, authentication, storage service
   ./teaclave_management_service &
   ./teaclave_scheduler_service &
   wait_port 17777 17780 # wait for management service and scheduler_service
-  ./teaclave_access_control_service &
   ./teaclave_frontend_service &
-  wait_port 17779 7777 # wait for other services
+  wait_port 7777 # wait for other services
 
   start_storage_server
 
@@ -450,7 +447,6 @@
         run_functional_tests
         run_sdk_tests
         run_examples
-        run_cancel_test
         run_libos_examples
         ;;
 esac
diff --git a/cmake/tomls/Cargo.sgx_trusted_lib.lock b/cmake/tomls/Cargo.sgx_trusted_lib.lock
index 7dfa342..00677f7 100644
--- a/cmake/tomls/Cargo.sgx_trusted_lib.lock
+++ b/cmake/tomls/Cargo.sgx_trusted_lib.lock
@@ -20,6 +20,19 @@
 ]
 
 [[package]]
+name = "ahash"
+version = "0.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f"
+dependencies = [
+ "cfg-if 1.0.0",
+ "const-random",
+ "getrandom",
+ "once_cell",
+ "version_check",
+]
+
+[[package]]
 name = "aho-corasick"
 version = "0.7.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -72,20 +85,20 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193"
 dependencies = [
- "proc-macro2 1.0.59",
- "quote 1.0.28",
- "syn 2.0.18",
+ "proc-macro2 1.0.63",
+ "quote 1.0.29",
+ "syn 2.0.23",
 ]
 
 [[package]]
 name = "async-trait"
-version = "0.1.68"
+version = "0.1.69"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842"
+checksum = "7b2d0f03b3640e3a630367e40c468cb7f309529c708ed1d88597047b0e7c6ef7"
 dependencies = [
- "proc-macro2 1.0.59",
- "quote 1.0.28",
- "syn 2.0.18",
+ "proc-macro2 1.0.63",
+ "quote 1.0.29",
+ "syn 2.0.23",
 ]
 
 [[package]]
@@ -158,6 +171,25 @@
 checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be"
 
 [[package]]
+name = "casbin"
+version = "2.0.9"
+source = "git+https://github.com/apache/incubator-teaclave-crates#2b87d3972d43fa0fee2496dfc703e4f772ffbe9f"
+dependencies = [
+ "async-trait",
+ "fixedbitset",
+ "getrandom",
+ "once_cell",
+ "parking_lot",
+ "petgraph",
+ "regex",
+ "rhai",
+ "ritelinked",
+ "serde",
+ "thiserror",
+ "tokio",
+]
+
+[[package]]
 name = "cc"
 version = "1.0.79"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -207,6 +239,28 @@
 ]
 
 [[package]]
+name = "const-random"
+version = "0.1.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "368a7a772ead6ce7e1de82bfb04c485f3db8ec744f72925af5735e29a22cc18e"
+dependencies = [
+ "const-random-macro",
+ "proc-macro-hack",
+]
+
+[[package]]
+name = "const-random-macro"
+version = "0.1.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9d7d6ab3c3a2282db210df5f02c4dab6e0a7057af0fb7ebd4070f30fe05c0ddb"
+dependencies = [
+ "getrandom",
+ "once_cell",
+ "proc-macro-hack",
+ "tiny-keccak",
+]
+
+[[package]]
 name = "core-foundation"
 version = "0.9.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -259,9 +313,9 @@
 
 [[package]]
 name = "crossbeam-epoch"
-version = "0.9.14"
+version = "0.9.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695"
+checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7"
 dependencies = [
  "autocfg",
  "cfg-if 1.0.0",
@@ -272,9 +326,9 @@
 
 [[package]]
 name = "crossbeam-utils"
-version = "0.8.15"
+version = "0.8.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b"
+checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294"
 dependencies = [
  "cfg-if 1.0.0",
 ]
@@ -288,7 +342,7 @@
 [[package]]
 name = "csv"
 version = "1.2.2"
-source = "git+https://github.com/apache/incubator-teaclave-crates#f29426149751440e96479d2d8f6698a14228ecd9"
+source = "git+https://github.com/apache/incubator-teaclave-crates#2b87d3972d43fa0fee2496dfc703e4f772ffbe9f"
 dependencies = [
  "csv-core",
  "itoa",
@@ -299,7 +353,7 @@
 [[package]]
 name = "csv-core"
 version = "0.1.10"
-source = "git+https://github.com/apache/incubator-teaclave-crates#f29426149751440e96479d2d8f6698a14228ecd9"
+source = "git+https://github.com/apache/incubator-teaclave-crates#2b87d3972d43fa0fee2496dfc703e4f772ffbe9f"
 dependencies = [
  "memchr",
 ]
@@ -310,7 +364,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096"
 dependencies = [
- "quote 1.0.28",
+ "quote 1.0.29",
  "syn 1.0.109",
 ]
 
@@ -346,9 +400,9 @@
 
 [[package]]
 name = "erased-serde"
-version = "0.3.25"
+version = "0.3.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4f2b0c2380453a92ea8b6c8e5f64ecaafccddde8ceab55ff7a8ac1029f894569"
+checksum = "c6984864d65d092d9e9ada107007a846a09f75d2e24046bcce9a38d14aa52052"
 dependencies = [
  "serde",
 ]
@@ -394,7 +448,7 @@
 [[package]]
 name = "fastfield_codecs"
 version = "0.3.1"
-source = "git+https://github.com/apache/incubator-teaclave-crates#f29426149751440e96479d2d8f6698a14228ecd9"
+source = "git+https://github.com/apache/incubator-teaclave-crates#2b87d3972d43fa0fee2496dfc703e4f772ffbe9f"
 dependencies = [
  "fastdivide",
  "itertools 0.10.5",
@@ -452,9 +506,9 @@
 
 [[package]]
 name = "form_urlencoded"
-version = "1.1.0"
+version = "1.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8"
+checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652"
 dependencies = [
  "percent-encoding",
 ]
@@ -513,9 +567,9 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72"
 dependencies = [
- "proc-macro2 1.0.59",
- "quote 1.0.28",
- "syn 2.0.18",
+ "proc-macro2 1.0.63",
+ "quote 1.0.29",
+ "syn 2.0.23",
 ]
 
 [[package]]
@@ -551,7 +605,7 @@
 [[package]]
 name = "gbdt"
 version = "0.1.1"
-source = "git+https://github.com/apache/incubator-teaclave-crates#f29426149751440e96479d2d8f6698a14228ecd9"
+source = "git+https://github.com/apache/incubator-teaclave-crates#2b87d3972d43fa0fee2496dfc703e4f772ffbe9f"
 dependencies = [
  "cfg-if 0.1.10",
  "rand",
@@ -563,9 +617,9 @@
 
 [[package]]
 name = "generator"
-version = "0.7.4"
+version = "0.7.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f3e123d9ae7c02966b4d892e550bdc32164f05853cd40ab570650ad600596a8a"
+checksum = "5cc16584ff22b460a382b7feec54b23d2908d858152e5739a120b949293bd74e"
 dependencies = [
  "cc",
  "libc",
@@ -576,31 +630,33 @@
 
 [[package]]
 name = "getrandom"
-version = "0.2.6"
-source = "git+https://github.com/apache/incubator-teaclave-crates#f29426149751440e96479d2d8f6698a14228ecd9"
+version = "0.2.10"
+source = "git+https://github.com/apache/incubator-teaclave-crates#2b87d3972d43fa0fee2496dfc703e4f772ffbe9f"
 dependencies = [
  "cfg-if 1.0.0",
+ "js-sys",
  "libc",
  "sgx_libc",
- "wasi 0.10.2+wasi-snapshot-preview1",
+ "wasi",
+ "wasm-bindgen",
 ]
 
 [[package]]
 name = "ghost"
-version = "0.1.9"
+version = "0.1.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e77ac7b51b8e6313251737fcef4b1c01a2ea102bde68415b62c0ee9268fec357"
+checksum = "fae7e09da323fc46f010e455cac340af26159678ba00ab18e963a5880ca6a9b6"
 dependencies = [
- "proc-macro2 1.0.59",
- "quote 1.0.28",
- "syn 2.0.18",
+ "proc-macro2 1.0.63",
+ "quote 1.0.29",
+ "syn 2.0.23",
 ]
 
 [[package]]
 name = "h2"
-version = "0.3.19"
+version = "0.3.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d357c7ae988e7d2182f7d7871d0b963962420b0678b0997ce7de72001aeab782"
+checksum = "97ec8491ebaf99c8eaa73058b045fe58073cd6be7f596ac993ced0b0a0c01049"
 dependencies = [
  "bytes",
  "fnv",
@@ -617,11 +673,20 @@
 
 [[package]]
 name = "hashbrown"
+version = "0.11.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
+dependencies = [
+ "ahash 0.7.6",
+]
+
+[[package]]
+name = "hashbrown"
 version = "0.12.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
 dependencies = [
- "ahash",
+ "ahash 0.7.6",
 ]
 
 [[package]]
@@ -700,9 +765,9 @@
 
 [[package]]
 name = "hyper"
-version = "0.14.26"
+version = "0.14.27"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ab302d72a6f11a3b910431ff93aae7e773078c769f0a3ef15fb9ec692ed147d4"
+checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468"
 dependencies = [
  "bytes",
  "futures-channel",
@@ -749,9 +814,9 @@
 
 [[package]]
 name = "idna"
-version = "0.3.0"
+version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6"
+checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c"
 dependencies = [
  "unicode-bidi",
  "unicode-normalization",
@@ -760,7 +825,7 @@
 [[package]]
 name = "image"
 version = "0.23.14"
-source = "git+https://github.com/apache/incubator-teaclave-crates#f29426149751440e96479d2d8f6698a14228ecd9"
+source = "git+https://github.com/apache/incubator-teaclave-crates#2b87d3972d43fa0fee2496dfc703e4f772ffbe9f"
 dependencies = [
  "bytemuck",
  "byteorder",
@@ -778,7 +843,7 @@
 checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
 dependencies = [
  "autocfg",
- "hashbrown",
+ "hashbrown 0.12.3",
 ]
 
 [[package]]
@@ -816,8 +881,8 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7e41b53715c6f0c4be49510bb82dee2c1e51c8586d885abe65396e82ed518548"
 dependencies = [
- "proc-macro2 1.0.59",
- "quote 1.0.28",
+ "proc-macro2 1.0.63",
+ "quote 1.0.29",
  "syn 1.0.109",
 ]
 
@@ -834,9 +899,9 @@
 
 [[package]]
 name = "ipnet"
-version = "2.7.2"
+version = "2.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "12b6ee2129af8d4fb011108c73d99a1b83a85977f23b82460c0ae2e25bb4b57f"
+checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6"
 
 [[package]]
 name = "itertools"
@@ -858,9 +923,9 @@
 
 [[package]]
 name = "itoa"
-version = "1.0.6"
+version = "1.0.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
+checksum = "62b02a5381cc465bd3041d84623d0fa3b66738b52b8e2fc3bab8ad63ab032f4a"
 
 [[package]]
 name = "jpeg-decoder"
@@ -870,9 +935,9 @@
 
 [[package]]
 name = "js-sys"
-version = "0.3.63"
+version = "0.3.64"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2f37a4a5928311ac501dee68b3c7613a1037d0edb30c8e5427bd832d55d1b790"
+checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a"
 dependencies = [
  "wasm-bindgen",
 ]
@@ -905,9 +970,9 @@
 
 [[package]]
 name = "libc"
-version = "0.2.145"
+version = "0.2.147"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fc86cde3ff845662b8f4ef6cb50ea0e20c524eb3d29ae048287e06a1b3fa6a81"
+checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
 
 [[package]]
 name = "libm"
@@ -922,10 +987,20 @@
 checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519"
 
 [[package]]
-name = "log"
-version = "0.4.18"
+name = "lock_api"
+version = "0.4.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "518ef76f2f87365916b142844c16d8fefd85039bc5699050210a7778ee1cd1de"
+checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16"
+dependencies = [
+ "autocfg",
+ "scopeguard",
+]
+
+[[package]]
+name = "log"
+version = "0.4.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4"
 dependencies = [
  "value-bag",
 ]
@@ -950,7 +1025,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e999beba7b6e8345721bd280141ed958096a2e4abdf74f67ff4ce49b4b54e47a"
 dependencies = [
- "hashbrown",
+ "hashbrown 0.12.3",
 ]
 
 [[package]]
@@ -989,9 +1064,9 @@
 
 [[package]]
 name = "memoffset"
-version = "0.8.0"
+version = "0.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1"
+checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c"
 dependencies = [
  "autocfg",
 ]
@@ -1014,11 +1089,11 @@
 [[package]]
 name = "mio"
 version = "0.8.6"
-source = "git+https://github.com/apache/incubator-teaclave-crates#f29426149751440e96479d2d8f6698a14228ecd9"
+source = "git+https://github.com/apache/incubator-teaclave-crates#2b87d3972d43fa0fee2496dfc703e4f772ffbe9f"
 dependencies = [
  "libc",
  "log",
- "wasi 0.11.0+wasi-snapshot-preview1",
+ "wasi",
  "windows-sys 0.48.0",
 ]
 
@@ -1167,7 +1242,7 @@
 [[package]]
 name = "num_cpus"
 version = "1.14.0"
-source = "git+https://github.com/apache/incubator-teaclave-crates#f29426149751440e96479d2d8f6698a14228ecd9"
+source = "git+https://github.com/apache/incubator-teaclave-crates#2b87d3972d43fa0fee2496dfc703e4f772ffbe9f"
 dependencies = [
  "hermit-abi 0.1.19",
  "libc",
@@ -1190,9 +1265,9 @@
 
 [[package]]
 name = "openssl"
-version = "0.10.54"
+version = "0.10.55"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "69b3f656a17a6cbc115b5c7a40c616947d213ba182135b014d6051b73ab6f019"
+checksum = "345df152bc43501c5eb9e4654ff05f794effb78d4efe3d53abc158baddc0703d"
 dependencies = [
  "bitflags",
  "cfg-if 1.0.0",
@@ -1209,9 +1284,9 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
 dependencies = [
- "proc-macro2 1.0.59",
- "quote 1.0.28",
- "syn 2.0.18",
+ "proc-macro2 1.0.63",
+ "quote 1.0.29",
+ "syn 2.0.23",
 ]
 
 [[package]]
@@ -1222,9 +1297,9 @@
 
 [[package]]
 name = "openssl-sys"
-version = "0.9.88"
+version = "0.9.90"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c2ce0f250f34a308dcfdbb351f511359857d4ed2134ba715a4eadd46e1ffd617"
+checksum = "374533b0e45f3a7ced10fcaeccca020e66656bc03dac384f852e4e5a7a8104a6"
 dependencies = [
  "cc",
  "libc",
@@ -1241,12 +1316,35 @@
 [[package]]
 name = "ownedbytes"
 version = "0.4.0"
-source = "git+https://github.com/apache/incubator-teaclave-crates#f29426149751440e96479d2d8f6698a14228ecd9"
+source = "git+https://github.com/apache/incubator-teaclave-crates#2b87d3972d43fa0fee2496dfc703e4f772ffbe9f"
 dependencies = [
  "stable_deref_trait",
 ]
 
 [[package]]
+name = "parking_lot"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
+dependencies = [
+ "lock_api",
+ "parking_lot_core",
+]
+
+[[package]]
+name = "parking_lot_core"
+version = "0.9.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447"
+dependencies = [
+ "cfg-if 1.0.0",
+ "libc",
+ "redox_syscall",
+ "smallvec",
+ "windows-targets",
+]
+
+[[package]]
 name = "pem"
 version = "0.8.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1259,9 +1357,9 @@
 
 [[package]]
 name = "percent-encoding"
-version = "2.2.0"
+version = "2.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
+checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94"
 
 [[package]]
 name = "petgraph"
@@ -1275,29 +1373,29 @@
 
 [[package]]
 name = "pin-project"
-version = "1.1.0"
+version = "1.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c95a7476719eab1e366eaf73d0260af3021184f18177925b07f54b30089ceead"
+checksum = "030ad2bc4db10a8944cb0d837f158bdfec4d4a4873ab701a95046770d11f8842"
 dependencies = [
  "pin-project-internal",
 ]
 
 [[package]]
 name = "pin-project-internal"
-version = "1.1.0"
+version = "1.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "39407670928234ebc5e6e580247dd567ad73a3578460c5990f9503df207e8f07"
+checksum = "ec2e072ecce94ec471b13398d5402c188e76ac03cf74dd1a975161b23a3f6d9c"
 dependencies = [
- "proc-macro2 1.0.59",
- "quote 1.0.28",
- "syn 2.0.18",
+ "proc-macro2 1.0.63",
+ "quote 1.0.29",
+ "syn 2.0.23",
 ]
 
 [[package]]
 name = "pin-project-lite"
-version = "0.2.9"
+version = "0.2.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
+checksum = "4c40d25201921e5ff0c862a505c6557ea88568a4e3ace775ab55e93f2f4f9d57"
 
 [[package]]
 name = "pin-utils"
@@ -1318,6 +1416,12 @@
 checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
 
 [[package]]
+name = "proc-macro-hack"
+version = "0.5.20+deprecated"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068"
+
+[[package]]
 name = "proc-macro2"
 version = "0.4.30"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1328,9 +1432,9 @@
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.59"
+version = "1.0.63"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6aeca18b86b413c660b781aa319e4e2648a3e6f9eadc9b47e9038e6fe9f3451b"
+checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb"
 dependencies = [
  "unicode-ident",
 ]
@@ -1373,8 +1477,8 @@
 dependencies = [
  "anyhow",
  "itertools 0.10.5",
- "proc-macro2 1.0.59",
- "quote 1.0.28",
+ "proc-macro2 1.0.63",
+ "quote 1.0.29",
  "syn 1.0.109",
 ]
 
@@ -1399,17 +1503,17 @@
 
 [[package]]
 name = "quote"
-version = "1.0.28"
+version = "1.0.29"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488"
+checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105"
 dependencies = [
- "proc-macro2 1.0.59",
+ "proc-macro2 1.0.63",
 ]
 
 [[package]]
 name = "rand"
 version = "0.8.5"
-source = "git+https://github.com/apache/incubator-teaclave-crates#f29426149751440e96479d2d8f6698a14228ecd9"
+source = "git+https://github.com/apache/incubator-teaclave-crates#2b87d3972d43fa0fee2496dfc703e4f772ffbe9f"
 dependencies = [
  "libc",
  "rand_chacha",
@@ -1419,7 +1523,7 @@
 [[package]]
 name = "rand_chacha"
 version = "0.3.1"
-source = "git+https://github.com/apache/incubator-teaclave-crates#f29426149751440e96479d2d8f6698a14228ecd9"
+source = "git+https://github.com/apache/incubator-teaclave-crates#2b87d3972d43fa0fee2496dfc703e4f772ffbe9f"
 dependencies = [
  "ppv-lite86",
  "rand_core 0.6.4 (git+https://github.com/apache/incubator-teaclave-crates)",
@@ -1437,7 +1541,7 @@
 [[package]]
 name = "rand_core"
 version = "0.6.4"
-source = "git+https://github.com/apache/incubator-teaclave-crates#f29426149751440e96479d2d8f6698a14228ecd9"
+source = "git+https://github.com/apache/incubator-teaclave-crates#2b87d3972d43fa0fee2496dfc703e4f772ffbe9f"
 dependencies = [
  "getrandom",
 ]
@@ -1461,7 +1565,7 @@
 [[package]]
 name = "rayon"
 version = "1.7.0"
-source = "git+https://github.com/apache/incubator-teaclave-crates#f29426149751440e96479d2d8f6698a14228ecd9"
+source = "git+https://github.com/apache/incubator-teaclave-crates#2b87d3972d43fa0fee2496dfc703e4f772ffbe9f"
 dependencies = [
  "either",
  "rayon-core",
@@ -1470,7 +1574,7 @@
 [[package]]
 name = "rayon-core"
 version = "1.11.0"
-source = "git+https://github.com/apache/incubator-teaclave-crates#f29426149751440e96479d2d8f6698a14228ecd9"
+source = "git+https://github.com/apache/incubator-teaclave-crates#2b87d3972d43fa0fee2496dfc703e4f772ffbe9f"
 dependencies = [
  "crossbeam-channel",
  "crossbeam-deque",
@@ -1498,9 +1602,9 @@
 
 [[package]]
 name = "regex"
-version = "1.8.3"
+version = "1.8.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "81ca098a9821bd52d6b24fd8b10bd081f47d39c22778cafaa75a2857a62c6390"
+checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f"
 dependencies = [
  "aho-corasick 1.0.2",
  "memchr",
@@ -1568,9 +1672,34 @@
 ]
 
 [[package]]
+name = "rhai"
+version = "1.15.0"
+source = "git+https://github.com/apache/incubator-teaclave-crates#2b87d3972d43fa0fee2496dfc703e4f772ffbe9f"
+dependencies = [
+ "ahash 0.8.3",
+ "bitflags",
+ "instant",
+ "num-traits",
+ "rhai_codegen",
+ "serde",
+ "smallvec",
+ "smartstring",
+]
+
+[[package]]
+name = "rhai_codegen"
+version = "1.5.0"
+source = "git+https://github.com/apache/incubator-teaclave-crates#2b87d3972d43fa0fee2496dfc703e4f772ffbe9f"
+dependencies = [
+ "proc-macro2 1.0.63",
+ "quote 1.0.29",
+ "syn 1.0.109",
+]
+
+[[package]]
 name = "ring"
 version = "0.16.20"
-source = "git+https://github.com/apache/incubator-teaclave-crates#f29426149751440e96479d2d8f6698a14228ecd9"
+source = "git+https://github.com/apache/incubator-teaclave-crates#2b87d3972d43fa0fee2496dfc703e4f772ffbe9f"
 dependencies = [
  "cc",
  "libc",
@@ -1582,6 +1711,16 @@
 ]
 
 [[package]]
+name = "ritelinked"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "98f2771d255fd99f0294f13249fecd0cae6e074f86b4197ec1f1689d537b44d3"
+dependencies = [
+ "ahash 0.7.6",
+ "hashbrown 0.11.2",
+]
+
+[[package]]
 name = "rulinalg"
 version = "0.4.2"
 source = "git+https://github.com/AtheMathmo/rulinalg?rev=1ed8b937#1ed8b937d7b54d08a440f7db91994142bfe47388"
@@ -1609,7 +1748,7 @@
 [[package]]
 name = "rustface"
 version = "0.1.7"
-source = "git+https://github.com/apache/incubator-teaclave-crates#f29426149751440e96479d2d8f6698a14228ecd9"
+source = "git+https://github.com/apache/incubator-teaclave-crates#2b87d3972d43fa0fee2496dfc703e4f772ffbe9f"
 dependencies = [
  "byteorder",
  "image",
@@ -1620,9 +1759,9 @@
 
 [[package]]
 name = "rustix"
-version = "0.37.19"
+version = "0.37.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d"
+checksum = "8818fa822adcc98b18fedbb3632a6a33213c070556b5aa7c4c8cc21cff565c4c"
 dependencies = [
  "bitflags",
  "errno",
@@ -1635,7 +1774,7 @@
 [[package]]
 name = "rustls"
 version = "0.19.1"
-source = "git+https://github.com/apache/incubator-teaclave-crates#f29426149751440e96479d2d8f6698a14228ecd9"
+source = "git+https://github.com/apache/incubator-teaclave-crates#2b87d3972d43fa0fee2496dfc703e4f772ffbe9f"
 dependencies = [
  "base64 0.13.1",
  "log",
@@ -1646,9 +1785,9 @@
 
 [[package]]
 name = "rustversion"
-version = "1.0.12"
+version = "1.0.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06"
+checksum = "dc31bd9b61a32c31f9650d18add92aa83a49ba979c143eefd27fe7177b05bd5f"
 
 [[package]]
 name = "rusty-leveldb"
@@ -1666,7 +1805,7 @@
 [[package]]
 name = "rusty-machine"
 version = "0.5.4"
-source = "git+https://github.com/apache/incubator-teaclave-crates#f29426149751440e96479d2d8f6698a14228ecd9"
+source = "git+https://github.com/apache/incubator-teaclave-crates#2b87d3972d43fa0fee2496dfc703e4f772ffbe9f"
 dependencies = [
  "num 0.1.42",
  "rand",
@@ -1678,17 +1817,17 @@
 
 [[package]]
 name = "ryu"
-version = "1.0.13"
+version = "1.0.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041"
+checksum = "fe232bdf6be8c8de797b22184ee71118d63780ea42ac85b61d1baa6d3b782ae9"
 
 [[package]]
 name = "schannel"
-version = "0.1.21"
+version = "0.1.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3"
+checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88"
 dependencies = [
- "windows-sys 0.42.0",
+ "windows-sys 0.48.0",
 ]
 
 [[package]]
@@ -1738,22 +1877,22 @@
 
 [[package]]
 name = "serde"
-version = "1.0.163"
+version = "1.0.166"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2113ab51b87a539ae008b5c6c02dc020ffa39afd2d83cffcb3f4eb2722cebec2"
+checksum = "d01b7404f9d441d3ad40e6a636a7782c377d2abdbe4fa2440e2edcc2f4f10db8"
 dependencies = [
  "serde_derive",
 ]
 
 [[package]]
 name = "serde_derive"
-version = "1.0.163"
+version = "1.0.166"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e"
+checksum = "5dd83d6dde2b6b2d466e14d9d1acce8816dedee94f735eac6395808b3483c6d6"
 dependencies = [
- "proc-macro2 1.0.59",
- "quote 1.0.28",
- "syn 2.0.18",
+ "proc-macro2 1.0.63",
+ "quote 1.0.29",
+ "syn 2.0.23",
 ]
 
 [[package]]
@@ -1767,9 +1906,9 @@
 
 [[package]]
 name = "serde_json"
-version = "1.0.96"
+version = "1.0.99"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1"
+checksum = "46266871c240a00b8f503b877622fe33430b3c7d963bdc0f2adc511e54a1eae3"
 dependencies = [
  "itoa",
  "ryu",
@@ -1854,8 +1993,8 @@
 name = "sgx_macros"
 version = "2.0.0"
 dependencies = [
- "proc-macro2 1.0.59",
- "quote 1.0.28",
+ "proc-macro2 1.0.63",
+ "quote 1.0.29",
  "syn 1.0.109",
 ]
 
@@ -2028,6 +2167,21 @@
 version = "1.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "smartstring"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3fb72c633efbaa2dd666986505016c32c3044395ceaf881518399d2f4127ee29"
+dependencies = [
+ "autocfg",
+ "serde",
+ "static_assertions",
+ "version_check",
+]
 
 [[package]]
 name = "snap"
@@ -2062,16 +2216,22 @@
 checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
 
 [[package]]
-name = "sval"
-version = "2.5.0"
+name = "static_assertions"
+version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0e6aa16ce8d9e472e21a528a52c875a76a49190f3968f2ec7e9b550ccc28b410"
+checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
+
+[[package]]
+name = "sval"
+version = "2.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b031320a434d3e9477ccf9b5756d57d4272937b8d22cb88af80b7633a1b78b1"
 
 [[package]]
 name = "sval_buffer"
-version = "2.5.0"
+version = "2.6.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "905c4373621186ee9637464b0aaa026389ea9e7f841f2225f160a32ba5d5bac4"
+checksum = "6bf7e9412af26b342f3f2cc5cc4122b0105e9d16eb76046cd14ed10106cf6028"
 dependencies = [
  "sval",
  "sval_ref",
@@ -2079,18 +2239,18 @@
 
 [[package]]
 name = "sval_dynamic"
-version = "2.5.0"
+version = "2.6.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ad6b4988322c5f22859a6a7649fa1249aa3dd01514caf8ed57d83735f997bb8b"
+checksum = "a0ef628e8a77a46ed3338db8d1b08af77495123cc229453084e47cd716d403cf"
 dependencies = [
  "sval",
 ]
 
 [[package]]
 name = "sval_fmt"
-version = "2.5.0"
+version = "2.6.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9d3ccd10346f925c2fbd97b75e8573b38e34431bfba04cc531cd23aad0fbabb8"
+checksum = "7dc09e9364c2045ab5fa38f7b04d077b3359d30c4c2b3ec4bae67a358bd64326"
 dependencies = [
  "itoa",
  "ryu",
@@ -2099,9 +2259,9 @@
 
 [[package]]
 name = "sval_json"
-version = "2.5.0"
+version = "2.6.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6a12e1488defd6344e23243c17ea4a1b185c547968749e8a281373fde0bde2d5"
+checksum = "ada6f627e38cbb8860283649509d87bc4a5771141daa41c78fd31f2b9485888d"
 dependencies = [
  "itoa",
  "ryu",
@@ -2110,18 +2270,18 @@
 
 [[package]]
 name = "sval_ref"
-version = "2.5.0"
+version = "2.6.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b797fc4b284dd0e45f7ec424479e604ea5be9bb191a1ef4e96c20c7685649938"
+checksum = "703ca1942a984bd0d9b5a4c0a65ab8b4b794038d080af4eb303c71bc6bf22d7c"
 dependencies = [
  "sval",
 ]
 
 [[package]]
 name = "sval_serde"
-version = "2.5.0"
+version = "2.6.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "810fa9a837e67a23e0efa7536250fc4d24043306cc1efd076f1943ba2fc2e62d"
+checksum = "830926cd0581f7c3e5d51efae4d35c6b6fc4db583842652891ba2f1bed8db046"
 dependencies = [
  "serde",
  "sval",
@@ -2146,26 +2306,26 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
 dependencies = [
- "proc-macro2 1.0.59",
- "quote 1.0.28",
+ "proc-macro2 1.0.63",
+ "quote 1.0.29",
  "unicode-ident",
 ]
 
 [[package]]
 name = "syn"
-version = "2.0.18"
+version = "2.0.23"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e"
+checksum = "59fb7d6d8281a51045d62b8eb3a7d1ce347b76f312af50cd3dc0af39c87c1737"
 dependencies = [
- "proc-macro2 1.0.59",
- "quote 1.0.28",
+ "proc-macro2 1.0.63",
+ "quote 1.0.29",
  "unicode-ident",
 ]
 
 [[package]]
 name = "tantivy"
 version = "0.19.2"
-source = "git+https://github.com/apache/incubator-teaclave-crates#f29426149751440e96479d2d8f6698a14228ecd9"
+source = "git+https://github.com/apache/incubator-teaclave-crates#2b87d3972d43fa0fee2496dfc703e4f772ffbe9f"
 dependencies = [
  "aho-corasick 0.7.20",
  "arc-swap",
@@ -2205,19 +2365,19 @@
  "tantivy-query-grammar",
  "thiserror",
  "time",
- "uuid 1.3.3",
+ "uuid 1.4.0",
  "winapi",
 ]
 
 [[package]]
 name = "tantivy-bitpacker"
 version = "0.3.0"
-source = "git+https://github.com/apache/incubator-teaclave-crates#f29426149751440e96479d2d8f6698a14228ecd9"
+source = "git+https://github.com/apache/incubator-teaclave-crates#2b87d3972d43fa0fee2496dfc703e4f772ffbe9f"
 
 [[package]]
 name = "tantivy-common"
 version = "0.4.0"
-source = "git+https://github.com/apache/incubator-teaclave-crates#f29426149751440e96479d2d8f6698a14228ecd9"
+source = "git+https://github.com/apache/incubator-teaclave-crates#2b87d3972d43fa0fee2496dfc703e4f772ffbe9f"
 dependencies = [
  "byteorder",
  "ownedbytes",
@@ -2237,7 +2397,7 @@
 [[package]]
 name = "tantivy-query-grammar"
 version = "0.19.0"
-source = "git+https://github.com/apache/incubator-teaclave-crates#f29426149751440e96479d2d8f6698a14228ecd9"
+source = "git+https://github.com/apache/incubator-teaclave-crates#2b87d3972d43fa0fee2496dfc703e4f772ffbe9f"
 dependencies = [
  "combine",
  "once_cell",
@@ -2249,7 +2409,9 @@
 version = "0.6.0"
 dependencies = [
  "anyhow",
+ "casbin",
  "cfg-if 0.1.10",
+ "csv",
  "log",
  "rand",
  "ring",
@@ -2746,8 +2908,8 @@
 name = "teaclave_test_utils_proc_macro"
 version = "0.0.1"
 dependencies = [
- "proc-macro2 1.0.59",
- "quote 1.0.28",
+ "proc-macro2 1.0.63",
+ "quote 1.0.29",
  "syn 1.0.109",
 ]
 
@@ -2825,15 +2987,16 @@
 
 [[package]]
 name = "tempfile"
-version = "3.5.0"
+version = "3.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998"
+checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6"
 dependencies = [
+ "autocfg",
  "cfg-if 1.0.0",
  "fastrand",
  "redox_syscall",
  "rustix",
- "windows-sys 0.45.0",
+ "windows-sys 0.48.0",
 ]
 
 [[package]]
@@ -2851,9 +3014,9 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f"
 dependencies = [
- "proc-macro2 1.0.59",
- "quote 1.0.28",
- "syn 2.0.18",
+ "proc-macro2 1.0.63",
+ "quote 1.0.29",
+ "syn 2.0.23",
 ]
 
 [[package]]
@@ -2868,9 +3031,9 @@
 
 [[package]]
 name = "time"
-version = "0.3.21"
+version = "0.3.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f3403384eaacbca9923fa06940178ac13e4edb725486d70e8e15881d0c836cc"
+checksum = "ea9e1b3cf1243ae005d9e74085d4d542f3125458f3a81af210d901dcd7411efd"
 dependencies = [
  "itoa",
  "serde",
@@ -2894,6 +3057,15 @@
 ]
 
 [[package]]
+name = "tiny-keccak"
+version = "2.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237"
+dependencies = [
+ "crunchy",
+]
+
+[[package]]
 name = "tinyvec"
 version = "1.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2940,8 +3112,8 @@
 version = "1.8.2"
 source = "git+https://github.com/tokio-rs/tokio.git?tag=tokio-1.24.0#dfe252d1fa82bdfefd7cba20f9a88cdd27e310cc"
 dependencies = [
- "proc-macro2 1.0.59",
- "quote 1.0.28",
+ "proc-macro2 1.0.63",
+ "quote 1.0.29",
  "syn 1.0.109",
 ]
 
@@ -3053,9 +3225,9 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9403f1bafde247186684b230dc6f38b5cd514584e8bec1dd32514be4745fa757"
 dependencies = [
- "proc-macro2 1.0.59",
+ "proc-macro2 1.0.63",
  "prost-build",
- "quote 1.0.28",
+ "quote 1.0.29",
  "syn 1.0.109",
 ]
 
@@ -3106,13 +3278,13 @@
 
 [[package]]
 name = "tracing-attributes"
-version = "0.1.24"
+version = "0.1.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0f57e3ca2a01450b1a921183a9c9cbfda207fd822cef4ccb00a65402cbba7a74"
+checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab"
 dependencies = [
- "proc-macro2 1.0.59",
- "quote 1.0.28",
- "syn 2.0.18",
+ "proc-macro2 1.0.63",
+ "quote 1.0.29",
+ "syn 2.0.23",
 ]
 
 [[package]]
@@ -3178,9 +3350,9 @@
 
 [[package]]
 name = "unicode-ident"
-version = "1.0.9"
+version = "1.0.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0"
+checksum = "22049a19f4a68748a168c0fc439f9516686aa045927ff767eca0a85101fb6e73"
 
 [[package]]
 name = "unicode-normalization"
@@ -3211,9 +3383,9 @@
 
 [[package]]
 name = "url"
-version = "2.3.1"
+version = "2.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643"
+checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb"
 dependencies = [
  "form_urlencoded",
  "idna",
@@ -3240,9 +3412,9 @@
 
 [[package]]
 name = "uuid"
-version = "1.3.3"
+version = "1.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "345444e32442451b267fc254ae85a209c64be56d2890e601a0c37ff0c3c5ecd2"
+checksum = "d023da39d1fde5a8a3fe1f3e01ca9632ada0a63e9797de55a879d6e2236277be"
 dependencies = [
  "getrandom",
  "serde",
@@ -3256,9 +3428,9 @@
 
 [[package]]
 name = "value-bag"
-version = "1.4.0"
+version = "1.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a4d330786735ea358f3bc09eea4caa098569c1c93f342d9aca0514915022fe7e"
+checksum = "d92ccd67fb88503048c01b59152a04effd0782d035a83a6d256ce6085f08f4a3"
 dependencies = [
  "value-bag-serde1",
  "value-bag-sval2",
@@ -3266,9 +3438,9 @@
 
 [[package]]
 name = "value-bag-serde1"
-version = "1.4.0"
+version = "1.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4735c95b4cca1447b448e2e2e87e98d7e7498f4da27e355cf7af02204521001d"
+checksum = "b0b9f3feef403a50d4d67e9741a6d8fc688bcbb4e4f31bd4aab72cc690284394"
 dependencies = [
  "erased-serde",
  "serde",
@@ -3277,9 +3449,9 @@
 
 [[package]]
 name = "value-bag-sval2"
-version = "1.4.0"
+version = "1.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "859cb4f0ce7da6a118b559ba74b0e63bf569bea867c20ba457a6b1c886a04e97"
+checksum = "30b24f4146b6f3361e91cbf527d1fb35e9376c3c0cef72ca5ec5af6d640fad7d"
 dependencies = [
  "sval",
  "sval_buffer",
@@ -3304,31 +3476,24 @@
 
 [[package]]
 name = "want"
-version = "0.3.0"
+version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0"
+checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
 dependencies = [
- "log",
  "try-lock",
 ]
 
 [[package]]
 name = "wasi"
-version = "0.10.2+wasi-snapshot-preview1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
-
-[[package]]
-name = "wasi"
 version = "0.11.0+wasi-snapshot-preview1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
 
 [[package]]
 name = "wasm-bindgen"
-version = "0.2.86"
+version = "0.2.87"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5bba0e8cb82ba49ff4e229459ff22a191bbe9a1cb3a341610c9c33efc27ddf73"
+checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342"
 dependencies = [
  "cfg-if 1.0.0",
  "wasm-bindgen-macro",
@@ -3336,24 +3501,24 @@
 
 [[package]]
 name = "wasm-bindgen-backend"
-version = "0.2.86"
+version = "0.2.87"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "19b04bc93f9d6bdee709f6bd2118f57dd6679cf1176a1af464fca3ab0d66d8fb"
+checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd"
 dependencies = [
  "bumpalo",
  "log",
  "once_cell",
- "proc-macro2 1.0.59",
- "quote 1.0.28",
- "syn 2.0.18",
+ "proc-macro2 1.0.63",
+ "quote 1.0.29",
+ "syn 2.0.23",
  "wasm-bindgen-shared",
 ]
 
 [[package]]
 name = "wasm-bindgen-futures"
-version = "0.4.36"
+version = "0.4.37"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2d1985d03709c53167ce907ff394f5316aa22cb4e12761295c5dc57dacb6297e"
+checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03"
 dependencies = [
  "cfg-if 1.0.0",
  "js-sys",
@@ -3363,32 +3528,32 @@
 
 [[package]]
 name = "wasm-bindgen-macro"
-version = "0.2.86"
+version = "0.2.87"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "14d6b024f1a526bb0234f52840389927257beb670610081360e5a03c5df9c258"
+checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d"
 dependencies = [
- "quote 1.0.28",
+ "quote 1.0.29",
  "wasm-bindgen-macro-support",
 ]
 
 [[package]]
 name = "wasm-bindgen-macro-support"
-version = "0.2.86"
+version = "0.2.87"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e128beba882dd1eb6200e1dc92ae6c5dbaa4311aa7bb211ca035779e5efc39f8"
+checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
 dependencies = [
- "proc-macro2 1.0.59",
- "quote 1.0.28",
- "syn 2.0.18",
+ "proc-macro2 1.0.63",
+ "quote 1.0.29",
+ "syn 2.0.23",
  "wasm-bindgen-backend",
  "wasm-bindgen-shared",
 ]
 
 [[package]]
 name = "wasm-bindgen-shared"
-version = "0.2.86"
+version = "0.2.87"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed9d5b4305409d1fc9482fee2d7f9bcbf24b3972bf59817ef757e23982242a93"
+checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1"
 
 [[package]]
 name = "wasm-streams"
@@ -3405,9 +3570,9 @@
 
 [[package]]
 name = "web-sys"
-version = "0.3.63"
+version = "0.3.64"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3bdd9ef4e984da1187bf8110c5cf5b845fbc87a23602cdf912386a76fcd3a7c2"
+checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b"
 dependencies = [
  "js-sys",
  "wasm-bindgen",
@@ -3471,7 +3636,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f"
 dependencies = [
- "windows-targets 0.48.0",
+ "windows-targets",
 ]
 
 [[package]]
@@ -3491,42 +3656,18 @@
 
 [[package]]
 name = "windows-sys"
-version = "0.45.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
-dependencies = [
- "windows-targets 0.42.2",
-]
-
-[[package]]
-name = "windows-sys"
 version = "0.48.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
 dependencies = [
- "windows-targets 0.48.0",
+ "windows-targets",
 ]
 
 [[package]]
 name = "windows-targets"
-version = "0.42.2"
+version = "0.48.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
-dependencies = [
- "windows_aarch64_gnullvm 0.42.2",
- "windows_aarch64_msvc 0.42.2",
- "windows_i686_gnu 0.42.2",
- "windows_i686_msvc 0.42.2",
- "windows_x86_64_gnu 0.42.2",
- "windows_x86_64_gnullvm 0.42.2",
- "windows_x86_64_msvc 0.42.2",
-]
-
-[[package]]
-name = "windows-targets"
-version = "0.48.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5"
+checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f"
 dependencies = [
  "windows_aarch64_gnullvm 0.48.0",
  "windows_aarch64_msvc 0.48.0",
diff --git a/cmake/tomls/Cargo.sgx_trusted_lib.toml b/cmake/tomls/Cargo.sgx_trusted_lib.toml
index f22d822..09d7257 100644
--- a/cmake/tomls/Cargo.sgx_trusted_lib.toml
+++ b/cmake/tomls/Cargo.sgx_trusted_lib.toml
@@ -56,6 +56,7 @@
 
 # SGX crates
 csv               = { git = "https://github.com/apache/incubator-teaclave-crates" }
+casbin            = { git = "https://github.com/apache/incubator-teaclave-crates" }
 gbdt              = { git = "https://github.com/apache/incubator-teaclave-crates" }
 getrandom         = { git = "https://github.com/apache/incubator-teaclave-crates" }
 image             = { git = "https://github.com/apache/incubator-teaclave-crates" }
@@ -64,6 +65,7 @@
 rand              = { git = "https://github.com/apache/incubator-teaclave-crates" }
 rayon             = { git = "https://github.com/apache/incubator-teaclave-crates" }
 ring              = { git = "https://github.com/apache/incubator-teaclave-crates" }
+rhai              = { git = "https://github.com/apache/incubator-teaclave-crates" }
 rustface          = { git = "https://github.com/apache/incubator-teaclave-crates" }
 rustls            = { git = "https://github.com/apache/incubator-teaclave-crates" }
 rusty-machine     = { git = "https://github.com/apache/incubator-teaclave-crates" }
diff --git a/cmake/tomls/Cargo.sgx_untrusted_app.lock b/cmake/tomls/Cargo.sgx_untrusted_app.lock
index 3dba2cd..552bb6a 100644
--- a/cmake/tomls/Cargo.sgx_untrusted_app.lock
+++ b/cmake/tomls/Cargo.sgx_untrusted_app.lock
@@ -3,6 +3,15 @@
 version = 3
 
 [[package]]
+name = "addr2line"
+version = "0.20.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3"
+dependencies = [
+ "gimli",
+]
+
+[[package]]
 name = "adler"
 version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -55,20 +64,20 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193"
 dependencies = [
- "proc-macro2 1.0.59",
- "quote 1.0.28",
- "syn 2.0.18",
+ "proc-macro2 1.0.63",
+ "quote 1.0.29",
+ "syn 2.0.23",
 ]
 
 [[package]]
 name = "async-trait"
-version = "0.1.68"
+version = "0.1.69"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842"
+checksum = "7b2d0f03b3640e3a630367e40c468cb7f309529c708ed1d88597047b0e7c6ef7"
 dependencies = [
- "proc-macro2 1.0.59",
- "quote 1.0.28",
- "syn 2.0.18",
+ "proc-macro2 1.0.63",
+ "quote 1.0.29",
+ "syn 2.0.23",
 ]
 
 [[package]]
@@ -98,6 +107,21 @@
 checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
 
 [[package]]
+name = "backtrace"
+version = "0.3.68"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12"
+dependencies = [
+ "addr2line",
+ "cc",
+ "cfg-if 1.0.0",
+ "libc",
+ "miniz_oxide",
+ "object",
+ "rustc-demangle",
+]
+
+[[package]]
 name = "base64"
 version = "0.13.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -255,7 +279,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096"
 dependencies = [
- "quote 1.0.28",
+ "quote 1.0.29",
  "syn 1.0.109",
 ]
 
@@ -266,7 +290,7 @@
 checksum = "2a011bbe2c35ce9c1f143b7af6f94f29a167beb4cd1d29e6740ce836f723120e"
 dependencies = [
  "nix",
- "windows-sys 0.48.0",
+ "windows-sys",
 ]
 
 [[package]]
@@ -308,9 +332,9 @@
 
 [[package]]
 name = "erased-serde"
-version = "0.3.25"
+version = "0.3.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4f2b0c2380453a92ea8b6c8e5f64ecaafccddde8ceab55ff7a8ac1029f894569"
+checksum = "c6984864d65d092d9e9ada107007a846a09f75d2e24046bcce9a38d14aa52052"
 dependencies = [
  "serde",
 ]
@@ -323,7 +347,7 @@
 dependencies = [
  "errno-dragonfly",
  "libc",
- "windows-sys 0.48.0",
+ "windows-sys",
 ]
 
 [[package]]
@@ -384,9 +408,9 @@
 
 [[package]]
 name = "form_urlencoded"
-version = "1.1.0"
+version = "1.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8"
+checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652"
 dependencies = [
  "percent-encoding",
 ]
@@ -451,9 +475,9 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72"
 dependencies = [
- "proc-macro2 1.0.59",
- "quote 1.0.28",
- "syn 2.0.18",
+ "proc-macro2 1.0.63",
+ "quote 1.0.29",
+ "syn 2.0.23",
 ]
 
 [[package]]
@@ -502,9 +526,9 @@
 
 [[package]]
 name = "getrandom"
-version = "0.2.9"
+version = "0.2.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4"
+checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
 dependencies = [
  "cfg-if 1.0.0",
  "libc",
@@ -513,20 +537,26 @@
 
 [[package]]
 name = "ghost"
-version = "0.1.9"
+version = "0.1.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e77ac7b51b8e6313251737fcef4b1c01a2ea102bde68415b62c0ee9268fec357"
+checksum = "fae7e09da323fc46f010e455cac340af26159678ba00ab18e963a5880ca6a9b6"
 dependencies = [
- "proc-macro2 1.0.59",
- "quote 1.0.28",
- "syn 2.0.18",
+ "proc-macro2 1.0.63",
+ "quote 1.0.29",
+ "syn 2.0.23",
 ]
 
 [[package]]
-name = "h2"
-version = "0.3.19"
+name = "gimli"
+version = "0.27.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d357c7ae988e7d2182f7d7871d0b963962420b0678b0997ce7de72001aeab782"
+checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e"
+
+[[package]]
+name = "h2"
+version = "0.3.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "97ec8491ebaf99c8eaa73058b045fe58073cd6be7f596ac993ced0b0a0c01049"
 dependencies = [
  "bytes",
  "fnv",
@@ -571,15 +601,6 @@
 
 [[package]]
 name = "hermit-abi"
-version = "0.2.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "hermit-abi"
 version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286"
@@ -635,9 +656,9 @@
 
 [[package]]
 name = "hyper"
-version = "0.14.26"
+version = "0.14.27"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ab302d72a6f11a3b910431ff93aae7e773078c769f0a3ef15fb9ec692ed147d4"
+checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468"
 dependencies = [
  "bytes",
  "futures-channel",
@@ -684,9 +705,9 @@
 
 [[package]]
 name = "idna"
-version = "0.3.0"
+version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6"
+checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c"
 dependencies = [
  "unicode-bidi",
  "unicode-normalization",
@@ -743,8 +764,8 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7e41b53715c6f0c4be49510bb82dee2c1e51c8586d885abe65396e82ed518548"
 dependencies = [
- "proc-macro2 1.0.59",
- "quote 1.0.28",
+ "proc-macro2 1.0.63",
+ "quote 1.0.29",
  "syn 1.0.109",
 ]
 
@@ -756,14 +777,14 @@
 dependencies = [
  "hermit-abi 0.3.1",
  "libc",
- "windows-sys 0.48.0",
+ "windows-sys",
 ]
 
 [[package]]
 name = "ipnet"
-version = "2.7.2"
+version = "2.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "12b6ee2129af8d4fb011108c73d99a1b83a85977f23b82460c0ae2e25bb4b57f"
+checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6"
 
 [[package]]
 name = "itertools"
@@ -785,9 +806,9 @@
 
 [[package]]
 name = "itoa"
-version = "1.0.6"
+version = "1.0.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
+checksum = "62b02a5381cc465bd3041d84623d0fa3b66738b52b8e2fc3bab8ad63ab032f4a"
 
 [[package]]
 name = "jpeg-decoder"
@@ -797,9 +818,9 @@
 
 [[package]]
 name = "js-sys"
-version = "0.3.63"
+version = "0.3.64"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2f37a4a5928311ac501dee68b3c7613a1037d0edb30c8e5427bd832d55d1b790"
+checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a"
 dependencies = [
  "wasm-bindgen",
 ]
@@ -812,9 +833,9 @@
 
 [[package]]
 name = "libc"
-version = "0.2.145"
+version = "0.2.147"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fc86cde3ff845662b8f4ef6cb50ea0e20c524eb3d29ae048287e06a1b3fa6a81"
+checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
 
 [[package]]
 name = "libm"
@@ -830,9 +851,9 @@
 
 [[package]]
 name = "log"
-version = "0.4.18"
+version = "0.4.19"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "518ef76f2f87365916b142844c16d8fefd85039bc5699050210a7778ee1cd1de"
+checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4"
 dependencies = [
  "value-bag",
 ]
@@ -875,7 +896,7 @@
 dependencies = [
  "libc",
  "wasi",
- "windows-sys 0.48.0",
+ "windows-sys",
 ]
 
 [[package]]
@@ -1015,15 +1036,24 @@
 
 [[package]]
 name = "num_cpus"
-version = "1.15.0"
+version = "1.16.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
+checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
 dependencies = [
- "hermit-abi 0.2.6",
+ "hermit-abi 0.3.1",
  "libc",
 ]
 
 [[package]]
+name = "object"
+version = "0.31.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
 name = "once_cell"
 version = "1.18.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1031,9 +1061,9 @@
 
 [[package]]
 name = "openssl"
-version = "0.10.54"
+version = "0.10.55"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "69b3f656a17a6cbc115b5c7a40c616947d213ba182135b014d6051b73ab6f019"
+checksum = "345df152bc43501c5eb9e4654ff05f794effb78d4efe3d53abc158baddc0703d"
 dependencies = [
  "bitflags",
  "cfg-if 1.0.0",
@@ -1050,9 +1080,9 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
 dependencies = [
- "proc-macro2 1.0.59",
- "quote 1.0.28",
- "syn 2.0.18",
+ "proc-macro2 1.0.63",
+ "quote 1.0.29",
+ "syn 2.0.23",
 ]
 
 [[package]]
@@ -1063,9 +1093,9 @@
 
 [[package]]
 name = "openssl-sys"
-version = "0.9.88"
+version = "0.9.90"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c2ce0f250f34a308dcfdbb351f511359857d4ed2134ba715a4eadd46e1ffd617"
+checksum = "374533b0e45f3a7ced10fcaeccca020e66656bc03dac384f852e4e5a7a8104a6"
 dependencies = [
  "cc",
  "libc",
@@ -1075,9 +1105,9 @@
 
 [[package]]
 name = "percent-encoding"
-version = "2.2.0"
+version = "2.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
+checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94"
 
 [[package]]
 name = "petgraph"
@@ -1091,29 +1121,29 @@
 
 [[package]]
 name = "pin-project"
-version = "1.1.0"
+version = "1.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c95a7476719eab1e366eaf73d0260af3021184f18177925b07f54b30089ceead"
+checksum = "030ad2bc4db10a8944cb0d837f158bdfec4d4a4873ab701a95046770d11f8842"
 dependencies = [
  "pin-project-internal",
 ]
 
 [[package]]
 name = "pin-project-internal"
-version = "1.1.0"
+version = "1.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "39407670928234ebc5e6e580247dd567ad73a3578460c5990f9503df207e8f07"
+checksum = "ec2e072ecce94ec471b13398d5402c188e76ac03cf74dd1a975161b23a3f6d9c"
 dependencies = [
- "proc-macro2 1.0.59",
- "quote 1.0.28",
- "syn 2.0.18",
+ "proc-macro2 1.0.63",
+ "quote 1.0.29",
+ "syn 2.0.23",
 ]
 
 [[package]]
 name = "pin-project-lite"
-version = "0.2.9"
+version = "0.2.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
+checksum = "4c40d25201921e5ff0c862a505c6557ea88568a4e3ace775ab55e93f2f4f9d57"
 
 [[package]]
 name = "pin-utils"
@@ -1140,8 +1170,8 @@
 checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
 dependencies = [
  "proc-macro-error-attr",
- "proc-macro2 1.0.59",
- "quote 1.0.28",
+ "proc-macro2 1.0.63",
+ "quote 1.0.29",
  "syn 1.0.109",
  "version_check",
 ]
@@ -1152,8 +1182,8 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
 dependencies = [
- "proc-macro2 1.0.59",
- "quote 1.0.28",
+ "proc-macro2 1.0.63",
+ "quote 1.0.29",
  "version_check",
 ]
 
@@ -1168,9 +1198,9 @@
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.59"
+version = "1.0.63"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6aeca18b86b413c660b781aa319e4e2648a3e6f9eadc9b47e9038e6fe9f3451b"
+checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb"
 dependencies = [
  "unicode-ident",
 ]
@@ -1213,8 +1243,8 @@
 dependencies = [
  "anyhow",
  "itertools 0.10.5",
- "proc-macro2 1.0.59",
- "quote 1.0.28",
+ "proc-macro2 1.0.63",
+ "quote 1.0.29",
  "syn 1.0.109",
 ]
 
@@ -1245,11 +1275,11 @@
 
 [[package]]
 name = "quote"
-version = "1.0.28"
+version = "1.0.29"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488"
+checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105"
 dependencies = [
- "proc-macro2 1.0.59",
+ "proc-macro2 1.0.63",
 ]
 
 [[package]]
@@ -1442,9 +1472,9 @@
 
 [[package]]
 name = "regex"
-version = "1.8.3"
+version = "1.8.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "81ca098a9821bd52d6b24fd8b10bd081f47d39c22778cafaa75a2857a62c6390"
+checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f"
 dependencies = [
  "aho-corasick",
  "memchr",
@@ -1521,9 +1551,15 @@
 ]
 
 [[package]]
+name = "rustc-demangle"
+version = "0.1.23"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
+
+[[package]]
 name = "rustface"
 version = "0.1.7"
-source = "git+https://github.com/apache/incubator-teaclave-crates#ede1f68d891798fe6cf995e33281f01d59be9320"
+source = "git+https://github.com/apache/incubator-teaclave-crates#2b87d3972d43fa0fee2496dfc703e4f772ffbe9f"
 dependencies = [
  "byteorder",
  "image",
@@ -1534,16 +1570,16 @@
 
 [[package]]
 name = "rustix"
-version = "0.37.19"
+version = "0.37.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d"
+checksum = "8818fa822adcc98b18fedbb3632a6a33213c070556b5aa7c4c8cc21cff565c4c"
 dependencies = [
  "bitflags",
  "errno",
  "io-lifetimes",
  "libc",
  "linux-raw-sys",
- "windows-sys 0.48.0",
+ "windows-sys",
 ]
 
 [[package]]
@@ -1562,7 +1598,7 @@
 [[package]]
 name = "rusty-machine"
 version = "0.5.4"
-source = "git+https://github.com/apache/incubator-teaclave-crates#ede1f68d891798fe6cf995e33281f01d59be9320"
+source = "git+https://github.com/apache/incubator-teaclave-crates#2b87d3972d43fa0fee2496dfc703e4f772ffbe9f"
 dependencies = [
  "num 0.1.42",
  "rand 0.8.5",
@@ -1574,17 +1610,17 @@
 
 [[package]]
 name = "ryu"
-version = "1.0.13"
+version = "1.0.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041"
+checksum = "fe232bdf6be8c8de797b22184ee71118d63780ea42ac85b61d1baa6d3b782ae9"
 
 [[package]]
 name = "schannel"
-version = "0.1.21"
+version = "0.1.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3"
+checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88"
 dependencies = [
- "windows-sys 0.42.0",
+ "windows-sys",
 ]
 
 [[package]]
@@ -1622,22 +1658,22 @@
 
 [[package]]
 name = "serde"
-version = "1.0.163"
+version = "1.0.166"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2113ab51b87a539ae008b5c6c02dc020ffa39afd2d83cffcb3f4eb2722cebec2"
+checksum = "d01b7404f9d441d3ad40e6a636a7782c377d2abdbe4fa2440e2edcc2f4f10db8"
 dependencies = [
  "serde_derive",
 ]
 
 [[package]]
 name = "serde_derive"
-version = "1.0.163"
+version = "1.0.166"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e"
+checksum = "5dd83d6dde2b6b2d466e14d9d1acce8816dedee94f735eac6395808b3483c6d6"
 dependencies = [
- "proc-macro2 1.0.59",
- "quote 1.0.28",
- "syn 2.0.18",
+ "proc-macro2 1.0.63",
+ "quote 1.0.29",
+ "syn 2.0.23",
 ]
 
 [[package]]
@@ -1651,9 +1687,9 @@
 
 [[package]]
 name = "serde_json"
-version = "1.0.96"
+version = "1.0.99"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1"
+checksum = "46266871c240a00b8f503b877622fe33430b3c7d963bdc0f2adc511e54a1eae3"
 dependencies = [
  "itoa",
  "ryu",
@@ -1726,8 +1762,8 @@
 name = "sgx_macros"
 version = "2.0.0"
 dependencies = [
- "proc-macro2 1.0.59",
- "quote 1.0.28",
+ "proc-macro2 1.0.63",
+ "quote 1.0.29",
  "syn 1.0.109",
 ]
 
@@ -1942,22 +1978,22 @@
 dependencies = [
  "heck",
  "proc-macro-error",
- "proc-macro2 1.0.59",
- "quote 1.0.28",
+ "proc-macro2 1.0.63",
+ "quote 1.0.29",
  "syn 1.0.109",
 ]
 
 [[package]]
 name = "sval"
-version = "2.5.0"
+version = "2.6.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0e6aa16ce8d9e472e21a528a52c875a76a49190f3968f2ec7e9b550ccc28b410"
+checksum = "8b031320a434d3e9477ccf9b5756d57d4272937b8d22cb88af80b7633a1b78b1"
 
 [[package]]
 name = "sval_buffer"
-version = "2.5.0"
+version = "2.6.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "905c4373621186ee9637464b0aaa026389ea9e7f841f2225f160a32ba5d5bac4"
+checksum = "6bf7e9412af26b342f3f2cc5cc4122b0105e9d16eb76046cd14ed10106cf6028"
 dependencies = [
  "sval",
  "sval_ref",
@@ -1965,18 +2001,18 @@
 
 [[package]]
 name = "sval_dynamic"
-version = "2.5.0"
+version = "2.6.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ad6b4988322c5f22859a6a7649fa1249aa3dd01514caf8ed57d83735f997bb8b"
+checksum = "a0ef628e8a77a46ed3338db8d1b08af77495123cc229453084e47cd716d403cf"
 dependencies = [
  "sval",
 ]
 
 [[package]]
 name = "sval_fmt"
-version = "2.5.0"
+version = "2.6.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9d3ccd10346f925c2fbd97b75e8573b38e34431bfba04cc531cd23aad0fbabb8"
+checksum = "7dc09e9364c2045ab5fa38f7b04d077b3359d30c4c2b3ec4bae67a358bd64326"
 dependencies = [
  "itoa",
  "ryu",
@@ -1985,9 +2021,9 @@
 
 [[package]]
 name = "sval_json"
-version = "2.5.0"
+version = "2.6.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6a12e1488defd6344e23243c17ea4a1b185c547968749e8a281373fde0bde2d5"
+checksum = "ada6f627e38cbb8860283649509d87bc4a5771141daa41c78fd31f2b9485888d"
 dependencies = [
  "itoa",
  "ryu",
@@ -1996,18 +2032,18 @@
 
 [[package]]
 name = "sval_ref"
-version = "2.5.0"
+version = "2.6.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b797fc4b284dd0e45f7ec424479e604ea5be9bb191a1ef4e96c20c7685649938"
+checksum = "703ca1942a984bd0d9b5a4c0a65ab8b4b794038d080af4eb303c71bc6bf22d7c"
 dependencies = [
  "sval",
 ]
 
 [[package]]
 name = "sval_serde"
-version = "2.5.0"
+version = "2.6.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "810fa9a837e67a23e0efa7536250fc4d24043306cc1efd076f1943ba2fc2e62d"
+checksum = "830926cd0581f7c3e5d51efae4d35c6b6fc4db583842652891ba2f1bed8db046"
 dependencies = [
  "serde",
  "sval",
@@ -2032,19 +2068,19 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
 dependencies = [
- "proc-macro2 1.0.59",
- "quote 1.0.28",
+ "proc-macro2 1.0.63",
+ "quote 1.0.29",
  "unicode-ident",
 ]
 
 [[package]]
 name = "syn"
-version = "2.0.18"
+version = "2.0.23"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e"
+checksum = "59fb7d6d8281a51045d62b8eb3a7d1ce347b76f312af50cd3dc0af39c87c1737"
 dependencies = [
- "proc-macro2 1.0.59",
- "quote 1.0.28",
+ "proc-macro2 1.0.63",
+ "quote 1.0.29",
  "unicode-ident",
 ]
 
@@ -2479,8 +2515,8 @@
 name = "teaclave_test_utils_proc_macro"
 version = "0.0.1"
 dependencies = [
- "proc-macro2 1.0.59",
- "quote 1.0.28",
+ "proc-macro2 1.0.63",
+ "quote 1.0.29",
  "syn 1.0.109",
 ]
 
@@ -2539,15 +2575,16 @@
 
 [[package]]
 name = "tempfile"
-version = "3.5.0"
+version = "3.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998"
+checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6"
 dependencies = [
+ "autocfg 1.1.0",
  "cfg-if 1.0.0",
  "fastrand",
  "redox_syscall",
  "rustix",
- "windows-sys 0.45.0",
+ "windows-sys",
 ]
 
 [[package]]
@@ -2583,9 +2620,9 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f"
 dependencies = [
- "proc-macro2 1.0.59",
- "quote 1.0.28",
- "syn 2.0.18",
+ "proc-macro2 1.0.63",
+ "quote 1.0.29",
+ "syn 2.0.23",
 ]
 
 [[package]]
@@ -2605,11 +2642,12 @@
 
 [[package]]
 name = "tokio"
-version = "1.28.2"
+version = "1.29.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94d7b1cfd2aa4011f2de74c2c4c63665e27a71006b0a192dcd2710272e73dfa2"
+checksum = "532826ff75199d5833b9d2c5fe410f29235e25704ee5f0ef599fb51c21f4a4da"
 dependencies = [
  "autocfg 1.1.0",
+ "backtrace",
  "bytes",
  "libc",
  "mio",
@@ -2617,7 +2655,7 @@
  "pin-project-lite",
  "socket2",
  "tokio-macros",
- "windows-sys 0.48.0",
+ "windows-sys",
 ]
 
 [[package]]
@@ -2636,9 +2674,9 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e"
 dependencies = [
- "proc-macro2 1.0.59",
- "quote 1.0.28",
- "syn 2.0.18",
+ "proc-macro2 1.0.63",
+ "quote 1.0.29",
+ "syn 2.0.23",
 ]
 
 [[package]]
@@ -2749,9 +2787,9 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9403f1bafde247186684b230dc6f38b5cd514584e8bec1dd32514be4745fa757"
 dependencies = [
- "proc-macro2 1.0.59",
+ "proc-macro2 1.0.63",
  "prost-build",
- "quote 1.0.28",
+ "quote 1.0.29",
  "syn 1.0.109",
 ]
 
@@ -2802,13 +2840,13 @@
 
 [[package]]
 name = "tracing-attributes"
-version = "0.1.24"
+version = "0.1.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0f57e3ca2a01450b1a921183a9c9cbfda207fd822cef4ccb00a65402cbba7a74"
+checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab"
 dependencies = [
- "proc-macro2 1.0.59",
- "quote 1.0.28",
- "syn 2.0.18",
+ "proc-macro2 1.0.63",
+ "quote 1.0.29",
+ "syn 2.0.23",
 ]
 
 [[package]]
@@ -2844,9 +2882,9 @@
 
 [[package]]
 name = "unicode-ident"
-version = "1.0.9"
+version = "1.0.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0"
+checksum = "22049a19f4a68748a168c0fc439f9516686aa045927ff767eca0a85101fb6e73"
 
 [[package]]
 name = "unicode-normalization"
@@ -2883,9 +2921,9 @@
 
 [[package]]
 name = "url"
-version = "2.3.1"
+version = "2.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643"
+checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb"
 dependencies = [
  "form_urlencoded",
  "idna",
@@ -2906,9 +2944,9 @@
 
 [[package]]
 name = "value-bag"
-version = "1.4.0"
+version = "1.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a4d330786735ea358f3bc09eea4caa098569c1c93f342d9aca0514915022fe7e"
+checksum = "d92ccd67fb88503048c01b59152a04effd0782d035a83a6d256ce6085f08f4a3"
 dependencies = [
  "value-bag-serde1",
  "value-bag-sval2",
@@ -2916,9 +2954,9 @@
 
 [[package]]
 name = "value-bag-serde1"
-version = "1.4.0"
+version = "1.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4735c95b4cca1447b448e2e2e87e98d7e7498f4da27e355cf7af02204521001d"
+checksum = "b0b9f3feef403a50d4d67e9741a6d8fc688bcbb4e4f31bd4aab72cc690284394"
 dependencies = [
  "erased-serde",
  "serde",
@@ -2927,9 +2965,9 @@
 
 [[package]]
 name = "value-bag-sval2"
-version = "1.4.0"
+version = "1.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "859cb4f0ce7da6a118b559ba74b0e63bf569bea867c20ba457a6b1c886a04e97"
+checksum = "30b24f4146b6f3361e91cbf527d1fb35e9376c3c0cef72ca5ec5af6d640fad7d"
 dependencies = [
  "sval",
  "sval_buffer",
@@ -2960,11 +2998,10 @@
 
 [[package]]
 name = "want"
-version = "0.3.0"
+version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0"
+checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
 dependencies = [
- "log",
  "try-lock",
 ]
 
@@ -2976,9 +3013,9 @@
 
 [[package]]
 name = "wasm-bindgen"
-version = "0.2.86"
+version = "0.2.87"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5bba0e8cb82ba49ff4e229459ff22a191bbe9a1cb3a341610c9c33efc27ddf73"
+checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342"
 dependencies = [
  "cfg-if 1.0.0",
  "wasm-bindgen-macro",
@@ -2986,24 +3023,24 @@
 
 [[package]]
 name = "wasm-bindgen-backend"
-version = "0.2.86"
+version = "0.2.87"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "19b04bc93f9d6bdee709f6bd2118f57dd6679cf1176a1af464fca3ab0d66d8fb"
+checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd"
 dependencies = [
  "bumpalo",
  "log",
  "once_cell",
- "proc-macro2 1.0.59",
- "quote 1.0.28",
- "syn 2.0.18",
+ "proc-macro2 1.0.63",
+ "quote 1.0.29",
+ "syn 2.0.23",
  "wasm-bindgen-shared",
 ]
 
 [[package]]
 name = "wasm-bindgen-futures"
-version = "0.4.36"
+version = "0.4.37"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2d1985d03709c53167ce907ff394f5316aa22cb4e12761295c5dc57dacb6297e"
+checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03"
 dependencies = [
  "cfg-if 1.0.0",
  "js-sys",
@@ -3013,32 +3050,32 @@
 
 [[package]]
 name = "wasm-bindgen-macro"
-version = "0.2.86"
+version = "0.2.87"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "14d6b024f1a526bb0234f52840389927257beb670610081360e5a03c5df9c258"
+checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d"
 dependencies = [
- "quote 1.0.28",
+ "quote 1.0.29",
  "wasm-bindgen-macro-support",
 ]
 
 [[package]]
 name = "wasm-bindgen-macro-support"
-version = "0.2.86"
+version = "0.2.87"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e128beba882dd1eb6200e1dc92ae6c5dbaa4311aa7bb211ca035779e5efc39f8"
+checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
 dependencies = [
- "proc-macro2 1.0.59",
- "quote 1.0.28",
- "syn 2.0.18",
+ "proc-macro2 1.0.63",
+ "quote 1.0.29",
+ "syn 2.0.23",
  "wasm-bindgen-backend",
  "wasm-bindgen-shared",
 ]
 
 [[package]]
 name = "wasm-bindgen-shared"
-version = "0.2.86"
+version = "0.2.87"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed9d5b4305409d1fc9482fee2d7f9bcbf24b3972bf59817ef757e23982242a93"
+checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1"
 
 [[package]]
 name = "wasm-streams"
@@ -3055,9 +3092,9 @@
 
 [[package]]
 name = "web-sys"
-version = "0.3.63"
+version = "0.3.64"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3bdd9ef4e984da1187bf8110c5cf5b845fbc87a23602cdf912386a76fcd3a7c2"
+checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b"
 dependencies = [
  "js-sys",
  "wasm-bindgen",
@@ -3126,74 +3163,29 @@
 
 [[package]]
 name = "windows-sys"
-version = "0.42.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
-dependencies = [
- "windows_aarch64_gnullvm 0.42.2",
- "windows_aarch64_msvc 0.42.2",
- "windows_i686_gnu 0.42.2",
- "windows_i686_msvc 0.42.2",
- "windows_x86_64_gnu 0.42.2",
- "windows_x86_64_gnullvm 0.42.2",
- "windows_x86_64_msvc 0.42.2",
-]
-
-[[package]]
-name = "windows-sys"
-version = "0.45.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
-dependencies = [
- "windows-targets 0.42.2",
-]
-
-[[package]]
-name = "windows-sys"
 version = "0.48.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
 dependencies = [
- "windows-targets 0.48.0",
+ "windows-targets",
 ]
 
 [[package]]
 name = "windows-targets"
-version = "0.42.2"
+version = "0.48.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
+checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f"
 dependencies = [
- "windows_aarch64_gnullvm 0.42.2",
- "windows_aarch64_msvc 0.42.2",
- "windows_i686_gnu 0.42.2",
- "windows_i686_msvc 0.42.2",
- "windows_x86_64_gnu 0.42.2",
- "windows_x86_64_gnullvm 0.42.2",
- "windows_x86_64_msvc 0.42.2",
+ "windows_aarch64_gnullvm",
+ "windows_aarch64_msvc",
+ "windows_i686_gnu",
+ "windows_i686_msvc",
+ "windows_x86_64_gnu",
+ "windows_x86_64_gnullvm",
+ "windows_x86_64_msvc",
 ]
 
 [[package]]
-name = "windows-targets"
-version = "0.48.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5"
-dependencies = [
- "windows_aarch64_gnullvm 0.48.0",
- "windows_aarch64_msvc 0.48.0",
- "windows_i686_gnu 0.48.0",
- "windows_i686_msvc 0.48.0",
- "windows_x86_64_gnu 0.48.0",
- "windows_x86_64_gnullvm 0.48.0",
- "windows_x86_64_msvc 0.48.0",
-]
-
-[[package]]
-name = "windows_aarch64_gnullvm"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
-
-[[package]]
 name = "windows_aarch64_gnullvm"
 version = "0.48.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3201,72 +3193,36 @@
 
 [[package]]
 name = "windows_aarch64_msvc"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
-
-[[package]]
-name = "windows_aarch64_msvc"
 version = "0.48.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
 
 [[package]]
 name = "windows_i686_gnu"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
-
-[[package]]
-name = "windows_i686_gnu"
 version = "0.48.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
 
 [[package]]
 name = "windows_i686_msvc"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
-
-[[package]]
-name = "windows_i686_msvc"
 version = "0.48.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
 
 [[package]]
 name = "windows_x86_64_gnu"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
-
-[[package]]
-name = "windows_x86_64_gnu"
 version = "0.48.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1"
 
 [[package]]
 name = "windows_x86_64_gnullvm"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
-
-[[package]]
-name = "windows_x86_64_gnullvm"
 version = "0.48.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
 
 [[package]]
 name = "windows_x86_64_msvc"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
-
-[[package]]
-name = "windows_x86_64_msvc"
 version = "0.48.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
diff --git a/cmake/tomls/Cargo.unix_app.lock b/cmake/tomls/Cargo.unix_app.lock
index cb33041..6e657f9 100644
--- a/cmake/tomls/Cargo.unix_app.lock
+++ b/cmake/tomls/Cargo.unix_app.lock
@@ -3,6 +3,15 @@
 version = 3
 
 [[package]]
+name = "addr2line"
+version = "0.20.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3"
+dependencies = [
+ "gimli",
+]
+
+[[package]]
 name = "adler"
 version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -20,9 +29,9 @@
 
 [[package]]
 name = "aes"
-version = "0.8.2"
+version = "0.8.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "433cfd6710c9986c576a25ca913c39d66a6474107b406f34f91d4a8923395241"
+checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2"
 dependencies = [
  "cfg-if 1.0.0",
  "cipher",
@@ -101,18 +110,18 @@
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.18",
+ "syn 2.0.23",
 ]
 
 [[package]]
 name = "async-trait"
-version = "0.1.68"
+version = "0.1.69"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842"
+checksum = "7b2d0f03b3640e3a630367e40c468cb7f309529c708ed1d88597047b0e7c6ef7"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.18",
+ "syn 2.0.23",
 ]
 
 [[package]]
@@ -139,6 +148,21 @@
 checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
 
 [[package]]
+name = "backtrace"
+version = "0.3.68"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12"
+dependencies = [
+ "addr2line",
+ "cc",
+ "cfg-if 1.0.0",
+ "libc",
+ "miniz_oxide",
+ "object",
+ "rustc-demangle",
+]
+
+[[package]]
 name = "base64"
 version = "0.11.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -273,7 +297,7 @@
  "rand",
  "sha2",
  "subtle",
- "time 0.3.21",
+ "time 0.3.22",
  "version_check",
 ]
 
@@ -285,9 +309,9 @@
 
 [[package]]
 name = "cpufeatures"
-version = "0.2.7"
+version = "0.2.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3e4c1eaa2012c47becbbad2ab175484c2a84d1185b566fb2cc5b8707343dfe58"
+checksum = "03e69e28e9f7f77debdedbaafa2866e1de9ba56df55a8bd7cfc724c25a09987c"
 dependencies = [
  "libc",
 ]
@@ -404,6 +428,12 @@
 ]
 
 [[package]]
+name = "equivalent"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "88bffebc5d80432c9b140ee17875ff173a8ab62faad5b257da912bd2f6c1c0a1"
+
+[[package]]
 name = "errno"
 version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -411,7 +441,7 @@
 dependencies = [
  "errno-dragonfly",
  "libc",
- "windows-sys 0.48.0",
+ "windows-sys",
 ]
 
 [[package]]
@@ -442,7 +472,7 @@
  "atomic",
  "pear",
  "serde",
- "toml 0.7.4",
+ "toml 0.7.5",
  "uncased",
  "version_check",
 ]
@@ -471,9 +501,9 @@
 
 [[package]]
 name = "form_urlencoded"
-version = "1.1.0"
+version = "1.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8"
+checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652"
 dependencies = [
  "percent-encoding",
 ]
@@ -534,7 +564,7 @@
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.18",
+ "syn 2.0.23",
 ]
 
 [[package]]
@@ -569,9 +599,9 @@
 
 [[package]]
 name = "generator"
-version = "0.7.4"
+version = "0.7.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f3e123d9ae7c02966b4d892e550bdc32164f05853cd40ab570650ad600596a8a"
+checksum = "5cc16584ff22b460a382b7feec54b23d2908d858152e5739a120b949293bd74e"
 dependencies = [
  "cc",
  "libc",
@@ -592,9 +622,9 @@
 
 [[package]]
 name = "getrandom"
-version = "0.2.9"
+version = "0.2.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4"
+checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
 dependencies = [
  "cfg-if 1.0.0",
  "libc",
@@ -613,16 +643,22 @@
 
 [[package]]
 name = "ghost"
-version = "0.1.9"
+version = "0.1.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e77ac7b51b8e6313251737fcef4b1c01a2ea102bde68415b62c0ee9268fec357"
+checksum = "fae7e09da323fc46f010e455cac340af26159678ba00ab18e963a5880ca6a9b6"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.18",
+ "syn 2.0.23",
 ]
 
 [[package]]
+name = "gimli"
+version = "0.27.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e"
+
+[[package]]
 name = "glob"
 version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -630,9 +666,9 @@
 
 [[package]]
 name = "h2"
-version = "0.3.19"
+version = "0.3.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d357c7ae988e7d2182f7d7871d0b963962420b0678b0997ce7de72001aeab782"
+checksum = "97ec8491ebaf99c8eaa73058b045fe58073cd6be7f596ac993ced0b0a0c01049"
 dependencies = [
  "bytes",
  "fnv",
@@ -640,7 +676,7 @@
  "futures-sink",
  "futures-util",
  "http",
- "indexmap",
+ "indexmap 1.9.3",
  "slab",
  "tokio",
  "tokio-util 0.7.8",
@@ -654,6 +690,12 @@
 checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
 
 [[package]]
+name = "hashbrown"
+version = "0.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a"
+
+[[package]]
 name = "hashbrown_tstd"
 version = "0.12.0"
 
@@ -677,15 +719,6 @@
 
 [[package]]
 name = "hermit-abi"
-version = "0.2.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "hermit-abi"
 version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286"
@@ -759,9 +792,9 @@
 
 [[package]]
 name = "hyper"
-version = "0.14.26"
+version = "0.14.27"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ab302d72a6f11a3b910431ff93aae7e773078c769f0a3ef15fb9ec692ed147d4"
+checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468"
 dependencies = [
  "bytes",
  "futures-channel",
@@ -795,9 +828,9 @@
 
 [[package]]
 name = "iana-time-zone"
-version = "0.1.56"
+version = "0.1.57"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0722cd7114b7de04316e7ea5456a0bbb20e4adb46fd27a3697adb812cff0f37c"
+checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613"
 dependencies = [
  "android_system_properties",
  "core-foundation-sys",
@@ -818,9 +851,9 @@
 
 [[package]]
 name = "idna"
-version = "0.3.0"
+version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6"
+checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c"
 dependencies = [
  "unicode-bidi",
  "unicode-normalization",
@@ -833,11 +866,21 @@
 checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
 dependencies = [
  "autocfg",
- "hashbrown",
+ "hashbrown 0.12.3",
  "serde",
 ]
 
 [[package]]
+name = "indexmap"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d"
+dependencies = [
+ "equivalent",
+ "hashbrown 0.14.0",
+]
+
+[[package]]
 name = "inlinable_string"
 version = "0.1.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -891,7 +934,7 @@
 dependencies = [
  "hermit-abi 0.3.1",
  "libc",
- "windows-sys 0.48.0",
+ "windows-sys",
 ]
 
 [[package]]
@@ -905,15 +948,15 @@
 
 [[package]]
 name = "itoa"
-version = "1.0.6"
+version = "1.0.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
+checksum = "62b02a5381cc465bd3041d84623d0fa3b66738b52b8e2fc3bab8ad63ab032f4a"
 
 [[package]]
 name = "js-sys"
-version = "0.3.63"
+version = "0.3.64"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2f37a4a5928311ac501dee68b3c7613a1037d0edb30c8e5427bd832d55d1b790"
+checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a"
 dependencies = [
  "wasm-bindgen",
 ]
@@ -926,9 +969,9 @@
 
 [[package]]
 name = "libc"
-version = "0.2.145"
+version = "0.2.147"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fc86cde3ff845662b8f4ef6cb50ea0e20c524eb3d29ae048287e06a1b3fa6a81"
+checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
 
 [[package]]
 name = "linux-raw-sys"
@@ -938,9 +981,9 @@
 
 [[package]]
 name = "lock_api"
-version = "0.4.9"
+version = "0.4.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df"
+checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16"
 dependencies = [
  "autocfg",
  "scopeguard",
@@ -948,9 +991,9 @@
 
 [[package]]
 name = "log"
-version = "0.4.18"
+version = "0.4.19"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "518ef76f2f87365916b142844c16d8fefd85039bc5699050210a7778ee1cd1de"
+checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4"
 
 [[package]]
 name = "loom"
@@ -1005,7 +1048,7 @@
 dependencies = [
  "libc",
  "wasi 0.11.0+wasi-snapshot-preview1",
- "windows-sys 0.48.0",
+ "windows-sys",
 ]
 
 [[package]]
@@ -1076,15 +1119,24 @@
 
 [[package]]
 name = "num_cpus"
-version = "1.15.0"
+version = "1.16.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
+checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
 dependencies = [
- "hermit-abi 0.2.6",
+ "hermit-abi 0.3.1",
  "libc",
 ]
 
 [[package]]
+name = "object"
+version = "0.31.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
 name = "once_cell"
 version = "1.18.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1114,15 +1166,15 @@
 
 [[package]]
 name = "parking_lot_core"
-version = "0.9.7"
+version = "0.9.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521"
+checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447"
 dependencies = [
  "cfg-if 1.0.0",
  "libc",
- "redox_syscall 0.2.16",
+ "redox_syscall",
  "smallvec",
- "windows-sys 0.45.0",
+ "windows-targets",
 ]
 
 [[package]]
@@ -1145,7 +1197,7 @@
  "proc-macro2",
  "proc-macro2-diagnostics 0.10.0",
  "quote",
- "syn 2.0.18",
+ "syn 2.0.23",
 ]
 
 [[package]]
@@ -1161,9 +1213,9 @@
 
 [[package]]
 name = "percent-encoding"
-version = "2.2.0"
+version = "2.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
+checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94"
 
 [[package]]
 name = "petgraph"
@@ -1172,34 +1224,34 @@
 checksum = "4dd7d28ee937e54fe3080c91faa1c3a46c06de6252988a7f4592ba2310ef22a4"
 dependencies = [
  "fixedbitset",
- "indexmap",
+ "indexmap 1.9.3",
 ]
 
 [[package]]
 name = "pin-project"
-version = "1.1.0"
+version = "1.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c95a7476719eab1e366eaf73d0260af3021184f18177925b07f54b30089ceead"
+checksum = "030ad2bc4db10a8944cb0d837f158bdfec4d4a4873ab701a95046770d11f8842"
 dependencies = [
  "pin-project-internal",
 ]
 
 [[package]]
 name = "pin-project-internal"
-version = "1.1.0"
+version = "1.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "39407670928234ebc5e6e580247dd567ad73a3578460c5990f9503df207e8f07"
+checksum = "ec2e072ecce94ec471b13398d5402c188e76ac03cf74dd1a975161b23a3f6d9c"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.18",
+ "syn 2.0.23",
 ]
 
 [[package]]
 name = "pin-project-lite"
-version = "0.2.9"
+version = "0.2.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
+checksum = "4c40d25201921e5ff0c862a505c6557ea88568a4e3ace775ab55e93f2f4f9d57"
 
 [[package]]
 name = "pin-utils"
@@ -1209,9 +1261,9 @@
 
 [[package]]
 name = "polyval"
-version = "0.6.0"
+version = "0.6.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7ef234e08c11dfcb2e56f79fd70f6f2eb7f025c0ce2333e82f4f0518ecad30c6"
+checksum = "d52cff9d1d4dee5fe6d03729099f4a310a41179e0a10dbf542039873f2e826fb"
 dependencies = [
  "cfg-if 1.0.0",
  "cpufeatures",
@@ -1251,9 +1303,9 @@
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.59"
+version = "1.0.63"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6aeca18b86b413c660b781aa319e4e2648a3e6f9eadc9b47e9038e6fe9f3451b"
+checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb"
 dependencies = [
  "unicode-ident",
 ]
@@ -1279,7 +1331,7 @@
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.18",
+ "syn 2.0.23",
  "version_check",
  "yansi",
 ]
@@ -1345,9 +1397,9 @@
 
 [[package]]
 name = "quote"
-version = "1.0.28"
+version = "1.0.29"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488"
+checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105"
 dependencies = [
  "proc-macro2",
 ]
@@ -1393,15 +1445,6 @@
 
 [[package]]
 name = "redox_syscall"
-version = "0.2.16"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
-dependencies = [
- "bitflags",
-]
-
-[[package]]
-name = "redox_syscall"
 version = "0.3.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
@@ -1411,29 +1454,29 @@
 
 [[package]]
 name = "ref-cast"
-version = "1.0.16"
+version = "1.0.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f43faa91b1c8b36841ee70e97188a869d37ae21759da6846d4be66de5bf7b12c"
+checksum = "85d07b1a5f16b5548f4255a978c94259971aff73f39e8d67e8250e8b2f6667c3"
 dependencies = [
  "ref-cast-impl",
 ]
 
 [[package]]
 name = "ref-cast-impl"
-version = "1.0.16"
+version = "1.0.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8d2275aab483050ab2a7364c1a46604865ee7d6906684e08db0f090acf74f9e7"
+checksum = "a930b010d9effee5834317bb7ff406b76af7724348fd572b38705b4bd099fa92"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.18",
+ "syn 2.0.23",
 ]
 
 [[package]]
 name = "regex"
-version = "1.8.3"
+version = "1.8.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "81ca098a9821bd52d6b24fd8b10bd081f47d39c22778cafaa75a2857a62c6390"
+checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f"
 dependencies = [
  "aho-corasick",
  "memchr",
@@ -1490,7 +1533,7 @@
  "either",
  "figment",
  "futures",
- "indexmap",
+ "indexmap 1.9.3",
  "log",
  "memchr",
  "multer",
@@ -1504,7 +1547,7 @@
  "serde",
  "state",
  "tempfile",
- "time 0.3.21",
+ "time 0.3.22",
  "tokio",
  "tokio-stream",
  "tokio-util 0.7.8",
@@ -1520,7 +1563,7 @@
 dependencies = [
  "devise",
  "glob",
- "indexmap",
+ "indexmap 1.9.3",
  "proc-macro2",
  "quote",
  "rocket_http",
@@ -1538,7 +1581,7 @@
  "futures",
  "http",
  "hyper",
- "indexmap",
+ "indexmap 1.9.3",
  "log",
  "memchr",
  "pear",
@@ -1551,24 +1594,30 @@
  "smallvec",
  "stable-pattern",
  "state",
- "time 0.3.21",
+ "time 0.3.22",
  "tokio",
  "tokio-rustls 0.23.4",
  "uncased",
 ]
 
 [[package]]
-name = "rustix"
-version = "0.37.19"
+name = "rustc-demangle"
+version = "0.1.23"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d"
+checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
+
+[[package]]
+name = "rustix"
+version = "0.37.22"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8818fa822adcc98b18fedbb3632a6a33213c070556b5aa7c4c8cc21cff565c4c"
 dependencies = [
  "bitflags",
  "errno",
  "io-lifetimes",
  "libc",
  "linux-raw-sys",
- "windows-sys 0.48.0",
+ "windows-sys",
 ]
 
 [[package]]
@@ -1598,24 +1647,24 @@
 
 [[package]]
 name = "rustls-pemfile"
-version = "1.0.2"
+version = "1.0.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b"
+checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2"
 dependencies = [
  "base64 0.21.2",
 ]
 
 [[package]]
 name = "rustversion"
-version = "1.0.12"
+version = "1.0.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06"
+checksum = "dc31bd9b61a32c31f9650d18add92aa83a49ba979c143eefd27fe7177b05bd5f"
 
 [[package]]
 name = "ryu"
-version = "1.0.13"
+version = "1.0.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041"
+checksum = "fe232bdf6be8c8de797b22184ee71118d63780ea42ac85b61d1baa6d3b782ae9"
 
 [[package]]
 name = "scoped-tls"
@@ -1651,29 +1700,29 @@
 
 [[package]]
 name = "serde"
-version = "1.0.163"
+version = "1.0.166"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2113ab51b87a539ae008b5c6c02dc020ffa39afd2d83cffcb3f4eb2722cebec2"
+checksum = "d01b7404f9d441d3ad40e6a636a7782c377d2abdbe4fa2440e2edcc2f4f10db8"
 dependencies = [
  "serde_derive",
 ]
 
 [[package]]
 name = "serde_derive"
-version = "1.0.163"
+version = "1.0.166"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e"
+checksum = "5dd83d6dde2b6b2d466e14d9d1acce8816dedee94f735eac6395808b3483c6d6"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.18",
+ "syn 2.0.23",
 ]
 
 [[package]]
 name = "serde_json"
-version = "1.0.96"
+version = "1.0.99"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1"
+checksum = "46266871c240a00b8f503b877622fe33430b3c7d963bdc0f2adc511e54a1eae3"
 dependencies = [
  "itoa",
  "ryu",
@@ -1682,9 +1731,9 @@
 
 [[package]]
 name = "serde_spanned"
-version = "0.6.2"
+version = "0.6.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "93107647184f6027e3b7dcb2e11034cf95ffa1e3a682c67951963ac69c1c007d"
+checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186"
 dependencies = [
  "serde",
 ]
@@ -1868,9 +1917,9 @@
 
 [[package]]
 name = "sha2"
-version = "0.10.6"
+version = "0.10.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0"
+checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8"
 dependencies = [
  "cfg-if 1.0.0",
  "cpufeatures",
@@ -1999,9 +2048,9 @@
 
 [[package]]
 name = "syn"
-version = "2.0.18"
+version = "2.0.23"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e"
+checksum = "59fb7d6d8281a51045d62b8eb3a7d1ce347b76f312af50cd3dc0af39c87c1737"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -2199,15 +2248,16 @@
 
 [[package]]
 name = "tempfile"
-version = "3.5.0"
+version = "3.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998"
+checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6"
 dependencies = [
+ "autocfg",
  "cfg-if 1.0.0",
  "fastrand",
- "redox_syscall 0.3.5",
+ "redox_syscall",
  "rustix",
- "windows-sys 0.45.0",
+ "windows-sys",
 ]
 
 [[package]]
@@ -2245,7 +2295,7 @@
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.18",
+ "syn 2.0.23",
 ]
 
 [[package]]
@@ -2271,9 +2321,9 @@
 
 [[package]]
 name = "time"
-version = "0.3.21"
+version = "0.3.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f3403384eaacbca9923fa06940178ac13e4edb725486d70e8e15881d0c836cc"
+checksum = "ea9e1b3cf1243ae005d9e74085d4d542f3125458f3a81af210d901dcd7411efd"
 dependencies = [
  "itoa",
  "serde",
@@ -2313,11 +2363,12 @@
 
 [[package]]
 name = "tokio"
-version = "1.28.2"
+version = "1.29.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94d7b1cfd2aa4011f2de74c2c4c63665e27a71006b0a192dcd2710272e73dfa2"
+checksum = "532826ff75199d5833b9d2c5fe410f29235e25704ee5f0ef599fb51c21f4a4da"
 dependencies = [
  "autocfg",
+ "backtrace",
  "bytes",
  "libc",
  "mio",
@@ -2326,7 +2377,7 @@
  "signal-hook-registry",
  "socket2",
  "tokio-macros",
- "windows-sys 0.48.0",
+ "windows-sys",
 ]
 
 [[package]]
@@ -2347,7 +2398,7 @@
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.18",
+ "syn 2.0.23",
 ]
 
 [[package]]
@@ -2422,9 +2473,9 @@
 
 [[package]]
 name = "toml"
-version = "0.7.4"
+version = "0.7.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d6135d499e69981f9ff0ef2167955a5333c35e36f6937d382974566b3d5b94ec"
+checksum = "1ebafdf5ad1220cb59e7d17cf4d2c72015297b75b19a10472f99b89225089240"
 dependencies = [
  "serde",
  "serde_spanned",
@@ -2434,20 +2485,20 @@
 
 [[package]]
 name = "toml_datetime"
-version = "0.6.2"
+version = "0.6.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a76a9312f5ba4c2dec6b9161fdf25d87ad8a09256ccea5a556fef03c706a10f"
+checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b"
 dependencies = [
  "serde",
 ]
 
 [[package]]
 name = "toml_edit"
-version = "0.19.10"
+version = "0.19.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2380d56e8670370eee6566b0bfd4265f65b3f432e8c6d85623f728d4fa31f739"
+checksum = "266f016b7f039eec8a1a80dfe6156b633d208b9fccca5e4db1d6775b0c4e34a7"
 dependencies = [
- "indexmap",
+ "indexmap 2.0.0",
  "serde",
  "serde_spanned",
  "toml_datetime",
@@ -2507,7 +2558,7 @@
 dependencies = [
  "futures-core",
  "futures-util",
- "indexmap",
+ "indexmap 1.9.3",
  "pin-project",
  "pin-project-lite",
  "rand",
@@ -2546,13 +2597,13 @@
 
 [[package]]
 name = "tracing-attributes"
-version = "0.1.24"
+version = "0.1.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0f57e3ca2a01450b1a921183a9c9cbfda207fd822cef4ccb00a65402cbba7a74"
+checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.18",
+ "syn 2.0.23",
 ]
 
 [[package]]
@@ -2643,9 +2694,9 @@
 
 [[package]]
 name = "unicode-ident"
-version = "1.0.9"
+version = "1.0.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0"
+checksum = "22049a19f4a68748a168c0fc439f9516686aa045927ff767eca0a85101fb6e73"
 
 [[package]]
 name = "unicode-normalization"
@@ -2692,9 +2743,9 @@
 
 [[package]]
 name = "url"
-version = "2.3.1"
+version = "2.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643"
+checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb"
 dependencies = [
  "form_urlencoded",
  "idna",
@@ -2733,11 +2784,10 @@
 
 [[package]]
 name = "want"
-version = "0.3.0"
+version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0"
+checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
 dependencies = [
- "log",
  "try-lock",
 ]
 
@@ -2755,9 +2805,9 @@
 
 [[package]]
 name = "wasm-bindgen"
-version = "0.2.86"
+version = "0.2.87"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5bba0e8cb82ba49ff4e229459ff22a191bbe9a1cb3a341610c9c33efc27ddf73"
+checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342"
 dependencies = [
  "cfg-if 1.0.0",
  "wasm-bindgen-macro",
@@ -2765,24 +2815,24 @@
 
 [[package]]
 name = "wasm-bindgen-backend"
-version = "0.2.86"
+version = "0.2.87"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "19b04bc93f9d6bdee709f6bd2118f57dd6679cf1176a1af464fca3ab0d66d8fb"
+checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd"
 dependencies = [
  "bumpalo",
  "log",
  "once_cell",
  "proc-macro2",
  "quote",
- "syn 2.0.18",
+ "syn 2.0.23",
  "wasm-bindgen-shared",
 ]
 
 [[package]]
 name = "wasm-bindgen-macro"
-version = "0.2.86"
+version = "0.2.87"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "14d6b024f1a526bb0234f52840389927257beb670610081360e5a03c5df9c258"
+checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d"
 dependencies = [
  "quote",
  "wasm-bindgen-macro-support",
@@ -2790,28 +2840,28 @@
 
 [[package]]
 name = "wasm-bindgen-macro-support"
-version = "0.2.86"
+version = "0.2.87"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e128beba882dd1eb6200e1dc92ae6c5dbaa4311aa7bb211ca035779e5efc39f8"
+checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.18",
+ "syn 2.0.23",
  "wasm-bindgen-backend",
  "wasm-bindgen-shared",
 ]
 
 [[package]]
 name = "wasm-bindgen-shared"
-version = "0.2.86"
+version = "0.2.87"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed9d5b4305409d1fc9482fee2d7f9bcbf24b3972bf59817ef757e23982242a93"
+checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1"
 
 [[package]]
 name = "web-sys"
-version = "0.3.63"
+version = "0.3.64"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3bdd9ef4e984da1187bf8110c5cf5b845fbc87a23602cdf912386a76fcd3a7c2"
+checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b"
 dependencies = [
  "js-sys",
  "wasm-bindgen",
@@ -2894,16 +2944,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f"
 dependencies = [
- "windows-targets 0.48.0",
-]
-
-[[package]]
-name = "windows-sys"
-version = "0.45.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
-dependencies = [
- "windows-targets 0.42.2",
+ "windows-targets",
 ]
 
 [[package]]
@@ -2912,46 +2953,25 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
 dependencies = [
- "windows-targets 0.48.0",
+ "windows-targets",
 ]
 
 [[package]]
 name = "windows-targets"
-version = "0.42.2"
+version = "0.48.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
+checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f"
 dependencies = [
- "windows_aarch64_gnullvm 0.42.2",
- "windows_aarch64_msvc 0.42.2",
- "windows_i686_gnu 0.42.2",
- "windows_i686_msvc 0.42.2",
- "windows_x86_64_gnu 0.42.2",
- "windows_x86_64_gnullvm 0.42.2",
- "windows_x86_64_msvc 0.42.2",
+ "windows_aarch64_gnullvm",
+ "windows_aarch64_msvc",
+ "windows_i686_gnu",
+ "windows_i686_msvc",
+ "windows_x86_64_gnu",
+ "windows_x86_64_gnullvm",
+ "windows_x86_64_msvc",
 ]
 
 [[package]]
-name = "windows-targets"
-version = "0.48.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5"
-dependencies = [
- "windows_aarch64_gnullvm 0.48.0",
- "windows_aarch64_msvc 0.48.0",
- "windows_i686_gnu 0.48.0",
- "windows_i686_msvc 0.48.0",
- "windows_x86_64_gnu 0.48.0",
- "windows_x86_64_gnullvm 0.48.0",
- "windows_x86_64_msvc 0.48.0",
-]
-
-[[package]]
-name = "windows_aarch64_gnullvm"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
-
-[[package]]
 name = "windows_aarch64_gnullvm"
 version = "0.48.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2959,81 +2979,45 @@
 
 [[package]]
 name = "windows_aarch64_msvc"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
-
-[[package]]
-name = "windows_aarch64_msvc"
 version = "0.48.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
 
 [[package]]
 name = "windows_i686_gnu"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
-
-[[package]]
-name = "windows_i686_gnu"
 version = "0.48.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
 
 [[package]]
 name = "windows_i686_msvc"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
-
-[[package]]
-name = "windows_i686_msvc"
 version = "0.48.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
 
 [[package]]
 name = "windows_x86_64_gnu"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
-
-[[package]]
-name = "windows_x86_64_gnu"
 version = "0.48.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1"
 
 [[package]]
 name = "windows_x86_64_gnullvm"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
-
-[[package]]
-name = "windows_x86_64_gnullvm"
 version = "0.48.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
 
 [[package]]
 name = "windows_x86_64_msvc"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
-
-[[package]]
-name = "windows_x86_64_msvc"
 version = "0.48.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
 
 [[package]]
 name = "winnow"
-version = "0.4.6"
+version = "0.4.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "61de7bac303dc551fe038e2b3cef0f571087a47571ea6e79a87692ac99b99699"
+checksum = "ca0ace3845f0d96209f0375e6d367e3eb87eb65d27d445bdc9f1843a26f39448"
 dependencies = [
  "memchr",
 ]
diff --git a/config/build.config.toml b/config/build.config.toml
index e4f3c33..ecb392d 100644
--- a/config/build.config.toml
+++ b/config/build.config.toml
@@ -35,19 +35,9 @@
 # Validity in seconds for a remote attestation report and endorsed attested TLS config
 attestation_validity_secs = 3600
 
-# Specify accepted inbound services to enforce incoming connections via mutual
-# attestation. Below figure illustrates current topology of Teaclave services.
-#
-# clients => authentication <-+       +----> storage <----+
-#                             |       |                   |
-# clients => frontend ----------> management            scheduler <-- execution
-#                                     |
-#                                     +--> access_control
-#
-#                                                   =>      api endpoint connections
-#                                                   -> internal endpoint connections
+# Refer to docs/service-internals.md for the service topology
 [inbound]
-access_control = ["teaclave_management_service"]
+access_control = ["teaclave_frontend_service", "teaclave_management_service"]
 authentication = ["teaclave_frontend_service"]
 storage        = ["teaclave_management_service", "teaclave_scheduler_service"]
 management     = ["teaclave_frontend_service"]
diff --git a/docs/service-internals.md b/docs/service-internals.md
index 3743ba0..7124ece 100644
--- a/docs/service-internals.md
+++ b/docs/service-internals.md
@@ -128,8 +128,8 @@
 clients => authentication <-+       +----> storage <----+
                             |       |                   |
 clients => frontend ----------> management            scheduler <-- execution
-                                    |
-                                    +--> access_control
+             |                      |
+             +--> access_control <--+
 
 
                                                   =>      api endpoint connections
diff --git a/examples/rust/builtin_ordered_set_intersect/src/main.rs b/examples/rust/builtin_ordered_set_intersect/src/main.rs
index a55706c..d67c59b 100644
--- a/examples/rust/builtin_ordered_set_intersect/src/main.rs
+++ b/examples/rust/builtin_ordered_set_intersect/src/main.rs
@@ -215,10 +215,10 @@
 fn main() -> Result<()> {
     let mut admin = PlatformAdmin::new("admin", "teaclave")?;
     // Ignore registering errors
-    let _ = admin.register_user("user0", "password", "PlatformAdmin", "");
+    let _ = admin.register_user("user_dataowner", "password", "DataOwner", "")?;
     let _ = admin.register_user("user1", "password", "PlatformAdmin", "");
-    let user0_data = UserData {
-        user_id: "user0".to_string(),
+    let user_dataowner_data = UserData {
+        user_id: "user_dataowner".to_string(),
         user_password: "password".to_string(),
         input_url: "http://localhost:6789/fixtures/functions/ordered_set_intersect/psi0.txt.enc"
             .to_string(),
@@ -252,30 +252,33 @@
             0xdd, 0x66,
         ],
         key: vec![0; 16],
-        peer_id: "user0".to_string(),
+        peer_id: "user_dataowner".to_string(),
         peer_input_label: "input_data1".to_string(),
         peer_output_label: "output_result1".to_string(),
     };
 
-    let mut user0 = Client::new(user0_data)?;
+    let mut user_dataowner = Client::new(user_dataowner_data)?;
     let mut user1 = Client::new(user1_data)?;
 
-    let task_id = user0.set_task()?;
+    // dataowner does not have the privilege to register_function
+    assert!(user_dataowner.set_task().is_err());
 
-    user0.register_data(&task_id)?;
+    let task_id = user1.set_task()?;
+
+    user_dataowner.register_data(&task_id)?;
     user1.register_data(&task_id)?;
 
-    user0.approve_task(&task_id)?;
+    user_dataowner.approve_task(&task_id)?;
     user1.approve_task(&task_id)?;
 
-    user0.run_task(&task_id)?;
+    user1.run_task(&task_id)?;
 
-    let result_user0 = user0.get_task_result(&task_id)?;
+    let result_user_dataowner = user_dataowner.get_task_result(&task_id)?;
 
     println!(
-        "[+] User 0 result: {:?} log: {:?} ",
-        String::from_utf8(result_user0.0),
-        result_user0.1
+        "[+] User dataowner result: {:?} log: {:?} ",
+        String::from_utf8(result_user_dataowner.0),
+        result_user_dataowner.1
     );
 
     let result_user1 = user1.get_task_result(&task_id)?;
diff --git a/services/access_control/enclave/Cargo.toml b/services/access_control/enclave/Cargo.toml
index bbb2eb6..f025131 100644
--- a/services/access_control/enclave/Cargo.toml
+++ b/services/access_control/enclave/Cargo.toml
@@ -44,7 +44,9 @@
 
 [dependencies]
 anyhow     = { version = "1.0.26" }
+casbin     = { version = "2.0.9", default-features = false, features = ["runtime-teaclave", "incremental"] }
 cfg-if     = { version = "0.1.9" }
+csv        = { version = "1.2.2" }
 log        = { version = "0.4.17", features = ["release_max_level_info"] }
 serde      = { version = "1.0.92" }
 serde_json = { version = "1.0.39" }
diff --git a/services/access_control/enclave/src/acs.rs b/services/access_control/enclave/src/acs.rs
index aa02623..44127cd 100644
--- a/services/access_control/enclave/src/acs.rs
+++ b/services/access_control/enclave/src/acs.rs
@@ -15,336 +15,112 @@
 // specific language governing permissions and limitations
 // under the License.
 
-use anyhow::{anyhow, Result};
-use std::collections::HashSet;
-use std::ffi::CString;
-use std::os::raw::c_char;
-use std::sync::{Arc, Mutex};
+use anyhow::{bail, Result};
+use casbin::prelude::*;
+use csv::{ReaderBuilder, StringRecord};
 
-const MODEL_TEXT: &str = include_str!("../../model.conf");
-extern "C" {
-    fn acs_setup_model(model_text: *const c_char) -> i32;
-    fn acs_enforce_request(request_type: *const c_char, request_content: *const c_char) -> i32;
-}
-#[cfg(test_mode)]
-extern "C" {
-    fn acs_announce_fact(fact_type: *const c_char, fact_vals: *const c_char) -> i32;
+pub async fn init_memory_enforcer() -> Result<Enforcer> {
+    const MODEL_TEXT: &str = include_str!("../../model.conf");
+    const POLICY_TEXT: &str = include_str!("../../policy.csv");
+
+    let model = DefaultModel::from_str(MODEL_TEXT).await?;
+    let adapter = MemoryAdapter::default();
+    let mut enforcer = Enforcer::new(model, adapter).await?;
+
+    let (general, grouping) = parse_policy_str(POLICY_TEXT)?;
+    enforcer.add_policies(general).await?;
+    enforcer.add_grouping_policies(grouping).await?;
+
+    Ok(enforcer)
 }
 
-pub(crate) enum EnforceRequest {
-    // user_access_data = usr, data
-    UserAccessData(String, String),
-    // user_access_function = usr, function
-    UserAccessFunction(String, String),
-    // user_access_task= usr, task
-    UserAccessTask(String, String),
-    // task_access_function = task, function
-    TaskAccessFunction(String, String),
-    // task_access_data = task, data
-    TaskAccessData(String, String),
-}
+type Policy = Vec<String>;
 
-#[cfg(test_mode)]
-pub(crate) enum AccessControlTerms {
-    // data_owner = data, usr
-    DataOwner(String, String),
-    // function_owner = functoin, usr
-    FunctionOwner(String, String),
-    // is_public_function = function
-    IsPublicFunction(String),
-    // task_participant = task, usr
-    TaskParticipant(String, String),
-}
+/// Parse casbin polices in bytes to general and grouping policies
+fn parse_policy_str(polices: &str) -> Result<(Vec<Policy>, Vec<Policy>)> {
+    let mut general = Vec::new();
+    let mut grouping = Vec::new();
 
-pub trait PyMarshallable {
-    fn marshal(&self, buffer: &mut String);
-}
+    let mut rdr = ReaderBuilder::new()
+        .has_headers(false)
+        .from_reader(polices.as_bytes());
+    for result in rdr.records() {
+        let policy = result?;
+        let policy_type = policy.get(0);
 
-impl<T> PyMarshallable for (T,)
-where
-    T: PyMarshallable,
-{
-    fn marshal(&self, buffer: &mut String) {
-        buffer.push('[');
-        self.0.marshal(buffer);
-        buffer.push(']');
-    }
-}
-
-impl<U, V> PyMarshallable for (U, V)
-where
-    U: PyMarshallable,
-    V: PyMarshallable,
-{
-    fn marshal(&self, buffer: &mut String) {
-        buffer.push('[');
-        self.0.marshal(buffer);
-        buffer.push(',');
-        self.1.marshal(buffer);
-        buffer.push(']');
-    }
-}
-
-impl<X, Y, Z> PyMarshallable for (X, Y, Z)
-where
-    X: PyMarshallable,
-    Y: PyMarshallable,
-    Z: PyMarshallable,
-{
-    fn marshal(&self, buffer: &mut String) {
-        buffer.push('[');
-        self.0.marshal(buffer);
-        buffer.push(',');
-        self.1.marshal(buffer);
-        buffer.push(',');
-        self.2.marshal(buffer);
-        buffer.push(']');
-    }
-}
-
-impl<T> PyMarshallable for [T]
-where
-    T: PyMarshallable,
-{
-    fn marshal(&self, buffer: &mut String) {
-        buffer.push('[');
-        for t in self {
-            t.marshal(buffer);
-            buffer.push(',');
-        }
-        buffer.push(']');
-    }
-}
-
-impl<T: PyMarshallable> PyMarshallable for &HashSet<T> {
-    fn marshal(&self, buffer: &mut String) {
-        buffer.push_str("set([");
-        for t in *self {
-            t.marshal(buffer);
-            buffer.push(',');
-        }
-        buffer.push_str("])");
-    }
-}
-
-impl PyMarshallable for String {
-    fn marshal(&self, buffer: &mut String) {
-        buffer.push('\'');
-        buffer.push_str(self);
-        buffer.push('\'');
-    }
-}
-
-impl PyMarshallable for &String {
-    fn marshal(&self, buffer: &mut String) {
-        buffer.push('\'');
-        buffer.push_str(self);
-        buffer.push('\'');
-    }
-}
-
-#[cfg(test_mode)]
-pub(crate) fn init_mock_data() -> Result<()> {
-    // mock data for AuthorizeData
-    let term = AccessControlTerms::DataOwner("mock_data".to_string(), "mock_user_a".to_string());
-    announce_fact(term)?;
-    let term = AccessControlTerms::DataOwner("mock_data".to_string(), "mock_user_b".to_string());
-    announce_fact(term)?;
-    let term = AccessControlTerms::DataOwner("mock_data".to_string(), "mock_user_c".to_string());
-    announce_fact(term)?;
-
-    // mock data for AuthorizeFunction
-    let term = AccessControlTerms::FunctionOwner(
-        "mock_private_function".to_string(),
-        "mock_private_function_owner".to_string(),
-    );
-    announce_fact(term)?;
-    let term = AccessControlTerms::FunctionOwner(
-        "mock_public_function".to_string(),
-        "mock_public_function_owner".to_string(),
-    );
-    announce_fact(term)?;
-    let term = AccessControlTerms::IsPublicFunction("mock_public_function".to_string());
-    announce_fact(term)?;
-
-    // mock data for AuthorizeTask
-    let term = AccessControlTerms::TaskParticipant(
-        "mock_task".to_string(),
-        "mock_participant_a".to_string(),
-    );
-    announce_fact(term)?;
-    let term = AccessControlTerms::TaskParticipant(
-        "mock_task".to_string(),
-        "mock_participant_b".to_string(),
-    );
-    announce_fact(term)?;
-
-    // mock data for AuthorizeStagedTask
-    let term = AccessControlTerms::TaskParticipant(
-        "mock_staged_task".to_string(),
-        "mock_staged_participant_a".to_string(),
-    );
-    announce_fact(term)?;
-    let term = AccessControlTerms::TaskParticipant(
-        "mock_staged_task".to_string(),
-        "mock_staged_participant_b".to_string(),
-    );
-    announce_fact(term)?;
-    let term = AccessControlTerms::FunctionOwner(
-        "mock_staged_allowed_private_function".to_string(),
-        "mock_staged_participant_a".to_string(),
-    );
-    announce_fact(term)?;
-    let term = AccessControlTerms::FunctionOwner(
-        "mock_staged_disallowed_private_function".to_string(),
-        "mock_staged_non_participant".to_string(),
-    );
-    announce_fact(term)?;
-    let term = AccessControlTerms::IsPublicFunction("mock_staged_public_function".to_string());
-    announce_fact(term)?;
-
-    let term = AccessControlTerms::DataOwner(
-        "mock_staged_allowed_data1".to_string(),
-        "mock_staged_participant_a".to_string(),
-    );
-    announce_fact(term)?;
-    let term = AccessControlTerms::DataOwner(
-        "mock_staged_allowed_data2".to_string(),
-        "mock_staged_participant_b".to_string(),
-    );
-    announce_fact(term)?;
-    let term = AccessControlTerms::DataOwner(
-        "mock_staged_allowed_data3".to_string(),
-        "mock_staged_participant_a".to_string(),
-    );
-    announce_fact(term)?;
-    let term = AccessControlTerms::DataOwner(
-        "mock_staged_allowed_data3".to_string(),
-        "mock_staged_participant_b".to_string(),
-    );
-    announce_fact(term)?;
-
-    let term = AccessControlTerms::DataOwner(
-        "mock_staged_disallowed_data1".to_string(),
-        "mock_staged_non_participant".to_string(),
-    );
-    announce_fact(term)?;
-    let term = AccessControlTerms::DataOwner(
-        "mock_staged_disallowed_data2".to_string(),
-        "mock_staged_participant_a".to_string(),
-    );
-    announce_fact(term)?;
-    let term = AccessControlTerms::DataOwner(
-        "mock_staged_disallowed_data2".to_string(),
-        "mock_staged_non_participant".to_string(),
-    );
-    announce_fact(term)?;
-
-    Ok(())
-}
-
-#[derive(Clone)]
-pub(crate) struct AccessControlModule {
-    lock: Arc<Mutex<u32>>,
-}
-
-impl AccessControlModule {
-    pub(crate) fn new() -> Self {
-        AccessControlModule {
-            lock: Arc::new(Mutex::new(0)),
-        }
-    }
-
-    pub(crate) fn enforce_request(&self, request: EnforceRequest) -> Result<bool> {
-        let (request_type, request_content) = match request {
-            EnforceRequest::UserAccessData(usr, data) => {
-                let mut buffer = String::new();
-                (usr, data).marshal(&mut buffer);
-                ("user_access_data", buffer)
+        match policy_type {
+            Some("p") => {
+                let rule = strip_first_element(policy);
+                general.push(rule);
             }
-            EnforceRequest::UserAccessFunction(usr, function) => {
-                let mut buffer = String::new();
-                (usr, function).marshal(&mut buffer);
-                ("user_access_function", buffer)
+            Some("g") => {
+                let rule = strip_first_element(policy);
+                grouping.push(rule);
             }
-            EnforceRequest::UserAccessTask(usr, task) => {
-                let mut buffer = String::new();
-                (usr, task).marshal(&mut buffer);
-                ("user_access_task", buffer)
-            }
-            EnforceRequest::TaskAccessFunction(task, function) => {
-                let mut buffer = String::new();
-                (task, function).marshal(&mut buffer);
-                ("task_access_function", buffer)
-            }
-            EnforceRequest::TaskAccessData(task, data) => {
-                let mut buffer = String::new();
-                (task, data).marshal(&mut buffer);
-                ("task_access_data", buffer)
-            }
-        };
-
-        let c_request_type = CString::new(request_type.to_string())?;
-        let c_request_content = CString::new(request_content)?;
-        let _lock = self
-            .lock
-            .lock()
-            .map_err(|_| anyhow!("failed to accquire lock"))?;
-        let py_ret =
-            unsafe { acs_enforce_request(c_request_type.as_ptr(), c_request_content.as_ptr()) };
-
-        match py_ret {
-            0 => Ok(false),
-            1 => Ok(true),
-            _ => Err(anyhow!("mesapy error")),
+            _ => bail!("invalid policy type: {:?}", policy_type),
         }
     }
-}
-pub(crate) fn init_acs() -> Result<()> {
-    let model_conf = CString::new(MODEL_TEXT).unwrap();
-    let ec = unsafe { acs_setup_model(model_conf.as_ptr()) };
 
-    if ec != 0 {
-        Err(anyhow!("failed to init mesapy"))
-    } else {
-        #[cfg(test_mode)]
-        init_mock_data()?;
-        Ok(())
-    }
+    Ok((general, grouping))
 }
 
-#[cfg(test_mode)]
-fn announce_fact(term: AccessControlTerms) -> Result<()> {
-    let (term_type, term_fact) = match term {
-        AccessControlTerms::DataOwner(data, usr) => {
-            let mut buffer = String::new();
-            (data, usr).marshal(&mut buffer);
-            ("data_owner", buffer)
-        }
-        AccessControlTerms::FunctionOwner(function, usr) => {
-            let mut buffer = String::new();
-            (function, usr).marshal(&mut buffer);
-            ("function_owner", buffer)
-        }
-        AccessControlTerms::IsPublicFunction(function) => {
-            let mut buffer = String::new();
-            (function,).marshal(&mut buffer);
-            ("is_public_function", buffer)
-        }
-        AccessControlTerms::TaskParticipant(task, usr) => {
-            let mut buffer = String::new();
-            (task, usr).marshal(&mut buffer);
-            ("task_participant", buffer)
-        }
-    };
-    let c_term_type = CString::new(term_type.to_string())?;
-    let c_term_fact = CString::new(term_fact)?;
+fn strip_first_element(record: StringRecord) -> Vec<String> {
+    record
+        .into_iter()
+        .skip(1)
+        .map(|s| s.trim().to_owned())
+        .collect()
+}
 
-    let py_ret = unsafe { acs_announce_fact(c_term_type.as_ptr(), c_term_fact.as_ptr()) };
+#[cfg(feature = "enclave_unit_test")]
+pub mod tests {
+    use super::*;
 
-    if py_ret != 0 {
-        Err(anyhow!("mesapy error"))
-    } else {
-        Ok(())
+    pub async fn test_access_api() {
+        let e = init_memory_enforcer().await.unwrap();
+
+        assert!(e.enforce(("PlatformAdmin", "arbitrary_api")).unwrap());
+        assert!(e.enforce(("PlatformAdmin", "query_audit_logs")).unwrap());
+
+        assert!(!e.enforce(("Invalid", "register_function")).unwrap());
+        assert!(!e.enforce(("Invalid", "register_input_file")).unwrap());
+        assert!(!e.enforce(("Invalid", "get_function")).unwrap());
+        assert!(!e.enforce(("Invalid", "query_audit_logs")).unwrap());
+
+        assert!(e.enforce(("FunctionOwner", "register_function")).unwrap());
+        assert!(e.enforce(("FunctionOwner", "update_function")).unwrap());
+        assert!(e.enforce(("FunctionOwner", "delete_function")).unwrap());
+        assert!(e.enforce(("FunctionOwner", "disable_function")).unwrap());
+        assert!(e.enforce(("FunctionOwner", "get_function")).unwrap());
+        assert!(e.enforce(("FunctionOwner", "list_functions")).unwrap());
+        assert!(e
+            .enforce(("FunctionOwner", "get_function_usage_stats"))
+            .unwrap());
+        assert!(!e.enforce(("FunctionOwner", "get_task")).unwrap());
+        assert!(!e.enforce(("FunctionOwner", "query_audit_logs")).unwrap());
+
+        assert!(e.enforce(("DataOwner", "register_input_file")).unwrap());
+        assert!(e.enforce(("DataOwner", "register_output_file")).unwrap());
+        assert!(e.enforce(("DataOwner", "update_input_file")).unwrap());
+        assert!(e.enforce(("DataOwner", "update_output_file")).unwrap());
+        assert!(e.enforce(("DataOwner", "register_fusion_output")).unwrap());
+        assert!(e
+            .enforce(("DataOwner", "register_input_from_output"))
+            .unwrap());
+        assert!(e.enforce(("DataOwner", "get_input_file")).unwrap());
+        assert!(e.enforce(("DataOwner", "get_output_file")).unwrap());
+        assert!(e.enforce(("DataOwner", "create_task")).unwrap());
+        assert!(e.enforce(("DataOwnerManager", "get_task")).unwrap());
+        assert!(e.enforce(("DataOwnerManager", "assign_data")).unwrap());
+        assert!(e.enforce(("DataOwnerManager", "approve_task")).unwrap());
+        assert!(e.enforce(("DataOwnerManager", "invoke_task")).unwrap());
+        assert!(e.enforce(("DataOwnerManager", "cancel_task")).unwrap());
+        assert!(e.enforce(("DataOwnerManager", "get_function")).unwrap());
+        assert!(e.enforce(("DataOwnerManager", "list_functions")).unwrap());
+        assert!(e
+            .enforce(("DataOwnerManager", "get_function_usage_stats"))
+            .unwrap());
+        assert!(!e.enforce(("DataOwner", "register_function")).unwrap());
+        assert!(!e.enforce(("DataOwnerManager", "query_audit_logs")).unwrap());
     }
 }
diff --git a/services/access_control/enclave/src/lib.rs b/services/access_control/enclave/src/lib.rs
index 056e713..8809780 100644
--- a/services/access_control/enclave/src/lib.rs
+++ b/services/access_control/enclave/src/lib.rs
@@ -43,12 +43,16 @@
 const N_WORKERS: usize = 8;
 
 async fn start_service(config: &RuntimeConfig) -> Result<()> {
+    info!("Starting Access control...");
+
     let listen_address = config.internal_endpoints.access_control.listen_address;
     let attestation_config = AttestationConfig::from_teaclave_config(config)?;
     let attested_tls_config = RemoteAttestation::new(attestation_config)
         .generate_and_endorse()?
         .attested_tls_config()
         .ok_or_else(|| anyhow!("cannot get attested TLS config"))?;
+    info!(" Starting Access control: Self attestation finished ...");
+
     let enclave_info = EnclaveInfo::verify_and_new(
         &config.audit.enclave_info_bytes,
         AUDITOR_PUBLIC_KEYS,
@@ -69,10 +73,11 @@
             verifier::universal_quote_verifier,
         )?
         .into();
-    acs::init_acs()?;
+    info!(" Starting Access control: Server config setup finished ...");
 
-    let service = service::TeaclaveAccessControlService::new();
+    let service = service::TeaclaveAccessControlService::new().await;
 
+    info!("Starting Access control: start listening ...");
     Server::builder()
         .tls_config(server_config)
         .map_err(|_| anyhow::anyhow!("TeaclaveFrontendServer tls config error"))?
@@ -125,15 +130,6 @@
     use teaclave_test_utils::*;
 
     pub fn run_tests() -> bool {
-        if crate::acs::init_acs().is_err() {
-            return false;
-        }
-        run_async_tests!(
-            service::tests::user_access_data,
-            service::tests::user_access_function,
-            service::tests::user_access_task,
-            service::tests::task_access_function,
-            service::tests::task_access_data,
-        )
+        run_async_tests!(acs::tests::test_access_api,)
     }
 }
diff --git a/services/access_control/enclave/src/service.rs b/services/access_control/enclave/src/service.rs
index b733ddd..f89e3cb 100644
--- a/services/access_control/enclave/src/service.rs
+++ b/services/access_control/enclave/src/service.rs
@@ -15,292 +15,41 @@
 // specific language governing permissions and limitations
 // under the License.
 
-use crate::acs::{AccessControlModule, EnforceRequest};
+use crate::acs::init_memory_enforcer;
 use crate::error::TeaclavAccessControlError;
-use teaclave_proto::teaclave_access_control_service::{
-    AuthorizeDataRequest, AuthorizeDataResponse, AuthorizeFunctionRequest,
-    AuthorizeFunctionResponse, AuthorizeStagedTaskRequest, AuthorizeStagedTaskResponse,
-    AuthorizeTaskRequest, AuthorizeTaskResponse, TeaclaveAccessControl,
-};
+use teaclave_proto::teaclave_access_control_service::*;
 use teaclave_rpc::{Request, Response};
-use teaclave_service_enclave_utils::bail;
 use teaclave_types::TeaclaveServiceResponseResult;
 
+use std::sync::{Arc, RwLock};
+
+use casbin::{CoreApi, Enforcer};
+
 #[derive(Clone)]
 pub(crate) struct TeaclaveAccessControlService {
-    access_control_module: AccessControlModule,
+    api_enforcer: Arc<RwLock<Enforcer>>,
 }
 
 impl TeaclaveAccessControlService {
-    pub(crate) fn new() -> Self {
-        TeaclaveAccessControlService {
-            access_control_module: AccessControlModule::new(),
-        }
+    pub(crate) async fn new() -> Self {
+        let api_enforcer = Arc::new(RwLock::new(init_memory_enforcer().await.unwrap()));
+        TeaclaveAccessControlService { api_enforcer }
     }
 }
 
 #[teaclave_rpc::async_trait]
 impl TeaclaveAccessControl for TeaclaveAccessControlService {
-    async fn authorize_data(
+    async fn authorize_api(
         &self,
-        request: Request<AuthorizeDataRequest>,
-    ) -> TeaclaveServiceResponseResult<AuthorizeDataResponse> {
+        request: Request<AuthorizeApiRequest>,
+    ) -> TeaclaveServiceResponseResult<AuthorizeApiResponse> {
+        let e = self.api_enforcer.read().unwrap();
         let request = request.into_inner();
-        let request =
-            EnforceRequest::UserAccessData(request.subject_user_id, request.object_data_id);
-        match self.access_control_module.enforce_request(request) {
-            Ok(accept) => {
-                let response = AuthorizeDataResponse::new(accept);
-                Ok(Response::new(response))
-            }
-            Err(_) => Err(TeaclavAccessControlError::AccessControlError.into()),
-        }
-    }
 
-    async fn authorize_function(
-        &self,
-        request: Request<AuthorizeFunctionRequest>,
-    ) -> TeaclaveServiceResponseResult<AuthorizeFunctionResponse> {
-        let request = request.into_inner();
-        let request =
-            EnforceRequest::UserAccessFunction(request.subject_user_id, request.object_function_id);
-        match self.access_control_module.enforce_request(request) {
-            Ok(accept) => {
-                let response = AuthorizeFunctionResponse::new(accept);
-                Ok(Response::new(response))
-            }
-            Err(_) => Err(TeaclavAccessControlError::AccessControlError.into()),
-        }
-    }
+        let accept = e
+            .enforce((request.user_role, request.api))
+            .map_err(|_| TeaclavAccessControlError::AccessControlError)?;
 
-    async fn authorize_task(
-        &self,
-        request: Request<AuthorizeTaskRequest>,
-    ) -> TeaclaveServiceResponseResult<AuthorizeTaskResponse> {
-        let request = request.into_inner();
-        let request =
-            EnforceRequest::UserAccessTask(request.subject_user_id, request.object_task_id);
-        match self.access_control_module.enforce_request(request) {
-            Ok(accept) => {
-                let response = AuthorizeTaskResponse::new(accept);
-                Ok(Response::new(response))
-            }
-            Err(_) => Err(TeaclavAccessControlError::AccessControlError.into()),
-        }
-    }
-
-    async fn authorize_staged_task(
-        &self,
-        request: Request<AuthorizeStagedTaskRequest>,
-    ) -> TeaclaveServiceResponseResult<AuthorizeStagedTaskResponse> {
-        let request = request.into_inner();
-        let enforce_access_function_request = EnforceRequest::TaskAccessFunction(
-            request.subject_task_id.clone(),
-            request.object_function_id,
-        );
-        match self
-            .access_control_module
-            .enforce_request(enforce_access_function_request)
-        {
-            Ok(accept) => {
-                if !accept {
-                    return Ok(Response::new(AuthorizeStagedTaskResponse::new(false)));
-                }
-            }
-            Err(_) => bail!(TeaclavAccessControlError::AccessControlError),
-        }
-        for object_data_id in request.object_input_data_id_list.iter() {
-            let enforce_access_data_request = EnforceRequest::TaskAccessData(
-                request.subject_task_id.clone(),
-                object_data_id.to_string(),
-            );
-            match self
-                .access_control_module
-                .enforce_request(enforce_access_data_request)
-            {
-                Ok(accept) => {
-                    if !accept {
-                        return Ok(Response::new(AuthorizeStagedTaskResponse::new(false)));
-                    }
-                }
-                Err(_) => bail!(TeaclavAccessControlError::AccessControlError),
-            }
-        }
-        for object_data_id in request.object_output_data_id_list.iter() {
-            let enforce_access_data_request = EnforceRequest::TaskAccessData(
-                request.subject_task_id.clone(),
-                object_data_id.to_string(),
-            );
-            match self
-                .access_control_module
-                .enforce_request(enforce_access_data_request)
-            {
-                Ok(accept) => {
-                    if !accept {
-                        return Ok(Response::new(AuthorizeStagedTaskResponse::new(false)));
-                    }
-                }
-                Err(_) => bail!(TeaclavAccessControlError::AccessControlError),
-            }
-        }
-        Ok(Response::new(AuthorizeStagedTaskResponse { accept: true }))
-    }
-}
-
-#[cfg(feature = "enclave_unit_test")]
-pub mod tests {
-    use super::*;
-    use teaclave_rpc::IntoRequest;
-
-    pub async fn user_access_data() {
-        let service = TeaclaveAccessControlService::new();
-        let request = AuthorizeDataRequest::new("mock_user_a", "mock_data").into_request();
-        let response = service.authorize_data(request).await;
-        assert!(response.is_ok());
-        assert!(response.unwrap().into_inner().accept);
-
-        let request = AuthorizeDataRequest::new("mock_user_b", "mock_data").into_request();
-        let response = service.authorize_data(request).await;
-        assert!(response.is_ok());
-        assert!(response.unwrap().into_inner().accept);
-
-        let request = AuthorizeDataRequest::new("mock_user_c", "mock_data").into_request();
-        let response = service.authorize_data(request).await;
-        assert!(response.is_ok());
-        assert!(response.unwrap().into_inner().accept);
-
-        let request = AuthorizeDataRequest::new("mock_user_d", "mock_data").into_request();
-        let response = service.authorize_data(request).await;
-        assert!(response.is_ok());
-        assert!(!response.unwrap().into_inner().accept);
-
-        let request = AuthorizeDataRequest::new("mock_user_a", "mock_data_b").into_request();
-        let response = service.authorize_data(request).await;
-        assert!(response.is_ok());
-        assert!(!response.unwrap().into_inner().accept);
-    }
-
-    pub async fn user_access_function() {
-        let service = TeaclaveAccessControlService::new();
-        let request =
-            AuthorizeFunctionRequest::new("mock_public_function_owner", "mock_public_function")
-                .into_request();
-        let response = service.authorize_function(request).await;
-        assert!(response.is_ok());
-        assert!(response.unwrap().into_inner().accept);
-        let request =
-            AuthorizeFunctionRequest::new("mock_private_function_owner", "mock_private_function")
-                .into_request();
-        let response = service.authorize_function(request).await;
-        assert!(response.is_ok());
-        assert!(response.unwrap().into_inner().accept);
-
-        let request =
-            AuthorizeFunctionRequest::new("mock_private_function_owner", "mock_public_function")
-                .into_request();
-        let response = service.authorize_function(request).await;
-        assert!(response.is_ok());
-        assert!(response.unwrap().into_inner().accept);
-
-        let request =
-            AuthorizeFunctionRequest::new("mock_public_function_owner", "mock_private_function")
-                .into_request();
-        let response = service.authorize_function(request).await;
-        assert!(response.is_ok());
-        assert!(!response.unwrap().into_inner().accept);
-    }
-
-    pub async fn user_access_task() {
-        let service = TeaclaveAccessControlService::new();
-        let request = AuthorizeTaskRequest::new("mock_participant_a", "mock_task").into_request();
-        let response = service.authorize_task(request).await;
-        assert!(response.is_ok());
-        assert!(response.unwrap().into_inner().accept);
-
-        let request = AuthorizeTaskRequest::new("mock_participant_b", "mock_task").into_request();
-        let response = service.authorize_task(request).await;
-        assert!(response.is_ok());
-        assert!(response.unwrap().into_inner().accept);
-
-        let request = AuthorizeTaskRequest::new("mock_participant_c", "mock_task").into_request();
-        let response = service.authorize_task(request).await;
-        assert!(response.is_ok());
-        assert!(!response.unwrap().into_inner().accept);
-    }
-
-    pub async fn task_access_function() {
-        let service = TeaclaveAccessControlService::new();
-        let mut request = get_correct_authorized_stage_task_req();
-        request.object_function_id = "mock_staged_allowed_private_function".to_string();
-        let response = service.authorize_staged_task(request.into_request()).await;
-        assert!(response.is_ok());
-        assert!(response.unwrap().into_inner().accept);
-
-        let mut request = get_correct_authorized_stage_task_req();
-        request.object_function_id = "mock_staged_public_function".to_string();
-        let response = service.authorize_staged_task(request.into_request()).await;
-        assert!(response.is_ok());
-        assert!(response.unwrap().into_inner().accept);
-
-        let mut request = get_correct_authorized_stage_task_req();
-        request.object_function_id = "mock_staged_disallowed_private_function".to_string();
-        let response = service.authorize_staged_task(request.into_request()).await;
-        assert!(response.is_ok());
-        assert!(!response.unwrap().into_inner().accept);
-    }
-
-    fn get_correct_authorized_stage_task_req() -> AuthorizeStagedTaskRequest {
-        AuthorizeStagedTaskRequest {
-            subject_task_id: "mock_staged_task".to_string(),
-            object_function_id: "mock_staged_allowed_private_function".to_string(),
-            object_input_data_id_list: vec![
-                "mock_staged_allowed_data1".to_string(),
-                "mock_staged_allowed_data2".to_string(),
-                "mock_staged_allowed_data3".to_string(),
-            ],
-            object_output_data_id_list: vec![
-                "mock_staged_allowed_data1".to_string(),
-                "mock_staged_allowed_data2".to_string(),
-                "mock_staged_allowed_data3".to_string(),
-            ],
-        }
-    }
-
-    pub async fn task_access_data() {
-        let service = TeaclaveAccessControlService::new();
-        let request = get_correct_authorized_stage_task_req().into_request();
-        let response = service.authorize_staged_task(request).await;
-        assert!(response.is_ok());
-        assert!(response.unwrap().into_inner().accept);
-        let mut request = get_correct_authorized_stage_task_req();
-        request
-            .object_input_data_id_list
-            .push("mock_staged_disallowed_data1".to_string());
-        let response = service.authorize_staged_task(request.into_request()).await;
-        assert!(response.is_ok());
-        assert!(!response.unwrap().into_inner().accept);
-        let mut request = get_correct_authorized_stage_task_req();
-        request
-            .object_input_data_id_list
-            .push("mock_staged_disallowed_data2".to_string());
-        let response = service.authorize_staged_task(request.into_request()).await;
-        assert!(response.is_ok());
-        assert!(!response.unwrap().into_inner().accept);
-
-        let mut request = get_correct_authorized_stage_task_req();
-        request
-            .object_output_data_id_list
-            .push("mock_staged_disallowed_data1".to_string());
-        let response = service.authorize_staged_task(request.into_request()).await;
-        assert!(response.is_ok());
-        assert!(!response.unwrap().into_inner().accept);
-
-        let mut request = get_correct_authorized_stage_task_req();
-        request
-            .object_output_data_id_list
-            .push("mock_staged_disallowed_data2".to_string());
-        let response = service.authorize_staged_task(request.into_request()).await;
-        assert!(response.is_ok());
-        assert!(!response.unwrap().into_inner().accept);
+        Ok(Response::new(AuthorizeApiResponse { accept }))
     }
 }
diff --git a/services/access_control/model.conf b/services/access_control/model.conf
index d05e8d1..4863b23 100644
--- a/services/access_control/model.conf
+++ b/services/access_control/model.conf
@@ -1,28 +1,14 @@
-[requests]
-user_access_data = usr, data
-user_access_function = usr, function
-user_access_task = usr, task
+[request_definition]
+r = sub, act
 
-task_access_function = task, function
-task_access_data = task, data
+[role_definition]
+g = _, _
 
-[terms]
-data_owner = data, usr
-function_owner = function, usr
-is_public_function = function
-task_participant = task, usr
+[policy_definition]
+p = sub, act
+
+[policy_effect]
+e = some(where (p.eft == allow))
 
 [matchers]
-user_access_data = data_owner(user_access_data.data, user_access_data.usr)
-
-user_access_function = \
-    is_public_function(user_access_function.function) or \
-    function_owner(user_access_function.function, user_access_function.usr)
-
-user_access_task = task_participant(user_access_task.task, user_access_task.usr)
-
-task_access_function = \
-    is_public_function(task_access_function.function) or \
-    function_owner(task_access_function.function, _) <= task_participant(task_access_function.task, _)
-
-task_access_data = data_owner(task_access_data.data, _) <= task_participant(task_access_data.task, _)
\ No newline at end of file
+m = g(r.sub, p.sub) && r.act == p.act || r.sub == "PlatformAdmin"
diff --git a/services/access_control/policy.csv b/services/access_control/policy.csv
new file mode 100644
index 0000000..669e1a3
--- /dev/null
+++ b/services/access_control/policy.csv
@@ -0,0 +1,28 @@
+p,rule_function_owner,register_function
+p,rule_function_owner,update_function
+p,rule_function_owner,delete_function
+p,rule_function_owner,disable_function
+p,rule_function_owner,get_function 
+p,rule_function_owner,list_functions
+p,rule_function_owner,get_function_usage_stats
+p,rule_data_owner,register_input_file
+p,rule_data_owner,register_output_file
+p,rule_data_owner,update_input_file
+p,rule_data_owner,update_output_file
+p,rule_data_owner,register_fusion_output
+p,rule_data_owner,register_input_from_output
+p,rule_data_owner,get_output_file
+p,rule_data_owner,get_input_file
+p,rule_data_owner,create_task
+p,rule_data_owner,get_task
+p,rule_data_owner,assign_data
+p,rule_data_owner,approve_task
+p,rule_data_owner,invoke_task
+p,rule_data_owner,cancel_task
+p,rule_data_owner,get_function
+p,rule_data_owner,list_functions
+p,rule_data_owner,get_function_usage_stats
+
+g,FunctionOwner,rule_function_owner
+g,DataOwnerManager,rule_data_owner
+g,DataOwner,rule_data_owner
diff --git a/services/access_control/python/acs_engine.py b/services/access_control/python/acs_engine.py
deleted file mode 100644
index d79fa4f..0000000
--- a/services/access_control/python/acs_engine.py
+++ /dev/null
@@ -1,648 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-###############################################################################
-# Parser Combinators
-###############################################################################
-class Pair(tuple):
-    def __new__(cls, a, b):
-        return super(Pair, cls).__new__(cls, [a, b])
-
-class Either(object):
-    def __init__(self, left, right):
-        self.__left = left
-        self.__right = right
-
-    def left(self):
-        if not self.is_left():
-            raise ValueError('wrong extractor for either')
-        return self.__left
-
-    def right(self):
-        if not self.is_right():
-            raise ValueError('wrong extractor for either')
-        return self.__right
-
-    def is_right(self):
-        return False
-
-    def is_left(self):
-        return False
-
-    def get(self):
-        if self.is_right():
-            return self.right()
-        if self.is_left():
-            return self.left()
-        raise ValueError('incomplete Either object')
-
-    def __str__(self):
-        if self.is_left():
-            return 'Left(' + str(self.left()) + ')'
-        else:
-            return 'Right(' + str(self.right()) + ')'
-
-    def __repr__(self):
-        if self.is_left():
-            return 'Left(' + repr(self.left()) + ')'
-        else:
-            return 'Right(' + repr(self.right()) + ')'
-
-class Left(Either):
-    def __init__(self, payload):
-        super(Left, self).__init__(payload, None)
-
-    def is_left(self):
-        return True
-
-class Right(Either):
-    def __init__(self, payload):
-        super(Right, self).__init__(None, payload)
-
-    def is_right(self):
-        return True
-
-class Stream(object):
-    WHITESPACES = [' ', '\t', '\r']
-    def __init__(self, items, pos = 0):
-        self.__items = items
-        self.__pos = pos
-
-    def accept_strlit(self, string):
-        # Typically parsers want to skip white spaces except line breaks
-        # In the future this should be configurable
-        pos = self.__pos
-        l = len(self.__items)
-        while pos < l and self.__items[pos] in self.WHITESPACES:
-            pos += 1
-
-        match_pos = 0
-        l = len(string)        
-        while match_pos < l and string[match_pos] in self.WHITESPACES:
-            match_pos += 1
-        if pos < match_pos:
-            raise ParsingError(self, 'expecting "{}"'.format(string))
-        if match_pos:
-            string = string[match_pos:]
-        if self.__items.startswith(string, pos):
-            return Stream(self.__items, pos + len(string))
-        raise ParsingError(self, 'expecting "{}"'.format(string))
-
-    def accept_matcher(self, matcher):
-        pos = self.__pos
-        l = len(self.__items)
-        while pos < l and self.__items[pos] in self.WHITESPACES:
-            pos += 1
-
-        res = matcher(self.__items, pos)
-        if res is None:
-            raise ParsingError(self, 'matcher for {} failed'.format(matcher.__doc__))
-        obj, npos = res
-        return obj, Stream(self.__items, npos)
-
-    def end(self):
-        return self.__pos == len(self.__items)
-
-    def pos(self):
-        return self.__pos
-
-    def __repr__(self):
-        line_start = self.__items.rfind('\n', 0, self.__pos) + 1
-        line_end = self.__items.find('\n', self.__pos)
-        if line_end == -1:
-            line_end = self.__pos
-
-        if line_end - line_start > 80:
-            line_start = max(line_start, self.__pos - 40)
-            line_end = min(line_start + 80, len(self.__items))
-
-        return ''.join([
-            self.__items[line_start:line_end],
-            '\n',
-            ' ' * (self.__pos - line_start),
-            '^',
-            ' ' * (line_end - self.__pos),
-            '\nerror at character ',
-            str(self.__pos),
-        ])
-
-class State(object):
-    def __init__(self, stream, payload = None, success = True):
-        self.stream = stream
-        self.payload = payload
-        self.success = success
-
-    def __bool__(self):
-        return self.success
-
-    def __nonzero__(self):
-        return self.__bool__()
-
-    def fmap(self, f):
-        if self:
-            return State(self.stream, f(self.payload))
-        return self
-
-class ParsingError(Exception):
-    def __init__(self, stream, msg = ''):
-        super(ParsingError, self).__init__(msg)
-        self.stream = stream
-
-    def __repr__(self):
-        return repr(self.stream)
-
-class Parser(object):
-    def __init__(self):
-        pass
-
-    def __call__(self, stream):
-        raise NotImplementedError("pure abstract parser cannot be called")
-
-    def parse_from(self, stream):
-        n_state = self(stream)
-        if not n_state:
-            raise ParsingError(n_state.stream, n_state.payload)
-        elif not n_state.stream.end():
-            raise ParsingError(n_state.stream, 'trailing unparsable input')
-        return n_state
-
-    def fail(self, exception):
-        return State(exception.stream, str(exception), False)
-
-    def ignore(self):
-        return Ignore(self)
-
-    def __or__(self, p):
-        return Or(self, p)
-
-    def __add__(self, p):
-        if isinstance(self, Ignore) and isinstance(p, Ignore):
-            return Ignore(Concat(self, p))
-        else:
-            return Concat(self, p)
-
-    def __invert__(self):
-        return Rep(self)
-
-    def __neg__(self):
-        return Optional(self)
-
-    def __pow__(self, f):
-        return Apply(self, f)
-
-class Optional(Parser):
-    def __init__(self, opt):
-        super(Optional, self).__init__()
-        self.__opt = opt
-
-    def __call__(self, stream):
-        n_state = self.__opt(stream)
-        if n_state:
-            return n_state.fmap(lambda x: Left(x))
-        return State(stream, Right(None))
-
-class StrLiteral(Parser):
-    def __init__(self, string):
-        super(StrLiteral, self).__init__()
-        self.__string = string
-
-    def __call__(self, stream):
-        if stream.end():
-            return self.fail(ParsingError(
-                stream, 'insufficient input, expecting {}'.format(self.__string))
-            )
-        try:
-            n_stream = stream.accept_strlit(self.__string)
-        except ParsingError as e:
-            return self.fail(e)
-
-        return State(n_stream, self.__string)
-
-class CustomMatcher(Parser):
-    def __init__(self, matcher):
-        super(CustomMatcher, self).__init__()
-        self.__matcher = matcher
-
-    def __call__(self, stream):
-        try:
-            res = stream.accept_matcher(self.__matcher)
-        except ParsingError as e:
-            return self.fail(e)
-
-        obj, n_stream = res
-        return State(n_stream, obj)
-
-class Concat(Parser):
-    def __init__(self, c1, c2):
-        super(Concat, self).__init__()
-        assert not isinstance(self, Ignore) or not isinstance(p, Ignore)
-        self.__first = c1
-        self.__second = c2
-
-    def __call__(self, stream):
-        n_state = self.__first(stream)
-        if not n_state:
-            return n_state
-        p1 = n_state.payload
-        n_state = self.__second(n_state.stream)
-        if not n_state:
-            return n_state
-        p2 = n_state.payload
-
-        if isinstance(self.__first, Ignore):
-            return State(n_state.stream, p2)
-        if isinstance(self.__second, Ignore):
-            return State(n_state.stream, p1)
-        # The construction of Concat ensures that at least
-        # one of this children is not Ignore
-        return State(n_state.stream, Pair(p1, p2))
-
-class Or(Parser):
-    def __init__(self, c1, c2):
-        super(Or, self).__init__()
-        self.__if = c1
-        self.__else = c2
-
-    def __call__(self, stream):
-        n_state = self.__if(stream)
-        if n_state:
-            return n_state.fmap(lambda x: Left(x))
-        n_state = self.__else(stream)
-        if n_state:
-            return n_state.fmap(lambda x: Right(x))
-        return n_state
-
-class Rep(Parser):
-    def __init__(self, c):
-        super(Rep, self).__init__()
-        self.__loop = c
-
-    def __call__(self, stream):
-        payload = []
-
-        n_state = self.__loop(stream)
-        if n_state:
-            payload.append(n_state.payload)
-            stream = n_state.stream
-            n_state = self(stream)
-            if n_state:
-                payload = payload + n_state.payload
-                stream = n_state.stream
-        return State(stream, payload)
-
-class Apply(Parser):
-    def __init__(self, base, f):
-        super(Apply, self).__init__()
-        self.__base = base
-        self.__trans = f
-
-    def __call__(self, stream):
-        return self.__base(stream).fmap(self.__trans)
-
-class Ignore(Parser):
-    def __init__(self, base):
-        super(Ignore, self).__init__()
-        self.__base = base
-
-    def __call__(self, stream):
-        return self.__base(stream)
-
-###############################################################################
-# Grammars for PERM model configuration 
-###############################################################################
-from operator import or_, add
-
-def extract(nested_or):
-    while isinstance(nested_or, Either):
-        nested_or = nested_or.left() if nested_or.is_left() else nested_or.right()
-    return nested_or
-
-def flatten(nested_concat):
-    res = []
-
-    def pre_order(pair, res):
-        if isinstance(pair, Pair):
-            pre_order(pair[0], res)
-            pre_order(pair[1], res)
-        else:
-            res.append(pair)
-
-    pre_order(nested_concat, res)
-    return res
-
-def one_of(parsers):
-    nested = reduce(or_, parsers)
-    return nested ** extract
-
-def join(sl):
-    return ''.join(sl)
-
-def rep_with_sep(to_rep, sep):
-    if not isinstance(sep, Ignore):
-        sep = sep.ignore()
-    r = to_rep + ~(sep + to_rep)
-    r = r ** (lambda x: [x[0]] + x[1])
-    return r
-
-ALPHA = set('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
-DIGIT = set('0123456789')
-ALPHA_DIGIT = ALPHA | DIGIT
-
-Alpha = one_of(map(StrLiteral, ALPHA))
-Digit = one_of(map(StrLiteral, DIGIT))
-
-Equal, Comma, Dot = [StrLiteral(c).ignore() for c in ['=', ',', '.']]
-Underscore = StrLiteral('_')
-NewLine = (~ StrLiteral('\n')).ignore()
-
-def identifier_matcher(text, pos):
-    """identifier"""
-    end = len(text)
-    start = pos
-    if pos >= end:
-        return None
-    first = text[pos]
-    if first != '_' and first not in ALPHA:
-        return None
-    pos += 1
-    while pos < end:
-        char = text[pos]
-        if char == '_' or char in ALPHA_DIGIT:
-            pos += 1
-        else:
-            break
-    return text[start:pos], pos
-
-Identifier = CustomMatcher(identifier_matcher)
-
-IdTuple = rep_with_sep(Identifier, Comma)
-
-Definition = Identifier + Equal + IdTuple + NewLine
-
-Relation = Identifier + Equal + IdTuple + NewLine
-Relation = Relation ** (lambda x: (x[0], 1 + len(x[1][1])))
-
-def pyparser_matcher(text, pos):
-    """syntactically correct python code"""
-    line_end = text.find('\n', pos)
-    if line_end == -1:
-        return None
-    try:
-        c = compile(text[pos:line_end], '__abac_model__.py', 'eval')
-    except SyntaxError:
-        return None
-    return c, line_end
-
-PyExpr = CustomMatcher(pyparser_matcher)
-Matcher = Identifier + Equal + PyExpr + NewLine
-
-RequestDefHeader = StrLiteral('[requests]') + NewLine
-TermDefHeader    = StrLiteral('[terms]') + NewLine
-MatchersHeader   = StrLiteral('[matchers]') + NewLine
-
-RequestDefSec = RequestDefHeader.ignore() + ~Definition
-TermDefSec = TermDefHeader.ignore() + ~Definition
-MatchersSec = MatchersHeader.ignore() + ~Matcher
-
-ModelDef = (RequestDefSec + TermDefSec + MatchersSec) ** flatten
-
-def preprocess(conf):
-    # process escaped line breaks
-    conf = conf.replace('\\\n', '')
-    # remove comments    
-    conf = '\n'.join(line.partition('#')[0] for line in conf.splitlines())
-    # remove redundant new lines
-    conf = conf.strip()
-
-    return conf + '\n'
-
-def parse_model(text):
-    text = preprocess(text)
-    raw_model = ModelDef.parse_from(Stream(text)).payload
-    return raw_model
-
-class InvalidModelDefinition(Exception):
-    def __init__(self, msg = ''):
-        super(InvalidModelDefinition, self).__init__(msg)        
-
-    @staticmethod
-    def redundant_def(redefined_vars, g1, g2):
-        msg_parts = [
-            'multiple definition(s) of identifiers(s)',
-            ', '.join(redfined_vars),
-            'found in sections',
-            g1, g2
-        ]
-        return InvalidModelDefinition(''.join(msg_parts))
-
-    @staticmethod
-    def missing_matchers(missing_matchers):
-        msg = 'missing matcher(s) for request type(s): {}'
-        return InvalidModelDefinition(msg.format(', '.join(missing_matchers)))
-
-    @staticmethod
-    def unknown_requests(unknown_requests):
-        msg = 'matcher(s) defined for unknown request type(s): {}'
-        return InvalidModelDefinition(msg.format(', '.join(unknown_requests)))
-
-class Request(object):
-    def __init__(self, attrs, vals):
-        assert len(attrs) == len(vals)
-        self.__named_attrs = attrs
-        for attr, val in zip(attrs, vals):
-            setattr(self, attr, val)
-
-    def __repr__(self):
-        parts = ['Request {\n']
-        for attr in self.__named_attrs:
-            parts.append('  ')
-            parts.append(attr)
-            parts.append(': ')
-            parts.append(repr(getattr(self, attr)))
-            parts.append('\n')
-        parts.append('}\n')
-        return ''.join(parts)
-
-class QueryResult(object):
-    def __init__(self, generator):
-        self.__gen = generator
-
-    def __iter__(self):
-        return self.__gen
-
-    def __le__(self, iterable):
-        return set(self) <= set(iterable)
-
-    def __lt__(self, iterable):
-        return set(self) < set(iterable)
-
-    def __ge__(self, iterable):
-        return set(self) >= set(iterable)
-
-    def __gt__(self, iterable):
-        return set(self) > set(iterable)
-
-class Term(object):
-    PLACEHOLDER = object()
-    WILDCARD = None
-    def __init__(self, arity):
-        self.__arity = arity
-        self.__facts = set()
-
-    def add_facts(self, facts):
-        for fact in facts:
-            self.add_fact(fact)
-
-    def add_fact(self, fact):
-        assert len(fact) == self.__arity
-        if not isinstance(fact, tuple):
-            fact = tuple(fact)
-        self.__facts.add(fact)
-
-    def __call__(self, *args):
-        assert len(args) == self.__arity
-        # When all arguments are concrete, calling a term just returns boolean results
-        # indicating whether the called tuple is part of the known facts
-        n_placeholders = sum(arg is Term.PLACEHOLDER for arg in args)
-        if not n_placeholders:
-            return any(all(a == b for a, b in zip(fact, args)) for fact in self.__facts)
-        # If arguments contain one or more placeholders, calling a term is more like a
-        # query. The call returns a generator that iterates all facts that match with
-        # the pattern described by the arguments
-        def gen():
-            for fact in self.__facts:
-                rns = []
-                matched = True
-                for a, b in zip(fact, args):
-                    if b is Term.PLACEHOLDER:
-                        rns.append(a)
-                    else:
-                        if a != b:
-                            matched = False
-                            break
-                if matched:
-                    if n_placeholders == 1:
-                        yield rns[0]
-                    else:
-                        yield tuple(rns)
-        return QueryResult(gen())
-
-class Model(object):
-    def __init__(self, raw_model):
-        request_def, term_def, matchers = raw_model
-        self.__request_template = { r[0]:r[1] for r in request_def }
-        self.__term_template = { t[0]:t[1] for t in term_def }
-        self.__matchers = { m[0]:m[1] for m in matchers }
-
-        def_sections = zip(
-            ['[requests]', '[terms]'],
-            [self.__request_template, self.__term_template],
-        )
-
-        n_sec = len(def_sections)
-        for i in range(n_sec):
-            for j in range(i + 1, n_sec):
-                overlap = set(def_sections[i][1].keys()) & set(def_sections[j][1].keys())
-                if overlap:
-                    raise InvalidModelDefinition.redundant_def(
-                        overalp, def_sections[i][0], def_sections[j][0]
-                    )
-
-        missing_matchers = set(self.__request_template.keys()) - set(self.__matchers.keys())
-        if missing_matchers:
-            raise InvalidModelDefinition.missing_matchers(missing_matchers)
-
-        unknown_requests = set(self.__matchers.keys()) - set(self.__request_template.keys())
-        if unknown_requests:
-            raise InvalidModelDefinition.unknown_requests(unknown_requests)
-
-        self.__term_knowledge_base = {
-            term_name:Term(len(term_tpl)) for term_name, term_tpl in self.__term_template.items()
-        }
-
-    def add_term_items(self, term_items):
-        for ti in term_items:
-            self.add_term_item(ti[0], ti[1:])
-
-    def add_term_item(self, term_name, fact):
-        term = self.__term_knowledge_base[term_name]
-        term.add_fact(fact)
-
-    def get_matcher_proxy(self, request_type, env):
-        def matcher_proxy():
-            return eval(self.__matchers[request_type], env)
-        return matcher_proxy
-
-    def enforce(self, request_type, request_content):
-        tpl = self.__request_template[request_type]
-        request = Request(tpl, request_content)
-
-        enforcer_env = {
-            request_type: request,
-            'true': True, 'false': False, 'null': None,
-            '_': Term.PLACEHOLDER,
-            'X': Term.WILDCARD,
-        }
-        enforcer_env.update(self.__term_knowledge_base)
-
-        return eval(self.__matchers[request_type], enforcer_env)
-
-global_perm_model = None
-
-if __name__ == '__builtin__':
-    from acs_py_enclave import ffi
-else:
-    class ffi:
-        @staticmethod
-        def def_extern():
-            return lambda x: x
-
-        @staticmethod
-        def string(s):
-            return s
-
-@ffi.def_extern()
-def acs_setup_model(conf):
-    try:
-        global global_perm_model
-        conf = ffi.string(conf)
-        global_perm_model = Model(parse_model(conf))
-    except:
-        return -1
-    return 0
-
-@ffi.def_extern()
-def acs_enforce_request(request_type, request_content):
-    try:
-        request_type = ffi.string(request_type)
-        # request_content is a list of ffi c strings which are syntactically valid
-        # python primitive-type objects, including strings, integers, foating point
-        # numbers, and lists/dictionaries of primitive-type objects
-        request_content = eval(ffi.string(request_content))
-        return global_perm_model.enforce(request_type, request_content)
-    except:
-        return -1
-
-@ffi.def_extern()
-def acs_announce_fact(term_type, term_fact):
-    try:
-        term_type = ffi.string(term_type)
-        term_fact = eval(ffi.string(term_fact))
-        global_perm_model.add_term_item(term_type, term_fact)
-    except:
-        return -1
-    return 0
diff --git a/services/access_control/python/acs_engine_test.py b/services/access_control/python/acs_engine_test.py
deleted file mode 100644
index 27aef6a..0000000
--- a/services/access_control/python/acs_engine_test.py
+++ /dev/null
@@ -1,100 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-if __name__ == '__main__':
-    import sys
-    import os
-    from acs_engine import *
-
-    model_path = os.path.join(os.path.dirname(__file__), '../model.conf')
-    with open(model_path) as modelfile:
-        test_model = modelfile.read()
-        acs_setup_model(test_model)
-
-    FUSION_TASK               = "data_fusion"
-    FUSION_TASK_PARTY_1       = "usr_party1"
-    FUSION_TASK_DATA_1        = "data1"
-    FUSION_TASK_PARTY_2       = "usr_party2"
-    FUSION_TASK_DATA_2        = "data2"
-    FUSION_TASK_SCRIPT        = "fusion_script"
-    FUSION_TASK_SCRIPT_WRITER = "usr_party3"
-    PUBLIC_SCRIPT             = "public_script"
-    PUBLIC_SCRIPT_WRITER      = "usr_party4"
-
-    IRRELEVANT_TASK           = "task_irrelevant"
-    IRRELEVANT_PARTY          = "usr_irrelevant"
-    IRRELEVANT_DATA           = "data_irrelevant"
-
-    acs_announce_fact('task_creator', repr([FUSION_TASK, FUSION_TASK_PARTY_1]))
-    acs_announce_fact('task_participant', repr([FUSION_TASK, FUSION_TASK_PARTY_1]))
-    acs_announce_fact('task_participant', repr([FUSION_TASK, FUSION_TASK_PARTY_2]))
-
-    acs_announce_fact('data_owner', repr([FUSION_TASK_DATA_1, FUSION_TASK_PARTY_1]))
-    acs_announce_fact('data_owner', repr([FUSION_TASK_DATA_2, FUSION_TASK_PARTY_2]))
-    acs_announce_fact('data_owner', repr([IRRELEVANT_DATA, IRRELEVANT_PARTY]))
-
-    acs_announce_fact('script_owner', repr([FUSION_TASK_SCRIPT, FUSION_TASK_SCRIPT_WRITER]))
-
-    acs_announce_fact('script_owner', repr([PUBLIC_SCRIPT, PUBLIC_SCRIPT_WRITER]))
-    acs_announce_fact('is_public_script', repr([PUBLIC_SCRIPT]))
-
-
-    assert acs_enforce_request('launch_task', repr([FUSION_TASK, set([FUSION_TASK_PARTY_1, FUSION_TASK_PARTY_2])]))
-    assert not acs_enforce_request('launch_task', repr([FUSION_TASK, set()]))
-    assert not acs_enforce_request('launch_task', repr([FUSION_TASK, set([FUSION_TASK_PARTY_1])]))
-    assert not acs_enforce_request('launch_task', repr([FUSION_TASK, set([FUSION_TASK_PARTY_2])]))
-
-    assert acs_enforce_request('access_data', repr([FUSION_TASK, FUSION_TASK_DATA_1]))
-    assert acs_enforce_request('access_data', repr([FUSION_TASK, FUSION_TASK_DATA_2]))
-    assert not acs_enforce_request('access_data', repr([FUSION_TASK, IRRELEVANT_DATA]))
-
-    assert acs_enforce_request('access_script', repr([FUSION_TASK, PUBLIC_SCRIPT]))
-    assert not acs_enforce_request('access_script', repr([FUSION_TASK, FUSION_TASK_SCRIPT]))
-
-    acs_announce_fact('task_participant', repr([FUSION_TASK, FUSION_TASK_SCRIPT_WRITER]))
-    assert acs_enforce_request('access_script', repr([FUSION_TASK, FUSION_TASK_SCRIPT]))
-
-    acs_announce_fact('task_participant', repr([FUSION_TASK, IRRELEVANT_PARTY]))
-    assert acs_enforce_request('access_script', repr([FUSION_TASK, FUSION_TASK_SCRIPT]))
-
-    acs_announce_fact('task_creator', repr([IRRELEVANT_TASK, IRRELEVANT_PARTY]))
-    acs_announce_fact('task_participant', repr([IRRELEVANT_TASK, IRRELEVANT_PARTY]))
-    acs_announce_fact('task_participant', repr([IRRELEVANT_TASK, FUSION_TASK_PARTY_2]))
-
-    assert acs_enforce_request('launch_task', repr([IRRELEVANT_TASK, set([IRRELEVANT_PARTY, FUSION_TASK_PARTY_2])]))
-    assert not acs_enforce_request('access_data', repr([IRRELEVANT_TASK, FUSION_TASK_DATA_1]))
-    assert acs_enforce_request('access_data', repr([IRRELEVANT_TASK, FUSION_TASK_DATA_2]))
-    assert not acs_enforce_request('access_script', repr([IRRELEVANT_TASK, FUSION_TASK_SCRIPT]))
-    assert acs_enforce_request('access_script', repr([IRRELEVANT_TASK, PUBLIC_SCRIPT]))
-
-    assert acs_enforce_request('delete_data', repr([FUSION_TASK_PARTY_1, FUSION_TASK_DATA_1]))
-    assert not acs_enforce_request('delete_data', repr([FUSION_TASK_PARTY_1, FUSION_TASK_DATA_2]))
-    assert not acs_enforce_request('delete_data', repr([FUSION_TASK_PARTY_1, IRRELEVANT_DATA]))
-    assert not acs_enforce_request('delete_script', repr([FUSION_TASK_PARTY_1, FUSION_TASK_SCRIPT]))
-    assert not acs_enforce_request('delete_script', repr([FUSION_TASK_PARTY_1, PUBLIC_SCRIPT]))
-
-    assert not acs_enforce_request('delete_data', repr([FUSION_TASK_PARTY_2, FUSION_TASK_DATA_1]))
-    assert acs_enforce_request('delete_data', repr([FUSION_TASK_PARTY_2, FUSION_TASK_DATA_2]))
-    assert not acs_enforce_request('delete_data', repr([FUSION_TASK_PARTY_2, IRRELEVANT_DATA]))
-    assert not acs_enforce_request('delete_script', repr([FUSION_TASK_PARTY_2, FUSION_TASK_SCRIPT]))
-    assert not acs_enforce_request('delete_script', repr([FUSION_TASK_PARTY_2, PUBLIC_SCRIPT]))
-
-    assert not acs_enforce_request('delete_data', repr([FUSION_TASK_SCRIPT_WRITER, FUSION_TASK_DATA_1]))
-    assert not acs_enforce_request('delete_data', repr([FUSION_TASK_SCRIPT_WRITER, FUSION_TASK_DATA_2]))
-    assert not acs_enforce_request('delete_data', repr([FUSION_TASK_SCRIPT_WRITER, IRRELEVANT_DATA]))
-    assert acs_enforce_request('delete_script', repr([FUSION_TASK_SCRIPT_WRITER, FUSION_TASK_SCRIPT]))
-    assert not acs_enforce_request('delete_script', repr([FUSION_TASK_SCRIPT_WRITER, PUBLIC_SCRIPT]))
diff --git a/services/access_control/python/acs_py_enclave.c b/services/access_control/python/acs_py_enclave.c
deleted file mode 100644
index 20eec4b..0000000
--- a/services/access_control/python/acs_py_enclave.c
+++ /dev/null
@@ -1,3191 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/*
- * DO NOT MODIFY THIS MANUALLY! This file was generated using pypy.
- * To generate this file:
- * 1. Get mesapy code from https://github.com/mesalock-linux/mesapy/tree/947fb3f598eede83ba0e33b5b5655b9a9597c2d8
- * 2. Run `PYTHONPATH=mesapy/sgx pypy ffi.py`.
- */
-
-#define _CFFI_USE_EMBEDDING
-#define _CFFI_
-
-/* We try to define Py_LIMITED_API before including Python.h.
-
-   Mess: we can only define it if Py_DEBUG, Py_TRACE_REFS and
-   Py_REF_DEBUG are not defined.  This is a best-effort approximation:
-   we can learn about Py_DEBUG from pyconfig.h, but it is unclear if
-   the same works for the other two macros.  Py_DEBUG implies them,
-   but not the other way around.
-
-   Issue #350 is still open: on Windows, the code here causes it to link
-   with PYTHON36.DLL (for example) instead of PYTHON3.DLL.  A fix was
-   attempted in 164e526a5515 and 14ce6985e1c3, but reverted: virtualenv
-   does not make PYTHON3.DLL available, and so the "correctly" compiled
-   version would not run inside a virtualenv.  We will re-apply the fix
-   after virtualenv has been fixed for some time.  For explanation, see
-   issue #355.  For a workaround if you want PYTHON3.DLL and don't worry
-   about virtualenv, see issue #350.  See also 'py_limited_api' in
-   setuptools_ext.py.
-*/
-#if !defined(_CFFI_USE_EMBEDDING) && !defined(Py_LIMITED_API)
-#  include <pyconfig.h>
-#  if !defined(Py_DEBUG) && !defined(Py_TRACE_REFS) && !defined(Py_REF_DEBUG)
-#    define Py_LIMITED_API
-#  endif
-#endif
-
-#include <Python.h>
-#ifdef __cplusplus
-extern "C" {
-#endif
-#include <stddef.h>
-
-/* This part is from file 'cffi/parse_c_type.h'.  It is copied at the
-   beginning of C sources generated by CFFI's ffi.set_source(). */
-
-typedef void *_cffi_opcode_t;
-
-#define _CFFI_OP(opcode, arg)   (_cffi_opcode_t)(opcode | (((uintptr_t)(arg)) << 8))
-#define _CFFI_GETOP(cffi_opcode)    ((unsigned char)(uintptr_t)cffi_opcode)
-#define _CFFI_GETARG(cffi_opcode)   (((intptr_t)cffi_opcode) >> 8)
-
-#define _CFFI_OP_PRIMITIVE       1
-#define _CFFI_OP_POINTER         3
-#define _CFFI_OP_ARRAY           5
-#define _CFFI_OP_OPEN_ARRAY      7
-#define _CFFI_OP_STRUCT_UNION    9
-#define _CFFI_OP_ENUM           11
-#define _CFFI_OP_FUNCTION       13
-#define _CFFI_OP_FUNCTION_END   15
-#define _CFFI_OP_NOOP           17
-#define _CFFI_OP_BITFIELD       19
-#define _CFFI_OP_TYPENAME       21
-#define _CFFI_OP_CPYTHON_BLTN_V 23   // varargs
-#define _CFFI_OP_CPYTHON_BLTN_N 25   // noargs
-#define _CFFI_OP_CPYTHON_BLTN_O 27   // O  (i.e. a single arg)
-#define _CFFI_OP_CONSTANT       29
-#define _CFFI_OP_CONSTANT_INT   31
-#define _CFFI_OP_GLOBAL_VAR     33
-#define _CFFI_OP_DLOPEN_FUNC    35
-#define _CFFI_OP_DLOPEN_CONST   37
-#define _CFFI_OP_GLOBAL_VAR_F   39
-#define _CFFI_OP_EXTERN_PYTHON  41
-
-#define _CFFI_PRIM_VOID          0
-#define _CFFI_PRIM_BOOL          1
-#define _CFFI_PRIM_CHAR          2
-#define _CFFI_PRIM_SCHAR         3
-#define _CFFI_PRIM_UCHAR         4
-#define _CFFI_PRIM_SHORT         5
-#define _CFFI_PRIM_USHORT        6
-#define _CFFI_PRIM_INT           7
-#define _CFFI_PRIM_UINT          8
-#define _CFFI_PRIM_LONG          9
-#define _CFFI_PRIM_ULONG        10
-#define _CFFI_PRIM_LONGLONG     11
-#define _CFFI_PRIM_ULONGLONG    12
-#define _CFFI_PRIM_FLOAT        13
-#define _CFFI_PRIM_DOUBLE       14
-#define _CFFI_PRIM_LONGDOUBLE   15
-
-#define _CFFI_PRIM_WCHAR        16
-#define _CFFI_PRIM_INT8         17
-#define _CFFI_PRIM_UINT8        18
-#define _CFFI_PRIM_INT16        19
-#define _CFFI_PRIM_UINT16       20
-#define _CFFI_PRIM_INT32        21
-#define _CFFI_PRIM_UINT32       22
-#define _CFFI_PRIM_INT64        23
-#define _CFFI_PRIM_UINT64       24
-#define _CFFI_PRIM_INTPTR       25
-#define _CFFI_PRIM_UINTPTR      26
-#define _CFFI_PRIM_PTRDIFF      27
-#define _CFFI_PRIM_SIZE         28
-#define _CFFI_PRIM_SSIZE        29
-#define _CFFI_PRIM_INT_LEAST8   30
-#define _CFFI_PRIM_UINT_LEAST8  31
-#define _CFFI_PRIM_INT_LEAST16  32
-#define _CFFI_PRIM_UINT_LEAST16 33
-#define _CFFI_PRIM_INT_LEAST32  34
-#define _CFFI_PRIM_UINT_LEAST32 35
-#define _CFFI_PRIM_INT_LEAST64  36
-#define _CFFI_PRIM_UINT_LEAST64 37
-#define _CFFI_PRIM_INT_FAST8    38
-#define _CFFI_PRIM_UINT_FAST8   39
-#define _CFFI_PRIM_INT_FAST16   40
-#define _CFFI_PRIM_UINT_FAST16  41
-#define _CFFI_PRIM_INT_FAST32   42
-#define _CFFI_PRIM_UINT_FAST32  43
-#define _CFFI_PRIM_INT_FAST64   44
-#define _CFFI_PRIM_UINT_FAST64  45
-#define _CFFI_PRIM_INTMAX       46
-#define _CFFI_PRIM_UINTMAX      47
-#define _CFFI_PRIM_FLOATCOMPLEX 48
-#define _CFFI_PRIM_DOUBLECOMPLEX 49
-#define _CFFI_PRIM_CHAR16       50
-#define _CFFI_PRIM_CHAR32       51
-
-#define _CFFI__NUM_PRIM         52
-#define _CFFI__UNKNOWN_PRIM           (-1)
-#define _CFFI__UNKNOWN_FLOAT_PRIM     (-2)
-#define _CFFI__UNKNOWN_LONG_DOUBLE    (-3)
-
-#define _CFFI__IO_FILE_STRUCT         (-1)
-
-
-struct _cffi_global_s {
-    const char *name;
-    void *address;
-    _cffi_opcode_t type_op;
-    void *size_or_direct_fn;  // OP_GLOBAL_VAR: size, or 0 if unknown
-                              // OP_CPYTHON_BLTN_*: addr of direct function
-};
-
-struct _cffi_getconst_s {
-    unsigned long long value;
-    const struct _cffi_type_context_s *ctx;
-    int gindex;
-};
-
-struct _cffi_struct_union_s {
-    const char *name;
-    int type_index;          // -> _cffi_types, on a OP_STRUCT_UNION
-    int flags;               // _CFFI_F_* flags below
-    size_t size;
-    int alignment;
-    int first_field_index;   // -> _cffi_fields array
-    int num_fields;
-};
-#define _CFFI_F_UNION         0x01   // is a union, not a struct
-#define _CFFI_F_CHECK_FIELDS  0x02   // complain if fields are not in the
-                                     // "standard layout" or if some are missing
-#define _CFFI_F_PACKED        0x04   // for CHECK_FIELDS, assume a packed struct
-#define _CFFI_F_EXTERNAL      0x08   // in some other ffi.include()
-#define _CFFI_F_OPAQUE        0x10   // opaque
-
-struct _cffi_field_s {
-    const char *name;
-    size_t field_offset;
-    size_t field_size;
-    _cffi_opcode_t field_type_op;
-};
-
-struct _cffi_enum_s {
-    const char *name;
-    int type_index;          // -> _cffi_types, on a OP_ENUM
-    int type_prim;           // _CFFI_PRIM_xxx
-    const char *enumerators; // comma-delimited string
-};
-
-struct _cffi_typename_s {
-    const char *name;
-    int type_index;   /* if opaque, points to a possibly artificial
-                         OP_STRUCT which is itself opaque */
-};
-
-struct _cffi_type_context_s {
-    _cffi_opcode_t *types;
-    const struct _cffi_global_s *globals;
-    const struct _cffi_field_s *fields;
-    const struct _cffi_struct_union_s *struct_unions;
-    const struct _cffi_enum_s *enums;
-    const struct _cffi_typename_s *typenames;
-    int num_globals;
-    int num_struct_unions;
-    int num_enums;
-    int num_typenames;
-    const char *const *includes;
-    int num_types;
-    int flags;      /* future extension */
-};
-
-struct _cffi_parse_info_s {
-    const struct _cffi_type_context_s *ctx;
-    _cffi_opcode_t *output;
-    unsigned int output_size;
-    size_t error_location;
-    const char *error_message;
-};
-
-struct _cffi_externpy_s {
-    const char *name;
-    size_t size_of_result;
-    void *reserved1, *reserved2;
-};
-
-#ifdef _CFFI_INTERNAL
-static int parse_c_type(struct _cffi_parse_info_s *info, const char *input);
-static int search_in_globals(const struct _cffi_type_context_s *ctx,
-                             const char *search, size_t search_len);
-static int search_in_struct_unions(const struct _cffi_type_context_s *ctx,
-                                   const char *search, size_t search_len);
-#endif
-
-/* this block of #ifs should be kept exactly identical between
-   c/_cffi_backend.c, cffi/vengine_cpy.py, cffi/vengine_gen.py
-   and cffi/_cffi_include.h */
-#if defined(_MSC_VER)
-# include <malloc.h>   /* for alloca() */
-# if _MSC_VER < 1600   /* MSVC < 2010 */
-   typedef __int8 int8_t;
-   typedef __int16 int16_t;
-   typedef __int32 int32_t;
-   typedef __int64 int64_t;
-   typedef unsigned __int8 uint8_t;
-   typedef unsigned __int16 uint16_t;
-   typedef unsigned __int32 uint32_t;
-   typedef unsigned __int64 uint64_t;
-   typedef __int8 int_least8_t;
-   typedef __int16 int_least16_t;
-   typedef __int32 int_least32_t;
-   typedef __int64 int_least64_t;
-   typedef unsigned __int8 uint_least8_t;
-   typedef unsigned __int16 uint_least16_t;
-   typedef unsigned __int32 uint_least32_t;
-   typedef unsigned __int64 uint_least64_t;
-   typedef __int8 int_fast8_t;
-   typedef __int16 int_fast16_t;
-   typedef __int32 int_fast32_t;
-   typedef __int64 int_fast64_t;
-   typedef unsigned __int8 uint_fast8_t;
-   typedef unsigned __int16 uint_fast16_t;
-   typedef unsigned __int32 uint_fast32_t;
-   typedef unsigned __int64 uint_fast64_t;
-   typedef __int64 intmax_t;
-   typedef unsigned __int64 uintmax_t;
-# else
-#  include <stdint.h>
-# endif
-# if _MSC_VER < 1800   /* MSVC < 2013 */
-#  ifndef __cplusplus
-    typedef unsigned char _Bool;
-#  endif
-# endif
-#else
-# include <stdint.h>
-# if (defined (__SVR4) && defined (__sun)) || defined(_AIX) || defined(__hpux)
-#  include <alloca.h>
-# endif
-#endif
-
-#ifdef __GNUC__
-# define _CFFI_UNUSED_FN  __attribute__((unused))
-#else
-# define _CFFI_UNUSED_FN  /* nothing */
-#endif
-
-#ifdef __cplusplus
-# ifndef _Bool
-   typedef bool _Bool;   /* semi-hackish: C++ has no _Bool; bool is builtin */
-# endif
-#endif
-
-/**********  CPython-specific section  **********/
-#ifndef PYPY_VERSION
-
-
-#if PY_MAJOR_VERSION >= 3
-# define PyInt_FromLong PyLong_FromLong
-#endif
-
-#define _cffi_from_c_double PyFloat_FromDouble
-#define _cffi_from_c_float PyFloat_FromDouble
-#define _cffi_from_c_long PyInt_FromLong
-#define _cffi_from_c_ulong PyLong_FromUnsignedLong
-#define _cffi_from_c_longlong PyLong_FromLongLong
-#define _cffi_from_c_ulonglong PyLong_FromUnsignedLongLong
-#define _cffi_from_c__Bool PyBool_FromLong
-
-#define _cffi_to_c_double PyFloat_AsDouble
-#define _cffi_to_c_float PyFloat_AsDouble
-
-#define _cffi_from_c_int(x, type)                                        \
-    (((type)-1) > 0 ? /* unsigned */                                     \
-        (sizeof(type) < sizeof(long) ?                                   \
-            PyInt_FromLong((long)x) :                                    \
-         sizeof(type) == sizeof(long) ?                                  \
-            PyLong_FromUnsignedLong((unsigned long)x) :                  \
-            PyLong_FromUnsignedLongLong((unsigned long long)x)) :        \
-        (sizeof(type) <= sizeof(long) ?                                  \
-            PyInt_FromLong((long)x) :                                    \
-            PyLong_FromLongLong((long long)x)))
-
-#define _cffi_to_c_int(o, type)                                          \
-    ((type)(                                                             \
-     sizeof(type) == 1 ? (((type)-1) > 0 ? (type)_cffi_to_c_u8(o)        \
-                                         : (type)_cffi_to_c_i8(o)) :     \
-     sizeof(type) == 2 ? (((type)-1) > 0 ? (type)_cffi_to_c_u16(o)       \
-                                         : (type)_cffi_to_c_i16(o)) :    \
-     sizeof(type) == 4 ? (((type)-1) > 0 ? (type)_cffi_to_c_u32(o)       \
-                                         : (type)_cffi_to_c_i32(o)) :    \
-     sizeof(type) == 8 ? (((type)-1) > 0 ? (type)_cffi_to_c_u64(o)       \
-                                         : (type)_cffi_to_c_i64(o)) :    \
-     (Py_FatalError("unsupported size for type " #type), (type)0)))
-
-#define _cffi_to_c_i8                                                    \
-                 ((int(*)(PyObject *))_cffi_exports[1])
-#define _cffi_to_c_u8                                                    \
-                 ((int(*)(PyObject *))_cffi_exports[2])
-#define _cffi_to_c_i16                                                   \
-                 ((int(*)(PyObject *))_cffi_exports[3])
-#define _cffi_to_c_u16                                                   \
-                 ((int(*)(PyObject *))_cffi_exports[4])
-#define _cffi_to_c_i32                                                   \
-                 ((int(*)(PyObject *))_cffi_exports[5])
-#define _cffi_to_c_u32                                                   \
-                 ((unsigned int(*)(PyObject *))_cffi_exports[6])
-#define _cffi_to_c_i64                                                   \
-                 ((long long(*)(PyObject *))_cffi_exports[7])
-#define _cffi_to_c_u64                                                   \
-                 ((unsigned long long(*)(PyObject *))_cffi_exports[8])
-#define _cffi_to_c_char                                                  \
-                 ((int(*)(PyObject *))_cffi_exports[9])
-#define _cffi_from_c_pointer                                             \
-    ((PyObject *(*)(char *, struct _cffi_ctypedescr *))_cffi_exports[10])
-#define _cffi_to_c_pointer                                               \
-    ((char *(*)(PyObject *, struct _cffi_ctypedescr *))_cffi_exports[11])
-#define _cffi_get_struct_layout                                          \
-    not used any more
-#define _cffi_restore_errno                                              \
-    ((void(*)(void))_cffi_exports[13])
-#define _cffi_save_errno                                                 \
-    ((void(*)(void))_cffi_exports[14])
-#define _cffi_from_c_char                                                \
-    ((PyObject *(*)(char))_cffi_exports[15])
-#define _cffi_from_c_deref                                               \
-    ((PyObject *(*)(char *, struct _cffi_ctypedescr *))_cffi_exports[16])
-#define _cffi_to_c                                                       \
-    ((int(*)(char *, struct _cffi_ctypedescr *, PyObject *))_cffi_exports[17])
-#define _cffi_from_c_struct                                              \
-    ((PyObject *(*)(char *, struct _cffi_ctypedescr *))_cffi_exports[18])
-#define _cffi_to_c_wchar_t                                               \
-    ((_cffi_wchar_t(*)(PyObject *))_cffi_exports[19])
-#define _cffi_from_c_wchar_t                                             \
-    ((PyObject *(*)(_cffi_wchar_t))_cffi_exports[20])
-#define _cffi_to_c_long_double                                           \
-    ((long double(*)(PyObject *))_cffi_exports[21])
-#define _cffi_to_c__Bool                                                 \
-    ((_Bool(*)(PyObject *))_cffi_exports[22])
-#define _cffi_prepare_pointer_call_argument                              \
-    ((Py_ssize_t(*)(struct _cffi_ctypedescr *,                           \
-                    PyObject *, char **))_cffi_exports[23])
-#define _cffi_convert_array_from_object                                  \
-    ((int(*)(char *, struct _cffi_ctypedescr *, PyObject *))_cffi_exports[24])
-#define _CFFI_CPIDX  25
-#define _cffi_call_python                                                \
-    ((void(*)(struct _cffi_externpy_s *, char *))_cffi_exports[_CFFI_CPIDX])
-#define _cffi_to_c_wchar3216_t                                           \
-    ((int(*)(PyObject *))_cffi_exports[26])
-#define _cffi_from_c_wchar3216_t                                         \
-    ((PyObject *(*)(int))_cffi_exports[27])
-#define _CFFI_NUM_EXPORTS 28
-
-struct _cffi_ctypedescr;
-
-static void *_cffi_exports[_CFFI_NUM_EXPORTS];
-
-#define _cffi_type(index)   (                           \
-    assert((((uintptr_t)_cffi_types[index]) & 1) == 0), \
-    (struct _cffi_ctypedescr *)_cffi_types[index])
-
-static PyObject *_cffi_init(const char *module_name, Py_ssize_t version,
-                            const struct _cffi_type_context_s *ctx)
-{
-    PyObject *module, *o_arg, *new_module;
-    void *raw[] = {
-        (void *)module_name,
-        (void *)version,
-        (void *)_cffi_exports,
-        (void *)ctx,
-    };
-
-    module = PyImport_ImportModule("_cffi_backend");
-    if (module == NULL)
-        goto failure;
-
-    o_arg = PyLong_FromVoidPtr((void *)raw);
-    if (o_arg == NULL)
-        goto failure;
-
-    new_module = PyObject_CallMethod(
-        module, (char *)"_init_cffi_1_0_external_module", (char *)"O", o_arg);
-
-    Py_DECREF(o_arg);
-    Py_DECREF(module);
-    return new_module;
-
-  failure:
-    Py_XDECREF(module);
-    return NULL;
-}
-
-
-#ifdef HAVE_WCHAR_H
-typedef wchar_t _cffi_wchar_t;
-#else
-typedef uint16_t _cffi_wchar_t;   /* same random pick as _cffi_backend.c */
-#endif
-
-_CFFI_UNUSED_FN static uint16_t _cffi_to_c_char16_t(PyObject *o)
-{
-    if (sizeof(_cffi_wchar_t) == 2)
-        return (uint16_t)_cffi_to_c_wchar_t(o);
-    else
-        return (uint16_t)_cffi_to_c_wchar3216_t(o);
-}
-
-_CFFI_UNUSED_FN static PyObject *_cffi_from_c_char16_t(uint16_t x)
-{
-    if (sizeof(_cffi_wchar_t) == 2)
-        return _cffi_from_c_wchar_t((_cffi_wchar_t)x);
-    else
-        return _cffi_from_c_wchar3216_t((int)x);
-}
-
-_CFFI_UNUSED_FN static int _cffi_to_c_char32_t(PyObject *o)
-{
-    if (sizeof(_cffi_wchar_t) == 4)
-        return (int)_cffi_to_c_wchar_t(o);
-    else
-        return (int)_cffi_to_c_wchar3216_t(o);
-}
-
-_CFFI_UNUSED_FN static PyObject *_cffi_from_c_char32_t(int x)
-{
-    if (sizeof(_cffi_wchar_t) == 4)
-        return _cffi_from_c_wchar_t((_cffi_wchar_t)x);
-    else
-        return _cffi_from_c_wchar3216_t(x);
-}
-
-
-/**********  end CPython-specific section  **********/
-#else
-_CFFI_UNUSED_FN
-static void (*_cffi_call_python_org)(struct _cffi_externpy_s *, char *);
-# define _cffi_call_python  _cffi_call_python_org
-#endif
-
-
-#define _cffi_array_len(array)   (sizeof(array) / sizeof((array)[0]))
-
-#define _cffi_prim_int(size, sign)                                      \
-    ((size) == 1 ? ((sign) ? _CFFI_PRIM_INT8  : _CFFI_PRIM_UINT8)  :    \
-     (size) == 2 ? ((sign) ? _CFFI_PRIM_INT16 : _CFFI_PRIM_UINT16) :    \
-     (size) == 4 ? ((sign) ? _CFFI_PRIM_INT32 : _CFFI_PRIM_UINT32) :    \
-     (size) == 8 ? ((sign) ? _CFFI_PRIM_INT64 : _CFFI_PRIM_UINT64) :    \
-     _CFFI__UNKNOWN_PRIM)
-
-#define _cffi_prim_float(size)                                          \
-    ((size) == sizeof(float) ? _CFFI_PRIM_FLOAT :                       \
-     (size) == sizeof(double) ? _CFFI_PRIM_DOUBLE :                     \
-     (size) == sizeof(long double) ? _CFFI__UNKNOWN_LONG_DOUBLE :       \
-     _CFFI__UNKNOWN_FLOAT_PRIM)
-
-#define _cffi_check_int(got, got_nonpos, expected)      \
-    ((got_nonpos) == (expected <= 0) &&                 \
-     (got) == (unsigned long long)expected)
-
-#ifdef MS_WIN32
-# define _cffi_stdcall  __stdcall
-#else
-# define _cffi_stdcall  /* nothing */
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#define _CFFI_MODULE_NAME  "acs_py_enclave"
-static const char _CFFI_PYTHON_STARTUP_CODE[] = {
-// # NB. this is not a string because of a size limit in MSVC
-// # Licensed to the Apache Software Foundation (ASF) under one
-35,32,76,105,99,101,110,115,101,100,32,116,111,32,116,104,101,32,65,112,97,99,
-104,101,32,83,111,102,116,119,97,114,101,32,70,111,117,110,100,97,116,105,111,
-110,32,40,65,83,70,41,32,117,110,100,101,114,32,111,110,101,10,
-// # or more contributor license agreements.  See the NOTICE file
-35,32,111,114,32,109,111,114,101,32,99,111,110,116,114,105,98,117,116,111,114,
-32,108,105,99,101,110,115,101,32,97,103,114,101,101,109,101,110,116,115,46,32,
-32,83,101,101,32,116,104,101,32,78,79,84,73,67,69,32,102,105,108,101,10,
-// # distributed with this work for additional information
-35,32,100,105,115,116,114,105,98,117,116,101,100,32,119,105,116,104,32,116,104,
-105,115,32,119,111,114,107,32,102,111,114,32,97,100,100,105,116,105,111,110,
-97,108,32,105,110,102,111,114,109,97,116,105,111,110,10,
-// # regarding copyright ownership.  The ASF licenses this file
-35,32,114,101,103,97,114,100,105,110,103,32,99,111,112,121,114,105,103,104,116,
-32,111,119,110,101,114,115,104,105,112,46,32,32,84,104,101,32,65,83,70,32,108,
-105,99,101,110,115,101,115,32,116,104,105,115,32,102,105,108,101,10,
-// # to you under the Apache License, Version 2.0 (the
-35,32,116,111,32,121,111,117,32,117,110,100,101,114,32,116,104,101,32,65,112,
-97,99,104,101,32,76,105,99,101,110,115,101,44,32,86,101,114,115,105,111,110,
-32,50,46,48,32,40,116,104,101,10,
-// # "License"); you may not use this file except in compliance
-35,32,34,76,105,99,101,110,115,101,34,41,59,32,121,111,117,32,109,97,121,32,
-110,111,116,32,117,115,101,32,116,104,105,115,32,102,105,108,101,32,101,120,
-99,101,112,116,32,105,110,32,99,111,109,112,108,105,97,110,99,101,10,
-// # with the License.  You may obtain a copy of the License at
-35,32,119,105,116,104,32,116,104,101,32,76,105,99,101,110,115,101,46,32,32,89,
-111,117,32,109,97,121,32,111,98,116,97,105,110,32,97,32,99,111,112,121,32,111,
-102,32,116,104,101,32,76,105,99,101,110,115,101,32,97,116,10,
-// #
-35,10,
-// #   http://www.apache.org/licenses/LICENSE-2.0
-35,32,32,32,104,116,116,112,58,47,47,119,119,119,46,97,112,97,99,104,101,46,
-111,114,103,47,108,105,99,101,110,115,101,115,47,76,73,67,69,78,83,69,45,50,
-46,48,10,
-// #
-35,10,
-// # Unless required by applicable law or agreed to in writing,
-35,32,85,110,108,101,115,115,32,114,101,113,117,105,114,101,100,32,98,121,32,
-97,112,112,108,105,99,97,98,108,101,32,108,97,119,32,111,114,32,97,103,114,101,
-101,100,32,116,111,32,105,110,32,119,114,105,116,105,110,103,44,10,
-// # software distributed under the License is distributed on an
-35,32,115,111,102,116,119,97,114,101,32,100,105,115,116,114,105,98,117,116,101,
-100,32,117,110,100,101,114,32,116,104,101,32,76,105,99,101,110,115,101,32,105,
-115,32,100,105,115,116,114,105,98,117,116,101,100,32,111,110,32,97,110,10,
-// # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-35,32,34,65,83,32,73,83,34,32,66,65,83,73,83,44,32,87,73,84,72,79,85,84,32,87,
-65,82,82,65,78,84,73,69,83,32,79,82,32,67,79,78,68,73,84,73,79,78,83,32,79,70,
-32,65,78,89,10,
-// # KIND, either express or implied.  See the License for the
-35,32,75,73,78,68,44,32,101,105,116,104,101,114,32,101,120,112,114,101,115,115,
-32,111,114,32,105,109,112,108,105,101,100,46,32,32,83,101,101,32,116,104,101,
-32,76,105,99,101,110,115,101,32,102,111,114,32,116,104,101,10,
-// # specific language governing permissions and limitations
-35,32,115,112,101,99,105,102,105,99,32,108,97,110,103,117,97,103,101,32,103,
-111,118,101,114,110,105,110,103,32,112,101,114,109,105,115,115,105,111,110,115,
-32,97,110,100,32,108,105,109,105,116,97,116,105,111,110,115,10,
-// # under the License.
-35,32,117,110,100,101,114,32,116,104,101,32,76,105,99,101,110,115,101,46,10,
-//
-10,
-// ###############################################################################
-35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,
-35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,
-35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,
-35,10,
-// # Parser Combinators
-35,32,80,97,114,115,101,114,32,67,111,109,98,105,110,97,116,111,114,115,10,
-// ###############################################################################
-35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,
-35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,
-35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,
-35,10,
-// class Pair(tuple):
-99,108,97,115,115,32,80,97,105,114,40,116,117,112,108,101,41,58,10,
-//     def __new__(cls, a, b):
-32,32,32,32,100,101,102,32,95,95,110,101,119,95,95,40,99,108,115,44,32,97,44,
-32,98,41,58,10,
-//         return super(Pair, cls).__new__(cls, [a, b])
-32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,115,117,112,101,114,40,80,
-97,105,114,44,32,99,108,115,41,46,95,95,110,101,119,95,95,40,99,108,115,44,32,
-91,97,44,32,98,93,41,10,
-//
-10,
-// class Either(object):
-99,108,97,115,115,32,69,105,116,104,101,114,40,111,98,106,101,99,116,41,58,10,
-//     def __init__(self, left, right):
-32,32,32,32,100,101,102,32,95,95,105,110,105,116,95,95,40,115,101,108,102,44,
-32,108,101,102,116,44,32,114,105,103,104,116,41,58,10,
-//         self.__left = left
-32,32,32,32,32,32,32,32,115,101,108,102,46,95,95,108,101,102,116,32,61,32,108,
-101,102,116,10,
-//         self.__right = right
-32,32,32,32,32,32,32,32,115,101,108,102,46,95,95,114,105,103,104,116,32,61,32,
-114,105,103,104,116,10,
-//
-10,
-//     def left(self):
-32,32,32,32,100,101,102,32,108,101,102,116,40,115,101,108,102,41,58,10,
-//         if not self.is_left():
-32,32,32,32,32,32,32,32,105,102,32,110,111,116,32,115,101,108,102,46,105,115,
-95,108,101,102,116,40,41,58,10,
-//             raise ValueError('wrong extractor for either')
-32,32,32,32,32,32,32,32,32,32,32,32,114,97,105,115,101,32,86,97,108,117,101,
-69,114,114,111,114,40,39,119,114,111,110,103,32,101,120,116,114,97,99,116,111,
-114,32,102,111,114,32,101,105,116,104,101,114,39,41,10,
-//         return self.__left
-32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,115,101,108,102,46,95,95,
-108,101,102,116,10,
-//
-10,
-//     def right(self):
-32,32,32,32,100,101,102,32,114,105,103,104,116,40,115,101,108,102,41,58,10,
-//         if not self.is_right():
-32,32,32,32,32,32,32,32,105,102,32,110,111,116,32,115,101,108,102,46,105,115,
-95,114,105,103,104,116,40,41,58,10,
-//             raise ValueError('wrong extractor for either')
-32,32,32,32,32,32,32,32,32,32,32,32,114,97,105,115,101,32,86,97,108,117,101,
-69,114,114,111,114,40,39,119,114,111,110,103,32,101,120,116,114,97,99,116,111,
-114,32,102,111,114,32,101,105,116,104,101,114,39,41,10,
-//         return self.__right
-32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,115,101,108,102,46,95,95,
-114,105,103,104,116,10,
-//
-10,
-//     def is_right(self):
-32,32,32,32,100,101,102,32,105,115,95,114,105,103,104,116,40,115,101,108,102,
-41,58,10,
-//         return False
-32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,70,97,108,115,101,10,
-//
-10,
-//     def is_left(self):
-32,32,32,32,100,101,102,32,105,115,95,108,101,102,116,40,115,101,108,102,41,
-58,10,
-//         return False
-32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,70,97,108,115,101,10,
-//
-10,
-//     def get(self):
-32,32,32,32,100,101,102,32,103,101,116,40,115,101,108,102,41,58,10,
-//         if self.is_right():
-32,32,32,32,32,32,32,32,105,102,32,115,101,108,102,46,105,115,95,114,105,103,
-104,116,40,41,58,10,
-//             return self.right()
-32,32,32,32,32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,115,101,108,102,
-46,114,105,103,104,116,40,41,10,
-//         if self.is_left():
-32,32,32,32,32,32,32,32,105,102,32,115,101,108,102,46,105,115,95,108,101,102,
-116,40,41,58,10,
-//             return self.left()
-32,32,32,32,32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,115,101,108,102,
-46,108,101,102,116,40,41,10,
-//         raise ValueError('incomplete Either object')
-32,32,32,32,32,32,32,32,114,97,105,115,101,32,86,97,108,117,101,69,114,114,111,
-114,40,39,105,110,99,111,109,112,108,101,116,101,32,69,105,116,104,101,114,32,
-111,98,106,101,99,116,39,41,10,
-//
-10,
-//     def __str__(self):
-32,32,32,32,100,101,102,32,95,95,115,116,114,95,95,40,115,101,108,102,41,58,
-10,
-//         if self.is_left():
-32,32,32,32,32,32,32,32,105,102,32,115,101,108,102,46,105,115,95,108,101,102,
-116,40,41,58,10,
-//             return 'Left(' + str(self.left()) + ')'
-32,32,32,32,32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,39,76,101,102,
-116,40,39,32,43,32,115,116,114,40,115,101,108,102,46,108,101,102,116,40,41,41,
-32,43,32,39,41,39,10,
-//         else:
-32,32,32,32,32,32,32,32,101,108,115,101,58,10,
-//             return 'Right(' + str(self.right()) + ')'
-32,32,32,32,32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,39,82,105,103,
-104,116,40,39,32,43,32,115,116,114,40,115,101,108,102,46,114,105,103,104,116,
-40,41,41,32,43,32,39,41,39,10,
-//
-10,
-//     def __repr__(self):
-32,32,32,32,100,101,102,32,95,95,114,101,112,114,95,95,40,115,101,108,102,41,
-58,10,
-//         if self.is_left():
-32,32,32,32,32,32,32,32,105,102,32,115,101,108,102,46,105,115,95,108,101,102,
-116,40,41,58,10,
-//             return 'Left(' + repr(self.left()) + ')'
-32,32,32,32,32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,39,76,101,102,
-116,40,39,32,43,32,114,101,112,114,40,115,101,108,102,46,108,101,102,116,40,
-41,41,32,43,32,39,41,39,10,
-//         else:
-32,32,32,32,32,32,32,32,101,108,115,101,58,10,
-//             return 'Right(' + repr(self.right()) + ')'
-32,32,32,32,32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,39,82,105,103,
-104,116,40,39,32,43,32,114,101,112,114,40,115,101,108,102,46,114,105,103,104,
-116,40,41,41,32,43,32,39,41,39,10,
-//
-10,
-// class Left(Either):
-99,108,97,115,115,32,76,101,102,116,40,69,105,116,104,101,114,41,58,10,
-//     def __init__(self, payload):
-32,32,32,32,100,101,102,32,95,95,105,110,105,116,95,95,40,115,101,108,102,44,
-32,112,97,121,108,111,97,100,41,58,10,
-//         super(Left, self).__init__(payload, None)
-32,32,32,32,32,32,32,32,115,117,112,101,114,40,76,101,102,116,44,32,115,101,
-108,102,41,46,95,95,105,110,105,116,95,95,40,112,97,121,108,111,97,100,44,32,
-78,111,110,101,41,10,
-//
-10,
-//     def is_left(self):
-32,32,32,32,100,101,102,32,105,115,95,108,101,102,116,40,115,101,108,102,41,
-58,10,
-//         return True
-32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,84,114,117,101,10,
-//
-10,
-// class Right(Either):
-99,108,97,115,115,32,82,105,103,104,116,40,69,105,116,104,101,114,41,58,10,
-//     def __init__(self, payload):
-32,32,32,32,100,101,102,32,95,95,105,110,105,116,95,95,40,115,101,108,102,44,
-32,112,97,121,108,111,97,100,41,58,10,
-//         super(Right, self).__init__(None, payload)
-32,32,32,32,32,32,32,32,115,117,112,101,114,40,82,105,103,104,116,44,32,115,
-101,108,102,41,46,95,95,105,110,105,116,95,95,40,78,111,110,101,44,32,112,97,
-121,108,111,97,100,41,10,
-//
-10,
-//     def is_right(self):
-32,32,32,32,100,101,102,32,105,115,95,114,105,103,104,116,40,115,101,108,102,
-41,58,10,
-//         return True
-32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,84,114,117,101,10,
-//
-10,
-// class Stream(object):
-99,108,97,115,115,32,83,116,114,101,97,109,40,111,98,106,101,99,116,41,58,10,
-//     WHITESPACES = [' ', '\t', '\r']
-32,32,32,32,87,72,73,84,69,83,80,65,67,69,83,32,61,32,91,39,32,39,44,32,39,92,
-116,39,44,32,39,92,114,39,93,10,
-//     def __init__(self, items, pos = 0):
-32,32,32,32,100,101,102,32,95,95,105,110,105,116,95,95,40,115,101,108,102,44,
-32,105,116,101,109,115,44,32,112,111,115,32,61,32,48,41,58,10,
-//         self.__items = items
-32,32,32,32,32,32,32,32,115,101,108,102,46,95,95,105,116,101,109,115,32,61,32,
-105,116,101,109,115,10,
-//         self.__pos = pos
-32,32,32,32,32,32,32,32,115,101,108,102,46,95,95,112,111,115,32,61,32,112,111,
-115,10,
-//
-10,
-//     def accept_strlit(self, string):
-32,32,32,32,100,101,102,32,97,99,99,101,112,116,95,115,116,114,108,105,116,40,
-115,101,108,102,44,32,115,116,114,105,110,103,41,58,10,
-//         # Typically parsers want to skip white spaces except line breaks
-32,32,32,32,32,32,32,32,35,32,84,121,112,105,99,97,108,108,121,32,112,97,114,
-115,101,114,115,32,119,97,110,116,32,116,111,32,115,107,105,112,32,119,104,105,
-116,101,32,115,112,97,99,101,115,32,101,120,99,101,112,116,32,108,105,110,101,
-32,98,114,101,97,107,115,10,
-//         # In the future this should be configurable
-32,32,32,32,32,32,32,32,35,32,73,110,32,116,104,101,32,102,117,116,117,114,101,
-32,116,104,105,115,32,115,104,111,117,108,100,32,98,101,32,99,111,110,102,105,
-103,117,114,97,98,108,101,10,
-//         pos = self.__pos
-32,32,32,32,32,32,32,32,112,111,115,32,61,32,115,101,108,102,46,95,95,112,111,
-115,10,
-//         l = len(self.__items)
-32,32,32,32,32,32,32,32,108,32,61,32,108,101,110,40,115,101,108,102,46,95,95,
-105,116,101,109,115,41,10,
-//         while pos < l and self.__items[pos] in self.WHITESPACES:
-32,32,32,32,32,32,32,32,119,104,105,108,101,32,112,111,115,32,60,32,108,32,97,
-110,100,32,115,101,108,102,46,95,95,105,116,101,109,115,91,112,111,115,93,32,
-105,110,32,115,101,108,102,46,87,72,73,84,69,83,80,65,67,69,83,58,10,
-//             pos += 1
-32,32,32,32,32,32,32,32,32,32,32,32,112,111,115,32,43,61,32,49,10,
-//
-10,
-//         match_pos = 0
-32,32,32,32,32,32,32,32,109,97,116,99,104,95,112,111,115,32,61,32,48,10,
-//         l = len(string)
-32,32,32,32,32,32,32,32,108,32,61,32,108,101,110,40,115,116,114,105,110,103,
-41,32,32,32,32,32,32,32,32,10,
-//         while match_pos < l and string[match_pos] in self.WHITESPACES:
-32,32,32,32,32,32,32,32,119,104,105,108,101,32,109,97,116,99,104,95,112,111,
-115,32,60,32,108,32,97,110,100,32,115,116,114,105,110,103,91,109,97,116,99,104,
-95,112,111,115,93,32,105,110,32,115,101,108,102,46,87,72,73,84,69,83,80,65,67,
-69,83,58,10,
-//             match_pos += 1
-32,32,32,32,32,32,32,32,32,32,32,32,109,97,116,99,104,95,112,111,115,32,43,61,
-32,49,10,
-//         if pos < match_pos:
-32,32,32,32,32,32,32,32,105,102,32,112,111,115,32,60,32,109,97,116,99,104,95,
-112,111,115,58,10,
-//             raise ParsingError(self, 'expecting "{}"'.format(string))
-32,32,32,32,32,32,32,32,32,32,32,32,114,97,105,115,101,32,80,97,114,115,105,
-110,103,69,114,114,111,114,40,115,101,108,102,44,32,39,101,120,112,101,99,116,
-105,110,103,32,34,123,125,34,39,46,102,111,114,109,97,116,40,115,116,114,105,
-110,103,41,41,10,
-//         if match_pos:
-32,32,32,32,32,32,32,32,105,102,32,109,97,116,99,104,95,112,111,115,58,10,
-//             string = string[match_pos:]
-32,32,32,32,32,32,32,32,32,32,32,32,115,116,114,105,110,103,32,61,32,115,116,
-114,105,110,103,91,109,97,116,99,104,95,112,111,115,58,93,10,
-//         if self.__items.startswith(string, pos):
-32,32,32,32,32,32,32,32,105,102,32,115,101,108,102,46,95,95,105,116,101,109,
-115,46,115,116,97,114,116,115,119,105,116,104,40,115,116,114,105,110,103,44,
-32,112,111,115,41,58,10,
-//             return Stream(self.__items, pos + len(string))
-32,32,32,32,32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,83,116,114,101,
-97,109,40,115,101,108,102,46,95,95,105,116,101,109,115,44,32,112,111,115,32,
-43,32,108,101,110,40,115,116,114,105,110,103,41,41,10,
-//         raise ParsingError(self, 'expecting "{}"'.format(string))
-32,32,32,32,32,32,32,32,114,97,105,115,101,32,80,97,114,115,105,110,103,69,114,
-114,111,114,40,115,101,108,102,44,32,39,101,120,112,101,99,116,105,110,103,32,
-34,123,125,34,39,46,102,111,114,109,97,116,40,115,116,114,105,110,103,41,41,
-10,
-//
-10,
-//     def accept_matcher(self, matcher):
-32,32,32,32,100,101,102,32,97,99,99,101,112,116,95,109,97,116,99,104,101,114,
-40,115,101,108,102,44,32,109,97,116,99,104,101,114,41,58,10,
-//         pos = self.__pos
-32,32,32,32,32,32,32,32,112,111,115,32,61,32,115,101,108,102,46,95,95,112,111,
-115,10,
-//         l = len(self.__items)
-32,32,32,32,32,32,32,32,108,32,61,32,108,101,110,40,115,101,108,102,46,95,95,
-105,116,101,109,115,41,10,
-//         while pos < l and self.__items[pos] in self.WHITESPACES:
-32,32,32,32,32,32,32,32,119,104,105,108,101,32,112,111,115,32,60,32,108,32,97,
-110,100,32,115,101,108,102,46,95,95,105,116,101,109,115,91,112,111,115,93,32,
-105,110,32,115,101,108,102,46,87,72,73,84,69,83,80,65,67,69,83,58,10,
-//             pos += 1
-32,32,32,32,32,32,32,32,32,32,32,32,112,111,115,32,43,61,32,49,10,
-//
-10,
-//         res = matcher(self.__items, pos)
-32,32,32,32,32,32,32,32,114,101,115,32,61,32,109,97,116,99,104,101,114,40,115,
-101,108,102,46,95,95,105,116,101,109,115,44,32,112,111,115,41,10,
-//         if res is None:
-32,32,32,32,32,32,32,32,105,102,32,114,101,115,32,105,115,32,78,111,110,101,
-58,10,
-//             raise ParsingError(self, 'matcher for {} failed'.format(matcher.__doc__))
-32,32,32,32,32,32,32,32,32,32,32,32,114,97,105,115,101,32,80,97,114,115,105,
-110,103,69,114,114,111,114,40,115,101,108,102,44,32,39,109,97,116,99,104,101,
-114,32,102,111,114,32,123,125,32,102,97,105,108,101,100,39,46,102,111,114,109,
-97,116,40,109,97,116,99,104,101,114,46,95,95,100,111,99,95,95,41,41,10,
-//         obj, npos = res
-32,32,32,32,32,32,32,32,111,98,106,44,32,110,112,111,115,32,61,32,114,101,115,
-10,
-//         return obj, Stream(self.__items, npos)
-32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,111,98,106,44,32,83,116,114,
-101,97,109,40,115,101,108,102,46,95,95,105,116,101,109,115,44,32,110,112,111,
-115,41,10,
-//
-10,
-//     def end(self):
-32,32,32,32,100,101,102,32,101,110,100,40,115,101,108,102,41,58,10,
-//         return self.__pos == len(self.__items)
-32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,115,101,108,102,46,95,95,
-112,111,115,32,61,61,32,108,101,110,40,115,101,108,102,46,95,95,105,116,101,
-109,115,41,10,
-//
-10,
-//     def pos(self):
-32,32,32,32,100,101,102,32,112,111,115,40,115,101,108,102,41,58,10,
-//         return self.__pos
-32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,115,101,108,102,46,95,95,
-112,111,115,10,
-//
-10,
-//     def __repr__(self):
-32,32,32,32,100,101,102,32,95,95,114,101,112,114,95,95,40,115,101,108,102,41,
-58,10,
-//         line_start = self.__items.rfind('\n', 0, self.__pos) + 1
-32,32,32,32,32,32,32,32,108,105,110,101,95,115,116,97,114,116,32,61,32,115,101,
-108,102,46,95,95,105,116,101,109,115,46,114,102,105,110,100,40,39,92,110,39,
-44,32,48,44,32,115,101,108,102,46,95,95,112,111,115,41,32,43,32,49,10,
-//         line_end = self.__items.find('\n', self.__pos)
-32,32,32,32,32,32,32,32,108,105,110,101,95,101,110,100,32,61,32,115,101,108,
-102,46,95,95,105,116,101,109,115,46,102,105,110,100,40,39,92,110,39,44,32,115,
-101,108,102,46,95,95,112,111,115,41,10,
-//         if line_end == -1:
-32,32,32,32,32,32,32,32,105,102,32,108,105,110,101,95,101,110,100,32,61,61,32,
-45,49,58,10,
-//             line_end = self.__pos
-32,32,32,32,32,32,32,32,32,32,32,32,108,105,110,101,95,101,110,100,32,61,32,
-115,101,108,102,46,95,95,112,111,115,10,
-//
-10,
-//         if line_end - line_start > 80:
-32,32,32,32,32,32,32,32,105,102,32,108,105,110,101,95,101,110,100,32,45,32,108,
-105,110,101,95,115,116,97,114,116,32,62,32,56,48,58,10,
-//             line_start = max(line_start, self.__pos - 40)
-32,32,32,32,32,32,32,32,32,32,32,32,108,105,110,101,95,115,116,97,114,116,32,
-61,32,109,97,120,40,108,105,110,101,95,115,116,97,114,116,44,32,115,101,108,
-102,46,95,95,112,111,115,32,45,32,52,48,41,10,
-//             line_end = min(line_start + 80, len(self.__items))
-32,32,32,32,32,32,32,32,32,32,32,32,108,105,110,101,95,101,110,100,32,61,32,
-109,105,110,40,108,105,110,101,95,115,116,97,114,116,32,43,32,56,48,44,32,108,
-101,110,40,115,101,108,102,46,95,95,105,116,101,109,115,41,41,10,
-//
-10,
-//         return ''.join([
-32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,39,39,46,106,111,105,110,
-40,91,10,
-//             self.__items[line_start:line_end],
-32,32,32,32,32,32,32,32,32,32,32,32,115,101,108,102,46,95,95,105,116,101,109,
-115,91,108,105,110,101,95,115,116,97,114,116,58,108,105,110,101,95,101,110,100,
-93,44,10,
-//             '\n',
-32,32,32,32,32,32,32,32,32,32,32,32,39,92,110,39,44,10,
-//             ' ' * (self.__pos - line_start),
-32,32,32,32,32,32,32,32,32,32,32,32,39,32,39,32,42,32,40,115,101,108,102,46,
-95,95,112,111,115,32,45,32,108,105,110,101,95,115,116,97,114,116,41,44,10,
-//             '^',
-32,32,32,32,32,32,32,32,32,32,32,32,39,94,39,44,10,
-//             ' ' * (line_end - self.__pos),
-32,32,32,32,32,32,32,32,32,32,32,32,39,32,39,32,42,32,40,108,105,110,101,95,
-101,110,100,32,45,32,115,101,108,102,46,95,95,112,111,115,41,44,10,
-//             '\nerror at character ',
-32,32,32,32,32,32,32,32,32,32,32,32,39,92,110,101,114,114,111,114,32,97,116,
-32,99,104,97,114,97,99,116,101,114,32,39,44,10,
-//             str(self.__pos),
-32,32,32,32,32,32,32,32,32,32,32,32,115,116,114,40,115,101,108,102,46,95,95,
-112,111,115,41,44,10,
-//         ])
-32,32,32,32,32,32,32,32,93,41,10,
-//
-10,
-// class State(object):
-99,108,97,115,115,32,83,116,97,116,101,40,111,98,106,101,99,116,41,58,10,
-//     def __init__(self, stream, payload = None, success = True):
-32,32,32,32,100,101,102,32,95,95,105,110,105,116,95,95,40,115,101,108,102,44,
-32,115,116,114,101,97,109,44,32,112,97,121,108,111,97,100,32,61,32,78,111,110,
-101,44,32,115,117,99,99,101,115,115,32,61,32,84,114,117,101,41,58,10,
-//         self.stream = stream
-32,32,32,32,32,32,32,32,115,101,108,102,46,115,116,114,101,97,109,32,61,32,115,
-116,114,101,97,109,10,
-//         self.payload = payload
-32,32,32,32,32,32,32,32,115,101,108,102,46,112,97,121,108,111,97,100,32,61,32,
-112,97,121,108,111,97,100,10,
-//         self.success = success
-32,32,32,32,32,32,32,32,115,101,108,102,46,115,117,99,99,101,115,115,32,61,32,
-115,117,99,99,101,115,115,10,
-//
-10,
-//     def __bool__(self):
-32,32,32,32,100,101,102,32,95,95,98,111,111,108,95,95,40,115,101,108,102,41,
-58,10,
-//         return self.success
-32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,115,101,108,102,46,115,117,
-99,99,101,115,115,10,
-//
-10,
-//     def __nonzero__(self):
-32,32,32,32,100,101,102,32,95,95,110,111,110,122,101,114,111,95,95,40,115,101,
-108,102,41,58,10,
-//         return self.__bool__()
-32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,115,101,108,102,46,95,95,
-98,111,111,108,95,95,40,41,10,
-//
-10,
-//     def fmap(self, f):
-32,32,32,32,100,101,102,32,102,109,97,112,40,115,101,108,102,44,32,102,41,58,
-10,
-//         if self:
-32,32,32,32,32,32,32,32,105,102,32,115,101,108,102,58,10,
-//             return State(self.stream, f(self.payload))
-32,32,32,32,32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,83,116,97,116,
-101,40,115,101,108,102,46,115,116,114,101,97,109,44,32,102,40,115,101,108,102,
-46,112,97,121,108,111,97,100,41,41,10,
-//         return self
-32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,115,101,108,102,10,
-//
-10,
-// class ParsingError(Exception):
-99,108,97,115,115,32,80,97,114,115,105,110,103,69,114,114,111,114,40,69,120,
-99,101,112,116,105,111,110,41,58,10,
-//     def __init__(self, stream, msg = ''):
-32,32,32,32,100,101,102,32,95,95,105,110,105,116,95,95,40,115,101,108,102,44,
-32,115,116,114,101,97,109,44,32,109,115,103,32,61,32,39,39,41,58,10,
-//         super(ParsingError, self).__init__(msg)
-32,32,32,32,32,32,32,32,115,117,112,101,114,40,80,97,114,115,105,110,103,69,
-114,114,111,114,44,32,115,101,108,102,41,46,95,95,105,110,105,116,95,95,40,109,
-115,103,41,10,
-//         self.stream = stream
-32,32,32,32,32,32,32,32,115,101,108,102,46,115,116,114,101,97,109,32,61,32,115,
-116,114,101,97,109,10,
-//
-10,
-//     def __repr__(self):
-32,32,32,32,100,101,102,32,95,95,114,101,112,114,95,95,40,115,101,108,102,41,
-58,10,
-//         return repr(self.stream)
-32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,114,101,112,114,40,115,101,
-108,102,46,115,116,114,101,97,109,41,10,
-//
-10,
-// class Parser(object):
-99,108,97,115,115,32,80,97,114,115,101,114,40,111,98,106,101,99,116,41,58,10,
-//     def __init__(self):
-32,32,32,32,100,101,102,32,95,95,105,110,105,116,95,95,40,115,101,108,102,41,
-58,10,
-//         pass
-32,32,32,32,32,32,32,32,112,97,115,115,10,
-//
-10,
-//     def __call__(self, stream):
-32,32,32,32,100,101,102,32,95,95,99,97,108,108,95,95,40,115,101,108,102,44,32,
-115,116,114,101,97,109,41,58,10,
-//         raise NotImplementedError("pure abstract parser cannot be called")
-32,32,32,32,32,32,32,32,114,97,105,115,101,32,78,111,116,73,109,112,108,101,
-109,101,110,116,101,100,69,114,114,111,114,40,34,112,117,114,101,32,97,98,115,
-116,114,97,99,116,32,112,97,114,115,101,114,32,99,97,110,110,111,116,32,98,101,
-32,99,97,108,108,101,100,34,41,10,
-//
-10,
-//     def parse_from(self, stream):
-32,32,32,32,100,101,102,32,112,97,114,115,101,95,102,114,111,109,40,115,101,
-108,102,44,32,115,116,114,101,97,109,41,58,10,
-//         n_state = self(stream)
-32,32,32,32,32,32,32,32,110,95,115,116,97,116,101,32,61,32,115,101,108,102,40,
-115,116,114,101,97,109,41,10,
-//         if not n_state:
-32,32,32,32,32,32,32,32,105,102,32,110,111,116,32,110,95,115,116,97,116,101,
-58,10,
-//             raise ParsingError(n_state.stream, n_state.payload)
-32,32,32,32,32,32,32,32,32,32,32,32,114,97,105,115,101,32,80,97,114,115,105,
-110,103,69,114,114,111,114,40,110,95,115,116,97,116,101,46,115,116,114,101,97,
-109,44,32,110,95,115,116,97,116,101,46,112,97,121,108,111,97,100,41,10,
-//         elif not n_state.stream.end():
-32,32,32,32,32,32,32,32,101,108,105,102,32,110,111,116,32,110,95,115,116,97,
-116,101,46,115,116,114,101,97,109,46,101,110,100,40,41,58,10,
-//             raise ParsingError(n_state.stream, 'trailing unparsable input')
-32,32,32,32,32,32,32,32,32,32,32,32,114,97,105,115,101,32,80,97,114,115,105,
-110,103,69,114,114,111,114,40,110,95,115,116,97,116,101,46,115,116,114,101,97,
-109,44,32,39,116,114,97,105,108,105,110,103,32,117,110,112,97,114,115,97,98,
-108,101,32,105,110,112,117,116,39,41,10,
-//         return n_state
-32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,110,95,115,116,97,116,101,
-10,
-//
-10,
-//     def fail(self, exception):
-32,32,32,32,100,101,102,32,102,97,105,108,40,115,101,108,102,44,32,101,120,99,
-101,112,116,105,111,110,41,58,10,
-//         return State(exception.stream, str(exception), False)
-32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,83,116,97,116,101,40,101,
-120,99,101,112,116,105,111,110,46,115,116,114,101,97,109,44,32,115,116,114,40,
-101,120,99,101,112,116,105,111,110,41,44,32,70,97,108,115,101,41,10,
-//
-10,
-//     def ignore(self):
-32,32,32,32,100,101,102,32,105,103,110,111,114,101,40,115,101,108,102,41,58,
-10,
-//         return Ignore(self)
-32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,73,103,110,111,114,101,40,
-115,101,108,102,41,10,
-//
-10,
-//     def __or__(self, p):
-32,32,32,32,100,101,102,32,95,95,111,114,95,95,40,115,101,108,102,44,32,112,
-41,58,10,
-//         return Or(self, p)
-32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,79,114,40,115,101,108,102,
-44,32,112,41,10,
-//
-10,
-//     def __add__(self, p):
-32,32,32,32,100,101,102,32,95,95,97,100,100,95,95,40,115,101,108,102,44,32,112,
-41,58,10,
-//         if isinstance(self, Ignore) and isinstance(p, Ignore):
-32,32,32,32,32,32,32,32,105,102,32,105,115,105,110,115,116,97,110,99,101,40,
-115,101,108,102,44,32,73,103,110,111,114,101,41,32,97,110,100,32,105,115,105,
-110,115,116,97,110,99,101,40,112,44,32,73,103,110,111,114,101,41,58,10,
-//             return Ignore(Concat(self, p))
-32,32,32,32,32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,73,103,110,111,
-114,101,40,67,111,110,99,97,116,40,115,101,108,102,44,32,112,41,41,10,
-//         else:
-32,32,32,32,32,32,32,32,101,108,115,101,58,10,
-//             return Concat(self, p)
-32,32,32,32,32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,67,111,110,99,
-97,116,40,115,101,108,102,44,32,112,41,10,
-//
-10,
-//     def __invert__(self):
-32,32,32,32,100,101,102,32,95,95,105,110,118,101,114,116,95,95,40,115,101,108,
-102,41,58,10,
-//         return Rep(self)
-32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,82,101,112,40,115,101,108,
-102,41,10,
-//
-10,
-//     def __neg__(self):
-32,32,32,32,100,101,102,32,95,95,110,101,103,95,95,40,115,101,108,102,41,58,
-10,
-//         return Optional(self)
-32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,79,112,116,105,111,110,97,
-108,40,115,101,108,102,41,10,
-//
-10,
-//     def __pow__(self, f):
-32,32,32,32,100,101,102,32,95,95,112,111,119,95,95,40,115,101,108,102,44,32,
-102,41,58,10,
-//         return Apply(self, f)
-32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,65,112,112,108,121,40,115,
-101,108,102,44,32,102,41,10,
-//
-10,
-// class Optional(Parser):
-99,108,97,115,115,32,79,112,116,105,111,110,97,108,40,80,97,114,115,101,114,
-41,58,10,
-//     def __init__(self, opt):
-32,32,32,32,100,101,102,32,95,95,105,110,105,116,95,95,40,115,101,108,102,44,
-32,111,112,116,41,58,10,
-//         super(Optional, self).__init__()
-32,32,32,32,32,32,32,32,115,117,112,101,114,40,79,112,116,105,111,110,97,108,
-44,32,115,101,108,102,41,46,95,95,105,110,105,116,95,95,40,41,10,
-//         self.__opt = opt
-32,32,32,32,32,32,32,32,115,101,108,102,46,95,95,111,112,116,32,61,32,111,112,
-116,10,
-//
-10,
-//     def __call__(self, stream):
-32,32,32,32,100,101,102,32,95,95,99,97,108,108,95,95,40,115,101,108,102,44,32,
-115,116,114,101,97,109,41,58,10,
-//         n_state = self.__opt(stream)
-32,32,32,32,32,32,32,32,110,95,115,116,97,116,101,32,61,32,115,101,108,102,46,
-95,95,111,112,116,40,115,116,114,101,97,109,41,10,
-//         if n_state:
-32,32,32,32,32,32,32,32,105,102,32,110,95,115,116,97,116,101,58,10,
-//             return n_state.fmap(lambda x: Left(x))
-32,32,32,32,32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,110,95,115,116,
-97,116,101,46,102,109,97,112,40,108,97,109,98,100,97,32,120,58,32,76,101,102,
-116,40,120,41,41,10,
-//         return State(stream, Right(None))
-32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,83,116,97,116,101,40,115,
-116,114,101,97,109,44,32,82,105,103,104,116,40,78,111,110,101,41,41,10,
-//
-10,
-// class StrLiteral(Parser):
-99,108,97,115,115,32,83,116,114,76,105,116,101,114,97,108,40,80,97,114,115,101,
-114,41,58,10,
-//     def __init__(self, string):
-32,32,32,32,100,101,102,32,95,95,105,110,105,116,95,95,40,115,101,108,102,44,
-32,115,116,114,105,110,103,41,58,10,
-//         super(StrLiteral, self).__init__()
-32,32,32,32,32,32,32,32,115,117,112,101,114,40,83,116,114,76,105,116,101,114,
-97,108,44,32,115,101,108,102,41,46,95,95,105,110,105,116,95,95,40,41,10,
-//         self.__string = string
-32,32,32,32,32,32,32,32,115,101,108,102,46,95,95,115,116,114,105,110,103,32,
-61,32,115,116,114,105,110,103,10,
-//
-10,
-//     def __call__(self, stream):
-32,32,32,32,100,101,102,32,95,95,99,97,108,108,95,95,40,115,101,108,102,44,32,
-115,116,114,101,97,109,41,58,10,
-//         if stream.end():
-32,32,32,32,32,32,32,32,105,102,32,115,116,114,101,97,109,46,101,110,100,40,
-41,58,10,
-//             return self.fail(ParsingError(
-32,32,32,32,32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,115,101,108,102,
-46,102,97,105,108,40,80,97,114,115,105,110,103,69,114,114,111,114,40,10,
-//                 stream, 'insufficient input, expecting {}'.format(self.__string))
-32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,115,116,114,101,97,109,44,32,
-39,105,110,115,117,102,102,105,99,105,101,110,116,32,105,110,112,117,116,44,
-32,101,120,112,101,99,116,105,110,103,32,123,125,39,46,102,111,114,109,97,116,
-40,115,101,108,102,46,95,95,115,116,114,105,110,103,41,41,10,
-//             )
-32,32,32,32,32,32,32,32,32,32,32,32,41,10,
-//         try:
-32,32,32,32,32,32,32,32,116,114,121,58,10,
-//             n_stream = stream.accept_strlit(self.__string)
-32,32,32,32,32,32,32,32,32,32,32,32,110,95,115,116,114,101,97,109,32,61,32,115,
-116,114,101,97,109,46,97,99,99,101,112,116,95,115,116,114,108,105,116,40,115,
-101,108,102,46,95,95,115,116,114,105,110,103,41,10,
-//         except ParsingError as e:
-32,32,32,32,32,32,32,32,101,120,99,101,112,116,32,80,97,114,115,105,110,103,
-69,114,114,111,114,32,97,115,32,101,58,10,
-//             return self.fail(e)
-32,32,32,32,32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,115,101,108,102,
-46,102,97,105,108,40,101,41,10,
-//
-10,
-//         return State(n_stream, self.__string)
-32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,83,116,97,116,101,40,110,
-95,115,116,114,101,97,109,44,32,115,101,108,102,46,95,95,115,116,114,105,110,
-103,41,10,
-//
-10,
-// class CustomMatcher(Parser):
-99,108,97,115,115,32,67,117,115,116,111,109,77,97,116,99,104,101,114,40,80,97,
-114,115,101,114,41,58,10,
-//     def __init__(self, matcher):
-32,32,32,32,100,101,102,32,95,95,105,110,105,116,95,95,40,115,101,108,102,44,
-32,109,97,116,99,104,101,114,41,58,10,
-//         super(CustomMatcher, self).__init__()
-32,32,32,32,32,32,32,32,115,117,112,101,114,40,67,117,115,116,111,109,77,97,
-116,99,104,101,114,44,32,115,101,108,102,41,46,95,95,105,110,105,116,95,95,40,
-41,10,
-//         self.__matcher = matcher
-32,32,32,32,32,32,32,32,115,101,108,102,46,95,95,109,97,116,99,104,101,114,32,
-61,32,109,97,116,99,104,101,114,10,
-//
-10,
-//     def __call__(self, stream):
-32,32,32,32,100,101,102,32,95,95,99,97,108,108,95,95,40,115,101,108,102,44,32,
-115,116,114,101,97,109,41,58,10,
-//         try:
-32,32,32,32,32,32,32,32,116,114,121,58,10,
-//             res = stream.accept_matcher(self.__matcher)
-32,32,32,32,32,32,32,32,32,32,32,32,114,101,115,32,61,32,115,116,114,101,97,
-109,46,97,99,99,101,112,116,95,109,97,116,99,104,101,114,40,115,101,108,102,
-46,95,95,109,97,116,99,104,101,114,41,10,
-//         except ParsingError as e:
-32,32,32,32,32,32,32,32,101,120,99,101,112,116,32,80,97,114,115,105,110,103,
-69,114,114,111,114,32,97,115,32,101,58,10,
-//             return self.fail(e)
-32,32,32,32,32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,115,101,108,102,
-46,102,97,105,108,40,101,41,10,
-//
-10,
-//         obj, n_stream = res
-32,32,32,32,32,32,32,32,111,98,106,44,32,110,95,115,116,114,101,97,109,32,61,
-32,114,101,115,10,
-//         return State(n_stream, obj)
-32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,83,116,97,116,101,40,110,
-95,115,116,114,101,97,109,44,32,111,98,106,41,10,
-//
-10,
-// class Concat(Parser):
-99,108,97,115,115,32,67,111,110,99,97,116,40,80,97,114,115,101,114,41,58,10,
-//     def __init__(self, c1, c2):
-32,32,32,32,100,101,102,32,95,95,105,110,105,116,95,95,40,115,101,108,102,44,
-32,99,49,44,32,99,50,41,58,10,
-//         super(Concat, self).__init__()
-32,32,32,32,32,32,32,32,115,117,112,101,114,40,67,111,110,99,97,116,44,32,115,
-101,108,102,41,46,95,95,105,110,105,116,95,95,40,41,10,
-//         assert not isinstance(self, Ignore) or not isinstance(p, Ignore)
-32,32,32,32,32,32,32,32,97,115,115,101,114,116,32,110,111,116,32,105,115,105,
-110,115,116,97,110,99,101,40,115,101,108,102,44,32,73,103,110,111,114,101,41,
-32,111,114,32,110,111,116,32,105,115,105,110,115,116,97,110,99,101,40,112,44,
-32,73,103,110,111,114,101,41,10,
-//         self.__first = c1
-32,32,32,32,32,32,32,32,115,101,108,102,46,95,95,102,105,114,115,116,32,61,32,
-99,49,10,
-//         self.__second = c2
-32,32,32,32,32,32,32,32,115,101,108,102,46,95,95,115,101,99,111,110,100,32,61,
-32,99,50,10,
-//
-10,
-//     def __call__(self, stream):
-32,32,32,32,100,101,102,32,95,95,99,97,108,108,95,95,40,115,101,108,102,44,32,
-115,116,114,101,97,109,41,58,10,
-//         n_state = self.__first(stream)
-32,32,32,32,32,32,32,32,110,95,115,116,97,116,101,32,61,32,115,101,108,102,46,
-95,95,102,105,114,115,116,40,115,116,114,101,97,109,41,10,
-//         if not n_state:
-32,32,32,32,32,32,32,32,105,102,32,110,111,116,32,110,95,115,116,97,116,101,
-58,10,
-//             return n_state
-32,32,32,32,32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,110,95,115,116,
-97,116,101,10,
-//         p1 = n_state.payload
-32,32,32,32,32,32,32,32,112,49,32,61,32,110,95,115,116,97,116,101,46,112,97,
-121,108,111,97,100,10,
-//         n_state = self.__second(n_state.stream)
-32,32,32,32,32,32,32,32,110,95,115,116,97,116,101,32,61,32,115,101,108,102,46,
-95,95,115,101,99,111,110,100,40,110,95,115,116,97,116,101,46,115,116,114,101,
-97,109,41,10,
-//         if not n_state:
-32,32,32,32,32,32,32,32,105,102,32,110,111,116,32,110,95,115,116,97,116,101,
-58,10,
-//             return n_state
-32,32,32,32,32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,110,95,115,116,
-97,116,101,10,
-//         p2 = n_state.payload
-32,32,32,32,32,32,32,32,112,50,32,61,32,110,95,115,116,97,116,101,46,112,97,
-121,108,111,97,100,10,
-//
-10,
-//         if isinstance(self.__first, Ignore):
-32,32,32,32,32,32,32,32,105,102,32,105,115,105,110,115,116,97,110,99,101,40,
-115,101,108,102,46,95,95,102,105,114,115,116,44,32,73,103,110,111,114,101,41,
-58,10,
-//             return State(n_state.stream, p2)
-32,32,32,32,32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,83,116,97,116,
-101,40,110,95,115,116,97,116,101,46,115,116,114,101,97,109,44,32,112,50,41,10,
-//         if isinstance(self.__second, Ignore):
-32,32,32,32,32,32,32,32,105,102,32,105,115,105,110,115,116,97,110,99,101,40,
-115,101,108,102,46,95,95,115,101,99,111,110,100,44,32,73,103,110,111,114,101,
-41,58,10,
-//             return State(n_state.stream, p1)
-32,32,32,32,32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,83,116,97,116,
-101,40,110,95,115,116,97,116,101,46,115,116,114,101,97,109,44,32,112,49,41,10,
-//         # The construction of Concat ensures that at least
-32,32,32,32,32,32,32,32,35,32,84,104,101,32,99,111,110,115,116,114,117,99,116,
-105,111,110,32,111,102,32,67,111,110,99,97,116,32,101,110,115,117,114,101,115,
-32,116,104,97,116,32,97,116,32,108,101,97,115,116,10,
-//         # one of this children is not Ignore
-32,32,32,32,32,32,32,32,35,32,111,110,101,32,111,102,32,116,104,105,115,32,99,
-104,105,108,100,114,101,110,32,105,115,32,110,111,116,32,73,103,110,111,114,
-101,10,
-//         return State(n_state.stream, Pair(p1, p2))
-32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,83,116,97,116,101,40,110,
-95,115,116,97,116,101,46,115,116,114,101,97,109,44,32,80,97,105,114,40,112,49,
-44,32,112,50,41,41,10,
-//
-10,
-// class Or(Parser):
-99,108,97,115,115,32,79,114,40,80,97,114,115,101,114,41,58,10,
-//     def __init__(self, c1, c2):
-32,32,32,32,100,101,102,32,95,95,105,110,105,116,95,95,40,115,101,108,102,44,
-32,99,49,44,32,99,50,41,58,10,
-//         super(Or, self).__init__()
-32,32,32,32,32,32,32,32,115,117,112,101,114,40,79,114,44,32,115,101,108,102,
-41,46,95,95,105,110,105,116,95,95,40,41,10,
-//         self.__if = c1
-32,32,32,32,32,32,32,32,115,101,108,102,46,95,95,105,102,32,61,32,99,49,10,
-//         self.__else = c2
-32,32,32,32,32,32,32,32,115,101,108,102,46,95,95,101,108,115,101,32,61,32,99,
-50,10,
-//
-10,
-//     def __call__(self, stream):
-32,32,32,32,100,101,102,32,95,95,99,97,108,108,95,95,40,115,101,108,102,44,32,
-115,116,114,101,97,109,41,58,10,
-//         n_state = self.__if(stream)
-32,32,32,32,32,32,32,32,110,95,115,116,97,116,101,32,61,32,115,101,108,102,46,
-95,95,105,102,40,115,116,114,101,97,109,41,10,
-//         if n_state:
-32,32,32,32,32,32,32,32,105,102,32,110,95,115,116,97,116,101,58,10,
-//             return n_state.fmap(lambda x: Left(x))
-32,32,32,32,32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,110,95,115,116,
-97,116,101,46,102,109,97,112,40,108,97,109,98,100,97,32,120,58,32,76,101,102,
-116,40,120,41,41,10,
-//         n_state = self.__else(stream)
-32,32,32,32,32,32,32,32,110,95,115,116,97,116,101,32,61,32,115,101,108,102,46,
-95,95,101,108,115,101,40,115,116,114,101,97,109,41,10,
-//         if n_state:
-32,32,32,32,32,32,32,32,105,102,32,110,95,115,116,97,116,101,58,10,
-//             return n_state.fmap(lambda x: Right(x))
-32,32,32,32,32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,110,95,115,116,
-97,116,101,46,102,109,97,112,40,108,97,109,98,100,97,32,120,58,32,82,105,103,
-104,116,40,120,41,41,10,
-//         return n_state
-32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,110,95,115,116,97,116,101,
-10,
-//
-10,
-// class Rep(Parser):
-99,108,97,115,115,32,82,101,112,40,80,97,114,115,101,114,41,58,10,
-//     def __init__(self, c):
-32,32,32,32,100,101,102,32,95,95,105,110,105,116,95,95,40,115,101,108,102,44,
-32,99,41,58,10,
-//         super(Rep, self).__init__()
-32,32,32,32,32,32,32,32,115,117,112,101,114,40,82,101,112,44,32,115,101,108,
-102,41,46,95,95,105,110,105,116,95,95,40,41,10,
-//         self.__loop = c
-32,32,32,32,32,32,32,32,115,101,108,102,46,95,95,108,111,111,112,32,61,32,99,
-10,
-//
-10,
-//     def __call__(self, stream):
-32,32,32,32,100,101,102,32,95,95,99,97,108,108,95,95,40,115,101,108,102,44,32,
-115,116,114,101,97,109,41,58,10,
-//         payload = []
-32,32,32,32,32,32,32,32,112,97,121,108,111,97,100,32,61,32,91,93,10,
-//
-10,
-//         n_state = self.__loop(stream)
-32,32,32,32,32,32,32,32,110,95,115,116,97,116,101,32,61,32,115,101,108,102,46,
-95,95,108,111,111,112,40,115,116,114,101,97,109,41,10,
-//         if n_state:
-32,32,32,32,32,32,32,32,105,102,32,110,95,115,116,97,116,101,58,10,
-//             payload.append(n_state.payload)
-32,32,32,32,32,32,32,32,32,32,32,32,112,97,121,108,111,97,100,46,97,112,112,
-101,110,100,40,110,95,115,116,97,116,101,46,112,97,121,108,111,97,100,41,10,
-//             stream = n_state.stream
-32,32,32,32,32,32,32,32,32,32,32,32,115,116,114,101,97,109,32,61,32,110,95,115,
-116,97,116,101,46,115,116,114,101,97,109,10,
-//             n_state = self(stream)
-32,32,32,32,32,32,32,32,32,32,32,32,110,95,115,116,97,116,101,32,61,32,115,101,
-108,102,40,115,116,114,101,97,109,41,10,
-//             if n_state:
-32,32,32,32,32,32,32,32,32,32,32,32,105,102,32,110,95,115,116,97,116,101,58,
-10,
-//                 payload = payload + n_state.payload
-32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,112,97,121,108,111,97,100,32,
-61,32,112,97,121,108,111,97,100,32,43,32,110,95,115,116,97,116,101,46,112,97,
-121,108,111,97,100,10,
-//                 stream = n_state.stream
-32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,115,116,114,101,97,109,32,61,
-32,110,95,115,116,97,116,101,46,115,116,114,101,97,109,10,
-//         return State(stream, payload)
-32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,83,116,97,116,101,40,115,
-116,114,101,97,109,44,32,112,97,121,108,111,97,100,41,10,
-//
-10,
-// class Apply(Parser):
-99,108,97,115,115,32,65,112,112,108,121,40,80,97,114,115,101,114,41,58,10,
-//     def __init__(self, base, f):
-32,32,32,32,100,101,102,32,95,95,105,110,105,116,95,95,40,115,101,108,102,44,
-32,98,97,115,101,44,32,102,41,58,10,
-//         super(Apply, self).__init__()
-32,32,32,32,32,32,32,32,115,117,112,101,114,40,65,112,112,108,121,44,32,115,
-101,108,102,41,46,95,95,105,110,105,116,95,95,40,41,10,
-//         self.__base = base
-32,32,32,32,32,32,32,32,115,101,108,102,46,95,95,98,97,115,101,32,61,32,98,97,
-115,101,10,
-//         self.__trans = f
-32,32,32,32,32,32,32,32,115,101,108,102,46,95,95,116,114,97,110,115,32,61,32,
-102,10,
-//
-10,
-//     def __call__(self, stream):
-32,32,32,32,100,101,102,32,95,95,99,97,108,108,95,95,40,115,101,108,102,44,32,
-115,116,114,101,97,109,41,58,10,
-//         return self.__base(stream).fmap(self.__trans)
-32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,115,101,108,102,46,95,95,
-98,97,115,101,40,115,116,114,101,97,109,41,46,102,109,97,112,40,115,101,108,
-102,46,95,95,116,114,97,110,115,41,10,
-//
-10,
-// class Ignore(Parser):
-99,108,97,115,115,32,73,103,110,111,114,101,40,80,97,114,115,101,114,41,58,10,
-//     def __init__(self, base):
-32,32,32,32,100,101,102,32,95,95,105,110,105,116,95,95,40,115,101,108,102,44,
-32,98,97,115,101,41,58,10,
-//         super(Ignore, self).__init__()
-32,32,32,32,32,32,32,32,115,117,112,101,114,40,73,103,110,111,114,101,44,32,
-115,101,108,102,41,46,95,95,105,110,105,116,95,95,40,41,10,
-//         self.__base = base
-32,32,32,32,32,32,32,32,115,101,108,102,46,95,95,98,97,115,101,32,61,32,98,97,
-115,101,10,
-//
-10,
-//     def __call__(self, stream):
-32,32,32,32,100,101,102,32,95,95,99,97,108,108,95,95,40,115,101,108,102,44,32,
-115,116,114,101,97,109,41,58,10,
-//         return self.__base(stream)
-32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,115,101,108,102,46,95,95,
-98,97,115,101,40,115,116,114,101,97,109,41,10,
-//
-10,
-// ###############################################################################
-35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,
-35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,
-35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,
-35,10,
-// # Grammars for PERM model configuration
-35,32,71,114,97,109,109,97,114,115,32,102,111,114,32,80,69,82,77,32,109,111,
-100,101,108,32,99,111,110,102,105,103,117,114,97,116,105,111,110,32,10,
-// ###############################################################################
-35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,
-35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,
-35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,
-35,10,
-// from operator import or_, add
-102,114,111,109,32,111,112,101,114,97,116,111,114,32,105,109,112,111,114,116,
-32,111,114,95,44,32,97,100,100,10,
-//
-10,
-// def extract(nested_or):
-100,101,102,32,101,120,116,114,97,99,116,40,110,101,115,116,101,100,95,111,114,
-41,58,10,
-//     while isinstance(nested_or, Either):
-32,32,32,32,119,104,105,108,101,32,105,115,105,110,115,116,97,110,99,101,40,
-110,101,115,116,101,100,95,111,114,44,32,69,105,116,104,101,114,41,58,10,
-//         nested_or = nested_or.left() if nested_or.is_left() else nested_or.right()
-32,32,32,32,32,32,32,32,110,101,115,116,101,100,95,111,114,32,61,32,110,101,
-115,116,101,100,95,111,114,46,108,101,102,116,40,41,32,105,102,32,110,101,115,
-116,101,100,95,111,114,46,105,115,95,108,101,102,116,40,41,32,101,108,115,101,
-32,110,101,115,116,101,100,95,111,114,46,114,105,103,104,116,40,41,10,
-//     return nested_or
-32,32,32,32,114,101,116,117,114,110,32,110,101,115,116,101,100,95,111,114,10,
-//
-10,
-// def flatten(nested_concat):
-100,101,102,32,102,108,97,116,116,101,110,40,110,101,115,116,101,100,95,99,111,
-110,99,97,116,41,58,10,
-//     res = []
-32,32,32,32,114,101,115,32,61,32,91,93,10,
-//
-10,
-//     def pre_order(pair, res):
-32,32,32,32,100,101,102,32,112,114,101,95,111,114,100,101,114,40,112,97,105,
-114,44,32,114,101,115,41,58,10,
-//         if isinstance(pair, Pair):
-32,32,32,32,32,32,32,32,105,102,32,105,115,105,110,115,116,97,110,99,101,40,
-112,97,105,114,44,32,80,97,105,114,41,58,10,
-//             pre_order(pair[0], res)
-32,32,32,32,32,32,32,32,32,32,32,32,112,114,101,95,111,114,100,101,114,40,112,
-97,105,114,91,48,93,44,32,114,101,115,41,10,
-//             pre_order(pair[1], res)
-32,32,32,32,32,32,32,32,32,32,32,32,112,114,101,95,111,114,100,101,114,40,112,
-97,105,114,91,49,93,44,32,114,101,115,41,10,
-//         else:
-32,32,32,32,32,32,32,32,101,108,115,101,58,10,
-//             res.append(pair)
-32,32,32,32,32,32,32,32,32,32,32,32,114,101,115,46,97,112,112,101,110,100,40,
-112,97,105,114,41,10,
-//
-10,
-//     pre_order(nested_concat, res)
-32,32,32,32,112,114,101,95,111,114,100,101,114,40,110,101,115,116,101,100,95,
-99,111,110,99,97,116,44,32,114,101,115,41,10,
-//     return res
-32,32,32,32,114,101,116,117,114,110,32,114,101,115,10,
-//
-10,
-// def one_of(parsers):
-100,101,102,32,111,110,101,95,111,102,40,112,97,114,115,101,114,115,41,58,10,
-//     nested = reduce(or_, parsers)
-32,32,32,32,110,101,115,116,101,100,32,61,32,114,101,100,117,99,101,40,111,114,
-95,44,32,112,97,114,115,101,114,115,41,10,
-//     return nested ** extract
-32,32,32,32,114,101,116,117,114,110,32,110,101,115,116,101,100,32,42,42,32,101,
-120,116,114,97,99,116,10,
-//
-10,
-// def join(sl):
-100,101,102,32,106,111,105,110,40,115,108,41,58,10,
-//     return ''.join(sl)
-32,32,32,32,114,101,116,117,114,110,32,39,39,46,106,111,105,110,40,115,108,41,
-10,
-//
-10,
-// def rep_with_sep(to_rep, sep):
-100,101,102,32,114,101,112,95,119,105,116,104,95,115,101,112,40,116,111,95,114,
-101,112,44,32,115,101,112,41,58,10,
-//     if not isinstance(sep, Ignore):
-32,32,32,32,105,102,32,110,111,116,32,105,115,105,110,115,116,97,110,99,101,
-40,115,101,112,44,32,73,103,110,111,114,101,41,58,10,
-//         sep = sep.ignore()
-32,32,32,32,32,32,32,32,115,101,112,32,61,32,115,101,112,46,105,103,110,111,
-114,101,40,41,10,
-//     r = to_rep + ~(sep + to_rep)
-32,32,32,32,114,32,61,32,116,111,95,114,101,112,32,43,32,126,40,115,101,112,
-32,43,32,116,111,95,114,101,112,41,10,
-//     r = r ** (lambda x: [x[0]] + x[1])
-32,32,32,32,114,32,61,32,114,32,42,42,32,40,108,97,109,98,100,97,32,120,58,32,
-91,120,91,48,93,93,32,43,32,120,91,49,93,41,10,
-//     return r
-32,32,32,32,114,101,116,117,114,110,32,114,10,
-//
-10,
-// ALPHA = set('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
-65,76,80,72,65,32,61,32,115,101,116,40,39,97,98,99,100,101,102,103,104,105,106,
-107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,65,66,67,68,
-69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,39,41,10,
-// DIGIT = set('0123456789')
-68,73,71,73,84,32,61,32,115,101,116,40,39,48,49,50,51,52,53,54,55,56,57,39,41,
-10,
-// ALPHA_DIGIT = ALPHA | DIGIT
-65,76,80,72,65,95,68,73,71,73,84,32,61,32,65,76,80,72,65,32,124,32,68,73,71,
-73,84,10,
-//
-10,
-// Alpha = one_of(map(StrLiteral, ALPHA))
-65,108,112,104,97,32,61,32,111,110,101,95,111,102,40,109,97,112,40,83,116,114,
-76,105,116,101,114,97,108,44,32,65,76,80,72,65,41,41,10,
-// Digit = one_of(map(StrLiteral, DIGIT))
-68,105,103,105,116,32,61,32,111,110,101,95,111,102,40,109,97,112,40,83,116,114,
-76,105,116,101,114,97,108,44,32,68,73,71,73,84,41,41,10,
-//
-10,
-// Equal, Comma, Dot = [StrLiteral(c).ignore() for c in ['=', ',', '.']]
-69,113,117,97,108,44,32,67,111,109,109,97,44,32,68,111,116,32,61,32,91,83,116,
-114,76,105,116,101,114,97,108,40,99,41,46,105,103,110,111,114,101,40,41,32,102,
-111,114,32,99,32,105,110,32,91,39,61,39,44,32,39,44,39,44,32,39,46,39,93,93,
-10,
-// Underscore = StrLiteral('_')
-85,110,100,101,114,115,99,111,114,101,32,61,32,83,116,114,76,105,116,101,114,
-97,108,40,39,95,39,41,10,
-// NewLine = (~ StrLiteral('\n')).ignore()
-78,101,119,76,105,110,101,32,61,32,40,126,32,83,116,114,76,105,116,101,114,97,
-108,40,39,92,110,39,41,41,46,105,103,110,111,114,101,40,41,10,
-//
-10,
-// def identifier_matcher(text, pos):
-100,101,102,32,105,100,101,110,116,105,102,105,101,114,95,109,97,116,99,104,
-101,114,40,116,101,120,116,44,32,112,111,115,41,58,10,
-//     """identifier"""
-32,32,32,32,34,34,34,105,100,101,110,116,105,102,105,101,114,34,34,34,10,
-//     end = len(text)
-32,32,32,32,101,110,100,32,61,32,108,101,110,40,116,101,120,116,41,10,
-//     start = pos
-32,32,32,32,115,116,97,114,116,32,61,32,112,111,115,10,
-//     if pos >= end:
-32,32,32,32,105,102,32,112,111,115,32,62,61,32,101,110,100,58,10,
-//         return None
-32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,78,111,110,101,10,
-//     first = text[pos]
-32,32,32,32,102,105,114,115,116,32,61,32,116,101,120,116,91,112,111,115,93,10,
-//     if first != '_' and first not in ALPHA:
-32,32,32,32,105,102,32,102,105,114,115,116,32,33,61,32,39,95,39,32,97,110,100,
-32,102,105,114,115,116,32,110,111,116,32,105,110,32,65,76,80,72,65,58,10,
-//         return None
-32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,78,111,110,101,10,
-//     pos += 1
-32,32,32,32,112,111,115,32,43,61,32,49,10,
-//     while pos < end:
-32,32,32,32,119,104,105,108,101,32,112,111,115,32,60,32,101,110,100,58,10,
-//         char = text[pos]
-32,32,32,32,32,32,32,32,99,104,97,114,32,61,32,116,101,120,116,91,112,111,115,
-93,10,
-//         if char == '_' or char in ALPHA_DIGIT:
-32,32,32,32,32,32,32,32,105,102,32,99,104,97,114,32,61,61,32,39,95,39,32,111,
-114,32,99,104,97,114,32,105,110,32,65,76,80,72,65,95,68,73,71,73,84,58,10,
-//             pos += 1
-32,32,32,32,32,32,32,32,32,32,32,32,112,111,115,32,43,61,32,49,10,
-//         else:
-32,32,32,32,32,32,32,32,101,108,115,101,58,10,
-//             break
-32,32,32,32,32,32,32,32,32,32,32,32,98,114,101,97,107,10,
-//     return text[start:pos], pos
-32,32,32,32,114,101,116,117,114,110,32,116,101,120,116,91,115,116,97,114,116,
-58,112,111,115,93,44,32,112,111,115,10,
-//
-10,
-// Identifier = CustomMatcher(identifier_matcher)
-73,100,101,110,116,105,102,105,101,114,32,61,32,67,117,115,116,111,109,77,97,
-116,99,104,101,114,40,105,100,101,110,116,105,102,105,101,114,95,109,97,116,
-99,104,101,114,41,10,
-//
-10,
-// IdTuple = rep_with_sep(Identifier, Comma)
-73,100,84,117,112,108,101,32,61,32,114,101,112,95,119,105,116,104,95,115,101,
-112,40,73,100,101,110,116,105,102,105,101,114,44,32,67,111,109,109,97,41,10,
-//
-10,
-// Definition = Identifier + Equal + IdTuple + NewLine
-68,101,102,105,110,105,116,105,111,110,32,61,32,73,100,101,110,116,105,102,105,
-101,114,32,43,32,69,113,117,97,108,32,43,32,73,100,84,117,112,108,101,32,43,
-32,78,101,119,76,105,110,101,10,
-//
-10,
-// Relation = Identifier + Equal + IdTuple + NewLine
-82,101,108,97,116,105,111,110,32,61,32,73,100,101,110,116,105,102,105,101,114,
-32,43,32,69,113,117,97,108,32,43,32,73,100,84,117,112,108,101,32,43,32,78,101,
-119,76,105,110,101,10,
-// Relation = Relation ** (lambda x: (x[0], 1 + len(x[1][1])))
-82,101,108,97,116,105,111,110,32,61,32,82,101,108,97,116,105,111,110,32,42,42,
-32,40,108,97,109,98,100,97,32,120,58,32,40,120,91,48,93,44,32,49,32,43,32,108,
-101,110,40,120,91,49,93,91,49,93,41,41,41,10,
-//
-10,
-// def pyparser_matcher(text, pos):
-100,101,102,32,112,121,112,97,114,115,101,114,95,109,97,116,99,104,101,114,40,
-116,101,120,116,44,32,112,111,115,41,58,10,
-//     """syntactically correct python code"""
-32,32,32,32,34,34,34,115,121,110,116,97,99,116,105,99,97,108,108,121,32,99,111,
-114,114,101,99,116,32,112,121,116,104,111,110,32,99,111,100,101,34,34,34,10,
-//     line_end = text.find('\n', pos)
-32,32,32,32,108,105,110,101,95,101,110,100,32,61,32,116,101,120,116,46,102,105,
-110,100,40,39,92,110,39,44,32,112,111,115,41,10,
-//     if line_end == -1:
-32,32,32,32,105,102,32,108,105,110,101,95,101,110,100,32,61,61,32,45,49,58,10,
-//         return None
-32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,78,111,110,101,10,
-//     try:
-32,32,32,32,116,114,121,58,10,
-//         c = compile(text[pos:line_end], '__abac_model__.py', 'eval')
-32,32,32,32,32,32,32,32,99,32,61,32,99,111,109,112,105,108,101,40,116,101,120,
-116,91,112,111,115,58,108,105,110,101,95,101,110,100,93,44,32,39,95,95,97,98,
-97,99,95,109,111,100,101,108,95,95,46,112,121,39,44,32,39,101,118,97,108,39,
-41,10,
-//     except SyntaxError:
-32,32,32,32,101,120,99,101,112,116,32,83,121,110,116,97,120,69,114,114,111,114,
-58,10,
-//         return None
-32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,78,111,110,101,10,
-//     return c, line_end
-32,32,32,32,114,101,116,117,114,110,32,99,44,32,108,105,110,101,95,101,110,100,
-10,
-//
-10,
-// PyExpr = CustomMatcher(pyparser_matcher)
-80,121,69,120,112,114,32,61,32,67,117,115,116,111,109,77,97,116,99,104,101,114,
-40,112,121,112,97,114,115,101,114,95,109,97,116,99,104,101,114,41,10,
-// Matcher = Identifier + Equal + PyExpr + NewLine
-77,97,116,99,104,101,114,32,61,32,73,100,101,110,116,105,102,105,101,114,32,
-43,32,69,113,117,97,108,32,43,32,80,121,69,120,112,114,32,43,32,78,101,119,76,
-105,110,101,10,
-//
-10,
-// RequestDefHeader = StrLiteral('[requests]') + NewLine
-82,101,113,117,101,115,116,68,101,102,72,101,97,100,101,114,32,61,32,83,116,
-114,76,105,116,101,114,97,108,40,39,91,114,101,113,117,101,115,116,115,93,39,
-41,32,43,32,78,101,119,76,105,110,101,10,
-// TermDefHeader    = StrLiteral('[terms]') + NewLine
-84,101,114,109,68,101,102,72,101,97,100,101,114,32,32,32,32,61,32,83,116,114,
-76,105,116,101,114,97,108,40,39,91,116,101,114,109,115,93,39,41,32,43,32,78,
-101,119,76,105,110,101,10,
-// MatchersHeader   = StrLiteral('[matchers]') + NewLine
-77,97,116,99,104,101,114,115,72,101,97,100,101,114,32,32,32,61,32,83,116,114,
-76,105,116,101,114,97,108,40,39,91,109,97,116,99,104,101,114,115,93,39,41,32,
-43,32,78,101,119,76,105,110,101,10,
-//
-10,
-// RequestDefSec = RequestDefHeader.ignore() + ~Definition
-82,101,113,117,101,115,116,68,101,102,83,101,99,32,61,32,82,101,113,117,101,
-115,116,68,101,102,72,101,97,100,101,114,46,105,103,110,111,114,101,40,41,32,
-43,32,126,68,101,102,105,110,105,116,105,111,110,10,
-// TermDefSec = TermDefHeader.ignore() + ~Definition
-84,101,114,109,68,101,102,83,101,99,32,61,32,84,101,114,109,68,101,102,72,101,
-97,100,101,114,46,105,103,110,111,114,101,40,41,32,43,32,126,68,101,102,105,
-110,105,116,105,111,110,10,
-// MatchersSec = MatchersHeader.ignore() + ~Matcher
-77,97,116,99,104,101,114,115,83,101,99,32,61,32,77,97,116,99,104,101,114,115,
-72,101,97,100,101,114,46,105,103,110,111,114,101,40,41,32,43,32,126,77,97,116,
-99,104,101,114,10,
-//
-10,
-// ModelDef = (RequestDefSec + TermDefSec + MatchersSec) ** flatten
-77,111,100,101,108,68,101,102,32,61,32,40,82,101,113,117,101,115,116,68,101,
-102,83,101,99,32,43,32,84,101,114,109,68,101,102,83,101,99,32,43,32,77,97,116,
-99,104,101,114,115,83,101,99,41,32,42,42,32,102,108,97,116,116,101,110,10,
-//
-10,
-// def preprocess(conf):
-100,101,102,32,112,114,101,112,114,111,99,101,115,115,40,99,111,110,102,41,58,
-10,
-//     # process escaped line breaks
-32,32,32,32,35,32,112,114,111,99,101,115,115,32,101,115,99,97,112,101,100,32,
-108,105,110,101,32,98,114,101,97,107,115,10,
-//     conf = conf.replace('\\\n', '')
-32,32,32,32,99,111,110,102,32,61,32,99,111,110,102,46,114,101,112,108,97,99,
-101,40,39,92,92,92,110,39,44,32,39,39,41,10,
-//     # remove comments
-32,32,32,32,35,32,114,101,109,111,118,101,32,99,111,109,109,101,110,116,115,
-32,32,32,32,10,
-//     conf = '\n'.join(line.partition('#')[0] for line in conf.splitlines())
-32,32,32,32,99,111,110,102,32,61,32,39,92,110,39,46,106,111,105,110,40,108,105,
-110,101,46,112,97,114,116,105,116,105,111,110,40,39,35,39,41,91,48,93,32,102,
-111,114,32,108,105,110,101,32,105,110,32,99,111,110,102,46,115,112,108,105,116,
-108,105,110,101,115,40,41,41,10,
-//     # remove redundant new lines
-32,32,32,32,35,32,114,101,109,111,118,101,32,114,101,100,117,110,100,97,110,
-116,32,110,101,119,32,108,105,110,101,115,10,
-//     conf = conf.strip()
-32,32,32,32,99,111,110,102,32,61,32,99,111,110,102,46,115,116,114,105,112,40,
-41,10,
-//
-10,
-//     return conf + '\n'
-32,32,32,32,114,101,116,117,114,110,32,99,111,110,102,32,43,32,39,92,110,39,
-10,
-//
-10,
-// def parse_model(text):
-100,101,102,32,112,97,114,115,101,95,109,111,100,101,108,40,116,101,120,116,
-41,58,10,
-//     text = preprocess(text)
-32,32,32,32,116,101,120,116,32,61,32,112,114,101,112,114,111,99,101,115,115,
-40,116,101,120,116,41,10,
-//     raw_model = ModelDef.parse_from(Stream(text)).payload
-32,32,32,32,114,97,119,95,109,111,100,101,108,32,61,32,77,111,100,101,108,68,
-101,102,46,112,97,114,115,101,95,102,114,111,109,40,83,116,114,101,97,109,40,
-116,101,120,116,41,41,46,112,97,121,108,111,97,100,10,
-//     return raw_model
-32,32,32,32,114,101,116,117,114,110,32,114,97,119,95,109,111,100,101,108,10,
-//
-10,
-// class InvalidModelDefinition(Exception):
-99,108,97,115,115,32,73,110,118,97,108,105,100,77,111,100,101,108,68,101,102,
-105,110,105,116,105,111,110,40,69,120,99,101,112,116,105,111,110,41,58,10,
-//     def __init__(self, msg = ''):
-32,32,32,32,100,101,102,32,95,95,105,110,105,116,95,95,40,115,101,108,102,44,
-32,109,115,103,32,61,32,39,39,41,58,10,
-//         super(InvalidModelDefinition, self).__init__(msg)
-32,32,32,32,32,32,32,32,115,117,112,101,114,40,73,110,118,97,108,105,100,77,
-111,100,101,108,68,101,102,105,110,105,116,105,111,110,44,32,115,101,108,102,
-41,46,95,95,105,110,105,116,95,95,40,109,115,103,41,32,32,32,32,32,32,32,32,
-10,
-//
-10,
-//     @staticmethod
-32,32,32,32,64,115,116,97,116,105,99,109,101,116,104,111,100,10,
-//     def redundant_def(redefined_vars, g1, g2):
-32,32,32,32,100,101,102,32,114,101,100,117,110,100,97,110,116,95,100,101,102,
-40,114,101,100,101,102,105,110,101,100,95,118,97,114,115,44,32,103,49,44,32,
-103,50,41,58,10,
-//         msg_parts = [
-32,32,32,32,32,32,32,32,109,115,103,95,112,97,114,116,115,32,61,32,91,10,
-//             'multiple definition(s) of identifiers(s)',
-32,32,32,32,32,32,32,32,32,32,32,32,39,109,117,108,116,105,112,108,101,32,100,
-101,102,105,110,105,116,105,111,110,40,115,41,32,111,102,32,105,100,101,110,
-116,105,102,105,101,114,115,40,115,41,39,44,10,
-//             ', '.join(redfined_vars),
-32,32,32,32,32,32,32,32,32,32,32,32,39,44,32,39,46,106,111,105,110,40,114,101,
-100,102,105,110,101,100,95,118,97,114,115,41,44,10,
-//             'found in sections',
-32,32,32,32,32,32,32,32,32,32,32,32,39,102,111,117,110,100,32,105,110,32,115,
-101,99,116,105,111,110,115,39,44,10,
-//             g1, g2
-32,32,32,32,32,32,32,32,32,32,32,32,103,49,44,32,103,50,10,
-//         ]
-32,32,32,32,32,32,32,32,93,10,
-//         return InvalidModelDefinition(''.join(msg_parts))
-32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,73,110,118,97,108,105,100,
-77,111,100,101,108,68,101,102,105,110,105,116,105,111,110,40,39,39,46,106,111,
-105,110,40,109,115,103,95,112,97,114,116,115,41,41,10,
-//
-10,
-//     @staticmethod
-32,32,32,32,64,115,116,97,116,105,99,109,101,116,104,111,100,10,
-//     def missing_matchers(missing_matchers):
-32,32,32,32,100,101,102,32,109,105,115,115,105,110,103,95,109,97,116,99,104,
-101,114,115,40,109,105,115,115,105,110,103,95,109,97,116,99,104,101,114,115,
-41,58,10,
-//         msg = 'missing matcher(s) for request type(s): {}'
-32,32,32,32,32,32,32,32,109,115,103,32,61,32,39,109,105,115,115,105,110,103,
-32,109,97,116,99,104,101,114,40,115,41,32,102,111,114,32,114,101,113,117,101,
-115,116,32,116,121,112,101,40,115,41,58,32,123,125,39,10,
-//         return InvalidModelDefinition(msg.format(', '.join(missing_matchers)))
-32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,73,110,118,97,108,105,100,
-77,111,100,101,108,68,101,102,105,110,105,116,105,111,110,40,109,115,103,46,
-102,111,114,109,97,116,40,39,44,32,39,46,106,111,105,110,40,109,105,115,115,
-105,110,103,95,109,97,116,99,104,101,114,115,41,41,41,10,
-//
-10,
-//     @staticmethod
-32,32,32,32,64,115,116,97,116,105,99,109,101,116,104,111,100,10,
-//     def unknown_requests(unknown_requests):
-32,32,32,32,100,101,102,32,117,110,107,110,111,119,110,95,114,101,113,117,101,
-115,116,115,40,117,110,107,110,111,119,110,95,114,101,113,117,101,115,116,115,
-41,58,10,
-//         msg = 'matcher(s) defined for unknown request type(s): {}'
-32,32,32,32,32,32,32,32,109,115,103,32,61,32,39,109,97,116,99,104,101,114,40,
-115,41,32,100,101,102,105,110,101,100,32,102,111,114,32,117,110,107,110,111,
-119,110,32,114,101,113,117,101,115,116,32,116,121,112,101,40,115,41,58,32,123,
-125,39,10,
-//         return InvalidModelDefinition(msg.format(', '.join(unknown_requests)))
-32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,73,110,118,97,108,105,100,
-77,111,100,101,108,68,101,102,105,110,105,116,105,111,110,40,109,115,103,46,
-102,111,114,109,97,116,40,39,44,32,39,46,106,111,105,110,40,117,110,107,110,
-111,119,110,95,114,101,113,117,101,115,116,115,41,41,41,10,
-//
-10,
-// class Request(object):
-99,108,97,115,115,32,82,101,113,117,101,115,116,40,111,98,106,101,99,116,41,
-58,10,
-//     def __init__(self, attrs, vals):
-32,32,32,32,100,101,102,32,95,95,105,110,105,116,95,95,40,115,101,108,102,44,
-32,97,116,116,114,115,44,32,118,97,108,115,41,58,10,
-//         assert len(attrs) == len(vals)
-32,32,32,32,32,32,32,32,97,115,115,101,114,116,32,108,101,110,40,97,116,116,
-114,115,41,32,61,61,32,108,101,110,40,118,97,108,115,41,10,
-//         self.__named_attrs = attrs
-32,32,32,32,32,32,32,32,115,101,108,102,46,95,95,110,97,109,101,100,95,97,116,
-116,114,115,32,61,32,97,116,116,114,115,10,
-//         for attr, val in zip(attrs, vals):
-32,32,32,32,32,32,32,32,102,111,114,32,97,116,116,114,44,32,118,97,108,32,105,
-110,32,122,105,112,40,97,116,116,114,115,44,32,118,97,108,115,41,58,10,
-//             setattr(self, attr, val)
-32,32,32,32,32,32,32,32,32,32,32,32,115,101,116,97,116,116,114,40,115,101,108,
-102,44,32,97,116,116,114,44,32,118,97,108,41,10,
-//
-10,
-//     def __repr__(self):
-32,32,32,32,100,101,102,32,95,95,114,101,112,114,95,95,40,115,101,108,102,41,
-58,10,
-//         parts = ['Request {\n']
-32,32,32,32,32,32,32,32,112,97,114,116,115,32,61,32,91,39,82,101,113,117,101,
-115,116,32,123,92,110,39,93,10,
-//         for attr in self.__named_attrs:
-32,32,32,32,32,32,32,32,102,111,114,32,97,116,116,114,32,105,110,32,115,101,
-108,102,46,95,95,110,97,109,101,100,95,97,116,116,114,115,58,10,
-//             parts.append('  ')
-32,32,32,32,32,32,32,32,32,32,32,32,112,97,114,116,115,46,97,112,112,101,110,
-100,40,39,32,32,39,41,10,
-//             parts.append(attr)
-32,32,32,32,32,32,32,32,32,32,32,32,112,97,114,116,115,46,97,112,112,101,110,
-100,40,97,116,116,114,41,10,
-//             parts.append(': ')
-32,32,32,32,32,32,32,32,32,32,32,32,112,97,114,116,115,46,97,112,112,101,110,
-100,40,39,58,32,39,41,10,
-//             parts.append(repr(getattr(self, attr)))
-32,32,32,32,32,32,32,32,32,32,32,32,112,97,114,116,115,46,97,112,112,101,110,
-100,40,114,101,112,114,40,103,101,116,97,116,116,114,40,115,101,108,102,44,32,
-97,116,116,114,41,41,41,10,
-//             parts.append('\n')
-32,32,32,32,32,32,32,32,32,32,32,32,112,97,114,116,115,46,97,112,112,101,110,
-100,40,39,92,110,39,41,10,
-//         parts.append('}\n')
-32,32,32,32,32,32,32,32,112,97,114,116,115,46,97,112,112,101,110,100,40,39,125,
-92,110,39,41,10,
-//         return ''.join(parts)
-32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,39,39,46,106,111,105,110,
-40,112,97,114,116,115,41,10,
-//
-10,
-// class QueryResult(object):
-99,108,97,115,115,32,81,117,101,114,121,82,101,115,117,108,116,40,111,98,106,
-101,99,116,41,58,10,
-//     def __init__(self, generator):
-32,32,32,32,100,101,102,32,95,95,105,110,105,116,95,95,40,115,101,108,102,44,
-32,103,101,110,101,114,97,116,111,114,41,58,10,
-//         self.__gen = generator
-32,32,32,32,32,32,32,32,115,101,108,102,46,95,95,103,101,110,32,61,32,103,101,
-110,101,114,97,116,111,114,10,
-//
-10,
-//     def __iter__(self):
-32,32,32,32,100,101,102,32,95,95,105,116,101,114,95,95,40,115,101,108,102,41,
-58,10,
-//         return self.__gen
-32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,115,101,108,102,46,95,95,
-103,101,110,10,
-//
-10,
-//     def __le__(self, iterable):
-32,32,32,32,100,101,102,32,95,95,108,101,95,95,40,115,101,108,102,44,32,105,
-116,101,114,97,98,108,101,41,58,10,
-//         return set(self) <= set(iterable)
-32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,115,101,116,40,115,101,108,
-102,41,32,60,61,32,115,101,116,40,105,116,101,114,97,98,108,101,41,10,
-//
-10,
-//     def __lt__(self, iterable):
-32,32,32,32,100,101,102,32,95,95,108,116,95,95,40,115,101,108,102,44,32,105,
-116,101,114,97,98,108,101,41,58,10,
-//         return set(self) < set(iterable)
-32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,115,101,116,40,115,101,108,
-102,41,32,60,32,115,101,116,40,105,116,101,114,97,98,108,101,41,10,
-//
-10,
-//     def __ge__(self, iterable):
-32,32,32,32,100,101,102,32,95,95,103,101,95,95,40,115,101,108,102,44,32,105,
-116,101,114,97,98,108,101,41,58,10,
-//         return set(self) >= set(iterable)
-32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,115,101,116,40,115,101,108,
-102,41,32,62,61,32,115,101,116,40,105,116,101,114,97,98,108,101,41,10,
-//
-10,
-//     def __gt__(self, iterable):
-32,32,32,32,100,101,102,32,95,95,103,116,95,95,40,115,101,108,102,44,32,105,
-116,101,114,97,98,108,101,41,58,10,
-//         return set(self) > set(iterable)
-32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,115,101,116,40,115,101,108,
-102,41,32,62,32,115,101,116,40,105,116,101,114,97,98,108,101,41,10,
-//
-10,
-// class Term(object):
-99,108,97,115,115,32,84,101,114,109,40,111,98,106,101,99,116,41,58,10,
-//     PLACEHOLDER = object()
-32,32,32,32,80,76,65,67,69,72,79,76,68,69,82,32,61,32,111,98,106,101,99,116,
-40,41,10,
-//     WILDCARD = None
-32,32,32,32,87,73,76,68,67,65,82,68,32,61,32,78,111,110,101,10,
-//     def __init__(self, arity):
-32,32,32,32,100,101,102,32,95,95,105,110,105,116,95,95,40,115,101,108,102,44,
-32,97,114,105,116,121,41,58,10,
-//         self.__arity = arity
-32,32,32,32,32,32,32,32,115,101,108,102,46,95,95,97,114,105,116,121,32,61,32,
-97,114,105,116,121,10,
-//         self.__facts = set()
-32,32,32,32,32,32,32,32,115,101,108,102,46,95,95,102,97,99,116,115,32,61,32,
-115,101,116,40,41,10,
-//
-10,
-//     def add_facts(self, facts):
-32,32,32,32,100,101,102,32,97,100,100,95,102,97,99,116,115,40,115,101,108,102,
-44,32,102,97,99,116,115,41,58,10,
-//         for fact in facts:
-32,32,32,32,32,32,32,32,102,111,114,32,102,97,99,116,32,105,110,32,102,97,99,
-116,115,58,10,
-//             self.add_fact(fact)
-32,32,32,32,32,32,32,32,32,32,32,32,115,101,108,102,46,97,100,100,95,102,97,
-99,116,40,102,97,99,116,41,10,
-//
-10,
-//     def add_fact(self, fact):
-32,32,32,32,100,101,102,32,97,100,100,95,102,97,99,116,40,115,101,108,102,44,
-32,102,97,99,116,41,58,10,
-//         assert len(fact) == self.__arity
-32,32,32,32,32,32,32,32,97,115,115,101,114,116,32,108,101,110,40,102,97,99,116,
-41,32,61,61,32,115,101,108,102,46,95,95,97,114,105,116,121,10,
-//         if not isinstance(fact, tuple):
-32,32,32,32,32,32,32,32,105,102,32,110,111,116,32,105,115,105,110,115,116,97,
-110,99,101,40,102,97,99,116,44,32,116,117,112,108,101,41,58,10,
-//             fact = tuple(fact)
-32,32,32,32,32,32,32,32,32,32,32,32,102,97,99,116,32,61,32,116,117,112,108,101,
-40,102,97,99,116,41,10,
-//         self.__facts.add(fact)
-32,32,32,32,32,32,32,32,115,101,108,102,46,95,95,102,97,99,116,115,46,97,100,
-100,40,102,97,99,116,41,10,
-//
-10,
-//     def __call__(self, *args):
-32,32,32,32,100,101,102,32,95,95,99,97,108,108,95,95,40,115,101,108,102,44,32,
-42,97,114,103,115,41,58,10,
-//         assert len(args) == self.__arity
-32,32,32,32,32,32,32,32,97,115,115,101,114,116,32,108,101,110,40,97,114,103,
-115,41,32,61,61,32,115,101,108,102,46,95,95,97,114,105,116,121,10,
-//         # When all arguments are concrete, calling a term just returns boolean results
-32,32,32,32,32,32,32,32,35,32,87,104,101,110,32,97,108,108,32,97,114,103,117,
-109,101,110,116,115,32,97,114,101,32,99,111,110,99,114,101,116,101,44,32,99,
-97,108,108,105,110,103,32,97,32,116,101,114,109,32,106,117,115,116,32,114,101,
-116,117,114,110,115,32,98,111,111,108,101,97,110,32,114,101,115,117,108,116,
-115,10,
-//         # indicating whether the called tuple is part of the known facts
-32,32,32,32,32,32,32,32,35,32,105,110,100,105,99,97,116,105,110,103,32,119,104,
-101,116,104,101,114,32,116,104,101,32,99,97,108,108,101,100,32,116,117,112,108,
-101,32,105,115,32,112,97,114,116,32,111,102,32,116,104,101,32,107,110,111,119,
-110,32,102,97,99,116,115,10,
-//         n_placeholders = sum(arg is Term.PLACEHOLDER for arg in args)
-32,32,32,32,32,32,32,32,110,95,112,108,97,99,101,104,111,108,100,101,114,115,
-32,61,32,115,117,109,40,97,114,103,32,105,115,32,84,101,114,109,46,80,76,65,
-67,69,72,79,76,68,69,82,32,102,111,114,32,97,114,103,32,105,110,32,97,114,103,
-115,41,10,
-//         if not n_placeholders:
-32,32,32,32,32,32,32,32,105,102,32,110,111,116,32,110,95,112,108,97,99,101,104,
-111,108,100,101,114,115,58,10,
-//             return any(all(a == b for a, b in zip(fact, args)) for fact in self.__facts)
-32,32,32,32,32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,97,110,121,40,
-97,108,108,40,97,32,61,61,32,98,32,102,111,114,32,97,44,32,98,32,105,110,32,
-122,105,112,40,102,97,99,116,44,32,97,114,103,115,41,41,32,102,111,114,32,102,
-97,99,116,32,105,110,32,115,101,108,102,46,95,95,102,97,99,116,115,41,10,
-//         # If arguments contain one or more placeholders, calling a term is more like a
-32,32,32,32,32,32,32,32,35,32,73,102,32,97,114,103,117,109,101,110,116,115,32,
-99,111,110,116,97,105,110,32,111,110,101,32,111,114,32,109,111,114,101,32,112,
-108,97,99,101,104,111,108,100,101,114,115,44,32,99,97,108,108,105,110,103,32,
-97,32,116,101,114,109,32,105,115,32,109,111,114,101,32,108,105,107,101,32,97,
-10,
-//         # query. The call returns a generator that iterates all facts that match with
-32,32,32,32,32,32,32,32,35,32,113,117,101,114,121,46,32,84,104,101,32,99,97,
-108,108,32,114,101,116,117,114,110,115,32,97,32,103,101,110,101,114,97,116,111,
-114,32,116,104,97,116,32,105,116,101,114,97,116,101,115,32,97,108,108,32,102,
-97,99,116,115,32,116,104,97,116,32,109,97,116,99,104,32,119,105,116,104,10,
-//         # the pattern described by the arguments
-32,32,32,32,32,32,32,32,35,32,116,104,101,32,112,97,116,116,101,114,110,32,100,
-101,115,99,114,105,98,101,100,32,98,121,32,116,104,101,32,97,114,103,117,109,
-101,110,116,115,10,
-//         def gen():
-32,32,32,32,32,32,32,32,100,101,102,32,103,101,110,40,41,58,10,
-//             for fact in self.__facts:
-32,32,32,32,32,32,32,32,32,32,32,32,102,111,114,32,102,97,99,116,32,105,110,
-32,115,101,108,102,46,95,95,102,97,99,116,115,58,10,
-//                 rns = []
-32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,114,110,115,32,61,32,91,93,10,
-//                 matched = True
-32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,109,97,116,99,104,101,100,32,
-61,32,84,114,117,101,10,
-//                 for a, b in zip(fact, args):
-32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,102,111,114,32,97,44,32,98,32,
-105,110,32,122,105,112,40,102,97,99,116,44,32,97,114,103,115,41,58,10,
-//                     if b is Term.PLACEHOLDER:
-32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,105,102,32,98,32,
-105,115,32,84,101,114,109,46,80,76,65,67,69,72,79,76,68,69,82,58,10,
-//                         rns.append(a)
-32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,114,
-110,115,46,97,112,112,101,110,100,40,97,41,10,
-//                     else:
-32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,101,108,115,101,
-58,10,
-//                         if a != b:
-32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,105,
-102,32,97,32,33,61,32,98,58,10,
-//                             matched = False
-32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,
-32,32,109,97,116,99,104,101,100,32,61,32,70,97,108,115,101,10,
-//                             break
-32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,
-32,32,98,114,101,97,107,10,
-//                 if matched:
-32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,105,102,32,109,97,116,99,104,
-101,100,58,10,
-//                     if n_placeholders == 1:
-32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,105,102,32,110,95,
-112,108,97,99,101,104,111,108,100,101,114,115,32,61,61,32,49,58,10,
-//                         yield rns[0]
-32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,121,
-105,101,108,100,32,114,110,115,91,48,93,10,
-//                     else:
-32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,101,108,115,101,
-58,10,
-//                         yield tuple(rns)
-32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,121,
-105,101,108,100,32,116,117,112,108,101,40,114,110,115,41,10,
-//         return QueryResult(gen())
-32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,81,117,101,114,121,82,101,
-115,117,108,116,40,103,101,110,40,41,41,10,
-//
-10,
-// class Model(object):
-99,108,97,115,115,32,77,111,100,101,108,40,111,98,106,101,99,116,41,58,10,
-//     def __init__(self, raw_model):
-32,32,32,32,100,101,102,32,95,95,105,110,105,116,95,95,40,115,101,108,102,44,
-32,114,97,119,95,109,111,100,101,108,41,58,10,
-//         request_def, term_def, matchers = raw_model
-32,32,32,32,32,32,32,32,114,101,113,117,101,115,116,95,100,101,102,44,32,116,
-101,114,109,95,100,101,102,44,32,109,97,116,99,104,101,114,115,32,61,32,114,
-97,119,95,109,111,100,101,108,10,
-//         self.__request_template = { r[0]:r[1] for r in request_def }
-32,32,32,32,32,32,32,32,115,101,108,102,46,95,95,114,101,113,117,101,115,116,
-95,116,101,109,112,108,97,116,101,32,61,32,123,32,114,91,48,93,58,114,91,49,
-93,32,102,111,114,32,114,32,105,110,32,114,101,113,117,101,115,116,95,100,101,
-102,32,125,10,
-//         self.__term_template = { t[0]:t[1] for t in term_def }
-32,32,32,32,32,32,32,32,115,101,108,102,46,95,95,116,101,114,109,95,116,101,
-109,112,108,97,116,101,32,61,32,123,32,116,91,48,93,58,116,91,49,93,32,102,111,
-114,32,116,32,105,110,32,116,101,114,109,95,100,101,102,32,125,10,
-//         self.__matchers = { m[0]:m[1] for m in matchers }
-32,32,32,32,32,32,32,32,115,101,108,102,46,95,95,109,97,116,99,104,101,114,115,
-32,61,32,123,32,109,91,48,93,58,109,91,49,93,32,102,111,114,32,109,32,105,110,
-32,109,97,116,99,104,101,114,115,32,125,10,
-//
-10,
-//         def_sections = zip(
-32,32,32,32,32,32,32,32,100,101,102,95,115,101,99,116,105,111,110,115,32,61,
-32,122,105,112,40,10,
-//             ['[requests]', '[terms]'],
-32,32,32,32,32,32,32,32,32,32,32,32,91,39,91,114,101,113,117,101,115,116,115,
-93,39,44,32,39,91,116,101,114,109,115,93,39,93,44,10,
-//             [self.__request_template, self.__term_template],
-32,32,32,32,32,32,32,32,32,32,32,32,91,115,101,108,102,46,95,95,114,101,113,
-117,101,115,116,95,116,101,109,112,108,97,116,101,44,32,115,101,108,102,46,95,
-95,116,101,114,109,95,116,101,109,112,108,97,116,101,93,44,10,
-//         )
-32,32,32,32,32,32,32,32,41,10,
-//
-10,
-//         n_sec = len(def_sections)
-32,32,32,32,32,32,32,32,110,95,115,101,99,32,61,32,108,101,110,40,100,101,102,
-95,115,101,99,116,105,111,110,115,41,10,
-//         for i in range(n_sec):
-32,32,32,32,32,32,32,32,102,111,114,32,105,32,105,110,32,114,97,110,103,101,
-40,110,95,115,101,99,41,58,10,
-//             for j in range(i + 1, n_sec):
-32,32,32,32,32,32,32,32,32,32,32,32,102,111,114,32,106,32,105,110,32,114,97,
-110,103,101,40,105,32,43,32,49,44,32,110,95,115,101,99,41,58,10,
-//                 overlap = set(def_sections[i][1].keys()) & set(def_sections[j][1].keys())
-32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,111,118,101,114,108,97,112,32,
-61,32,115,101,116,40,100,101,102,95,115,101,99,116,105,111,110,115,91,105,93,
-91,49,93,46,107,101,121,115,40,41,41,32,38,32,115,101,116,40,100,101,102,95,
-115,101,99,116,105,111,110,115,91,106,93,91,49,93,46,107,101,121,115,40,41,41,
-10,
-//                 if overlap:
-32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,105,102,32,111,118,101,114,108,
-97,112,58,10,
-//                     raise InvalidModelDefinition.redundant_def(
-32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,114,97,105,115,101,
-32,73,110,118,97,108,105,100,77,111,100,101,108,68,101,102,105,110,105,116,105,
-111,110,46,114,101,100,117,110,100,97,110,116,95,100,101,102,40,10,
-//                         overalp, def_sections[i][0], def_sections[j][0]
-32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,111,
-118,101,114,97,108,112,44,32,100,101,102,95,115,101,99,116,105,111,110,115,91,
-105,93,91,48,93,44,32,100,101,102,95,115,101,99,116,105,111,110,115,91,106,93,
-91,48,93,10,
-//                     )
-32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,41,10,
-//
-10,
-//         missing_matchers = set(self.__request_template.keys()) - set(self.__matchers.keys())
-32,32,32,32,32,32,32,32,109,105,115,115,105,110,103,95,109,97,116,99,104,101,
-114,115,32,61,32,115,101,116,40,115,101,108,102,46,95,95,114,101,113,117,101,
-115,116,95,116,101,109,112,108,97,116,101,46,107,101,121,115,40,41,41,32,45,
-32,115,101,116,40,115,101,108,102,46,95,95,109,97,116,99,104,101,114,115,46,
-107,101,121,115,40,41,41,10,
-//         if missing_matchers:
-32,32,32,32,32,32,32,32,105,102,32,109,105,115,115,105,110,103,95,109,97,116,
-99,104,101,114,115,58,10,
-//             raise InvalidModelDefinition.missing_matchers(missing_matchers)
-32,32,32,32,32,32,32,32,32,32,32,32,114,97,105,115,101,32,73,110,118,97,108,
-105,100,77,111,100,101,108,68,101,102,105,110,105,116,105,111,110,46,109,105,
-115,115,105,110,103,95,109,97,116,99,104,101,114,115,40,109,105,115,115,105,
-110,103,95,109,97,116,99,104,101,114,115,41,10,
-//
-10,
-//         unknown_requests = set(self.__matchers.keys()) - set(self.__request_template.keys())
-32,32,32,32,32,32,32,32,117,110,107,110,111,119,110,95,114,101,113,117,101,115,
-116,115,32,61,32,115,101,116,40,115,101,108,102,46,95,95,109,97,116,99,104,101,
-114,115,46,107,101,121,115,40,41,41,32,45,32,115,101,116,40,115,101,108,102,
-46,95,95,114,101,113,117,101,115,116,95,116,101,109,112,108,97,116,101,46,107,
-101,121,115,40,41,41,10,
-//         if unknown_requests:
-32,32,32,32,32,32,32,32,105,102,32,117,110,107,110,111,119,110,95,114,101,113,
-117,101,115,116,115,58,10,
-//             raise InvalidModelDefinition.unknown_requests(unknown_requests)
-32,32,32,32,32,32,32,32,32,32,32,32,114,97,105,115,101,32,73,110,118,97,108,
-105,100,77,111,100,101,108,68,101,102,105,110,105,116,105,111,110,46,117,110,
-107,110,111,119,110,95,114,101,113,117,101,115,116,115,40,117,110,107,110,111,
-119,110,95,114,101,113,117,101,115,116,115,41,10,
-//
-10,
-//         self.__term_knowledge_base = {
-32,32,32,32,32,32,32,32,115,101,108,102,46,95,95,116,101,114,109,95,107,110,
-111,119,108,101,100,103,101,95,98,97,115,101,32,61,32,123,10,
-//             term_name:Term(len(term_tpl)) for term_name, term_tpl in self.__term_template.items()
-32,32,32,32,32,32,32,32,32,32,32,32,116,101,114,109,95,110,97,109,101,58,84,
-101,114,109,40,108,101,110,40,116,101,114,109,95,116,112,108,41,41,32,102,111,
-114,32,116,101,114,109,95,110,97,109,101,44,32,116,101,114,109,95,116,112,108,
-32,105,110,32,115,101,108,102,46,95,95,116,101,114,109,95,116,101,109,112,108,
-97,116,101,46,105,116,101,109,115,40,41,10,
-//         }
-32,32,32,32,32,32,32,32,125,10,
-//
-10,
-//     def add_term_items(self, term_items):
-32,32,32,32,100,101,102,32,97,100,100,95,116,101,114,109,95,105,116,101,109,
-115,40,115,101,108,102,44,32,116,101,114,109,95,105,116,101,109,115,41,58,10,
-//         for ti in term_items:
-32,32,32,32,32,32,32,32,102,111,114,32,116,105,32,105,110,32,116,101,114,109,
-95,105,116,101,109,115,58,10,
-//             self.add_term_item(ti[0], ti[1:])
-32,32,32,32,32,32,32,32,32,32,32,32,115,101,108,102,46,97,100,100,95,116,101,
-114,109,95,105,116,101,109,40,116,105,91,48,93,44,32,116,105,91,49,58,93,41,
-10,
-//
-10,
-//     def add_term_item(self, term_name, fact):
-32,32,32,32,100,101,102,32,97,100,100,95,116,101,114,109,95,105,116,101,109,
-40,115,101,108,102,44,32,116,101,114,109,95,110,97,109,101,44,32,102,97,99,116,
-41,58,10,
-//         term = self.__term_knowledge_base[term_name]
-32,32,32,32,32,32,32,32,116,101,114,109,32,61,32,115,101,108,102,46,95,95,116,
-101,114,109,95,107,110,111,119,108,101,100,103,101,95,98,97,115,101,91,116,101,
-114,109,95,110,97,109,101,93,10,
-//         term.add_fact(fact)
-32,32,32,32,32,32,32,32,116,101,114,109,46,97,100,100,95,102,97,99,116,40,102,
-97,99,116,41,10,
-//
-10,
-//     def get_matcher_proxy(self, request_type, env):
-32,32,32,32,100,101,102,32,103,101,116,95,109,97,116,99,104,101,114,95,112,114,
-111,120,121,40,115,101,108,102,44,32,114,101,113,117,101,115,116,95,116,121,
-112,101,44,32,101,110,118,41,58,10,
-//         def matcher_proxy():
-32,32,32,32,32,32,32,32,100,101,102,32,109,97,116,99,104,101,114,95,112,114,
-111,120,121,40,41,58,10,
-//             return eval(self.__matchers[request_type], env)
-32,32,32,32,32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,101,118,97,108,
-40,115,101,108,102,46,95,95,109,97,116,99,104,101,114,115,91,114,101,113,117,
-101,115,116,95,116,121,112,101,93,44,32,101,110,118,41,10,
-//         return matcher_proxy
-32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,109,97,116,99,104,101,114,
-95,112,114,111,120,121,10,
-//
-10,
-//     def enforce(self, request_type, request_content):
-32,32,32,32,100,101,102,32,101,110,102,111,114,99,101,40,115,101,108,102,44,
-32,114,101,113,117,101,115,116,95,116,121,112,101,44,32,114,101,113,117,101,
-115,116,95,99,111,110,116,101,110,116,41,58,10,
-//         tpl = self.__request_template[request_type]
-32,32,32,32,32,32,32,32,116,112,108,32,61,32,115,101,108,102,46,95,95,114,101,
-113,117,101,115,116,95,116,101,109,112,108,97,116,101,91,114,101,113,117,101,
-115,116,95,116,121,112,101,93,10,
-//         request = Request(tpl, request_content)
-32,32,32,32,32,32,32,32,114,101,113,117,101,115,116,32,61,32,82,101,113,117,
-101,115,116,40,116,112,108,44,32,114,101,113,117,101,115,116,95,99,111,110,116,
-101,110,116,41,10,
-//
-10,
-//         enforcer_env = {
-32,32,32,32,32,32,32,32,101,110,102,111,114,99,101,114,95,101,110,118,32,61,
-32,123,10,
-//             request_type: request,
-32,32,32,32,32,32,32,32,32,32,32,32,114,101,113,117,101,115,116,95,116,121,112,
-101,58,32,114,101,113,117,101,115,116,44,10,
-//             'true': True, 'false': False, 'null': None,
-32,32,32,32,32,32,32,32,32,32,32,32,39,116,114,117,101,39,58,32,84,114,117,101,
-44,32,39,102,97,108,115,101,39,58,32,70,97,108,115,101,44,32,39,110,117,108,
-108,39,58,32,78,111,110,101,44,10,
-//             '_': Term.PLACEHOLDER,
-32,32,32,32,32,32,32,32,32,32,32,32,39,95,39,58,32,84,101,114,109,46,80,76,65,
-67,69,72,79,76,68,69,82,44,10,
-//             'X': Term.WILDCARD,
-32,32,32,32,32,32,32,32,32,32,32,32,39,88,39,58,32,84,101,114,109,46,87,73,76,
-68,67,65,82,68,44,10,
-//         }
-32,32,32,32,32,32,32,32,125,10,
-//         enforcer_env.update(self.__term_knowledge_base)
-32,32,32,32,32,32,32,32,101,110,102,111,114,99,101,114,95,101,110,118,46,117,
-112,100,97,116,101,40,115,101,108,102,46,95,95,116,101,114,109,95,107,110,111,
-119,108,101,100,103,101,95,98,97,115,101,41,10,
-//
-10,
-//         return eval(self.__matchers[request_type], enforcer_env)
-32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,101,118,97,108,40,115,101,
-108,102,46,95,95,109,97,116,99,104,101,114,115,91,114,101,113,117,101,115,116,
-95,116,121,112,101,93,44,32,101,110,102,111,114,99,101,114,95,101,110,118,41,
-10,
-//
-10,
-// global_perm_model = None
-103,108,111,98,97,108,95,112,101,114,109,95,109,111,100,101,108,32,61,32,78,
-111,110,101,10,
-//
-10,
-// if __name__ == '__builtin__':
-105,102,32,95,95,110,97,109,101,95,95,32,61,61,32,39,95,95,98,117,105,108,116,
-105,110,95,95,39,58,10,
-//     from acs_py_enclave import ffi
-32,32,32,32,102,114,111,109,32,97,99,115,95,112,121,95,101,110,99,108,97,118,
-101,32,105,109,112,111,114,116,32,102,102,105,10,
-// else:
-101,108,115,101,58,10,
-//     class ffi:
-32,32,32,32,99,108,97,115,115,32,102,102,105,58,10,
-//         @staticmethod
-32,32,32,32,32,32,32,32,64,115,116,97,116,105,99,109,101,116,104,111,100,10,
-//         def def_extern():
-32,32,32,32,32,32,32,32,100,101,102,32,100,101,102,95,101,120,116,101,114,110,
-40,41,58,10,
-//             return lambda x: x
-32,32,32,32,32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,108,97,109,98,
-100,97,32,120,58,32,120,10,
-//
-10,
-//         @staticmethod
-32,32,32,32,32,32,32,32,64,115,116,97,116,105,99,109,101,116,104,111,100,10,
-//         def string(s):
-32,32,32,32,32,32,32,32,100,101,102,32,115,116,114,105,110,103,40,115,41,58,
-10,
-//             return s
-32,32,32,32,32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,115,10,
-//
-10,
-// @ffi.def_extern()
-64,102,102,105,46,100,101,102,95,101,120,116,101,114,110,40,41,10,
-// def acs_setup_model(conf):
-100,101,102,32,97,99,115,95,115,101,116,117,112,95,109,111,100,101,108,40,99,
-111,110,102,41,58,10,
-//     try:
-32,32,32,32,116,114,121,58,10,
-//         global global_perm_model
-32,32,32,32,32,32,32,32,103,108,111,98,97,108,32,103,108,111,98,97,108,95,112,
-101,114,109,95,109,111,100,101,108,10,
-//         conf = ffi.string(conf)
-32,32,32,32,32,32,32,32,99,111,110,102,32,61,32,102,102,105,46,115,116,114,105,
-110,103,40,99,111,110,102,41,10,
-//         global_perm_model = Model(parse_model(conf))
-32,32,32,32,32,32,32,32,103,108,111,98,97,108,95,112,101,114,109,95,109,111,
-100,101,108,32,61,32,77,111,100,101,108,40,112,97,114,115,101,95,109,111,100,
-101,108,40,99,111,110,102,41,41,10,
-//     except:
-32,32,32,32,101,120,99,101,112,116,58,10,
-//         return -1
-32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,45,49,10,
-//     return 0
-32,32,32,32,114,101,116,117,114,110,32,48,10,
-//
-10,
-// @ffi.def_extern()
-64,102,102,105,46,100,101,102,95,101,120,116,101,114,110,40,41,10,
-// def acs_enforce_request(request_type, request_content):
-100,101,102,32,97,99,115,95,101,110,102,111,114,99,101,95,114,101,113,117,101,
-115,116,40,114,101,113,117,101,115,116,95,116,121,112,101,44,32,114,101,113,
-117,101,115,116,95,99,111,110,116,101,110,116,41,58,10,
-//     try:
-32,32,32,32,116,114,121,58,10,
-//         request_type = ffi.string(request_type)
-32,32,32,32,32,32,32,32,114,101,113,117,101,115,116,95,116,121,112,101,32,61,
-32,102,102,105,46,115,116,114,105,110,103,40,114,101,113,117,101,115,116,95,
-116,121,112,101,41,10,
-//         # request_content is a list of ffi c strings which are syntactically valid
-32,32,32,32,32,32,32,32,35,32,114,101,113,117,101,115,116,95,99,111,110,116,
-101,110,116,32,105,115,32,97,32,108,105,115,116,32,111,102,32,102,102,105,32,
-99,32,115,116,114,105,110,103,115,32,119,104,105,99,104,32,97,114,101,32,115,
-121,110,116,97,99,116,105,99,97,108,108,121,32,118,97,108,105,100,10,
-//         # python primitive-type objects, including strings, integers, foating point
-32,32,32,32,32,32,32,32,35,32,112,121,116,104,111,110,32,112,114,105,109,105,
-116,105,118,101,45,116,121,112,101,32,111,98,106,101,99,116,115,44,32,105,110,
-99,108,117,100,105,110,103,32,115,116,114,105,110,103,115,44,32,105,110,116,
-101,103,101,114,115,44,32,102,111,97,116,105,110,103,32,112,111,105,110,116,
-10,
-//         # numbers, and lists/dictionaries of primitive-type objects
-32,32,32,32,32,32,32,32,35,32,110,117,109,98,101,114,115,44,32,97,110,100,32,
-108,105,115,116,115,47,100,105,99,116,105,111,110,97,114,105,101,115,32,111,
-102,32,112,114,105,109,105,116,105,118,101,45,116,121,112,101,32,111,98,106,
-101,99,116,115,10,
-//         request_content = eval(ffi.string(request_content))
-32,32,32,32,32,32,32,32,114,101,113,117,101,115,116,95,99,111,110,116,101,110,
-116,32,61,32,101,118,97,108,40,102,102,105,46,115,116,114,105,110,103,40,114,
-101,113,117,101,115,116,95,99,111,110,116,101,110,116,41,41,10,
-//         return global_perm_model.enforce(request_type, request_content)
-32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,103,108,111,98,97,108,95,
-112,101,114,109,95,109,111,100,101,108,46,101,110,102,111,114,99,101,40,114,
-101,113,117,101,115,116,95,116,121,112,101,44,32,114,101,113,117,101,115,116,
-95,99,111,110,116,101,110,116,41,10,
-//     except:
-32,32,32,32,101,120,99,101,112,116,58,10,
-//         return -1
-32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,45,49,10,
-//
-10,
-// @ffi.def_extern()
-64,102,102,105,46,100,101,102,95,101,120,116,101,114,110,40,41,10,
-// def acs_announce_fact(term_type, term_fact):
-100,101,102,32,97,99,115,95,97,110,110,111,117,110,99,101,95,102,97,99,116,40,
-116,101,114,109,95,116,121,112,101,44,32,116,101,114,109,95,102,97,99,116,41,
-58,10,
-//     try:
-32,32,32,32,116,114,121,58,10,
-//         term_type = ffi.string(term_type)
-32,32,32,32,32,32,32,32,116,101,114,109,95,116,121,112,101,32,61,32,102,102,
-105,46,115,116,114,105,110,103,40,116,101,114,109,95,116,121,112,101,41,10,
-//         term_fact = eval(ffi.string(term_fact))
-32,32,32,32,32,32,32,32,116,101,114,109,95,102,97,99,116,32,61,32,101,118,97,
-108,40,102,102,105,46,115,116,114,105,110,103,40,116,101,114,109,95,102,97,99,
-116,41,41,10,
-//         global_perm_model.add_term_item(term_type, term_fact)
-32,32,32,32,32,32,32,32,103,108,111,98,97,108,95,112,101,114,109,95,109,111,
-100,101,108,46,97,100,100,95,116,101,114,109,95,105,116,101,109,40,116,101,114,
-109,95,116,121,112,101,44,32,116,101,114,109,95,102,97,99,116,41,10,
-//     except:
-32,32,32,32,101,120,99,101,112,116,58,10,
-//         return -1
-32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,45,49,10,
-//     return 0
-32,32,32,32,114,101,116,117,114,110,32,48,10,
-0 };
-#ifdef PYPY_VERSION
-# define _CFFI_PYTHON_STARTUP_FUNC  _cffi_pypyinit_acs_py_enclave
-#elif PY_MAJOR_VERSION >= 3
-# define _CFFI_PYTHON_STARTUP_FUNC  PyInit_acs_py_enclave
-#else
-# define _CFFI_PYTHON_STARTUP_FUNC  initacs_py_enclave
-#endif
-
-/***** Support code for embedding *****/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-#if defined(_WIN32)
-#  define CFFI_DLLEXPORT  __declspec(dllexport)
-#elif defined(__GNUC__)
-#  define CFFI_DLLEXPORT  __attribute__((visibility("default")))
-#else
-#  define CFFI_DLLEXPORT  /* nothing */
-#endif
-
-
-/* There are two global variables of type _cffi_call_python_fnptr:
-
-   * _cffi_call_python, which we declare just below, is the one called
-     by ``extern "Python"`` implementations.
-
-   * _cffi_call_python_org, which on CPython is actually part of the
-     _cffi_exports[] array, is the function pointer copied from
-     _cffi_backend.
-
-   After initialization is complete, both are equal.  However, the
-   first one remains equal to &_cffi_start_and_call_python until the
-   very end of initialization, when we are (or should be) sure that
-   concurrent threads also see a completely initialized world, and
-   only then is it changed.
-*/
-#undef _cffi_call_python
-typedef void (*_cffi_call_python_fnptr)(struct _cffi_externpy_s *, char *);
-static void _cffi_start_and_call_python(struct _cffi_externpy_s *, char *);
-static _cffi_call_python_fnptr _cffi_call_python = &_cffi_start_and_call_python;
-
-
-#ifndef _MSC_VER
-   /* --- Assuming a GCC not infinitely old --- */
-# define cffi_compare_and_swap(l,o,n)  __sync_bool_compare_and_swap(l,o,n)
-# define cffi_write_barrier()          __sync_synchronize()
-# if !defined(__amd64__) && !defined(__x86_64__) &&   \
-     !defined(__i386__) && !defined(__i386)
-#   define cffi_read_barrier()         __sync_synchronize()
-# else
-#   define cffi_read_barrier()         (void)0
-# endif
-#else
-   /* --- Windows threads version --- */
-# include <Windows.h>
-# define cffi_compare_and_swap(l,o,n) \
-                               (InterlockedCompareExchangePointer(l,n,o) == (o))
-# define cffi_write_barrier()       InterlockedCompareExchange(&_cffi_dummy,0,0)
-# define cffi_read_barrier()           (void)0
-static volatile LONG _cffi_dummy;
-#endif
-
-#ifdef WITH_THREAD
-# ifndef _MSC_VER
-#  include <pthread.h>
-   static pthread_mutex_t _cffi_embed_startup_lock;
-# else
-   static CRITICAL_SECTION _cffi_embed_startup_lock;
-# endif
-  static char _cffi_embed_startup_lock_ready = 0;
-#endif
-
-static void _cffi_acquire_reentrant_mutex(void)
-{
-    static void *volatile lock = NULL;
-
-    while (!cffi_compare_and_swap(&lock, NULL, (void *)1)) {
-        /* should ideally do a spin loop instruction here, but
-           hard to do it portably and doesn't really matter I
-           think: pthread_mutex_init() should be very fast, and
-           this is only run at start-up anyway. */
-    }
-
-#ifdef WITH_THREAD
-    if (!_cffi_embed_startup_lock_ready) {
-# ifndef _MSC_VER
-        pthread_mutexattr_t attr;
-        pthread_mutexattr_init(&attr);
-        pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
-        pthread_mutex_init(&_cffi_embed_startup_lock, &attr);
-# else
-        InitializeCriticalSection(&_cffi_embed_startup_lock);
-# endif
-        _cffi_embed_startup_lock_ready = 1;
-    }
-#endif
-
-    while (!cffi_compare_and_swap(&lock, (void *)1, NULL))
-        ;
-
-#ifndef _MSC_VER
-    pthread_mutex_lock(&_cffi_embed_startup_lock);
-#else
-    EnterCriticalSection(&_cffi_embed_startup_lock);
-#endif
-}
-
-static void _cffi_release_reentrant_mutex(void)
-{
-#ifndef _MSC_VER
-    pthread_mutex_unlock(&_cffi_embed_startup_lock);
-#else
-    LeaveCriticalSection(&_cffi_embed_startup_lock);
-#endif
-}
-
-
-/**********  CPython-specific section  **********/
-#ifndef PYPY_VERSION
-
-#ifndef CFFI_MESSAGEBOX
-# ifdef _MSC_VER
-#  define CFFI_MESSAGEBOX  1
-# else
-#  define CFFI_MESSAGEBOX  0
-# endif
-#endif
-
-
-#if CFFI_MESSAGEBOX
-/* Windows only: logic to take the Python-CFFI embedding logic
-   initialization errors and display them in a background thread
-   with MessageBox.  The idea is that if the whole program closes
-   as a result of this problem, then likely it is already a console
-   program and you can read the stderr output in the console too.
-   If it is not a console program, then it will likely show its own
-   dialog to complain, or generally not abruptly close, and for this
-   case the background thread should stay alive.
-*/
-static void *volatile _cffi_bootstrap_text;
-
-static PyObject *_cffi_start_error_capture(void)
-{
-    PyObject *result = NULL;
-    PyObject *x, *m, *bi;
-
-    if (InterlockedCompareExchangePointer(&_cffi_bootstrap_text,
-            (void *)1, NULL) != NULL)
-        return (PyObject *)1;
-
-    m = PyImport_AddModule("_cffi_error_capture");
-    if (m == NULL)
-        goto error;
-
-    result = PyModule_GetDict(m);
-    if (result == NULL)
-        goto error;
-
-#if PY_MAJOR_VERSION >= 3
-    bi = PyImport_ImportModule("builtins");
-#else
-    bi = PyImport_ImportModule("__builtin__");
-#endif
-    if (bi == NULL)
-        goto error;
-    PyDict_SetItemString(result, "__builtins__", bi);
-    Py_DECREF(bi);
-
-    x = PyRun_String(
-        "import sys\n"
-        "class FileLike:\n"
-        "  def write(self, x):\n"
-        "    of.write(x)\n"
-        "    self.buf += x\n"
-        "fl = FileLike()\n"
-        "fl.buf = ''\n"
-        "of = sys.stderr\n"
-        "sys.stderr = fl\n"
-        "def done():\n"
-        "  sys.stderr = of\n"
-        "  return fl.buf\n",   /* make sure the returned value stays alive */
-        Py_file_input,
-        result, result);
-    Py_XDECREF(x);
-
- error:
-    if (PyErr_Occurred())
-    {
-        PyErr_WriteUnraisable(Py_None);
-        PyErr_Clear();
-    }
-    return result;
-}
-
-#pragma comment(lib, "user32.lib")
-
-static DWORD WINAPI _cffi_bootstrap_dialog(LPVOID ignored)
-{
-    Sleep(666);    /* may be interrupted if the whole process is closing */
-#if PY_MAJOR_VERSION >= 3
-    MessageBoxW(NULL, (wchar_t *)_cffi_bootstrap_text,
-                L"Python-CFFI error",
-                MB_OK | MB_ICONERROR);
-#else
-    MessageBoxA(NULL, (char *)_cffi_bootstrap_text,
-                "Python-CFFI error",
-                MB_OK | MB_ICONERROR);
-#endif
-    _cffi_bootstrap_text = NULL;
-    return 0;
-}
-
-static void _cffi_stop_error_capture(PyObject *ecap)
-{
-    PyObject *s;
-    void *text;
-
-    if (ecap == (PyObject *)1)
-        return;
-
-    if (ecap == NULL)
-        goto error;
-
-    s = PyRun_String("done()", Py_eval_input, ecap, ecap);
-    if (s == NULL)
-        goto error;
-
-    /* Show a dialog box, but in a background thread, and
-       never show multiple dialog boxes at once. */
-#if PY_MAJOR_VERSION >= 3
-    text = PyUnicode_AsWideCharString(s, NULL);
-#else
-    text = PyString_AsString(s);
-#endif
-
-    _cffi_bootstrap_text = text;
-
-    if (text != NULL)
-    {
-        HANDLE h;
-        h = CreateThread(NULL, 0, _cffi_bootstrap_dialog,
-                         NULL, 0, NULL);
-        if (h != NULL)
-            CloseHandle(h);
-    }
-    /* decref the string, but it should stay alive as 'fl.buf'
-       in the small module above.  It will really be freed only if
-       we later get another similar error.  So it's a leak of at
-       most one copy of the small module.  That's fine for this
-       situation which is usually a "fatal error" anyway. */
-    Py_DECREF(s);
-    PyErr_Clear();
-    return;
-
-  error:
-    _cffi_bootstrap_text = NULL;
-    PyErr_Clear();
-}
-
-#else
-
-static PyObject *_cffi_start_error_capture(void) { return NULL; }
-static void _cffi_stop_error_capture(PyObject *ecap) { }
-
-#endif
-
-
-#define _cffi_call_python_org  _cffi_exports[_CFFI_CPIDX]
-
-PyMODINIT_FUNC _CFFI_PYTHON_STARTUP_FUNC(void);   /* forward */
-
-static void _cffi_py_initialize(void)
-{
-    /* XXX use initsigs=0, which "skips initialization registration of
-       signal handlers, which might be useful when Python is
-       embedded" according to the Python docs.  But review and think
-       if it should be a user-controllable setting.
-
-       XXX we should also give a way to write errors to a buffer
-       instead of to stderr.
-
-       XXX if importing 'site' fails, CPython (any version) calls
-       exit().  Should we try to work around this behavior here?
-    */
-    Py_InitializeEx(0);
-}
-
-static int _cffi_initialize_python(void)
-{
-    /* This initializes Python, imports _cffi_backend, and then the
-       present .dll/.so is set up as a CPython C extension module.
-    */
-    int result;
-    PyGILState_STATE state;
-    PyObject *pycode=NULL, *global_dict=NULL, *x;
-
-    state = PyGILState_Ensure();
-
-    /* Call the initxxx() function from the present module.  It will
-       create and initialize us as a CPython extension module, instead
-       of letting the startup Python code do it---it might reimport
-       the same .dll/.so and get maybe confused on some platforms.
-       It might also have troubles locating the .dll/.so again for all
-       I know.
-    */
-    (void)_CFFI_PYTHON_STARTUP_FUNC();
-    if (PyErr_Occurred())
-        goto error;
-
-    /* Now run the Python code provided to ffi.embedding_init_code().
-     */
-    pycode = Py_CompileString(_CFFI_PYTHON_STARTUP_CODE,
-                              "<init code for '" _CFFI_MODULE_NAME "'>",
-                              Py_file_input);
-    if (pycode == NULL)
-        goto error;
-    global_dict = PyDict_New();
-    if (global_dict == NULL)
-        goto error;
-    if (PyDict_SetItemString(global_dict, "__builtins__",
-                             PyThreadState_GET()->interp->builtins) < 0)
-        goto error;
-    x = PyEval_EvalCode(
-#if PY_MAJOR_VERSION < 3
-                        (PyCodeObject *)
-#endif
-                        pycode, global_dict, global_dict);
-    if (x == NULL)
-        goto error;
-    Py_DECREF(x);
-
-    /* Done!  Now if we've been called from
-       _cffi_start_and_call_python() in an ``extern "Python"``, we can
-       only hope that the Python code did correctly set up the
-       corresponding @ffi.def_extern() function.  Otherwise, the
-       general logic of ``extern "Python"`` functions (inside the
-       _cffi_backend module) will find that the reference is still
-       missing and print an error.
-     */
-    result = 0;
- done:
-    Py_XDECREF(pycode);
-    Py_XDECREF(global_dict);
-    PyGILState_Release(state);
-    return result;
-
- error:;
-    {
-        /* Print as much information as potentially useful.
-           Debugging load-time failures with embedding is not fun
-        */
-        PyObject *ecap;
-        PyObject *exception, *v, *tb, *f, *modules, *mod;
-        PyErr_Fetch(&exception, &v, &tb);
-        ecap = _cffi_start_error_capture();
-        f = PySys_GetObject((char *)"stderr");
-        if (f != NULL && f != Py_None) {
-            PyFile_WriteString(
-                "Failed to initialize the Python-CFFI embedding logic:\n\n", f);
-        }
-
-        if (exception != NULL) {
-            PyErr_NormalizeException(&exception, &v, &tb);
-            PyErr_Display(exception, v, tb);
-        }
-        Py_XDECREF(exception);
-        Py_XDECREF(v);
-        Py_XDECREF(tb);
-
-        if (f != NULL && f != Py_None) {
-            PyFile_WriteString("\nFrom: " _CFFI_MODULE_NAME
-                               "\ncompiled with cffi version: 1.11.5"
-                               "\n_cffi_backend module: ", f);
-            modules = PyImport_GetModuleDict();
-            mod = PyDict_GetItemString(modules, "_cffi_backend");
-            if (mod == NULL) {
-                PyFile_WriteString("not loaded", f);
-            }
-            else {
-                v = PyObject_GetAttrString(mod, "__file__");
-                PyFile_WriteObject(v, f, 0);
-                Py_XDECREF(v);
-            }
-            PyFile_WriteString("\nsys.path: ", f);
-            PyFile_WriteObject(PySys_GetObject((char *)"path"), f, 0);
-            PyFile_WriteString("\n\n", f);
-        }
-        _cffi_stop_error_capture(ecap);
-    }
-    result = -1;
-    goto done;
-}
-
-PyAPI_DATA(char *) _PyParser_TokenNames[];  /* from CPython */
-
-static int _cffi_carefully_make_gil(void)
-{
-    /* This does the basic initialization of Python.  It can be called
-       completely concurrently from unrelated threads.  It assumes
-       that we don't hold the GIL before (if it exists), and we don't
-       hold it afterwards.
-
-       (What it really does used to be completely different in Python 2
-       and Python 3, with the Python 2 solution avoiding the spin-lock
-       around the Py_InitializeEx() call.  However, after recent changes
-       to CPython 2.7 (issue #358) it no longer works.  So we use the
-       Python 3 solution everywhere.)
-
-       This initializes Python by calling Py_InitializeEx().
-       Important: this must not be called concurrently at all.
-       So we use a global variable as a simple spin lock.  This global
-       variable must be from 'libpythonX.Y.so', not from this
-       cffi-based extension module, because it must be shared from
-       different cffi-based extension modules.  We choose
-       _PyParser_TokenNames[0] as a completely arbitrary pointer value
-       that is never written to.  The default is to point to the
-       string "ENDMARKER".  We change it temporarily to point to the
-       next character in that string.  (Yes, I know it's REALLY
-       obscure.)
-    */
-
-#ifdef WITH_THREAD
-    char *volatile *lock = (char *volatile *)_PyParser_TokenNames;
-    char *old_value;
-
-    while (1) {    /* spin loop */
-        old_value = *lock;
-        if (old_value[0] == 'E') {
-            assert(old_value[1] == 'N');
-            if (cffi_compare_and_swap(lock, old_value, old_value + 1))
-                break;
-        }
-        else {
-            assert(old_value[0] == 'N');
-            /* should ideally do a spin loop instruction here, but
-               hard to do it portably and doesn't really matter I
-               think: PyEval_InitThreads() should be very fast, and
-               this is only run at start-up anyway. */
-        }
-    }
-#endif
-
-    /* call Py_InitializeEx() */
-    {
-        PyGILState_STATE state = PyGILState_UNLOCKED;
-        if (!Py_IsInitialized())
-            _cffi_py_initialize();
-        else
-            state = PyGILState_Ensure();
-
-        PyEval_InitThreads();
-        PyGILState_Release(state);
-    }
-
-#ifdef WITH_THREAD
-    /* release the lock */
-    while (!cffi_compare_and_swap(lock, old_value + 1, old_value))
-        ;
-#endif
-
-    return 0;
-}
-
-/**********  end CPython-specific section  **********/
-
-
-#else
-
-
-/**********  PyPy-specific section  **********/
-
-PyMODINIT_FUNC _CFFI_PYTHON_STARTUP_FUNC(const void *[]);   /* forward */
-
-static struct _cffi_pypy_init_s {
-    const char *name;
-    void (*func)(const void *[]);
-    const char *code;
-} _cffi_pypy_init = {
-    _CFFI_MODULE_NAME,
-    (void(*)(const void *[]))_CFFI_PYTHON_STARTUP_FUNC,
-    _CFFI_PYTHON_STARTUP_CODE,
-};
-
-extern int pypy_carefully_make_gil(const char *);
-extern int pypy_init_embedded_cffi_module(int, struct _cffi_pypy_init_s *);
-
-static int _cffi_carefully_make_gil(void)
-{
-    return pypy_carefully_make_gil(_CFFI_MODULE_NAME);
-}
-
-static int _cffi_initialize_python(void)
-{
-    return pypy_init_embedded_cffi_module(0xB011, &_cffi_pypy_init);
-}
-
-/**********  end PyPy-specific section  **********/
-
-
-#endif
-
-
-#ifdef __GNUC__
-__attribute__((noinline))
-#endif
-static _cffi_call_python_fnptr _cffi_start_python(void)
-{
-    /* Delicate logic to initialize Python.  This function can be
-       called multiple times concurrently, e.g. when the process calls
-       its first ``extern "Python"`` functions in multiple threads at
-       once.  It can also be called recursively, in which case we must
-       ignore it.  We also have to consider what occurs if several
-       different cffi-based extensions reach this code in parallel
-       threads---it is a different copy of the code, then, and we
-       can't have any shared global variable unless it comes from
-       'libpythonX.Y.so'.
-
-       Idea:
-
-       * _cffi_carefully_make_gil(): "carefully" call
-         PyEval_InitThreads() (possibly with Py_InitializeEx() first).
-
-       * then we use a (local) custom lock to make sure that a call to this
-         cffi-based extension will wait if another call to the *same*
-         extension is running the initialization in another thread.
-         It is reentrant, so that a recursive call will not block, but
-         only one from a different thread.
-
-       * then we grab the GIL and (Python 2) we call Py_InitializeEx().
-         At this point, concurrent calls to Py_InitializeEx() are not
-         possible: we have the GIL.
-
-       * do the rest of the specific initialization, which may
-         temporarily release the GIL but not the custom lock.
-         Only release the custom lock when we are done.
-    */
-    static char called = 0;
-
-    if (_cffi_carefully_make_gil() != 0)
-        return NULL;
-
-#ifndef SGX
-    _cffi_acquire_reentrant_mutex();
-#endif
-
-    /* Here the GIL exists, but we don't have it.  We're only protected
-       from concurrency by the reentrant mutex. */
-
-    /* This file only initializes the embedded module once, the first
-       time this is called, even if there are subinterpreters. */
-    if (!called) {
-        called = 1;  /* invoke _cffi_initialize_python() only once,
-                        but don't set '_cffi_call_python' right now,
-                        otherwise concurrent threads won't call
-                        this function at all (we need them to wait) */
-        if (_cffi_initialize_python() == 0) {
-            /* now initialization is finished.  Switch to the fast-path. */
-
-            /* We would like nobody to see the new value of
-               '_cffi_call_python' without also seeing the rest of the
-               data initialized.  However, this is not possible.  But
-               the new value of '_cffi_call_python' is the function
-               'cffi_call_python()' from _cffi_backend.  So:  */
-            cffi_write_barrier();
-            /* ^^^ we put a write barrier here, and a corresponding
-               read barrier at the start of cffi_call_python().  This
-               ensures that after that read barrier, we see everything
-               done here before the write barrier.
-            */
-
-            assert(_cffi_call_python_org != NULL);
-            _cffi_call_python = (_cffi_call_python_fnptr)_cffi_call_python_org;
-        }
-        else {
-            /* initialization failed.  Reset this to NULL, even if it was
-               already set to some other value.  Future calls to
-               _cffi_start_python() are still forced to occur, and will
-               always return NULL from now on. */
-            _cffi_call_python_org = NULL;
-        }
-    }
-
-#ifndef SGX
-    _cffi_release_reentrant_mutex();
-#endif
-
-    return (_cffi_call_python_fnptr)_cffi_call_python_org;
-}
-
-static
-void _cffi_start_and_call_python(struct _cffi_externpy_s *externpy, char *args)
-{
-    _cffi_call_python_fnptr fnptr;
-    int current_err = errno;
-#ifdef _MSC_VER
-    int current_lasterr = GetLastError();
-#endif
-    fnptr = _cffi_start_python();
-    if (fnptr == NULL) {
-        fprintf(stderr, "function %s() called, but initialization code "
-                        "failed.  Returning 0.\n", externpy->name);
-        memset(args, 0, externpy->size_of_result);
-    }
-#ifdef _MSC_VER
-    SetLastError(current_lasterr);
-#endif
-    errno = current_err;
-
-    if (fnptr != NULL)
-        fnptr(externpy, args);
-}
-
-
-/* The cffi_start_python() function makes sure Python is initialized
-   and our cffi module is set up.  It can be called manually from the
-   user C code.  The same effect is obtained automatically from any
-   dll-exported ``extern "Python"`` function.  This function returns
-   -1 if initialization failed, 0 if all is OK.  */
-_CFFI_UNUSED_FN
-static int cffi_start_python(void)
-{
-    if (_cffi_call_python == &_cffi_start_and_call_python) {
-        if (_cffi_start_python() == NULL)
-            return -1;
-    }
-    cffi_read_barrier();
-    return 0;
-}
-
-#undef cffi_compare_and_swap
-#undef cffi_write_barrier
-#undef cffi_read_barrier
-
-#ifdef __cplusplus
-}
-#endif
-
-/************************************************************/
-
-
-
-/************************************************************/
-
-static void *_cffi_types[] = {
-/*  0 */ _CFFI_OP(_CFFI_OP_FUNCTION, 10), // int()(char const *)
-/*  1 */ _CFFI_OP(_CFFI_OP_POINTER, 7), // char const *
-/*  2 */ _CFFI_OP(_CFFI_OP_FUNCTION_END, 0),
-/*  3 */ _CFFI_OP(_CFFI_OP_FUNCTION, 10), // int()(char const *, char const *)
-/*  4 */ _CFFI_OP(_CFFI_OP_NOOP, 1),
-/*  5 */ _CFFI_OP(_CFFI_OP_NOOP, 1),
-/*  6 */ _CFFI_OP(_CFFI_OP_FUNCTION_END, 0),
-/*  7 */ _CFFI_OP(_CFFI_OP_PRIMITIVE, 2), // char
-/*  8 */ _CFFI_OP(_CFFI_OP_POINTER, 0), // int(*)(char const *)
-/*  9 */ _CFFI_OP(_CFFI_OP_POINTER, 3), // int(*)(char const *, char const *)
-/* 10 */ _CFFI_OP(_CFFI_OP_PRIMITIVE, 7), // int
-};
-
-static struct _cffi_externpy_s _cffi_externpy__acs_announce_fact =
-  { "acs_py_enclave.acs_announce_fact", (int)sizeof(int) };
-
-CFFI_DLLEXPORT int acs_announce_fact(char const * a0, char const * a1)
-{
-  char a[16];
-  char *p = a;
-  *(char const * *)(p + 0) = a0;
-  *(char const * *)(p + 8) = a1;
-  _cffi_call_python(&_cffi_externpy__acs_announce_fact, p);
-  return *(int *)p;
-}
-
-static struct _cffi_externpy_s _cffi_externpy__acs_enforce_request =
-  { "acs_py_enclave.acs_enforce_request", (int)sizeof(int) };
-
-CFFI_DLLEXPORT int acs_enforce_request(char const * a0, char const * a1)
-{
-  char a[16];
-  char *p = a;
-  *(char const * *)(p + 0) = a0;
-  *(char const * *)(p + 8) = a1;
-  _cffi_call_python(&_cffi_externpy__acs_enforce_request, p);
-  return *(int *)p;
-}
-
-static struct _cffi_externpy_s _cffi_externpy__acs_setup_model =
-  { "acs_py_enclave.acs_setup_model", (int)sizeof(int) };
-
-CFFI_DLLEXPORT int acs_setup_model(char const * a0)
-{
-  char a[8];
-  char *p = a;
-  *(char const * *)(p + 0) = a0;
-  _cffi_call_python(&_cffi_externpy__acs_setup_model, p);
-  return *(int *)p;
-}
-
-static const struct _cffi_global_s _cffi_globals[] = {
-  { "acs_announce_fact", (void *)&_cffi_externpy__acs_announce_fact, _CFFI_OP(_CFFI_OP_EXTERN_PYTHON, 9), (void *)acs_announce_fact },
-  { "acs_enforce_request", (void *)&_cffi_externpy__acs_enforce_request, _CFFI_OP(_CFFI_OP_EXTERN_PYTHON, 9), (void *)acs_enforce_request },
-  { "acs_setup_model", (void *)&_cffi_externpy__acs_setup_model, _CFFI_OP(_CFFI_OP_EXTERN_PYTHON, 8), (void *)acs_setup_model },
-};
-
-static const struct _cffi_type_context_s _cffi_type_context = {
-  _cffi_types,
-  _cffi_globals,
-  NULL,  /* no fields */
-  NULL,  /* no struct_unions */
-  NULL,  /* no enums */
-  NULL,  /* no typenames */
-  3,  /* num_globals */
-  0,  /* num_struct_unions */
-  0,  /* num_enums */
-  0,  /* num_typenames */
-  NULL,  /* no includes */
-  11,  /* num_types */
-  1,  /* flags */
-};
-
-#ifdef __GNUC__
-#  pragma GCC visibility push(default)  /* for -fvisibility= */
-#endif
-
-#ifdef PYPY_VERSION
-PyMODINIT_FUNC
-_cffi_pypyinit_acs_py_enclave(const void *p[])
-{
-    if (((intptr_t)p[0]) >= 0x0A03) {
-        _cffi_call_python_org = (void(*)(struct _cffi_externpy_s *, char *))p[1];
-    }
-    p[0] = (const void *)0x2701;
-    p[1] = &_cffi_type_context;
-#if PY_MAJOR_VERSION >= 3
-    return NULL;
-#endif
-}
-#  ifdef _MSC_VER
-     PyMODINIT_FUNC
-#  if PY_MAJOR_VERSION >= 3
-     PyInit_acs_py_enclave(void) { return NULL; }
-#  else
-     initacs_py_enclave(void) { }
-#  endif
-#  endif
-#elif PY_MAJOR_VERSION >= 3
-PyMODINIT_FUNC
-PyInit_acs_py_enclave(void)
-{
-  return _cffi_init("acs_py_enclave", 0x2701, &_cffi_type_context);
-}
-#else
-PyMODINIT_FUNC
-initacs_py_enclave(void)
-{
-  _cffi_init("acs_py_enclave", 0x2701, &_cffi_type_context);
-}
-#endif
-
-#ifdef __GNUC__
-#  pragma GCC visibility pop
-#endif
diff --git a/services/access_control/python/ffi.py b/services/access_control/python/ffi.py
deleted file mode 100644
index d1955e2..0000000
--- a/services/access_control/python/ffi.py
+++ /dev/null
@@ -1,33 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-import os
-import sgx_cffi
-import _cffi_backend as backend
-
-ffi = sgx_cffi.FFI(backend)
-
-ffi.embedding_api("int acs_setup_model(const char *configuration);")
-ffi.embedding_api("""int acs_enforce_request(const char *request_type,
-                                             const char *request_content);""")
-ffi.embedding_api("""int acs_announce_fact(const char *term_type,
-                                           const char *term_fact);""")
-with open(os.path.join(os.path.dirname(os.path.abspath(__file__)), "acs_engine.py")) as f:
-    ffi.embedding_init_code(f.read())
-ffi.set_source('acs_py_enclave', '')
-ffi.emit_c_code(os.environ.get('PYPY_FFI_OUTDIR', ".") + "/acs_py_enclave.c")
diff --git a/services/frontend/enclave/src/lib.rs b/services/frontend/enclave/src/lib.rs
index 78a63b7..d0845d9 100644
--- a/services/frontend/enclave/src/lib.rs
+++ b/services/frontend/enclave/src/lib.rs
@@ -32,12 +32,14 @@
 use teaclave_binder::{handle_ecall, register_ecall_handler};
 use teaclave_config::build::AS_ROOT_CA_CERT;
 use teaclave_config::RuntimeConfig;
+use teaclave_proto::teaclave_access_control_service::TeaclaveAccessControlClient;
 use teaclave_proto::teaclave_authentication_service::TeaclaveAuthenticationInternalClient;
 use teaclave_proto::teaclave_frontend_service::TeaclaveFrontendServer;
 use teaclave_proto::teaclave_management_service::TeaclaveManagementClient;
 use teaclave_rpc::{config::SgxTrustedTlsServerConfig, transport::Server};
 use teaclave_service_enclave_utils::{
-    create_trusted_authentication_endpoint, create_trusted_management_endpoint, ServiceEnclave,
+    create_trusted_access_control_endpoint, create_trusted_authentication_endpoint,
+    create_trusted_management_endpoint, ServiceEnclave,
 };
 use teaclave_types::{TeeServiceError, TeeServiceResult};
 
@@ -88,7 +90,7 @@
         &enclave_info,
         AS_ROOT_CA_CERT,
         verifier::universal_quote_verifier,
-        attested_tls_config,
+        attested_tls_config.clone(),
     )?;
 
     let management_channel = management_service_endpoint
@@ -101,15 +103,37 @@
 
     info!(" Starting FrontEnd: setup management client finished ...");
 
+    let access_control_service_endpoint = create_trusted_access_control_endpoint(
+        &config.internal_endpoints.access_control.advertised_address,
+        &enclave_info,
+        AS_ROOT_CA_CERT,
+        verifier::universal_quote_verifier,
+        attested_tls_config.clone(),
+    )?;
+
+    let access_control_channel = access_control_service_endpoint
+        .connect()
+        .await
+        .map_err(|e| anyhow!("Failed to connect to access_control service, retry {:?}", e))?;
+    let access_control_client = Arc::new(Mutex::new(TeaclaveAccessControlClient::new(
+        access_control_channel,
+    )));
+
+    info!(" Starting FrontEnd: setup access_control client finished ...");
+
     let log_buffer = Arc::new(Mutex::new(Vec::new()));
     let audit_agent = audit::AuditAgent::new(management_client.clone(), log_buffer.clone());
     let agent_handle = tokio::spawn(async move {
         audit_agent.run().await;
     });
 
-    let service =
-        service::TeaclaveFrontendService::new(authentication_client, management_client, log_buffer)
-            .await?;
+    let service = service::TeaclaveFrontendService::new(
+        authentication_client,
+        management_client,
+        access_control_client,
+        log_buffer,
+    )
+    .await?;
 
     info!(" Starting FrontEnd: start listening ...");
     Server::builder()
@@ -163,14 +187,7 @@
 
 #[cfg(feature = "enclave_unit_test")]
 pub mod tests {
-    use super::*;
-    use teaclave_test_utils::*;
-
     pub fn run_tests() -> bool {
-        run_tests!(
-            service::tests::test_authorize_platform_admin,
-            service::tests::test_authorize_function_owner,
-            service::tests::test_authorize_data_owner,
-        )
+        true
     }
 }
diff --git a/services/frontend/enclave/src/service.rs b/services/frontend/enclave/src/service.rs
index 288c398..5ffd90b 100644
--- a/services/frontend/enclave/src/service.rs
+++ b/services/frontend/enclave/src/service.rs
@@ -21,6 +21,9 @@
 use anyhow::Result;
 use std::net::{IpAddr, Ipv6Addr};
 use std::sync::Arc;
+use teaclave_proto::teaclave_access_control_service::{
+    AuthorizeApiRequest, TeaclaveAccessControlClient,
+};
 use teaclave_proto::teaclave_authentication_service::{
     TeaclaveAuthenticationInternalClient, UserAuthenticateRequest,
 };
@@ -42,13 +45,11 @@
 use teaclave_rpc::transport::Channel;
 use teaclave_rpc::Request;
 use teaclave_service_enclave_utils::bail;
-use teaclave_types::{
-    Entry, EntryBuilder, TeaclaveServiceResponseResult, UserAuthClaims, UserRole,
-};
+use teaclave_types::{Entry, EntryBuilder, TeaclaveServiceResponseResult, UserAuthClaims};
 use tokio::sync::Mutex;
 
 macro_rules! authentication_and_forward_to_management {
-    ($service: ident, $request: ident, $func: ident, $endpoint: expr) => {{
+    ($service: ident, $request: ident, $func: ident) => {{
         let function_name = stringify!($func).to_owned();
         let ip_option = $request.remote_addr().map(|s| s.ip());
         let ip = match ip_option {
@@ -61,12 +62,17 @@
 
         let claims = match $service.authenticate(&$request).await {
             Ok(claims) => {
-                if authorize(&claims, $endpoint) {
+                if $service
+                    .check_api_privilege(
+                        claims.get_role().to_string().split('-').next().unwrap(),
+                        stringify!($func),
+                    )
+                    .await
+                {
                     claims
                 } else {
                     log::debug!(
-                        "User is not authorized to access endpoint: {}, func: {}",
-                        stringify!($endpoint),
+                        "User is not authorized to access func: {}",
                         stringify!($func)
                     );
 
@@ -81,8 +87,7 @@
             }
             Err(e) => {
                 log::debug!(
-                    "User is not authenticated to access endpoint: {}, func: {}",
-                    stringify!($endpoint),
+                    "User is not authenticated to access func: {}",
                     stringify!($func)
                 );
 
@@ -130,72 +135,11 @@
     }};
 }
 
-// TODO: remove this structure as it is the same with RPC interface
-enum Endpoints {
-    RegisterInputFile,
-    RegisterOutputFile,
-    UpdateInputFile,
-    UpdateOutputFile,
-    RegisterFusionOutput,
-    RegisterInputFromOutput,
-    GetOutputFile,
-    GetInputFile,
-    RegisterFunction,
-    GetFunction,
-    GetFunctionUsageStats,
-    UpdateFunction,
-    ListFunctions,
-    DeleteFunction,
-    DisableFunction,
-    CreateTask,
-    GetTask,
-    AssignData,
-    ApproveTask,
-    InvokeTask,
-    CancelTask,
-    QueryAuditLogs,
-}
-
-fn authorize(claims: &UserAuthClaims, request: Endpoints) -> bool {
-    let role = claims.get_role();
-
-    if role == UserRole::Invalid {
-        return false;
-    }
-    if role == UserRole::PlatformAdmin {
-        return true;
-    }
-
-    match request {
-        Endpoints::RegisterFunction
-        | Endpoints::UpdateFunction
-        | Endpoints::DeleteFunction
-        | Endpoints::DisableFunction => role.is_function_owner(),
-        Endpoints::RegisterInputFile
-        | Endpoints::RegisterOutputFile
-        | Endpoints::UpdateInputFile
-        | Endpoints::UpdateOutputFile
-        | Endpoints::RegisterFusionOutput
-        | Endpoints::RegisterInputFromOutput
-        | Endpoints::GetOutputFile
-        | Endpoints::GetInputFile
-        | Endpoints::CreateTask
-        | Endpoints::GetTask
-        | Endpoints::AssignData
-        | Endpoints::ApproveTask
-        | Endpoints::InvokeTask
-        | Endpoints::CancelTask => role.is_data_owner(),
-        Endpoints::GetFunction | Endpoints::ListFunctions | Endpoints::GetFunctionUsageStats => {
-            role.is_function_owner() || role.is_data_owner()
-        }
-        Endpoints::QueryAuditLogs => false,
-    }
-}
-
 #[derive(Clone)]
 pub(crate) struct TeaclaveFrontendService {
     authentication_client: Arc<Mutex<TeaclaveAuthenticationInternalClient<Channel>>>,
     management_client: Arc<Mutex<TeaclaveManagementClient<Channel>>>,
+    access_control_client: Arc<Mutex<TeaclaveAccessControlClient<Channel>>>,
     audit_log_buffer: Arc<Mutex<Vec<Entry>>>,
 }
 
@@ -203,11 +147,13 @@
     pub(crate) async fn new(
         authentication_client: Arc<Mutex<TeaclaveAuthenticationInternalClient<Channel>>>,
         management_client: Arc<Mutex<TeaclaveManagementClient<Channel>>>,
+        access_control_client: Arc<Mutex<TeaclaveAccessControlClient<Channel>>>,
         audit_log_buffer: Arc<Mutex<Vec<Entry>>>,
     ) -> Result<Self> {
         Ok(Self {
             authentication_client,
             management_client,
+            access_control_client,
             audit_log_buffer,
         })
     }
@@ -216,6 +162,17 @@
         let mut buffer_lock = self.audit_log_buffer.lock().await;
         buffer_lock.push(entry);
     }
+
+    async fn check_api_privilege(&self, user_role: &str, api: &str) -> bool {
+        let request = AuthorizeApiRequest {
+            user_role: user_role.to_owned(),
+            api: api.to_owned(),
+        };
+
+        let mut acs_client = self.access_control_client.lock().await;
+        let result = acs_client.authorize_api(request).await;
+        result.map(|r| r.into_inner().accept).unwrap_or(false)
+    }
 }
 
 #[teaclave_rpc::async_trait]
@@ -224,239 +181,154 @@
         &self,
         request: Request<RegisterInputFileRequest>,
     ) -> TeaclaveServiceResponseResult<RegisterInputFileResponse> {
-        authentication_and_forward_to_management!(
-            self,
-            request,
-            register_input_file,
-            Endpoints::RegisterInputFile
-        )
+        authentication_and_forward_to_management!(self, request, register_input_file)
     }
 
     async fn update_input_file(
         &self,
         request: Request<UpdateInputFileRequest>,
     ) -> TeaclaveServiceResponseResult<UpdateInputFileResponse> {
-        authentication_and_forward_to_management!(
-            self,
-            request,
-            update_input_file,
-            Endpoints::UpdateInputFile
-        )
+        authentication_and_forward_to_management!(self, request, update_input_file)
     }
 
     async fn register_output_file(
         &self,
         request: Request<RegisterOutputFileRequest>,
     ) -> TeaclaveServiceResponseResult<RegisterOutputFileResponse> {
-        authentication_and_forward_to_management!(
-            self,
-            request,
-            register_output_file,
-            Endpoints::RegisterOutputFile
-        )
+        authentication_and_forward_to_management!(self, request, register_output_file)
     }
 
     async fn update_output_file(
         &self,
         request: Request<UpdateOutputFileRequest>,
     ) -> TeaclaveServiceResponseResult<UpdateOutputFileResponse> {
-        authentication_and_forward_to_management!(
-            self,
-            request,
-            update_output_file,
-            Endpoints::UpdateOutputFile
-        )
+        authentication_and_forward_to_management!(self, request, update_output_file)
     }
 
     async fn register_fusion_output(
         &self,
         request: Request<RegisterFusionOutputRequest>,
     ) -> TeaclaveServiceResponseResult<RegisterFusionOutputResponse> {
-        authentication_and_forward_to_management!(
-            self,
-            request,
-            register_fusion_output,
-            Endpoints::RegisterFusionOutput
-        )
+        authentication_and_forward_to_management!(self, request, register_fusion_output)
     }
 
     async fn register_input_from_output(
         &self,
         request: Request<RegisterInputFromOutputRequest>,
     ) -> TeaclaveServiceResponseResult<RegisterInputFromOutputResponse> {
-        authentication_and_forward_to_management!(
-            self,
-            request,
-            register_input_from_output,
-            Endpoints::RegisterInputFromOutput
-        )
+        authentication_and_forward_to_management!(self, request, register_input_from_output)
     }
 
     async fn get_output_file(
         &self,
         request: Request<GetOutputFileRequest>,
     ) -> TeaclaveServiceResponseResult<GetOutputFileResponse> {
-        authentication_and_forward_to_management!(
-            self,
-            request,
-            get_output_file,
-            Endpoints::GetOutputFile
-        )
+        authentication_and_forward_to_management!(self, request, get_output_file)
     }
 
     async fn get_input_file(
         &self,
         request: Request<GetInputFileRequest>,
     ) -> TeaclaveServiceResponseResult<GetInputFileResponse> {
-        authentication_and_forward_to_management!(
-            self,
-            request,
-            get_input_file,
-            Endpoints::GetInputFile
-        )
+        authentication_and_forward_to_management!(self, request, get_input_file)
     }
 
     async fn register_function(
         &self,
         request: Request<RegisterFunctionRequest>,
     ) -> TeaclaveServiceResponseResult<RegisterFunctionResponse> {
-        authentication_and_forward_to_management!(
-            self,
-            request,
-            register_function,
-            Endpoints::RegisterFunction
-        )
+        authentication_and_forward_to_management!(self, request, register_function)
     }
 
     async fn update_function(
         &self,
         request: Request<UpdateFunctionRequest>,
     ) -> TeaclaveServiceResponseResult<UpdateFunctionResponse> {
-        authentication_and_forward_to_management!(
-            self,
-            request,
-            update_function,
-            Endpoints::UpdateFunction
-        )
+        authentication_and_forward_to_management!(self, request, update_function)
     }
 
     async fn get_function(
         &self,
         request: Request<GetFunctionRequest>,
     ) -> TeaclaveServiceResponseResult<GetFunctionResponse> {
-        authentication_and_forward_to_management!(
-            self,
-            request,
-            get_function,
-            Endpoints::GetFunction
-        )
+        authentication_and_forward_to_management!(self, request, get_function)
     }
 
     async fn get_function_usage_stats(
         &self,
         request: Request<GetFunctionUsageStatsRequest>,
     ) -> TeaclaveServiceResponseResult<GetFunctionUsageStatsResponse> {
-        authentication_and_forward_to_management!(
-            self,
-            request,
-            get_function_usage_stats,
-            Endpoints::GetFunctionUsageStats
-        )
+        authentication_and_forward_to_management!(self, request, get_function_usage_stats)
     }
 
     async fn delete_function(
         &self,
         request: Request<DeleteFunctionRequest>,
     ) -> TeaclaveServiceResponseResult<()> {
-        authentication_and_forward_to_management!(
-            self,
-            request,
-            delete_function,
-            Endpoints::DeleteFunction
-        )
+        authentication_and_forward_to_management!(self, request, delete_function)
     }
 
     async fn disable_function(
         &self,
         request: Request<DisableFunctionRequest>,
     ) -> TeaclaveServiceResponseResult<()> {
-        authentication_and_forward_to_management!(
-            self,
-            request,
-            disable_function,
-            Endpoints::DisableFunction
-        )
+        authentication_and_forward_to_management!(self, request, disable_function)
     }
 
     async fn list_functions(
         &self,
         request: Request<ListFunctionsRequest>,
     ) -> TeaclaveServiceResponseResult<ListFunctionsResponse> {
-        authentication_and_forward_to_management!(
-            self,
-            request,
-            list_functions,
-            Endpoints::ListFunctions
-        )
+        authentication_and_forward_to_management!(self, request, list_functions)
     }
 
     async fn create_task(
         &self,
         request: Request<CreateTaskRequest>,
     ) -> TeaclaveServiceResponseResult<CreateTaskResponse> {
-        authentication_and_forward_to_management!(self, request, create_task, Endpoints::CreateTask)
+        authentication_and_forward_to_management!(self, request, create_task)
     }
 
     async fn get_task(
         &self,
         request: Request<GetTaskRequest>,
     ) -> TeaclaveServiceResponseResult<GetTaskResponse> {
-        authentication_and_forward_to_management!(self, request, get_task, Endpoints::GetTask)
+        authentication_and_forward_to_management!(self, request, get_task)
     }
 
     async fn assign_data(
         &self,
         request: Request<AssignDataRequest>,
     ) -> TeaclaveServiceResponseResult<()> {
-        authentication_and_forward_to_management!(self, request, assign_data, Endpoints::AssignData)
+        authentication_and_forward_to_management!(self, request, assign_data)
     }
 
     async fn approve_task(
         &self,
         request: Request<ApproveTaskRequest>,
     ) -> TeaclaveServiceResponseResult<()> {
-        authentication_and_forward_to_management!(
-            self,
-            request,
-            approve_task,
-            Endpoints::ApproveTask
-        )
+        authentication_and_forward_to_management!(self, request, approve_task)
     }
 
     async fn invoke_task(
         &self,
         request: Request<InvokeTaskRequest>,
     ) -> TeaclaveServiceResponseResult<()> {
-        authentication_and_forward_to_management!(self, request, invoke_task, Endpoints::InvokeTask)
+        authentication_and_forward_to_management!(self, request, invoke_task)
     }
 
     async fn cancel_task(
         &self,
         request: Request<CancelTaskRequest>,
     ) -> TeaclaveServiceResponseResult<()> {
-        authentication_and_forward_to_management!(self, request, cancel_task, Endpoints::CancelTask)
+        authentication_and_forward_to_management!(self, request, cancel_task)
     }
 
     async fn query_audit_logs(
         &self,
         request: Request<QueryAuditLogsRequest>,
     ) -> TeaclaveServiceResponseResult<QueryAuditLogsResponse> {
-        authentication_and_forward_to_management!(
-            self,
-            request,
-            query_audit_logs,
-            Endpoints::QueryAuditLogs
-        )
+        authentication_and_forward_to_management!(self, request, query_audit_logs)
     }
 }
 
@@ -493,52 +365,3 @@
         Ok(claims)
     }
 }
-
-#[cfg(feature = "enclave_unit_test")]
-pub mod tests {
-    use super::*;
-
-    pub fn test_authorize_platform_admin() {
-        let claims = UserAuthClaims {
-            role: "PlatformAdmin".to_string(),
-            ..Default::default()
-        };
-        let result = authorize(&claims, Endpoints::GetFunction);
-        assert!(result);
-    }
-
-    pub fn test_authorize_function_owner() {
-        let claims = UserAuthClaims {
-            role: "FunctionOwner".to_string(),
-            ..Default::default()
-        };
-        let result = authorize(&claims, Endpoints::GetFunction);
-        assert!(result);
-        let result = authorize(&claims, Endpoints::RegisterFunction);
-        assert!(result);
-        let result = authorize(&claims, Endpoints::UpdateFunction);
-        assert!(result);
-        let result = authorize(&claims, Endpoints::InvokeTask);
-        assert!(!result);
-    }
-
-    pub fn test_authorize_data_owner() {
-        let claims = UserAuthClaims {
-            role: "DataOwnerManager-Attribute".to_string(),
-            ..Default::default()
-        };
-        let result = authorize(&claims, Endpoints::GetFunction);
-        assert!(result);
-        let result = authorize(&claims, Endpoints::InvokeTask);
-        assert!(result);
-
-        let claims = UserAuthClaims {
-            role: "DataOwner-Attribute".to_string(),
-            ..Default::default()
-        };
-        let result = authorize(&claims, Endpoints::GetFunction);
-        assert!(result);
-        let result = authorize(&claims, Endpoints::InvokeTask);
-        assert!(result);
-    }
-}
diff --git a/services/proto/src/proto/teaclave_access_control_service.proto b/services/proto/src/proto/teaclave_access_control_service.proto
index 92dd829..a2e1c7f 100644
--- a/services/proto/src/proto/teaclave_access_control_service.proto
+++ b/services/proto/src/proto/teaclave_access_control_service.proto
@@ -22,47 +22,15 @@
 
 package teaclave_access_control_service_proto;
 
-message AuthorizeDataRequest {
-  string subject_user_id = 1;
-  string object_data_id = 2;
+message AuthorizeApiRequest {
+  string user_role = 1;
+  string api = 2;
 }
 
-message AuthorizeDataResponse {
-  bool accept = 1;
-}
-
-message AuthorizeFunctionRequest {
-  string subject_user_id = 1;
-  string object_function_id = 2;
-}
-
-message AuthorizeFunctionResponse {
-  bool accept = 1;
-}
-
-message AuthorizeTaskRequest {
-  string subject_user_id = 1;
-  string object_task_id = 2;
-}
-
-message AuthorizeTaskResponse {
-  bool accept = 1;
-}
-
-message AuthorizeStagedTaskRequest {
-  string subject_task_id = 1;
-  string object_function_id = 2;
-  repeated string object_input_data_id_list = 3;
-  repeated string object_output_data_id_list = 4;
-}
-
-message AuthorizeStagedTaskResponse {
+message AuthorizeApiResponse {
   bool accept = 1;
 }
 
 service TeaclaveAccessControl {
-  rpc AuthorizeData (AuthorizeDataRequest) returns (AuthorizeDataResponse);
-  rpc AuthorizeFunction (AuthorizeFunctionRequest) returns (AuthorizeFunctionResponse);
-  rpc AuthorizeTask (AuthorizeTaskRequest) returns (AuthorizeTaskResponse);
-  rpc AuthorizeStagedTask (AuthorizeStagedTaskRequest) returns (AuthorizeStagedTaskResponse);
+  rpc AuthorizeApi (AuthorizeApiRequest) returns (AuthorizeApiResponse);
 }
diff --git a/services/proto/src/teaclave_access_control_service.rs b/services/proto/src/teaclave_access_control_service.rs
index ca7d159..87b8a83 100644
--- a/services/proto/src/teaclave_access_control_service.rs
+++ b/services/proto/src/teaclave_access_control_service.rs
@@ -21,54 +21,3 @@
     TeaclaveAccessControl, TeaclaveAccessControlServer,
 };
 pub use proto::*;
-
-impl AuthorizeDataRequest {
-    pub fn new(subject_user_id: impl Into<String>, object_data_id: impl Into<String>) -> Self {
-        Self {
-            subject_user_id: subject_user_id.into(),
-            object_data_id: object_data_id.into(),
-        }
-    }
-}
-
-impl AuthorizeDataResponse {
-    pub fn new(accept: bool) -> Self {
-        Self { accept }
-    }
-}
-
-impl AuthorizeFunctionRequest {
-    pub fn new(subject_user_id: impl Into<String>, object_function_id: impl Into<String>) -> Self {
-        Self {
-            subject_user_id: subject_user_id.into(),
-            object_function_id: object_function_id.into(),
-        }
-    }
-}
-
-impl AuthorizeFunctionResponse {
-    pub fn new(accept: bool) -> Self {
-        Self { accept }
-    }
-}
-
-impl AuthorizeTaskRequest {
-    pub fn new(subject_user_id: impl Into<String>, object_task_id: impl Into<String>) -> Self {
-        Self {
-            subject_user_id: subject_user_id.into(),
-            object_task_id: object_task_id.into(),
-        }
-    }
-}
-
-impl AuthorizeTaskResponse {
-    pub fn new(accept: bool) -> Self {
-        Self { accept }
-    }
-}
-
-impl AuthorizeStagedTaskResponse {
-    pub fn new(accept: bool) -> Self {
-        Self { accept }
-    }
-}
diff --git a/services/utils/service_enclave_utils/src/lib.rs b/services/utils/service_enclave_utils/src/lib.rs
index 0a9be50..d48a2da 100644
--- a/services/utils/service_enclave_utils/src/lib.rs
+++ b/services/utils/service_enclave_utils/src/lib.rs
@@ -166,3 +166,7 @@
     create_trusted_scheduler_endpoint,
     "teaclave_scheduler_service"
 );
+impl_create_trusted_endpoint_fn!(
+    create_trusted_access_control_endpoint,
+    "teaclave_access_control_service"
+);
diff --git a/tests/functional/enclave/src/access_control_service.rs b/tests/functional/enclave/src/access_control_service.rs
index b52f80d..ea955b3 100644
--- a/tests/functional/enclave/src/access_control_service.rs
+++ b/tests/functional/enclave/src/access_control_service.rs
@@ -19,139 +19,32 @@
 use futures::FutureExt;
 use teaclave_proto::teaclave_access_control_service::*;
 use teaclave_test_utils::async_test_case;
-#[async_test_case]
-async fn test_authorize_data_success() {
+
+async fn test_authorize_api() {
     let mut client = get_access_control_client().await;
-
-    let request = AuthorizeDataRequest::new("mock_user_a", "mock_data");
-    let response_result = client.authorize_data(request).await;
-    assert!(response_result.is_ok());
-    assert!(response_result.unwrap().into_inner().accept);
-}
-
-#[async_test_case]
-async fn test_authorize_data_fail() {
-    let mut client = get_access_control_client().await;
-
-    let request = AuthorizeDataRequest::new("mock_user_d", "mock_data");
-    let response_result = client.authorize_data(request).await;
-    assert!(response_result.is_ok());
-    assert!(!response_result.unwrap().into_inner().accept);
-
-    let request = AuthorizeDataRequest::new("mock_user_a", "mock_data_b");
-    let response_result = client.authorize_data(request).await;
-    assert!(response_result.is_ok());
-    assert!(!response_result.unwrap().into_inner().accept);
-}
-
-#[async_test_case]
-async fn test_authorize_function_success() {
-    let mut client = get_access_control_client().await;
-
-    let request =
-        AuthorizeFunctionRequest::new("mock_public_function_owner", "mock_public_function");
-    let response_result = client.authorize_function(request).await;
-    assert!(response_result.is_ok());
-    assert!(response_result.unwrap().into_inner().accept);
-
-    let request =
-        AuthorizeFunctionRequest::new("mock_private_function_owner", "mock_private_function");
-    let response_result = client.authorize_function(request).await;
-    assert!(response_result.is_ok());
-    assert!(response_result.unwrap().into_inner().accept);
-
-    let request =
-        AuthorizeFunctionRequest::new("mock_private_function_owner", "mock_public_function");
-    let response_result = client.authorize_function(request).await;
-    assert!(response_result.is_ok());
-    assert!(response_result.unwrap().into_inner().accept);
-}
-
-#[async_test_case]
-async fn test_authorize_function_fail() {
-    let mut client = get_access_control_client().await;
-    let request =
-        AuthorizeFunctionRequest::new("mock_public_function_owner", "mock_private_function");
-    let response_result = client.authorize_function(request).await;
-    assert!(response_result.is_ok());
-    assert!(!response_result.unwrap().into_inner().accept);
-}
-
-#[async_test_case]
-async fn test_authorize_task_success() {
-    let mut client = get_access_control_client().await;
-    let request = AuthorizeTaskRequest::new("mock_participant_a", "mock_task");
-    let response_result = client.authorize_task(request).await;
-    assert!(response_result.is_ok());
-    assert!(response_result.unwrap().into_inner().accept);
-
-    let request = AuthorizeTaskRequest::new("mock_participant_b", "mock_task");
-    let response_result = client.authorize_task(request).await;
-    assert!(response_result.is_ok());
-    assert!(response_result.unwrap().into_inner().accept);
-}
-
-#[async_test_case]
-async fn test_authorize_task_fail() {
-    let mut client = get_access_control_client().await;
-    let request = AuthorizeTaskRequest::new("mock_participant_c", "mock_task");
-    let response_result = client.authorize_task(request).await;
-    assert!(response_result.is_ok());
-    assert!(!response_result.unwrap().into_inner().accept);
-}
-
-#[async_test_case]
-async fn test_authorize_staged_task_success() {
-    let mut client = get_access_control_client().await;
-    let request = AuthorizeStagedTaskRequest {
-        subject_task_id: "mock_staged_task".to_string(),
-        object_function_id: "mock_staged_allowed_private_function".to_string(),
-        object_input_data_id_list: vec![
-            "mock_staged_allowed_data1".to_string(),
-            "mock_staged_allowed_data2".to_string(),
-            "mock_staged_allowed_data3".to_string(),
-        ],
-        object_output_data_id_list: vec![
-            "mock_staged_allowed_data1".to_string(),
-            "mock_staged_allowed_data2".to_string(),
-            "mock_staged_allowed_data3".to_string(),
-        ],
+    let request = AuthorizeApiRequest {
+        user_role: "PlatformAdmin".to_owned(),
+        api: "Arbitrary_api".to_owned(),
     };
-    let response_result = client.authorize_staged_task(request).await;
+    let response_result = client.authorize_api(request).await;
     assert!(response_result.is_ok());
     assert!(response_result.unwrap().into_inner().accept);
-}
 
-#[async_test_case]
-async fn test_authorize_staged_task_fail() {
     let mut client = get_access_control_client().await;
-    let request = AuthorizeStagedTaskRequest {
-        subject_task_id: "mock_staged_task".to_string(),
-        object_function_id: "mock_staged_disallowed_private_function".to_string(),
-        object_input_data_id_list: vec![],
-        object_output_data_id_list: vec![],
+    let request = AuthorizeApiRequest {
+        user_role: "DataOwner".to_owned(),
+        api: "get_function".to_owned(),
     };
-    let response_result = client.authorize_staged_task(request).await;
+    let response_result = client.authorize_api(request).await;
     assert!(response_result.is_ok());
-    assert!(!response_result.unwrap().into_inner().accept);
+    assert!(response_result.unwrap().into_inner().accept);
 
-    let request = AuthorizeStagedTaskRequest {
-        subject_task_id: "mock_staged_task".to_string(),
-        object_function_id: "mock_staged_allowed_private_function".to_string(),
-        object_input_data_id_list: vec!["mock_staged_disallowed_data1".to_string()],
-        object_output_data_id_list: vec![],
+    let mut client = get_access_control_client().await;
+    let request = AuthorizeApiRequest {
+        user_role: "FunctionOwner".to_owned(),
+        api: "invoke_task".to_owned(),
     };
-    let response_result = client.authorize_staged_task(request).await;
-    assert!(response_result.is_ok());
-    assert!(!response_result.unwrap().into_inner().accept);
-
-    let request = AuthorizeStagedTaskRequest {
-        subject_task_id: "mock_staged_task".to_string(),
-        object_function_id: "mock_staged_allowed_private_function".to_string(),
-        object_input_data_id_list: vec![],
-        object_output_data_id_list: vec!["mock_staged_disallowed_data2".to_string()],
-    };
-    let response_result = client.authorize_staged_task(request).await;
+    let response_result = client.authorize_api(request).await;
     assert!(response_result.is_ok());
     assert!(!response_result.unwrap().into_inner().accept);
 }
@@ -162,10 +55,7 @@
     for _i in 0..10 {
         let child = std::thread::spawn(move || async {
             for _j in 0..10 {
-                test_authorize_data_fail().await;
-                test_authorize_function_fail().await;
-                test_authorize_task_success().await;
-                test_authorize_staged_task_fail().await;
+                test_authorize_api().await;
             }
         });
         thread_pool.push(child);
diff --git a/tests/functional/enclave/src/end_to_end/mod.rs b/tests/functional/enclave/src/end_to_end/mod.rs
index 1f8e986..010b437 100644
--- a/tests/functional/enclave/src/end_to_end/mod.rs
+++ b/tests/functional/enclave/src/end_to_end/mod.rs
@@ -22,8 +22,6 @@
 use url::Url;
 mod builtin_echo;
 mod builtin_gbdt_train;
-mod mesapy_data_fusion;
-mod mesapy_echo;
 use teaclave_rpc::CredentialService;
 
 async fn get_task(
diff --git a/third_party/rust-sgx-sdk b/third_party/rust-sgx-sdk
index 5fd7766..ec44320 160000
--- a/third_party/rust-sgx-sdk
+++ b/third_party/rust-sgx-sdk
@@ -1 +1 @@
-Subproject commit 5fd7766403ce313c9d5c0fe98a9cdb19809c2de2
+Subproject commit ec4432014b02f6007fd8fb7c4ea9bc3e8c96d6ef