diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 00000000..0dab1ed1
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,2 @@
+build/**/*
+build
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 67c3f15a..d939f797 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -15,9 +15,9 @@ concurrency:
 
 jobs:
   unix:
-    
+
     runs-on: ${{ matrix.os }}
-     
+
     strategy:
       fail-fast: false
       matrix:
@@ -74,14 +74,14 @@ jobs:
         shell: bash -l {0}
         run: |
           cd build/test
+          export CPLUS_INCLUDE_PATH=$CONDA_PREFIX/include:$CONDA_BUILD_SYSROOT:$CONDA_BUILD_SYSROOT/..:$CONDA_BUILD_SYSROOT/../x86_64-conda-linux-gnu/include/c++/12.3.0:$CONDA_BUILD_SYSROOT/../x86_64-conda-linux-gnu/include/c++/12.3.0/include:$CONDA_BUILD_SYSROOT/../include:$CONDA_BUILD_SYSROOT/usr/include:/home/runner/micromamba-root/envs/xeus-cpp/bin/../lib/gcc/x86_64-conda-linux-gnu/12.3.0/include:/home/runner/micromamba-root/envs/xeus-cpp/bin/../lib/gcc/x86_64-conda-linux-gnu/12.3.0/include-fixed:/home/runner/micromamba-root/envs/xeus-cpp/bin/../lib/gcc/x86_64-conda-linux-gnu/12.3.0/../../../../x86_64-conda-linux-gnu/include:/home/runner/micromamba-root/envs/xeus-cpp/bin/../x86_64-conda-linux-gnu/sysroot/usr/include
           ./test_xeus_cpp
         timeout-minutes: 4
 
       - name: test
         shell: bash -l {0}
         run: |
-          cd test
-          pytest .  --reruns 5
+          $CONDA_PREFIX/bin/pytest test --reruns 5
 
       - name: Prepare code coverage report
         if: ${{ success() && (matrix.coverage == true) }}
@@ -109,10 +109,11 @@ jobs:
         uses: mxschmitt/action-tmate@v3
         # When debugging increase to a suitable value!
         timeout-minutes: 30
+
   win:
-    
+
     runs-on: ${{ matrix.os }}
-     
+
     strategy:
       fail-fast: false
       matrix:
@@ -177,7 +178,7 @@ jobs:
           emsdk activate ${{matrix.emsdk_ver}}
           source $CONDA_EMSDK_DIR/emsdk_env.sh
           micromamba create -f environment-wasm-host.yml --platform=emscripten-wasm32
-          
+
           mkdir build
           pushd build
 
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 66833cb1..09a9def0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -19,6 +19,10 @@ set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake;${CMAKE_MODULE_PATH}")
 
 set(XEUS_CPP_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)
 
+enable_language(CXX)
+set(CMAKE_CXX_EXTENSIONS NO)
+set(CMAKE_POSITION_INDEPENDENT_CODE ON)
+
 # Versionning
 # ===========
 
@@ -40,12 +44,52 @@ include(GNUInstallDirs)
 
 if (NOT DEFINED XEUS_CPP_KERNELSPEC_PATH)
     set(XEUS_CPP_KERNELSPEC_PATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}/")
+    set(XEUS_CPP_RESOURCE_DIR ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/clang/17)
 endif ()
 
-configure_file (
-    "${CMAKE_CURRENT_SOURCE_DIR}/share/jupyter/kernels/xcpp/kernel.json.in"
-    "${CMAKE_CURRENT_SOURCE_DIR}/share/jupyter/kernels/xcpp/kernel.json"
-)
+function(configure_kernel kernel)
+  set(CMAKE_CPLUS_INCLUDE_PATH "$ENV{CPLUS_INCLUDE_PATH}")
+  set(CMAKE_PATH "$ENV{PATH}")
+  set(CMAKE_LD_LIBRARY_PATH "$ENV{LD_LIBRARY_PATH}")
+  set(CMAKE_PYTHONPATH "$ENV{PYTHONPATH}")
+  set(CMAKE_VENV_PATH "$ENV{VENV}")
+
+  message(STATUS "Debug: Replace in kernels")
+  message(STATUS "Debug: CMAKE_CPLUS_INCLUDE_PATH=${CMAKE_CPLUS_INCLUDE_PATH}")
+  message(STATUS "Debug: CMAKE_PATH=${CMAKE_PATH}")
+  message(STATUS "Debug: CMAKE_LD_LIBRARY_PATH=${CMAKE_LD_LIBRARY_PATH}")
+  message(STATUS "Debug: CMAKE_PYTHONPATH=${CMAKE_PYTHONPATH}")
+  message(STATUS "Debug: CMAKE_VENV_PATH=${CMAKE_VENV_PATH}")
+  message(STATUS "Debug: CMAKE_CURRENT_SOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}")
+  message(STATUS "Debug: CMAKE_CURRENT_BINARY_DIR=${CMAKE_CURRENT_BINARY_DIR}")
+
+  configure_file (
+    "${CMAKE_CURRENT_SOURCE_DIR}/${kernel}/kernel.json.in"
+    "${CMAKE_CURRENT_BINARY_DIR}/${kernel}/kernel.json"
+    )
+  file(GLOB files "${CMAKE_CURRENT_SOURCE_DIR}/${kernel}/*.png")
+  foreach(file ${files})
+    configure_file(
+      "${file}"
+      "${CMAKE_CURRENT_BINARY_DIR}/${kernel}/"
+      COPYONLY
+      )
+  endforeach()
+  file(GLOB files "${CMAKE_CURRENT_SOURCE_DIR}/${kernel}/*.svg")
+  foreach(file ${files})
+    configure_file(
+      "${file}"
+      "${CMAKE_CURRENT_BINARY_DIR}/${kernel}/"
+      COPYONLY
+      )
+  endforeach()
+endfunction()
+
+file(GLOB _kernels LIST_DIRECTORIES true RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "share/jupyter/kernels/*")
+foreach(_kernel IN LISTS _kernels)
+  message("Configure kernel: ${_kernel}")
+  configure_kernel("${_kernel}")
+endforeach()
 
 # Build options
 # =============
@@ -54,8 +98,8 @@ option(XEUS_CPP_BUILD_STATIC "Build xeus-cpp static library" ON)
 OPTION(XEUS_CPP_BUILD_SHARED "Split xcpp build into executable and library" ON)
 OPTION(XEUS_CPP_BUILD_EXECUTABLE "Build the xcpp executable" ON)
 
-OPTION(XEUS_CPP_USE_SHARED_XEUS "Link xcpp  with the xeus shared library (instead of the static library)" ON)
-OPTION(XEUS_CPP_USE_SHARED_XEUS_CPP "Link xcpp  with the xeus shared library (instead of the static library)" ON)
+OPTION(XEUS_CPP_USE_SHARED_XEUS "Link xcpp with the xeus shared library (instead of the static library)" ON)
+OPTION(XEUS_CPP_USE_SHARED_XEUS_CPP "Link xcpp with the xeus shared library (instead of the static library)" ON)
 
 # Test options
 OPTION(XEUS_CPP_BUILD_TESTS "xeus-cpp test suite" ON)
@@ -110,8 +154,11 @@ else()
   add_compile_options(-fexceptions)
 endif ()
 
-if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Intel")
-    if(NOT EMSCRIPTEN)
+if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR
+    CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR
+    CMAKE_CXX_COMPILER_ID MATCHES "Intel")
+
+    if(NOT XEUS_CPP_EMSCRIPTEN_WASM_BUILD)
         add_compile_options(-Wunused-parameter -Wextra -Wreorder)
     endif()
 endif ()
@@ -121,12 +168,15 @@ if(EMSCRIPTEN)
     set(EMSCRIPTEN_FEATURES "${EMSCRIPTEN_FEATURES} -s \"EXTRA_EXPORTED_RUNTIME_METHODS=[ENV']\"")
 endif()
 
-find_package(Clang REQUIRED)
-include(AddLLVM)
-include(HandleLLVMOptions)
-add_definitions(${LLVM_DEFINITIONS})
+find_package(CppInterOp REQUIRED CONFIG PATHS "${CMAKE_PREFIX_PATH}" "${CMAKE_PREFIX_PATH}/lib" "${CPPINTEROP_DIR}" "${CPPINTEROP_DIR}/lib")
+if(CppInterOp_FOUND)
+  message(STATUS "Found CppInterOp: config=${CppInterOp_CONFIG} dir=${CppInterOp_DIR} (found version=${CppInterOp_VERSION})")
+endif()
+
 find_package(argparse REQUIRED)
 find_package(pugixml REQUIRED)
+set(Python_FIND_VIRTUALENV ONLY)
+find_package(Python COMPONENTS Interpreter Development)
 
 # Source files
 # ============
@@ -155,10 +205,18 @@ set(XEUS_CPP_SRC
     src/xoptions.cpp
     src/xparser.cpp
     src/xutils.cpp
+    src/xdemangle.hpp
+    src/xinspect.hpp
+    src/xsystem.hpp
+    src/xparser.hpp
+    src/xmagics/os.hpp
+    src/xmagics/os.cpp
 )
 
 if(EMSCRIPTEN)
     list(APPEND XEUS_CPP_SRC src/xinterpreter_wasm.cpp)
+else()
+    list(APPEND XEUS_CPP_SRC src/xmagics/pythonexec.hpp src/xmagics/pythonexec.cpp)
 endif()
 
 set(XEUS_CPP_MAIN_SRC
@@ -172,7 +230,8 @@ include(CheckCXXCompilerFlag)
 
 string(TOUPPER "${CMAKE_BUILD_TYPE}" U_CMAKE_BUILD_TYPE)
 
-set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib; ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}")
+set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib;${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}")
+list(REMOVE_DUPLICATES CMAKE_INSTALL_RPATH)
 
 macro(xeus_cpp_set_common_options target_name)
     if (MSVC)
@@ -226,7 +285,6 @@ macro(xeus_cpp_set_kernel_options target_name)
         find_package(Threads)
         target_link_libraries(${target_name} PRIVATE ${CMAKE_THREAD_LIBS_INIT})
     endif()
-    
 endmacro()
 
 # Common macro for shared and static library
@@ -262,7 +320,14 @@ macro(xeus_cpp_create_target target_name linkage output_name)
         set(XEUS_CPP_XEUS_TARGET xeus-static)
     endif ()
 
-    target_link_libraries(${target_name} PUBLIC ${XEUS_CPP_XEUS_TARGET} clangInterpreter pugixml argparse::argparse xtl)
+    target_link_libraries(${target_name} PUBLIC ${XEUS_CPP_XEUS_TARGET} clangCppInterOp pugixml argparse::argparse xtl)
+    if (EMSCRIPTEN)
+      # For some reason emscripten cannot find Python::Python.
+      target_link_libraries(${target_name} PUBLIC Development.Embed)
+    else()
+      target_link_libraries(${target_name} PUBLIC Python::Python)
+    endif()
+
     if (WIN32 OR CYGWIN)
         #
     elseif (APPLE)
@@ -272,7 +337,7 @@ macro(xeus_cpp_create_target target_name linkage output_name)
         find_package(Threads) # TODO: add Threads as a dependence of xeus-static?
         target_link_libraries(${target_name} PRIVATE ${CMAKE_THREAD_LIBS_INIT})
     endif()
-    
+
 endmacro()
 
 # xeus-cpp-headers
@@ -319,6 +384,30 @@ if (XEUS_CPP_BUILD_EXECUTABLE)
     xeus_cpp_set_common_options(xcpp)
     xeus_cpp_set_kernel_options(xcpp)
     target_link_libraries(xcpp PRIVATE xeus-zmq)
+    set_target_properties(xcpp PROPERTIES
+      ENABLE_EXPORTS 1
+      CXX_STANDARD ${CMAKE_CXX_STANDARD})
+    target_link_libraries(xcpp PUBLIC xeus-cpp pthread Python::Python)
+
+    ##TODO: We may be need sse RPATH
+    set_target_properties(xcpp clangCppInterOp PROPERTIES INSTALL_RPATH_USE_LINK_PATH TRUE)
+    if(APPLE)
+      target_link_libraries(xcpp PUBLIC -Wl,-w -Wl,-bind_at_load -Wl,-undefined,dynamic_lookup)
+    elseif(NOT MSVC)
+      target_link_libraries(xcpp PUBLIC -Wl,--unresolved-symbols=ignore-in-object-files)
+    endif()
+
+    target_include_directories(xeus-cpp PUBLIC ${Python_INCLUDE_DIRS})
+    target_link_libraries(xeus-cpp PUBLIC ${PYTHON_LIBRARIES})
+    target_link_libraries(xeus-cpp ${PYTHON_LIBRARIES_Development_Main})
+    set_target_properties(xeus-cpp PROPERTIES
+                      PUBLIC_HEADER "${XEUS_CPP_HEADERS}"
+                      COMPILE_DEFINITIONS "XEUS_CPP_EXPORTS"
+                      PREFIX ""
+                      VERSION ${${PROJECT_NAME}_VERSION}
+                      SOVERSION ${XEUS_CPP_VERSION_MAJOR}
+                      OUTPUT_NAME "libxeus-cpp"
+                      CXX_STANDARD ${CMAKE_CXX_STANDARD})
 endif()
 
 if(EMSCRIPTEN)
@@ -348,10 +437,10 @@ set(XEUS_CPP_CMAKECONFIG_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NA
 if (XEUS_CPP_BUILD_SHARED)
     install(TARGETS ${XEUS_CPP_TARGETS}
             EXPORT ${PROJECT_NAME}-targets
-            ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
-            LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-            RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
-            PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/xeus-cpp)
+            ARCHIVE DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}
+            LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}
+            RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}
+            PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/xeus-cpp)
 
     # Makes the project importable from the build directory
     export(EXPORT ${PROJECT_NAME}-targets
@@ -359,22 +448,23 @@ if (XEUS_CPP_BUILD_SHARED)
 endif ()
 
 # Install xcpp
+if ("${CMAKE_VENV_PATH}" STREQUAL "")
+  set(CMAKE_VENV_PATH "${CMAKE_INSTALL_PREFIX}")
+endif()
 if (XEUS_CPP_BUILD_EXECUTABLE)
     install(TARGETS xcpp
-            RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
-endif()
+            RUNTIME DESTINATION ${CMAKE_VENV_PATH}/bin)
+endif(XEUS_CPP_BUILD_EXECUTABLE)
 
 if(XEUS_CPP_BUILD_EXECUTABLE OR EMSCRIPTEN)
     # Configuration and data directories for jupyter and xeus-cpp
     set(XJUPYTER_DATA_DIR "share/jupyter"    CACHE STRING "Jupyter data directory")
-
     # Install xcpp Jupyter kernelspec
-    set(KERNELSPEC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/share/jupyter/kernels)
+    set(KERNELSPEC_DIR ${CMAKE_CURRENT_BINARY_DIR}/share/jupyter/kernels)
     install(DIRECTORY ${KERNELSPEC_DIR}
             DESTINATION ${XJUPYTER_DATA_DIR}
             PATTERN "*.in" EXCLUDE)
 
-
     # Extra path for installing Jupyter kernelspec
     if (XEXTRA_JUPYTER_DATA_DIR)
         install(DIRECTORY ${KERNELSPEC_DIR}
@@ -439,3 +529,7 @@ if(EMSCRIPTEN)
             "$<TARGET_FILE_DIR:xcpp>/xcpp.wasm"
             DESTINATION ${CMAKE_INSTALL_BINDIR})
 endif ()
+
+if(XEUS_CPP_INCLUDE_DOCS)
+    add_subdirectory(docs)
+endif()
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 00000000..9fec1e7b
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,280 @@
+# Copyright (c) Jupyter Development Team.
+# Distributed under the terms of the Modified BSD License.
+
+# https://hub.docker.com/r/jupyter/base-notebook/tags
+ARG BASE_CONTAINER=jupyter/base-notebook
+ARG BASE_TAG=latest
+ARG BUILD_TYPE=Debug
+
+
+FROM $BASE_CONTAINER:$BASE_TAG
+
+LABEL maintainer="Xeus-cpp Project"
+
+SHELL ["/bin/bash", "--login", "-o", "pipefail", "-c"]
+
+USER root
+
+ENV TAG="$BASE_TAG"
+
+ENV LC_ALL=en_US.UTF-8 \
+    LANG=en_US.UTF-8 \
+    LANGUAGE=en_US.UTF-8
+
+# Install all OS dependencies for notebook server that starts but lacks all
+# features (e.g., download as all possible file formats)
+RUN \
+    set -x && \
+    apt-get update --yes && \
+    apt-get install --yes --no-install-recommends pciutils && \
+    export _CUDA_="$(lspci -nn | grep '\[03' | grep NVIDIA)" && \
+    apt-get install --yes --no-install-recommends \
+      #fonts-liberation, pandoc, run-one are inherited from base-notebook container image
+    # Other "our" apt installs
+      unzip \
+      curl \
+      jq \
+      ###libomp-dev \
+    # Other "our" apt installs (development and testing)
+      build-essential \
+      git \
+      nano-tiny \
+      less \
+      gdb valgrind \
+      emacs \
+    # CUDA
+      #cuda \
+      $([ -n "$_CUDA_" ] && echo nvidia-cuda-toolkit) \
+    && \
+    apt-get clean && rm -rf /var/lib/apt/lists/* && \
+    echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && \
+    locale-gen
+
+ENV LC_ALL=en_US.UTF-8 \
+    LANG=en_US.UTF-8 \
+    LANGUAGE=en_US.UTF-8
+
+# Create alternative for nano -> nano-tiny
+#RUN update-alternatives --install /usr/bin/nano nano /bin/nano-tiny 10
+
+USER ${NB_UID}
+
+# Copy git repository to home directory of container
+COPY --chown=${NB_UID}:${NB_GID} . "${HOME}"/
+
+EXPOSE 9999
+ENV JUPYTER_PORT=9999
+
+# Configure container startup
+CMD ["start-notebook.sh", "--debug", "&>/home/jovyan/log.txt"]
+
+USER root
+
+# Fix start-notebook.sh
+RUN sed -i '2 i source /home/jovyan/.conda.init && conda activate .venv' /usr/local/bin/start-notebook.sh
+
+### Make /home/runner directory and fix permisions
+##RUN mkdir /home/runner && fix-permissions /home/runner
+
+# Switch back to jovyan to avoid accidental container runs as root
+USER ${NB_UID}
+
+WORKDIR "${HOME}"
+
+ENV NB_PYTHON_PREFIX=${CONDA_DIR} \
+    KERNEL_PYTHON_PREFIX=${CONDA_DIR} \
+    VENV=${CONDA_DIR}/envs/.venv \
+    # CUDA
+    NVIDIA_VISIBLE_DEVICES=all \
+    NVIDIA_DRIVER_CAPABILITIES=compute,utility \
+    NVIDIA_REQUIRE_CUDA="cuda>=12.1.1 driver>=530" \
+    #
+    PATH=/opt/conda/envs/.venv/bin:/opt/conda/bin:/opt/conda/envs/.venv/bin:/opt/conda/condabin:/opt/conda/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \
+    LD_LIBRARY_PATH=/home/jovyan/cppyy-backend/python/cppyy_backend/lib:/opt/conda/envs/.venv/lib:/opt/conda/lib:/home/jovyan/cppyy-backend/python/cppyy_backend/lib:/opt/conda/envs/.venv/lib \
+    PYTHONPATH=/home/jovyan/CPyCppyy/build:/home/jovyan/cppyy-backend/python:/home/jovyan \
+    CPLUS_INCLUDE_PATH=/opt/conda/envs/.venv/include:\
+/opt/conda/envs/.venv/include/python3.10:\
+/home/jovyan/clad/include:\
+/home/jovyan/CPyCppyy/include:\
+/home/jovyan/cppyy-backend/python/cppyy_backend/include:\
+/opt/conda/envs/.venv/include/llvm:\
+/opt/conda/envs/.venv/include/clang:\
+/opt/conda/include:\
+/home/jovyan/clad/include:\
+/home/jovyan/CppInterOp/include:\
+/opt/conda/include:\
+#
+/opt/conda/envs/.venv/lib/gcc/x86_64-conda-linux-gnu/12.3.0/include:\
+/opt/conda/envs/.venv/lib/gcc/x86_64-conda-linux-gnu/12.3.0/include-fixed:\
+/opt/conda/envs/.venv/lib/gcc/x86_64-conda-linux-gnu/12.3.0/../../../../x86_64-conda-linux-gnu/include:\
+/opt/conda/envs/.venv/x86_64-conda-linux-gnu/include/c++/12.3.0:\
+/opt/conda/envs/.venv/x86_64-conda-linux-gnu/include/c++/12.3.0/x86_64-conda-linux-gnu:\
+/opt/conda/envs/.venv/x86_64-conda-linux-gnu/include/c++/12.3.0/backward:\
+/opt/conda/envs/.venv/x86_64-conda-linux-gnu/sysroot/usr/include:\
+#
+/usr/include
+
+# VENV
+
+# Jupyter Notebook, Lab, and Hub are installed in base image
+# ReGenerate a notebook server config
+# Cleanup temporary files
+# Correct permissions
+# Do all this in a single RUN command to avoid duplicating all of the
+# files across image layers when the permissions change
+#RUN mamba update --all --quiet --yes -c conda-forge && \
+RUN \
+    set -x && \
+    # setup virtual environment
+    mamba create -y -n .venv python=3.10.6 && \
+    #
+    #echo "echo \"@ @ @  PROFILE @ @ @ \"" >> ~/.profile && \
+    #echo "echo \"@ @ @  BASHRC @ @ @ \"" >> /home/jovyan/.bashrc && \
+    mv /home/jovyan/.bashrc /home/jovyan/.bashrc.tmp && \
+    touch /home/jovyan/.bashrc && \
+    conda init bash && \
+    mv /home/jovyan/.bashrc /home/jovyan/.conda.init && \
+    mv /home/jovyan/.bashrc.tmp /home/jovyan/.bashrc && \
+    conda init bash && \
+    echo "source /home/jovyan/.conda.init && conda activate .venv" >> /home/jovyan/.bashrc && \
+    #
+    source /home/jovyan/.conda.init && \
+    conda activate .venv && \
+    fix-permissions "${CONDA_DIR}" && \
+    #
+    mamba install --quiet --yes -c conda-forge \
+      # notebook, jpyterhub, jupyterlab are inherited from base-notebook container image
+    # Other "our" conda installs
+      #
+    # Build dependencies
+      make \
+      cmake \
+      cxx-compiler \
+    # Host dependencies
+      'xeus-zmq>=1.0.2,<2.0' \
+      nlohmann_json \
+      cppzmq \
+      xtl \
+      'clangdev>=17' \
+      'llvm-openmp' \
+      pugixml \
+      cpp-argparse \
+      zlib \
+    #
+      ipykernel \
+    # Test dependencies
+      pytest \
+      'jupyter_kernel_test>=0.4.3' \
+      nbval \
+      pytest-rerunfailures \
+      doctest \
+      && \
+    hash -r && \
+    pip install ipython && \
+    #rm /home/jovyan/.jupyter/jupyter_notebook_config.py && \
+    jupyter notebook --generate-config -y && \
+    mamba clean --all -f -y && \
+    npm cache clean --force && \
+    jupyter lab clean && \
+    rm -rf "/home/${NB_USER}/.cache/yarn" && \
+    fix-permissions "${CONDA_DIR}" && \
+    fix-permissions "/home/${NB_USER}"
+
+### Post Build
+RUN \
+    set -x && \
+    source /home/jovyan/.conda.init && \
+    conda activate .venv && \
+    source /home/jovyan/.conda.init && \
+    conda activate .venv && \
+    #
+    export PATH_TO_LLVM_BUILD=${VENV} && \
+    ###export PATH=${VENV}/bin:${CONDA_DIR}/bin:$PATH_TO_LLVM_BUILD/bin:$PATH && \
+    ##export PATH=${VENV}/bin:${CONDA_DIR}/bin:$PATH && \
+    echo "export EDITOR=emacs" >> ~/.profile && \
+    #
+    # Build CppInterOp
+    #
+    #sys_incs=$(LC_ALL=C c++ -xc++ -E -v /dev/null 2>&1 | LC_ALL=C sed -ne '/starts here/,/End of/p' | LC_ALL=C sed '/^ /!d' | cut -c2- | tr '\n' ':') && \
+    git clone https://github.com/compiler-research/CppInterOp.git && \
+    export CB_PYTHON_DIR="$PWD/cppyy-backend/python" && \
+    export CPPINTEROP_DIR="$CB_PYTHON_DIR/cppyy_backend" && \
+    cd CppInterOp && \
+    mkdir build && \
+    cd build && \
+    export CPPINTEROP_BUILD_DIR=$PWD && \
+    cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DUSE_CLING=OFF -DUSE_REPL=ON -DLLVM_DIR=$PATH_TO_LLVM_BUILD -DLLVM_CONFIG_EXTRA_PATH_HINTS=${PATH_TO_LLVM_BUILD}/lib -DLLVM_USE_LINKER=gold -DBUILD_SHARED_LIBS=ON -DCMAKE_INSTALL_PREFIX=$CPPINTEROP_DIR .. && \
+    cmake --build . --parallel $(nproc --all) && \
+    #make install -j$(nproc --all)
+    cd ../.. && \
+    #
+    # Build and Install cppyy-backend
+    #
+    git clone https://github.com/compiler-research/cppyy-backend.git && \
+    cd cppyy-backend && \
+    mkdir -p $CPPINTEROP_DIR/lib build && cd build && \
+    # Install CppInterOp
+    (cd $CPPINTEROP_BUILD_DIR && cmake --build . --target install --parallel $(nproc --all)) && \
+    # Build and Install cppyy-backend
+    cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCppInterOp_DIR=$CPPINTEROP_DIR .. && \
+    cmake --build . --parallel $(nproc --all) && \
+    cp libcppyy-backend.so $CPPINTEROP_DIR/lib/ && \
+    cd ../.. && \
+    #
+    # Build and Install CPyCppyy
+    #
+    # Install CPyCppyy
+    git clone https://github.com/compiler-research/CPyCppyy.git && \
+    cd CPyCppyy && \
+    mkdir build && cd build && \
+    cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE .. && \
+    cmake --build . --parallel $(nproc --all) && \
+    export CPYCPPYY_DIR=$PWD && \
+    cd ../.. && \
+    #
+    # Build and Install cppyy
+    #
+    # Install cppyy
+    git clone https://github.com/compiler-research/cppyy.git && \
+    cd cppyy && \
+    python -m pip install --upgrade . --no-deps && \
+    cd .. && \
+    # Run cppyy
+    #TODO: Fix cppyy path (/home/jovyan) to path to installed module
+    ###python -c "import cppyy" && \
+    #
+    # Build and Install xeus-cpp
+    #
+    mkdir build && \
+    cd build && \
+    cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_PREFIX_PATH=$KERNEL_PYTHON_PREFIX -DCMAKE_INSTALL_PREFIX=$KERNEL_PYTHON_PREFIX -DCMAKE_INSTALL_LIBDIR=lib -DCPPINTEROP_DIR=$CPPINTEROP_BUILD_DIR .. && \
+    make install -j$(nproc --all) && \
+    cd .. && \
+    #
+    # Build and Install Clad
+    #
+    git clone --depth=1 https://github.com/vgvassilev/clad.git && \
+    cd clad && \
+    mkdir build && \
+    cd build && \
+    cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE .. -DClang_DIR=${PATH_TO_LLVM_BUILD}/lib/cmake/clang/ -DLLVM_DIR=${PATH_TO_LLVM_BUILD}/lib/cmake/llvm/ -DCMAKE_INSTALL_PREFIX=${CONDA_DIR} -DLLVM_EXTERNAL_LIT="$(which lit)" && \
+    #make -j$(nproc --all) && \
+    make && \
+    make install && \
+    #
+    # xtensor
+    #
+    git clone https://github.com/xtensor-stack/xtensor.git && \
+    cd xtensor && \
+    mkdir build && cd build && \
+    cmake -DCMAKE_INSTALL_PREFIX=$KERNEL_PYTHON_PREFIX .. && \
+    make install && \
+    #
+    # Fixes and patches
+    #
+    # Web password and token set to ""
+    echo "c.NotebookApp.token = ''" >> /home/jovyan/.jupyter/jupyter_notebook_config.py && \
+    echo "c.NotebookApp.password = ''" >> /home/jovyan/.jupyter/jupyter_notebook_config.py && \
+    # Patch /opt/conda/share/jupyter/kernels/python3/kernel.json to use .venv
+    k="/opt/conda/share/jupyter/kernels/python3/kernel.json" && \
+    jq ".argv[0] = \"${VENV}/bin/python\"" $k > $k.$$.tmp && mv $k.$$.tmp $k
diff --git a/bash-docker.sh b/bash-docker.sh
new file mode 100755
index 00000000..52d413d2
--- /dev/null
+++ b/bash-docker.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+if [ "$#" -eq 0 ]; then
+    user="root"
+else
+    user="$1"
+fi
+
+docker exec -u "$user" -t -i xeus-cpp-c /bin/bash --login
diff --git a/environment-dev.yml b/environment-dev.yml
index 0c2df603..3c1622d6 100644
--- a/environment-dev.yml
+++ b/environment-dev.yml
@@ -11,10 +11,10 @@ dependencies:
   - nlohmann_json
   - cppzmq
   - xtl
-  - clangdev >=16,<17
   - pugixml
-  - cpp-argparse
+  - cpp-argparse <3.0
   - zlib
+  - CppInterOp
   # Test dependencies
   - pytest
   - jupyter_kernel_test>=0.4.3
diff --git a/environment-wasm-host.yml b/environment-wasm-host.yml
index 4bb96d48..2434910c 100644
--- a/environment-wasm-host.yml
+++ b/environment-wasm-host.yml
@@ -7,6 +7,6 @@ dependencies:
   - xeus-lite
   - xeus >=3.0.5,<4.0
   - xtl >=0.7,<0.8
-  - llvm =16.0.6
   - cpp-argparse
   - pugixml
+  - CppInterOp
diff --git a/include/xcpp/xdisplay.hpp b/include/xcpp/xdisplay.hpp
index 1cb1d443..05acdccf 100644
--- a/include/xcpp/xdisplay.hpp
+++ b/include/xcpp/xdisplay.hpp
@@ -14,6 +14,8 @@
 
 #include "xcpp/xmime.hpp"
 
+#include "xeus/xinterpreter.hpp"
+
 namespace nl = nlohmann;
 
 namespace xcpp
diff --git a/include/xeus-cpp/xinterpreter.hpp b/include/xeus-cpp/xinterpreter.hpp
index bec47613..c8cddca2 100644
--- a/include/xeus-cpp/xinterpreter.hpp
+++ b/include/xeus-cpp/xinterpreter.hpp
@@ -16,7 +16,8 @@
 #include <string>
 #include <vector>
 
-#include <clang/Interpreter/Interpreter.h>
+//#include <clang/Interpreter/Interpreter.h>
+#include "clang/Interpreter/CppInterOp.h" // from CppInterOp package
 
 #include <nlohmann/json.hpp>
 
@@ -78,8 +79,6 @@ namespace xcpp
 
         std::string get_stdopt(int argc, const char* const* argv);
 
-        std::unique_ptr<clang::Interpreter> m_interpreter;
-
         std::string m_version;
 
         xmagics_manager xmagics;
diff --git a/remove-docker.sh b/remove-docker.sh
new file mode 100755
index 00000000..15a5b419
--- /dev/null
+++ b/remove-docker.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+docker rm xeus-cpp-c -f
+docker rmi xeus-cpp
diff --git a/run-docker.sh b/run-docker.sh
new file mode 100755
index 00000000..2d7f7506
--- /dev/null
+++ b/run-docker.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+docker container run --rm -i hadolint/hadolint hadolint - < Dockerfile
+
+jupyter-repo2docker \
+    --no-run \
+    --user-name=jovyan \
+    --image-name xeus-cpp \
+    .
+
+#docker run --gpus all --publish 8888:8888 --name xeus-cpp-c -i -t xeus-cpp "start-notebook.sh"
+docker run --rm --runtime=nvidia --gpus all --publish 9999:9999 --name xeus-cpp-c -i -t xeus-cpp "start-notebook.sh"
+
+#    --editable \
+#    --ref InterOpIntegration \
+#    https://github.com/alexander-penev/xeus-cpp.git \
diff --git a/share/jupyter/kernels/clad-xcpp17/kernel.json.in b/share/jupyter/kernels/clad-xcpp17/kernel.json.in
new file mode 100644
index 00000000..84b82da0
--- /dev/null
+++ b/share/jupyter/kernels/clad-xcpp17/kernel.json.in
@@ -0,0 +1,19 @@
+{
+  "display_name": "C++17 (+Clad)",
+  "env": {
+      "CPLUS_INCLUDE_PATH":"@CMAKE_CPLUS_INCLUDE_PATH@",
+      "PATH":"@CMAKE_PATH@",
+      "LD_LIBRARY_PATH":"@CMAKE_LD_LIBRARY_PATH@",
+      "PYTHONPATH":"@CMAKE_PYTHONPATH@"
+  },
+  "argv": [
+      "@XEUS_CPP_KERNELSPEC_PATH@xcpp",
+      "-f",
+      "{connection_file}",
+      "-resource-dir", "@XEUS_CPP_RESOURCE_DIR@",
+      "-fplugin=/opt/conda/lib/clad.so",
+      "-std=c++17"@CMAKE_OMP@
+  ],
+  "language": "C++17",
+  "metadata": {"debugger": false}
+}
diff --git a/share/jupyter/kernels/clad-xcpp17/logo-32x32.png b/share/jupyter/kernels/clad-xcpp17/logo-32x32.png
new file mode 100644
index 00000000..c09c4585
Binary files /dev/null and b/share/jupyter/kernels/clad-xcpp17/logo-32x32.png differ
diff --git a/share/jupyter/kernels/clad-xcpp17/logo-64x64.png b/share/jupyter/kernels/clad-xcpp17/logo-64x64.png
new file mode 100644
index 00000000..396c2446
Binary files /dev/null and b/share/jupyter/kernels/clad-xcpp17/logo-64x64.png differ
diff --git a/share/jupyter/kernels/clad-xcpp17/logo-svg.svg b/share/jupyter/kernels/clad-xcpp17/logo-svg.svg
new file mode 100644
index 00000000..5e117077
--- /dev/null
+++ b/share/jupyter/kernels/clad-xcpp17/logo-svg.svg
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+	 width="306px" height="344.35px" viewBox="0 0 306 344.35" enable-background="new 0 0 306 344.35" xml:space="preserve">
+<path fill="#00599C" d="M302.107,258.262c2.401-4.159,3.893-8.845,3.893-13.053V99.14c0-4.208-1.49-8.893-3.892-13.052L153,172.175
+	L302.107,258.262z"/>
+<path fill="#004482" d="M166.25,341.193l126.5-73.034c3.644-2.104,6.956-5.737,9.357-9.897L153,172.175L3.893,258.263
+	c2.401,4.159,5.714,7.793,9.357,9.896l126.5,73.034C147.037,345.401,158.963,345.401,166.25,341.193z"/>
+<path fill="#659AD2" d="M302.108,86.087c-2.402-4.16-5.715-7.793-9.358-9.897L166.25,3.156c-7.287-4.208-19.213-4.208-26.5,0
+	L13.25,76.19C5.962,80.397,0,90.725,0,99.14v146.069c0,4.208,1.491,8.894,3.893,13.053L153,172.175L302.108,86.087z"/>
+<g>
+	<path fill="#FFFFFF" d="M153,274.175c-56.243,0-102-45.757-102-102s45.757-102,102-102c36.292,0,70.139,19.53,88.331,50.968
+		l-44.143,25.544c-9.105-15.736-26.038-25.512-44.188-25.512c-28.122,0-51,22.878-51,51c0,28.121,22.878,51,51,51
+		c18.152,0,35.085-9.776,44.191-25.515l44.143,25.543C223.142,254.644,189.294,274.175,153,274.175z"/>
+</g>
+<g>
+	<polygon fill="#FFFFFF" points="255,166.508 243.666,166.508 243.666,155.175 232.334,155.175 232.334,166.508 221,166.508 
+		221,177.841 232.334,177.841 232.334,189.175 243.666,189.175 243.666,177.841 255,177.841 	"/>
+</g>
+<g>
+	<polygon fill="#FFFFFF" points="297.5,166.508 286.166,166.508 286.166,155.175 274.834,155.175 274.834,166.508 263.5,166.508 
+		263.5,177.841 274.834,177.841 274.834,189.175 286.166,189.175 286.166,177.841 297.5,177.841 	"/>
+</g>
+</svg>
diff --git a/share/jupyter/kernels/cppinterop-xcpp17/kernel.json.in b/share/jupyter/kernels/cppinterop-xcpp17/kernel.json.in
new file mode 100644
index 00000000..45edb421
--- /dev/null
+++ b/share/jupyter/kernels/cppinterop-xcpp17/kernel.json.in
@@ -0,0 +1,19 @@
+{
+  "display_name": "CppInterOp (C++17)",
+  "env": {
+      "CPLUS_INCLUDE_PATH":"@CMAKE_CPLUS_INCLUDE_PATH@",
+      "PATH":"@CMAKE_PATH@",
+      "LD_LIBRARY_PATH":"@CMAKE_LD_LIBRARY_PATH@",
+      "PYTHONPATH":"@CMAKE_PYTHONPATH@"
+  },
+  "argv": [
+      "@XEUS_CPP_KERNELSPEC_PATH@xcpp",
+      "-f",
+      "{connection_file}",
+      "-cuda",
+      "-resource-dir", "@XEUS_CPP_RESOURCE_DIR@",
+      "-std=c++17"@CMAKE_OMP@
+  ],
+  "language": "CUDA",
+  "metadata": {"debugger": false}
+}
diff --git a/share/jupyter/kernels/omp-xcpp17/kernel.json.in b/share/jupyter/kernels/omp-xcpp17/kernel.json.in
new file mode 100644
index 00000000..fe906d03
--- /dev/null
+++ b/share/jupyter/kernels/omp-xcpp17/kernel.json.in
@@ -0,0 +1,19 @@
+{
+  "display_name": "C++17 (+OpenMP)",
+  "env": {
+      "CPLUS_INCLUDE_PATH":"@CMAKE_CPLUS_INCLUDE_PATH@",
+      "PATH":"@CMAKE_PATH@",
+      "LD_LIBRARY_PATH":"@CMAKE_LD_LIBRARY_PATH@",
+      "PYTHONPATH":"@CMAKE_PYTHONPATH@"
+  },
+  "argv": [
+      "@XEUS_CPP_KERNELSPEC_PATH@xcpp",
+      "-f",
+      "{connection_file}",
+      "-resource-dir", "@XEUS_CPP_RESOURCE_DIR@",
+      "-fopenmp",
+      "-std=c++17"
+  ],
+  "language": "C++17",
+  "metadata": {"debugger": false}
+}
diff --git a/share/jupyter/kernels/omp-xcpp17/logo-32x32.png b/share/jupyter/kernels/omp-xcpp17/logo-32x32.png
new file mode 100644
index 00000000..c09c4585
Binary files /dev/null and b/share/jupyter/kernels/omp-xcpp17/logo-32x32.png differ
diff --git a/share/jupyter/kernels/omp-xcpp17/logo-64x64.png b/share/jupyter/kernels/omp-xcpp17/logo-64x64.png
new file mode 100644
index 00000000..396c2446
Binary files /dev/null and b/share/jupyter/kernels/omp-xcpp17/logo-64x64.png differ
diff --git a/share/jupyter/kernels/omp-xcpp17/logo-svg.svg b/share/jupyter/kernels/omp-xcpp17/logo-svg.svg
new file mode 100644
index 00000000..5e117077
--- /dev/null
+++ b/share/jupyter/kernels/omp-xcpp17/logo-svg.svg
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+	 width="306px" height="344.35px" viewBox="0 0 306 344.35" enable-background="new 0 0 306 344.35" xml:space="preserve">
+<path fill="#00599C" d="M302.107,258.262c2.401-4.159,3.893-8.845,3.893-13.053V99.14c0-4.208-1.49-8.893-3.892-13.052L153,172.175
+	L302.107,258.262z"/>
+<path fill="#004482" d="M166.25,341.193l126.5-73.034c3.644-2.104,6.956-5.737,9.357-9.897L153,172.175L3.893,258.263
+	c2.401,4.159,5.714,7.793,9.357,9.896l126.5,73.034C147.037,345.401,158.963,345.401,166.25,341.193z"/>
+<path fill="#659AD2" d="M302.108,86.087c-2.402-4.16-5.715-7.793-9.358-9.897L166.25,3.156c-7.287-4.208-19.213-4.208-26.5,0
+	L13.25,76.19C5.962,80.397,0,90.725,0,99.14v146.069c0,4.208,1.491,8.894,3.893,13.053L153,172.175L302.108,86.087z"/>
+<g>
+	<path fill="#FFFFFF" d="M153,274.175c-56.243,0-102-45.757-102-102s45.757-102,102-102c36.292,0,70.139,19.53,88.331,50.968
+		l-44.143,25.544c-9.105-15.736-26.038-25.512-44.188-25.512c-28.122,0-51,22.878-51,51c0,28.121,22.878,51,51,51
+		c18.152,0,35.085-9.776,44.191-25.515l44.143,25.543C223.142,254.644,189.294,274.175,153,274.175z"/>
+</g>
+<g>
+	<polygon fill="#FFFFFF" points="255,166.508 243.666,166.508 243.666,155.175 232.334,155.175 232.334,166.508 221,166.508 
+		221,177.841 232.334,177.841 232.334,189.175 243.666,189.175 243.666,177.841 255,177.841 	"/>
+</g>
+<g>
+	<polygon fill="#FFFFFF" points="297.5,166.508 286.166,166.508 286.166,155.175 274.834,155.175 274.834,166.508 263.5,166.508 
+		263.5,177.841 274.834,177.841 274.834,189.175 286.166,189.175 286.166,177.841 297.5,177.841 	"/>
+</g>
+</svg>
diff --git a/share/jupyter/kernels/xcpp/kernel.json.in b/share/jupyter/kernels/xcpp/kernel.json.in
index f053f27c..ab65403a 100644
--- a/share/jupyter/kernels/xcpp/kernel.json.in
+++ b/share/jupyter/kernels/xcpp/kernel.json.in
@@ -1,11 +1,19 @@
 {
-  "display_name": "cpp 14 (xcpp)",
+  "display_name": "C++17 (xcpp)",
+  "env": {
+      "CPLUS_INCLUDE_PATH":"@CMAKE_CPLUS_INCLUDE_PATH@",
+      "PATH":"@CMAKE_PATH@",
+      "LD_LIBRARY_PATH":"@CMAKE_LD_LIBRARY_PATH@",
+      "PYTHONPATH":"@CMAKE_PYTHONPATH@"
+  },
   "argv": [
       "@XEUS_CPP_KERNELSPEC_PATH@xcpp",
       "-f",
-      "{connection_file}"
+      "{connection_file}",
+      "-cuda",
+      "-resource-dir", "@XEUS_CPP_RESOURCE_DIR@",
+      "-std=c++17"@CMAKE_OMP@
   ],
   "language": "cpp",
-  "metadata": {"debugger": false
-  }
+  "metadata": {"debugger": false}
 }
diff --git a/share/jupyter/kernels/xcpp11/kernel.json.in b/share/jupyter/kernels/xcpp11/kernel.json.in
new file mode 100644
index 00000000..6cf70935
--- /dev/null
+++ b/share/jupyter/kernels/xcpp11/kernel.json.in
@@ -0,0 +1,18 @@
+{
+  "display_name": "C++11",
+  "env": {
+      "CPLUS_INCLUDE_PATH":"@CMAKE_CPLUS_INCLUDE_PATH@",
+      "PATH":"@CMAKE_PATH@",
+      "LD_LIBRARY_PATH":"@CMAKE_LD_LIBRARY_PATH@",
+      "PYTHONPATH":"@CMAKE_PYTHONPATH@"
+  },
+  "argv": [
+      "@XEUS_CPP_KERNELSPEC_PATH@xcpp",
+      "-f",
+      "{connection_file}",
+      "-resource-dir", "@XEUS_CPP_RESOURCE_DIR@",
+      "-std=c++11"@CMAKE_OMP@
+  ],
+  "language": "C++11",
+  "metadata": {"debugger": false}
+}
diff --git a/share/jupyter/kernels/xcpp11/logo-32x32.png b/share/jupyter/kernels/xcpp11/logo-32x32.png
new file mode 100644
index 00000000..c09c4585
Binary files /dev/null and b/share/jupyter/kernels/xcpp11/logo-32x32.png differ
diff --git a/share/jupyter/kernels/xcpp11/logo-64x64.png b/share/jupyter/kernels/xcpp11/logo-64x64.png
new file mode 100644
index 00000000..396c2446
Binary files /dev/null and b/share/jupyter/kernels/xcpp11/logo-64x64.png differ
diff --git a/share/jupyter/kernels/xcpp11/logo-svg.svg b/share/jupyter/kernels/xcpp11/logo-svg.svg
new file mode 100644
index 00000000..5e117077
--- /dev/null
+++ b/share/jupyter/kernels/xcpp11/logo-svg.svg
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+	 width="306px" height="344.35px" viewBox="0 0 306 344.35" enable-background="new 0 0 306 344.35" xml:space="preserve">
+<path fill="#00599C" d="M302.107,258.262c2.401-4.159,3.893-8.845,3.893-13.053V99.14c0-4.208-1.49-8.893-3.892-13.052L153,172.175
+	L302.107,258.262z"/>
+<path fill="#004482" d="M166.25,341.193l126.5-73.034c3.644-2.104,6.956-5.737,9.357-9.897L153,172.175L3.893,258.263
+	c2.401,4.159,5.714,7.793,9.357,9.896l126.5,73.034C147.037,345.401,158.963,345.401,166.25,341.193z"/>
+<path fill="#659AD2" d="M302.108,86.087c-2.402-4.16-5.715-7.793-9.358-9.897L166.25,3.156c-7.287-4.208-19.213-4.208-26.5,0
+	L13.25,76.19C5.962,80.397,0,90.725,0,99.14v146.069c0,4.208,1.491,8.894,3.893,13.053L153,172.175L302.108,86.087z"/>
+<g>
+	<path fill="#FFFFFF" d="M153,274.175c-56.243,0-102-45.757-102-102s45.757-102,102-102c36.292,0,70.139,19.53,88.331,50.968
+		l-44.143,25.544c-9.105-15.736-26.038-25.512-44.188-25.512c-28.122,0-51,22.878-51,51c0,28.121,22.878,51,51,51
+		c18.152,0,35.085-9.776,44.191-25.515l44.143,25.543C223.142,254.644,189.294,274.175,153,274.175z"/>
+</g>
+<g>
+	<polygon fill="#FFFFFF" points="255,166.508 243.666,166.508 243.666,155.175 232.334,155.175 232.334,166.508 221,166.508 
+		221,177.841 232.334,177.841 232.334,189.175 243.666,189.175 243.666,177.841 255,177.841 	"/>
+</g>
+<g>
+	<polygon fill="#FFFFFF" points="297.5,166.508 286.166,166.508 286.166,155.175 274.834,155.175 274.834,166.508 263.5,166.508 
+		263.5,177.841 274.834,177.841 274.834,189.175 286.166,189.175 286.166,177.841 297.5,177.841 	"/>
+</g>
+</svg>
diff --git a/share/jupyter/kernels/xcpp14/kernel.json.in b/share/jupyter/kernels/xcpp14/kernel.json.in
new file mode 100644
index 00000000..a4dcf764
--- /dev/null
+++ b/share/jupyter/kernels/xcpp14/kernel.json.in
@@ -0,0 +1,21 @@
+{
+  "display_name": "C++14",
+  "env": {
+      "CPLUS_INCLUDE_PATH":"@CMAKE_CPLUS_INCLUDE_PATH@",
+      "PATH":"@CMAKE_PATH@",
+      "LD_LIBRARY_PATH":"@CMAKE_LD_LIBRARY_PATH@",
+      "PYTHONPATH":"@CMAKE_PYTHONPATH@"
+  },
+  "argv": [
+      "@XEUS_CPP_KERNELSPEC_PATH@xcpp",
+      "-f",
+      "{connection_file}",
+      "-resource-dir", "@XEUS_CPP_RESOURCE_DIR@",
+      "-std=c++14",
+      "-fno-exceptions",
+      "-O2",
+      "-v"@CMAKE_OMP@
+  ],
+  "language": "C++14",
+  "metadata": {"debugger": false}
+}
diff --git a/share/jupyter/kernels/xcpp14/logo-32x32.png b/share/jupyter/kernels/xcpp14/logo-32x32.png
new file mode 100644
index 00000000..c09c4585
Binary files /dev/null and b/share/jupyter/kernels/xcpp14/logo-32x32.png differ
diff --git a/share/jupyter/kernels/xcpp14/logo-64x64.png b/share/jupyter/kernels/xcpp14/logo-64x64.png
new file mode 100644
index 00000000..396c2446
Binary files /dev/null and b/share/jupyter/kernels/xcpp14/logo-64x64.png differ
diff --git a/share/jupyter/kernels/xcpp14/logo-svg.svg b/share/jupyter/kernels/xcpp14/logo-svg.svg
new file mode 100644
index 00000000..5e117077
--- /dev/null
+++ b/share/jupyter/kernels/xcpp14/logo-svg.svg
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+	 width="306px" height="344.35px" viewBox="0 0 306 344.35" enable-background="new 0 0 306 344.35" xml:space="preserve">
+<path fill="#00599C" d="M302.107,258.262c2.401-4.159,3.893-8.845,3.893-13.053V99.14c0-4.208-1.49-8.893-3.892-13.052L153,172.175
+	L302.107,258.262z"/>
+<path fill="#004482" d="M166.25,341.193l126.5-73.034c3.644-2.104,6.956-5.737,9.357-9.897L153,172.175L3.893,258.263
+	c2.401,4.159,5.714,7.793,9.357,9.896l126.5,73.034C147.037,345.401,158.963,345.401,166.25,341.193z"/>
+<path fill="#659AD2" d="M302.108,86.087c-2.402-4.16-5.715-7.793-9.358-9.897L166.25,3.156c-7.287-4.208-19.213-4.208-26.5,0
+	L13.25,76.19C5.962,80.397,0,90.725,0,99.14v146.069c0,4.208,1.491,8.894,3.893,13.053L153,172.175L302.108,86.087z"/>
+<g>
+	<path fill="#FFFFFF" d="M153,274.175c-56.243,0-102-45.757-102-102s45.757-102,102-102c36.292,0,70.139,19.53,88.331,50.968
+		l-44.143,25.544c-9.105-15.736-26.038-25.512-44.188-25.512c-28.122,0-51,22.878-51,51c0,28.121,22.878,51,51,51
+		c18.152,0,35.085-9.776,44.191-25.515l44.143,25.543C223.142,254.644,189.294,274.175,153,274.175z"/>
+</g>
+<g>
+	<polygon fill="#FFFFFF" points="255,166.508 243.666,166.508 243.666,155.175 232.334,155.175 232.334,166.508 221,166.508 
+		221,177.841 232.334,177.841 232.334,189.175 243.666,189.175 243.666,177.841 255,177.841 	"/>
+</g>
+<g>
+	<polygon fill="#FFFFFF" points="297.5,166.508 286.166,166.508 286.166,155.175 274.834,155.175 274.834,166.508 263.5,166.508 
+		263.5,177.841 274.834,177.841 274.834,189.175 286.166,189.175 286.166,177.841 297.5,177.841 	"/>
+</g>
+</svg>
diff --git a/share/jupyter/kernels/xcpp17/kernel.json.in b/share/jupyter/kernels/xcpp17/kernel.json.in
new file mode 100644
index 00000000..c0852cfb
--- /dev/null
+++ b/share/jupyter/kernels/xcpp17/kernel.json.in
@@ -0,0 +1,18 @@
+{
+  "display_name": "C++17",
+  "env": {
+      "CPLUS_INCLUDE_PATH":"@CMAKE_CPLUS_INCLUDE_PATH@",
+      "PATH":"@CMAKE_PATH@",
+      "LD_LIBRARY_PATH":"@CMAKE_LD_LIBRARY_PATH@",
+      "PYTHONPATH":"@CMAKE_PYTHONPATH@"
+  },
+  "argv": [
+      "@XEUS_CPP_KERNELSPEC_PATH@xcpp",
+      "-f",
+      "{connection_file}",
+      "-resource-dir", "@XEUS_CPP_RESOURCE_DIR@",
+      "-std=c++17"@CMAKE_OMP@
+  ],
+  "language": "C++17",
+  "metadata": {"debugger": false}
+}
diff --git a/share/jupyter/kernels/xcpp17/logo-32x32.png b/share/jupyter/kernels/xcpp17/logo-32x32.png
new file mode 100644
index 00000000..c09c4585
Binary files /dev/null and b/share/jupyter/kernels/xcpp17/logo-32x32.png differ
diff --git a/share/jupyter/kernels/xcpp17/logo-64x64.png b/share/jupyter/kernels/xcpp17/logo-64x64.png
new file mode 100644
index 00000000..396c2446
Binary files /dev/null and b/share/jupyter/kernels/xcpp17/logo-64x64.png differ
diff --git a/share/jupyter/kernels/xcpp17/logo-svg.svg b/share/jupyter/kernels/xcpp17/logo-svg.svg
new file mode 100644
index 00000000..5e117077
--- /dev/null
+++ b/share/jupyter/kernels/xcpp17/logo-svg.svg
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+	 width="306px" height="344.35px" viewBox="0 0 306 344.35" enable-background="new 0 0 306 344.35" xml:space="preserve">
+<path fill="#00599C" d="M302.107,258.262c2.401-4.159,3.893-8.845,3.893-13.053V99.14c0-4.208-1.49-8.893-3.892-13.052L153,172.175
+	L302.107,258.262z"/>
+<path fill="#004482" d="M166.25,341.193l126.5-73.034c3.644-2.104,6.956-5.737,9.357-9.897L153,172.175L3.893,258.263
+	c2.401,4.159,5.714,7.793,9.357,9.896l126.5,73.034C147.037,345.401,158.963,345.401,166.25,341.193z"/>
+<path fill="#659AD2" d="M302.108,86.087c-2.402-4.16-5.715-7.793-9.358-9.897L166.25,3.156c-7.287-4.208-19.213-4.208-26.5,0
+	L13.25,76.19C5.962,80.397,0,90.725,0,99.14v146.069c0,4.208,1.491,8.894,3.893,13.053L153,172.175L302.108,86.087z"/>
+<g>
+	<path fill="#FFFFFF" d="M153,274.175c-56.243,0-102-45.757-102-102s45.757-102,102-102c36.292,0,70.139,19.53,88.331,50.968
+		l-44.143,25.544c-9.105-15.736-26.038-25.512-44.188-25.512c-28.122,0-51,22.878-51,51c0,28.121,22.878,51,51,51
+		c18.152,0,35.085-9.776,44.191-25.515l44.143,25.543C223.142,254.644,189.294,274.175,153,274.175z"/>
+</g>
+<g>
+	<polygon fill="#FFFFFF" points="255,166.508 243.666,166.508 243.666,155.175 232.334,155.175 232.334,166.508 221,166.508 
+		221,177.841 232.334,177.841 232.334,189.175 243.666,189.175 243.666,177.841 255,177.841 	"/>
+</g>
+<g>
+	<polygon fill="#FFFFFF" points="297.5,166.508 286.166,166.508 286.166,155.175 274.834,155.175 274.834,166.508 263.5,166.508 
+		263.5,177.841 274.834,177.841 274.834,189.175 286.166,189.175 286.166,177.841 297.5,177.841 	"/>
+</g>
+</svg>
diff --git a/src/main.cpp b/src/main.cpp
index 83f6f73f..31a18aba 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -29,6 +29,73 @@
 #include "xeus-cpp/xinterpreter.hpp"
 #include "xeus-cpp/xutils.hpp"
 
+#ifdef __GNUC__
+void handler(int sig)
+{
+    void* array[10];
+
+    // get void*'s for all entries on the stack
+    std::size_t size = backtrace(array, 10);
+
+    // print out all the frames to stderr
+    fprintf(stderr, "Error: signal %d:\n", sig);
+    backtrace_symbols_fd(array, size, STDERR_FILENO);
+    exit(1);
+}
+#endif
+
+void stop_handler(int /*sig*/)
+{
+    exit(0);
+}
+
+bool should_print_version(int argc, char* argv[])
+{
+    for (int i = 0; i < argc; ++i)
+    {
+        if (std::string(argv[i]) == "--version")
+        {
+            return true;
+        }
+    }
+    return false;
+}
+
+std::string extract_filename(int& argc, char* argv[])
+{
+    std::string res = "";
+    for (int i = 0; i < argc; ++i)
+    {
+        if ((std::string(argv[i]) == "-f") && (i + 1 < argc))
+        {
+            res = argv[i + 1];
+            for (int j = i; j < argc - 2; ++j)
+            {
+                argv[j] = argv[j + 2];
+            }
+            argc -= 2;
+            break;
+        }
+    }
+    return res;
+}
+
+using interpreter_ptr = std::unique_ptr<xcpp::interpreter>;
+
+interpreter_ptr build_interpreter(int argc, char** argv)
+{
+  std::vector<const char*> interpreter_args;
+  for (int i = 1; i < argc; i++) {
+    if (argv[i] == "-f") {
+      i++; // skip the value of -f which is a json file.
+      continue;
+    }
+    interpreter_args.push_back(argv[i]);
+  }
+  interpreter_ptr interp_ptr = interpreter_ptr(new xcpp::interpreter(interpreter_args.size(), interpreter_args.data()));
+  return interp_ptr;
+}
+
 int main(int argc, char* argv[])
 {
     if (xcpp::should_print_version(argc, argv))
@@ -97,8 +164,8 @@ int main(int argc, char* argv[])
             xeus::make_xserver_zmq,
             xeus::make_in_memory_history_manager(),
             xeus::make_console_logger(
-                xeus::xlogger::msg_type,
-                xeus::make_file_logger(xeus::xlogger::content, "xeus.log")
+                    xeus::xlogger::msg_type,
+                    xeus::make_file_logger(xeus::xlogger::content, "xeus.log")
             )
         );
 
diff --git a/src/xinspect.hpp b/src/xinspect.hpp
index 15b8d523..b7c22c8c 100644
--- a/src/xinspect.hpp
+++ b/src/xinspect.hpp
@@ -9,10 +9,10 @@
 #ifndef XEUS_CPP_INSPECT_HPP
 #define XEUS_CPP_INSPECT_HPP
 
+#include <filesystem>
 #include <fstream>
 #include <string>
 
-
 #include <pugixml.hpp>
 
 #include <xtl/xsystem.hpp>
@@ -23,8 +23,11 @@
 #include "xdemangle.hpp"
 #include "xparser.hpp"
 
-#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/Path.h"
+//#include "llvm/Support/FileSystem.h"
+//#include "llvm/Support/Path.h"
+
+//#include "clang/Interpreter/CppInterOp.h"
+
 
 namespace xcpp
 {
@@ -81,7 +84,27 @@ namespace xcpp
         }
     };
 
-    std::string find_type(const std::string& expression, clang::Interpreter& interpreter)
+
+    std::string find_type_slow(const std::string& expression) {
+        static unsigned long long var_count = 0;
+
+        if (auto type = Cpp::GetType(expression))
+            return Cpp::GetQualifiedName(type);
+
+        // Here we might need to deal with integral types such as 3.14.
+
+        std::string id = "__Xeus_GetType_" + std::to_string(var_count++);
+        std::string using_clause = "using " + id + " = __typeof__(" + expression + ");\n";
+
+        if (!Cpp::Declare(using_clause.c_str(), /*silent=*/false)) {
+            Cpp::TCppScope_t lookup = Cpp::GetNamed(id, 0);
+            Cpp::TCppType_t lookup_ty = Cpp::GetTypeFromScope(lookup);
+            return Cpp::GetQualifiedCompleteName(Cpp::GetCanonicalType(lookup_ty));
+        }
+        return "";
+    }
+/*
+    std::string find_type(const std::string& expression)
     {
         auto PTU = interpreter.Parse(expression + ";");
         if (llvm::Error Err = PTU.takeError()) {
@@ -89,19 +112,29 @@ namespace xcpp
             return "";
         }
 
-	    clang::Decl *D = *PTU->TUPart->decls_begin();
-	    if (!llvm::isa<clang::TopLevelStmtDecl>(D))
-	        return "";
+        clang::Decl *D = *PTU->TUPart->decls_begin();
+        if (!llvm::isa<clang::TopLevelStmtDecl>(D))
+          return "";
 
-	    clang::Expr *E = llvm::cast<clang::Expr>(llvm::cast<clang::TopLevelStmtDecl>(D)->getStmt());
+        clang::Expr *E = llvm::cast<clang::Expr>(llvm::cast<clang::TopLevelStmtDecl>(D)->getStmt());
 
-	    clang::QualType QT = E->getType();
+        clang::QualType QT = E->getType();
         return  QT.getAsString();
     }
-
+*/
     static nl::json read_tagconfs(const char* path)
     {
         nl::json result = nl::json::array();
+        for (auto &entry: std::filesystem::directory_iterator(path)) {
+            if (entry.path().extension() != ".json")
+              continue;
+            std::ifstream i(entry.path());
+            nl::json json_entry;
+            i >> json_entry;
+            result.emplace_back(std::move(json_entry));
+        }
+        return result;
+/*
         std::error_code EC;
         for (llvm::sys::fs::directory_iterator File(path, EC), FileEnd;
              File != FileEnd && !EC; File.increment(EC)) {
@@ -115,19 +148,19 @@ namespace xcpp
           result.emplace_back(std::move(entry));
         }
         return result;
+*/
     }
 
-    std::pair<bool, std::smatch> is_inspect_request(const std::string code, std::regex re) 
+    std::pair<bool, std::smatch> is_inspect_request(const std::string code, std::regex re)
     {
         std::smatch inspect;
         if (std::regex_search(code, inspect, re)){
             return std::make_pair(true, inspect);
         }
         return std::make_pair(false, inspect);
-       
     }
 
-    void inspect(const std::string& code, nl::json& kernel_res, clang::Interpreter& interpreter)
+    void inspect(const std::string& code, nl::json& kernel_res)
     {
         std::string tagconf_dir = XCPP_TAGCONFS_DIR;
         std::string tagfiles_dir = XCPP_TAGFILES_DIR;
@@ -150,7 +183,7 @@ namespace xcpp
         // Method or variable of class found (xxxx.yyyy)
         if (std::regex_search(to_inspect, method, std::regex(R"((.*)\.(\w*)$)")))
         {
-            std::string typename_ = find_type(method[1], interpreter);
+            std::string typename_ = find_type_slow(method[1]);
 
             if (!typename_.empty())
             {
@@ -160,7 +193,7 @@ namespace xcpp
                     tagfile = it->at("tagfile");
                     std::string filename = tagfiles_dir + "/" + tagfile;
                     pugi::xml_document doc;
-                    doc.load_file(filename.c_str());
+                    pugi::xml_parse_result result = doc.load_file(filename.c_str());
                     class_member_predicate predicate{typename_, "function", method[2]};
                     auto node = doc.find_node(predicate);
                     if (!node.empty())
@@ -184,7 +217,7 @@ namespace xcpp
             }
             else
             {
-                std::string typename_ = find_type(to_inspect, interpreter);
+                std::string typename_ = find_type_slow(to_inspect);
                 find_string = (typename_.empty()) ? to_inspect : typename_;
             }
 
@@ -194,7 +227,7 @@ namespace xcpp
                 tagfile = it->at("tagfile");
                 std::string filename = tagfiles_dir + "/" + tagfile;
                 pugi::xml_document doc;
-                doc.load_file(filename.c_str());
+                pugi::xml_parse_result result = doc.load_file(filename.c_str());
                 for (auto c : check)
                 {
                     node_predicate predicate{c, find_string};
@@ -272,8 +305,7 @@ namespace xcpp
         using xpreamble::pattern;
         const std::string spattern = R"(^\?)";
 
-        xintrospection(clang::Interpreter& p)
-            : m_interpreter{p}
+        xintrospection()
         {
             pattern = spattern;
         }
@@ -283,17 +315,14 @@ namespace xcpp
             std::regex re(spattern + R"((.*))");
             std::smatch to_inspect;
             std::regex_search(code, to_inspect, re);
-            inspect(to_inspect[1], kernel_res, m_interpreter);
+            inspect(to_inspect[1], kernel_res);
         }
 
         virtual xpreamble* clone() const override
         {
             return new xintrospection(*this);
         }
-
-    private:
-
-        clang::Interpreter& m_interpreter;
     };
+
 }
 #endif
diff --git a/src/xinterpreter.cpp b/src/xinterpreter.cpp
index 09fb27ce..257016b8 100644
--- a/src/xinterpreter.cpp
+++ b/src/xinterpreter.cpp
@@ -7,241 +7,42 @@
  * The full license is in the file LICENSE, distributed with this software.         *
  ************************************************************************************/
 
-#include "xeus-cpp/xinterpreter.hpp"
-
-#include "xinput.hpp"
-#include "xinspect.hpp"
-// #include "xmagics/executable.hpp"
-// #include "xmagics/execution.hpp"
-#include "xmagics/os.hpp"
-#include "xparser.hpp"
-#include "xsystem.hpp"
-
-#include <xeus/xhelper.hpp>
-
-#include "xeus-cpp/xbuffer.hpp"
-#include "xeus-cpp/xeus_cpp_config.hpp"
-
-#include "xeus-cpp/xmagics.hpp"
-
-#include <xtl/xsystem.hpp>
-
-#include <pugixml.hpp>
-
-#include <llvm/ExecutionEngine/Orc/LLJIT.h>
-#include <llvm/Support/Casting.h>
-#include <llvm/Support/DynamicLibrary.h>
-#include <llvm/Support/TargetSelect.h>
-
-#include <clang/Basic/SourceManager.h>
-#include <clang/Frontend/CompilerInstance.h>
-#include <clang/Frontend/TextDiagnosticPrinter.h>
-#include <clang/Lex/HeaderSearchOptions.h>
-#include <clang/Lex/Preprocessor.h>
-//#include <clang/Interpreter/Value.h>
-
-
-
 #include <algorithm>
 #include <cinttypes>  // required before including llvm/ExecutionEngine/Orc/LLJIT.h because missing llvm/Object/SymbolicFile.h
 #include <cstdarg>
 #include <cstdio>
 #include <memory>
-#include <fstream>
 #include <sstream>
 #include <string>
 #include <vector>
 
-std::string DiagnosticOutput;
-llvm::raw_string_ostream DiagnosticsOS(DiagnosticOutput);
-auto DiagPrinter = std::make_unique<clang::TextDiagnosticPrinter>(DiagnosticsOS, new clang::DiagnosticOptions());
-
-///\returns true on error.
-static bool
-process_code(clang::Interpreter& Interp, const std::string& code, llvm::raw_string_ostream& error_stream)
-{
-    
-    if (code.substr(0, 1) == "?")
-    {   
-        error_stream << "  ";
-        return true;
-    }
-    else {
-        auto PTU = Interp.Parse(code);
-        if (!PTU)
-        {
-            auto Err = PTU.takeError();
-            error_stream << DiagnosticsOS.str();
-            // avoid printing the "Parsing failed error"
-            // llvm::logAllUnhandledErrors(std::move(Err), error_stream, "error: ");
-            return true;
-        }
-        if (PTU->TheModule)
-        {
-            llvm::Error ex = Interp.Execute(*PTU);
-            error_stream << DiagnosticsOS.str();
-            if (code.substr(0, 3) == "int")
-            {
-                for (clang::Decl* D : PTU->TUPart->decls())
-                {
-                    if (clang::VarDecl* VD = llvm::dyn_cast<clang::VarDecl>(D))
-                    {
-                        auto Name = VD->getNameAsString();
-                        auto Addr = Interp.getSymbolAddress(clang::GlobalDecl(VD));
-                        if (!Addr)
-                        {
-                            llvm::logAllUnhandledErrors(Addr.takeError(), error_stream, "error: ");
-                            return true;
-                        }
-                    }
-                }
-            }
-            else if (code.substr(0, 16) == "std::vector<int>")
-            {
-                for (clang::Decl* D : PTU->TUPart->decls())
-                {
-                    if (clang::VarDecl* VD = llvm::dyn_cast<clang::VarDecl>(D))
-                    {
-                        auto Name = VD->getNameAsString();
-                        auto Addr = Interp.getSymbolAddress(clang::GlobalDecl(VD));
-                        if (!Addr)
-                        {
-                            llvm::logAllUnhandledErrors(Addr.takeError(), error_stream, "error: ");
-                            return true;
-                        }
-                    }
-                }
-            }
-
-            llvm::logAllUnhandledErrors(std::move(ex), error_stream, "error: ");
-            return false;
-        }
-    }
-    return false;
-}
-
-using Args = std::vector<const char*>;
-
-static std::unique_ptr<clang::Interpreter>
-create_interpreter(const Args& ExtraArgs = {}, clang::DiagnosticConsumer* Client = nullptr)
-{
-    llvm::InitializeNativeTarget();
-    llvm::InitializeNativeTargetAsmPrinter();
-
-    Args ClangArgs = {"-Xclang", "-emit-llvm-only", "-Xclang", "-diagnostic-log-file", "-Xclang", "-", "-xc++"};
-    ClangArgs.insert(ClangArgs.end(), ExtraArgs.begin(), ExtraArgs.end());
-    auto CI = cantFail(clang::IncrementalCompilerBuilder::create(ClangArgs));
-    if (Client)
-    {
-        CI->getDiagnostics().setClient(Client, /*ShouldOwnClient=*/false);
-    }
-    return cantFail(clang::Interpreter::create(std::move(CI)));
-}
-
-static void
-inject_symbol(llvm::StringRef LinkerMangledName, llvm::JITTargetAddress KnownAddr, clang::Interpreter& Interp)
-{
-    using namespace llvm;
-    using namespace llvm::orc;
-
-    auto Symbol = Interp.getSymbolAddress(LinkerMangledName);  //, /*IncludeFromHost=*/true);
-
-    if (Error Err = Symbol.takeError())
-    {
-        logAllUnhandledErrors(std::move(Err), errs(), "[IncrementalJIT] define() failed1: ");
-        return;
-    }
-
-    // Nothing to define, we are redefining the same function. FIXME: Diagnose.
-    if (*Symbol && (JITTargetAddress) *Symbol == KnownAddr)
-    {
-        return;
-    }
-
-    // Let's inject it
-    bool Inserted;
-    SymbolMap::iterator It;
-    static llvm::orc::SymbolMap m_InjectedSymbols;
-
-    llvm::orc::LLJIT* Jit = const_cast<llvm::orc::LLJIT*>(Interp.getExecutionEngine());
-    JITDylib& DyLib = Jit->getMainJITDylib();
-
-    std::tie(It, Inserted) = m_InjectedSymbols.try_emplace(
-        Jit->getExecutionSession().intern(LinkerMangledName),
-        JITEvaluatedSymbol(KnownAddr, JITSymbolFlags::Exported)
-    );
-    assert(Inserted && "Why wasn't this found in the initial Jit lookup?");
-
-    // We want to replace a symbol with a custom provided one.
-    if (Symbol && KnownAddr)
-    {
-        // The symbol be in the DyLib or in-process.
-        if (auto Err = DyLib.remove({It->first}))
-        {
-            logAllUnhandledErrors(std::move(Err), errs(), "[IncrementalJIT] define() failed2: ");
-            return;
-        }
-    }
-
-    if (Error Err = DyLib.define(absoluteSymbols({*It})))
-    {
-        logAllUnhandledErrors(std::move(Err), errs(), "[IncrementalJIT] define() failed3: ");
-    }
-}
-
-namespace utils
-{
-    void AddIncludePath(llvm::StringRef Path, clang::HeaderSearchOptions& HOpts)
-    {
-        bool Exists = false;
-        for (const clang::HeaderSearchOptions::Entry& E : HOpts.UserEntries)
-        {
-            if ((Exists = E.Path == Path))
-            {
-                break;
-            }
-        }
-        if (Exists)
-        {
-            return;
-        }
+#include <xtl/xsystem.hpp>
 
-        HOpts.AddPath(Path, clang::frontend::Angled, false /* IsFramework */, true /* IsSysRootRelative */);
+#include <xeus/xhelper.hpp>
 
-        if (HOpts.Verbose)
-        {
-            //    std::clog << "Added include paths " << Path << std::endl;
-        }
-    }
-}
+#include "xeus-cpp/xbuffer.hpp"
+#include "xeus-cpp/xeus_cpp_config.hpp"
 
-void AddIncludePath(clang::Interpreter& Interp, llvm::StringRef Path)
-{
-    clang::CompilerInstance* CI = const_cast<clang::CompilerInstance*>(Interp.getCompilerInstance());
-    clang::HeaderSearchOptions& HOpts = CI->getHeaderSearchOpts();
+#include "xeus-cpp/xinterpreter.hpp"
+#include "xeus-cpp/xmagics.hpp"
 
-    // Save the current number of entries
-    std::size_t Idx = HOpts.UserEntries.size();
-    utils::AddIncludePath(Path, HOpts);
+#include "xinput.hpp"
+#include "xinspect.hpp"
+// #include "xmagics/executable.hpp"
+// #include "xmagics/execution.hpp"
+#include "xmagics/os.hpp"
+#include "xmagics/pythonexec.hpp"
+#include "xparser.hpp"
+#include "xsystem.hpp"
 
-    clang::Preprocessor& PP = CI->getPreprocessor();
-    clang::SourceManager& SM = CI->getSourceManager();
-    clang::FileManager& FM = SM.getFileManager();
-    clang::HeaderSearch& HSearch = PP.getHeaderSearchInfo();
-    const bool isFramework = false;
+using Args = std::vector<const char*>;
 
-    // Add all the new entries into Preprocessor
-    for (; Idx < HOpts.UserEntries.size(); ++Idx)
-    {
-        const clang::HeaderSearchOptions::Entry& E = HOpts.UserEntries[Idx];
-        if (auto DE = FM.getOptionalDirectoryRef(E.Path))
-        {
-            HSearch.AddSearchPath(
-                clang::DirectoryLookup(*DE, clang::SrcMgr::C_User, isFramework),
-                E.Group == clang::frontend::Angled
-            );
-        }
-    }
+void* createInterpreter(const Args &ExtraArgs = {}) {
+  Args ClangArgs = {/*"-xc++"*/}; // ? {"-Xclang", "-emit-llvm-only", "-Xclang", "-diagnostic-log-file", "-Xclang", "-", "-xc++"};
+  ClangArgs.insert(ClangArgs.end(), ExtraArgs.begin(), ExtraArgs.end());
+  // FIXME: We should process the kernel input options and conditionally pass
+  // the gpu args here.
+  return Cpp::CreateInterpreter(ClangArgs, {"-cuda"});
 }
 
 using namespace std::placeholders;
@@ -250,19 +51,11 @@ namespace xcpp
 {
     void interpreter::configure_impl()
     {
-        // todo: why is error_stream necessary
-        std::string error_message;
-        llvm::raw_string_ostream error_stream(error_message);
-        // Expose xinterpreter instance to interpreted C++
-        process_code(*m_interpreter, "#include \"xeus/xinterpreter.hpp\"", error_stream);
-        std::string code = "xeus::register_interpreter(static_cast<xeus::xinterpreter*>((void*)"
-                           + std::to_string(intptr_t(this)) + "));";
-        process_code(*m_interpreter, code.c_str(), error_stream);
+        xeus::register_interpreter(this);
     }
 
     interpreter::interpreter(int argc, const char* const* argv)
-        : m_interpreter(create_interpreter(Args() /*argv + 1, argv + argc)*/, DiagPrinter.get()))
-        , m_version(get_stdopt(argc, argv))
+        : m_version(get_stdopt(argc, argv))
         ,  // Extract C++ language standard version from command-line option
         xmagics()
         , p_cout_strbuf(nullptr)
@@ -270,7 +63,9 @@ namespace xcpp
         , m_cout_buffer(std::bind(&interpreter::publish_stdout, this, _1))
         , m_cerr_buffer(std::bind(&interpreter::publish_stderr, this, _1))
     {
+        createInterpreter(Args(argv ? argv + 1 : argv, argv + argc));
         redirect_output();
+        // Bootstrap the execution engine
         init_includes();
         init_preamble();
         init_magic();
@@ -322,13 +117,19 @@ namespace xcpp
 
         // Scope guard performing the temporary redirection of input requests.
         auto input_guard = input_redirection(allow_stdin);
-        std::string error_message;
-        llvm::raw_string_ostream error_stream(error_message);
+
+        std::string err;
+        std::string out;
+
         // Attempt normal evaluation
-        
         try
         {
-            compilation_result = process_code(*m_interpreter, code, error_stream);
+            Cpp::BeginStdStreamCapture(Cpp::kStdErr);
+            Cpp::BeginStdStreamCapture(Cpp::kStdOut);
+            compilation_result = Cpp::Process(code.c_str());
+            out = Cpp::EndStdStreamCapture();
+            err = Cpp::EndStdStreamCapture();
+            std::cout << out;
         }
         catch (std::exception& e)
         {
@@ -341,17 +142,14 @@ namespace xcpp
             errorlevel = 1;
             ename = "Error :";
         }
-    
+
         if (compilation_result)
         {
             errorlevel = 1;
-            ename = "Error :";
-            evalue = error_stream.str();
+            ename = "Error";
+            std::cerr << err;
         }
 
-        error_stream.str().clear();
-        DiagnosticsOS.str().clear();
-
         // Flush streams
         std::cout << std::flush;
         std::cerr << std::flush;
@@ -423,7 +221,7 @@ namespace xcpp
         auto inspect_request = is_inspect_request(code.substr(0, cursor_pos), re);
         if (inspect_request.first)
         {
-            inspect(inspect_request.second[0], kernel_res, *m_interpreter);
+            inspect(inspect_request.second[0], kernel_res);
         }
         return kernel_res;
     }
@@ -498,49 +296,6 @@ namespace xcpp
         return s;
     }
 
-    static int printf_jit(const char* format, ...)
-    {
-        std::va_list args;
-        va_start(args, format);
-
-        std::string buf = c_format(format, args);
-        std::cout << buf;
-
-        va_end(args);
-
-        return buf.size();
-    }
-
-    static int fprintf_jit(std::FILE* stream, const char* format, ...)
-    {
-        std::va_list args;
-        va_start(args, format);
-
-        int ret;
-        if (stream == stdout || stream == stderr)
-        {
-            std::string buf = c_format(format, args);
-            if (stream == stdout)
-            {
-                std::cout << buf;
-            }
-            else if (stream == stderr)
-            {
-                std::cerr << buf;
-            }
-            ret = buf.size();
-        }
-        else
-        {
-            // Just forward to vfprintf.
-            ret = vfprintf(stream, format, args);
-        }
-
-        va_end(args);
-
-        return ret;
-    }
-
     void interpreter::redirect_output()
     {
         p_cout_strbuf = std::cout.rdbuf();
@@ -548,20 +303,12 @@ namespace xcpp
 
         std::cout.rdbuf(&m_cout_buffer);
         std::cerr.rdbuf(&m_cerr_buffer);
-
-        // Inject versions of printf and fprintf that output to std::cout
-        // and std::cerr (see implementation above).
-        inject_symbol("printf", llvm::pointerToJITTargetAddress(printf_jit), *m_interpreter);
-        inject_symbol("fprintf", llvm::pointerToJITTargetAddress(fprintf_jit), *m_interpreter);
     }
 
     void interpreter::restore_output()
     {
         std::cout.rdbuf(p_cout_strbuf);
         std::cerr.rdbuf(p_cerr_strbuf);
-
-        // No need to remove the injected versions of [f]printf: As they forward
-        // to std::cout and std::cerr, these are handled implicitly.
     }
 
     void interpreter::publish_stdout(const std::string& s)
@@ -576,23 +323,21 @@ namespace xcpp
 
     void interpreter::init_includes()
     {
-        AddIncludePath(*m_interpreter, xtl::prefix_path() + "/include/");
     }
 
     void interpreter::init_preamble()
     {
-        preamble_manager.register_preamble("introspection", new xintrospection(*m_interpreter));
+        preamble_manager.register_preamble("introspection", new xintrospection());
         preamble_manager.register_preamble("magics", new xmagics_manager());
         preamble_manager.register_preamble("shell", new xsystem());
     }
 
     void interpreter::init_magic()
     {
-        //        preamble_manager["magics"].get_cast<xmagics_manager>().register_magic("executable",
-        //        executable(m_interpreter));
-        //        preamble_manager["magics"].get_cast<xmagics_manager>().register_magic("file", writefile());
-        //        preamble_manager["magics"].get_cast<xmagics_manager>().register_magic("timeit",
-        //        timeit(&m_interpreter));
+        // preamble_manager["magics"].get_cast<xmagics_manager>().register_magic("executable", executable(m_interpreter));
+        // preamble_manager["magics"].get_cast<xmagics_manager>().register_magic("file", writefile());
+        // preamble_manager["magics"].get_cast<xmagics_manager>().register_magic("timeit", timeit(&m_interpreter));
+        preamble_manager["magics"].get_cast<xmagics_manager>().register_magic("python", pythonexec());
     }
 
     std::string interpreter::get_stdopt(int argc, const char* const* argv)
diff --git a/src/xmagics/pythonexec.cpp b/src/xmagics/pythonexec.cpp
new file mode 100644
index 00000000..03d5a488
--- /dev/null
+++ b/src/xmagics/pythonexec.cpp
@@ -0,0 +1,208 @@
+//===------------ pythonexec.hpp - Python/C++ Interoperability ------------===//
+//
+// Licensed under the Apache License v2.0.
+// SPDX-License-Identifier: Apache-2.0
+//
+// The full license is in the file LICENSE, distributed with this software.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the Python/C++ interoperability in which two cells within
+//  the same notebook can be in a either language.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Python.h"
+
+#include "pythonexec.hpp"
+#include "../xparser.hpp"
+
+#include <cstddef>
+#include <fstream>
+#include <iostream>
+#include <sstream>
+#include <string>
+#include <vector>
+
+namespace xcpp {
+static PyObject *gMainDict = 0;
+
+void pythonexec::startup() {
+    static bool isInitialized = false;
+    if (isInitialized)
+        return;
+
+    Py_Initialize();
+
+    PyRun_SimpleString("import sys\nprint(sys.path)");
+
+    // Import cppyy module
+    PyObject* cppyyModule = PyImport_ImportModule("cppyy");
+    if (!cppyyModule) {
+        PyErr_Print();
+        Py_Finalize();
+        return; // Handle import error as needed
+    }
+
+    PyObject* mainModule = PyImport_AddModule("__main__");
+    PyObject_SetAttrString(mainModule, "cppyy", cppyyModule);
+    Py_XDECREF(cppyyModule);
+    isInitialized = true;
+    // gMainDict = PyModule_GetDict(mainModule);
+    // Py_INCREF(gMainDict);
+    // if (!gMainDict)
+    //   printf("Could not add module __main__");
+
+    // // Retrieve the dictionary of cppyy module
+    // PyObject* cppyyDict = PyModule_GetDict(cppyyModule);
+    // Py_DECREF(cppyyModule);
+    // if (!cppyyDict) {
+    //     PyErr_Print();
+    //     Py_Finalize();
+    //     return; // Handle retrieval error as needed
+    // }
+
+    // // Add cppyyDict to gMainDict (if needed for further usage)
+    // PyDict_Update(gMainDict, cppyyDict);
+
+    // Py_DECREF(cppyyDict);
+    // PyRun_SimpleString("import cppyy");
+}
+
+void pythonexec::get_options(argparser &argpars) {
+}
+
+void pythonexec::execute(std::string &line, std::string &cell) {
+  // std::istringstream iss(line);
+  // std::vector<std::string> results((std::istream_iterator<std::string>(iss)),
+  //                          std::istream_iterator<std::string>());
+  startup();
+
+//  argparser argpars{"python", "Start executing Python Cell"};
+//  auto argpars = get_options();
+//  argpars.parse(line);
+
+  std::string code;
+
+  code += cell;
+  if (trim(code).empty())
+    return;
+  // PyRun_SimpleString(
+  //     "globals_copy_lists = "
+  //     "globals().copy()\nfirst_dict_ints={k:globals_copy_lists[k] for k in "
+  //     "set(globals_copy_lists) if type(globals_copy_lists[k]) == "
+  //     "int}\nfirst_dict_lists={k:globals_copy_lists[k] for k in "
+  //     "set(globals_copy_lists) if type(globals_copy_lists[k]) == list}");
+
+  // PyRun_SimpleString("tmp = globals().copy()\nvars = [f'int {k} = {v};' for
+  // k,v in tmp.items() if type(v) == int and not k.startswith('_') and k!='tmp'
+  // and k!='In' and k!='Out' and k!='sys' and not hasattr(v,
+  // '__call__')]\nprint(vars)"); PyRun_SimpleString("b =
+  // globals().copy()\nnew_ints = ' '.join([f'int {k} = {b[k]};' for k in set(b)
+  // - set(first_dict) if type(b[k]) == int])\nprint('new_ints: ', new_ints)");
+
+  Cpp::BeginStdStreamCapture(Cpp::kStdErr);
+  Cpp::BeginStdStreamCapture(Cpp::kStdOut);
+
+  PyRun_SimpleString(code.c_str());
+
+  std::cout << Cpp::EndStdStreamCapture();
+  std::cerr << Cpp::EndStdStreamCapture();
+
+  //   PyObject* objectsRepresentation = PyObject_Repr(gMainDict);
+  //   const char* s = PyUnicode_AsUTF8(objectsRepresentation);
+  //   printf("REPR of global dict: %s\n", s);
+}
+
+void pythonexec::update_python_dict_var(const char *name, int value) {
+  if (!gMainDict)
+    startup();
+  PyObject *s;
+  s = PyLong_FromLong(value);
+  PyDict_SetItemString(gMainDict, name, s);
+  Py_DECREF(s);
+}
+
+void pythonexec::update_python_dict_var_vector(const char *name,
+                                               std::vector<int> &data) {
+  if (!gMainDict)
+    startup();
+  PyObject *listObj = PyList_New(data.size());
+  if (!listObj)
+    throw std::logic_error("Unable to allocate memory for Python list");
+  for (unsigned int i = 0; i < data.size(); i++) {
+    PyObject *num = PyLong_FromLong((int)data[i]);
+    if (!num) {
+      Py_DECREF(listObj);
+      throw std::logic_error("Unable to allocate memory for Python list");
+    }
+    PyList_SET_ITEM(listObj, i, num);
+  }
+  PyDict_SetItemString(gMainDict, name, listObj);
+}
+
+// check python globals
+void pythonexec::check_python_globals() {
+  if (!Py_IsInitialized())
+    return;
+  // execute the command
+  PyRun_SimpleString("print(globals())");
+}
+
+// execute a python comand
+void pythonexec::exec_python_simple_command(const std::string code) {
+  if (!Py_IsInitialized())
+    return;
+  // execute the command
+  PyRun_SimpleString(code.c_str());
+}
+
+std::string pythonexec::transfer_python_ints_utility() {
+  if (!Py_IsInitialized())
+    return " ";
+  // transfer ints utility
+  PyRun_SimpleString(
+      "def getNewInts():\n    glob_ints_utils = globals().copy()\n    new_ints "
+      "= ' '.join([f'int {k} = {glob_ints_utils[k]};' for k in "
+      "set(glob_ints_utils) - set(first_dict_ints) if type(glob_ints_utils[k]) "
+      "== int])\n    return new_ints");
+  PyObject *ints_result =
+      PyObject_CallFunction(PyDict_GetItemString(gMainDict, "getNewInts"), 0);
+  if (!ints_result) {
+    printf("Could not retrieve Python integers!\n");
+    return " ";
+  } else {
+    std::string newPythonInts = PyUnicode_AsUTF8(ints_result);
+    // printf("new ints %s\n", PyUnicode_AsUTF8(ints_result));
+    Py_DECREF(ints_result);
+    return newPythonInts;
+  }
+}
+
+std::string pythonexec::transfer_python_lists_utility() {
+  if (!Py_IsInitialized())
+    return " ";
+  // transfer lists utility
+  PyRun_SimpleString("def getNewLists():\n    l = globals().copy()\n    "
+                     "new_lists = ' '.join([f'int {k}() = {l[k]};' for k in "
+                     "set(l) - set(first_dict_lists) if type(l[k]) == "
+                     "list]).replace('[','{').replace(']','}').replace('(','[')"
+                     ".replace(')',']')\n    return new_lists");
+  PyObject *lists_result =
+      PyObject_CallFunction(PyDict_GetItemString(gMainDict, "getNewLists"), 0);
+  if (!lists_result) {
+    printf("Could not retrieve Python lists!\n");
+    return " ";
+  } else {
+    std::string newPythonLists = PyUnicode_AsUTF8(lists_result);
+    Py_DECREF(lists_result);
+    return newPythonLists;
+  }
+}
+
+bool pythonexec::python_check_for_initialisation() {
+  if (!Py_IsInitialized())
+    return false;
+  return true;
+}
+} // namespace xcpp
diff --git a/src/xmagics/pythonexec.hpp b/src/xmagics/pythonexec.hpp
new file mode 100644
index 00000000..bd8a69ce
--- /dev/null
+++ b/src/xmagics/pythonexec.hpp
@@ -0,0 +1,55 @@
+//===------- pythonexec.hpp - Python/C++ Interoperability -------*- C++ -*-===//
+//
+// Licensed under the Apache License v2.0.
+// SPDX-License-Identifier: Apache-2.0
+//
+// The full license is in the file LICENSE, distributed with this software.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the Python/C++ interoperability in which two cells within
+//  the same notebook can be in a either language.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef XMAGICS_PYTHONEXEC_HPP
+#define XMAGICS_PYTHONEXEC_HPP
+
+#include "xeus-cpp/xbuffer.hpp"
+#include "xeus-cpp/xinterpreter.hpp"
+#include "xeus-cpp/xmagics.hpp"
+#include "xeus-cpp/xoptions.hpp"
+
+#include <cstddef>
+#include <string>
+
+namespace xcpp {
+
+    class pythonexec: public xmagic_cell
+    {
+    public:
+
+        void get_options(argparser &argpars);
+        virtual void operator()(const std::string& line, const std::string& cell) override {
+          std::string cline = line;
+          std::string ccell = cell;
+          execute(cline, ccell);
+        };
+
+        static void update_python_dict_var(const char *name, int value);
+        static void update_python_dict_var_vector(const char *name,
+                                            std::vector<int> &data);
+        void check_python_globals();
+        void exec_python_simple_command(const std::string code);
+        static std::string transfer_python_ints_utility();
+        static std::string transfer_python_lists_utility();
+        static bool python_check_for_initialisation();
+
+    private:
+
+        static void startup();
+        void execute(std::string &line, std::string &cell);
+    };
+
+} // namespace xcpp
+#endif
diff --git a/src/xsystem.hpp b/src/xsystem.hpp
index 99d67b1e..c43abfc4 100644
--- a/src/xsystem.hpp
+++ b/src/xsystem.hpp
@@ -32,6 +32,8 @@ namespace xcpp
             std::smatch to_execute;
             std::regex_search(code, to_execute, re);
 
+            int ret = 1; // ???
+
             // Redirection of stderr to stdout
             std::string command = to_execute.str(1) + " 2>&1";
 
@@ -43,6 +45,9 @@ namespace xcpp
             if (shell_result)
             {
                 char buff[512];
+
+                ret = 0; // ???
+
                 while (fgets(buff, sizeof(buff), shell_result))
                 {
                     std::cout << buff;
diff --git a/test/pytest.ini b/test/pytest.ini
index 5aacf83b..e580d2bc 100644
--- a/test/pytest.ini
+++ b/test/pytest.ini
@@ -1,3 +1,4 @@
 [pytest]
 testpaths = test
-addopts = --nbval --current-env
+#addopts = --nbval --current-env
+addopts = --nbval --nbval-current-env
diff --git a/test/test_interpreter.cpp b/test/test_interpreter.cpp
index 392b58d9..e422b3ae 100644
--- a/test/test_interpreter.cpp
+++ b/test/test_interpreter.cpp
@@ -14,11 +14,13 @@ TEST_SUITE("execute_request")
 {
     TEST_CASE("fetch_documentation")
     {
-
-        xcpp::interpreter interpreter(0, nullptr);
+        std::vector<const char*> Args = {/*"-v", "resource-dir", "....."*/};
+        xcpp::interpreter interpreter(Args.size(), Args.data());
 
         std::string code = "?std::vector";
         std::string inspect_result = "https://en.cppreference.com/w/cpp/container/vector";
+        //std::string code = "#include <string>\\n#include \"xcpp/xdisplay.hpp\"\\nstd::string test(\"foobar\");\\nxcpp::display(test);";
+        //std::string inspect_result = "foobar";
         nl::json user_expressions = nl::json::object();
 
         nl::json result = interpreter.execute_request(