diff --git a/Cargo.toml b/Cargo.toml
index 641b295..44403c7 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,10 +1,14 @@
 [workspace]
 members = [
-    "nested",
-#    "terminal/display_server",
-#    "terminal/ansi_parser",
-#    "math/str2int",
-#    "math/int2str",
-#    "math/radix_transform",
-#    "math/fib"
+    "lib-nested-core",
+    "lib-nested-tty",
+
+    "srv-tty-output",
+    "srv-pty-capture",
+
+    "examples/tty-01-hello",
+    "examples/tty-02-digit",
+    "examples/tty-03-string",
+    "examples/tty-04-posint",
 ]
+
diff --git a/math/radix_transform/Cargo.toml b/examples/tty-01-hello/Cargo.toml
similarity index 53%
rename from math/radix_transform/Cargo.toml
rename to examples/tty-01-hello/Cargo.toml
index 678a012..4582fd7 100644
--- a/math/radix_transform/Cargo.toml
+++ b/examples/tty-01-hello/Cargo.toml
@@ -1,13 +1,18 @@
 [package]
-name = "radix_transform"
+name = "tty-01-hello"
 version = "0.1.0"
-edition = "2018"
+edition = "2021"
 
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
 [dependencies]
-nested = { path = "../../nested" }
+r3vi = { path = "../../../lib-r3vi" }
+nested = { path = "../../lib-nested-core" }
+nested-tty = { path = "../../lib-nested-tty" }
+termion = "*"
+cgmath = "*"
 
 [dependencies.async-std]
 version = "1.9.0"
 features = ["unstable", "attributes"]
+
diff --git a/examples/tty-01-hello/README.md b/examples/tty-01-hello/README.md
new file mode 100644
index 0000000..b1be4e7
--- /dev/null
+++ b/examples/tty-01-hello/README.md
@@ -0,0 +1,8 @@
+# tty-01-hello
+
+This example shows how to:
+ - initialize the TTY backend (`lib-nestetd-tty`),
+ - create a simple 'Hello World' output,
+ - create color gradients on the outputted text
+   utilizing basic projection functionality from `lib-r3vi`,
+ - perform basic layouting & compositing.
diff --git a/examples/tty-01-hello/src/main.rs b/examples/tty-01-hello/src/main.rs
new file mode 100644
index 0000000..468d8f5
--- /dev/null
+++ b/examples/tty-01-hello/src/main.rs
@@ -0,0 +1,60 @@
+//! This example shows how to:
+//!  - initialize the TTY backend (`lib-nestetd-tty`),
+//!  - create a simple 'Hello World' output,
+//!  - create color gradients on the outputted text
+//!    utilizing basic projection functionality from `lib-r3vi`,
+//!  - perform basic layouting & compositing.
+
+extern crate cgmath;
+extern crate nested;
+extern crate nested_tty;
+extern crate r3vi;
+extern crate termion;
+
+use {
+    cgmath::Vector2,
+    nested::repr_tree::Context,
+    nested_tty::{Terminal, TerminalCompositor, TTYApplication, TerminalEvent, TerminalStyle, TerminalView},
+    r3vi::view::{port::UpdateTask, ViewPort},
+    std::sync::{Arc, RwLock},
+    termion::event::{Event, Key},
+};
+
+#[async_std::main]
+async fn main() {
+    /* Initialize our terminal.
+     */
+    let tty_app = TTYApplication::new(|event| { /* handle event */ });
+
+    /* Setup our "root" view of the application.
+     * This will be the compositor, which is able to
+     * mix multiple `TerminalView`-Views together.
+     * Its output is routed to the `app.port` Viewport,
+     * so it will be displayed on TTY-output.
+     */
+    let compositor = TerminalCompositor::new(tty_app.port.inner());
+
+    /* Add the label 'test' at position (7, 2)
+     */
+    compositor
+        .write()
+        .unwrap()
+        .push(nested_tty::make_label("test").offset(Vector2::new(7, 2)));
+
+    /* Add a 'Hello World' label at position (5, 3)
+     * and set a coloring determined by formula from
+     * the position of each character.
+     */
+    compositor.write().unwrap().push(
+        nested_tty::make_label("Hello World")
+            .map_item(|p, a| {
+                a.add_style_back(TerminalStyle::fg_color(((25 * p.x % 255) as u8, 200, 0)))
+            })
+            .offset(Vector2::new(5, 3)),
+    );
+
+    /* write the changes in the root-view to the terminal
+     */
+    tty_app.show().await.expect("output error!");
+}
+
diff --git a/examples/tty-02-digit/Cargo.toml b/examples/tty-02-digit/Cargo.toml
new file mode 100644
index 0000000..b875ea5
--- /dev/null
+++ b/examples/tty-02-digit/Cargo.toml
@@ -0,0 +1,19 @@
+[package]
+name = "tty-02-digit"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+laddertypes = { path = "../../../lib-laddertypes" }
+r3vi = { path = "../../../lib-r3vi" }
+nested = { path = "../../lib-nested-core" }
+nested-tty = { path = "../../lib-nested-tty" }
+termion = "*"
+cgmath = "*"
+
+[dependencies.async-std]
+version = "1.9.0"
+features = ["unstable", "attributes"]
+
diff --git a/examples/tty-02-digit/README.md b/examples/tty-02-digit/README.md
new file mode 100644
index 0000000..23b502b
--- /dev/null
+++ b/examples/tty-02-digit/README.md
@@ -0,0 +1,4 @@
+# tty-02-digit
+
+This example demonstrates how a very simple editor for hexadecimal digits
+can be created with `lib-nested` and the `lib-nested-tty` backend.
diff --git a/examples/tty-02-digit/src/main.rs b/examples/tty-02-digit/src/main.rs
new file mode 100644
index 0000000..9279cc5
--- /dev/null
+++ b/examples/tty-02-digit/src/main.rs
@@ -0,0 +1,137 @@
+//! This example demonstrates how a very simple editor for hexadecimal digits
+//! can be created with `lib-nested` and the `lib-nested-tty` backend.
+
+extern crate cgmath;
+extern crate nested;
+extern crate nested_tty;
+extern crate r3vi;
+extern crate termion;
+
+use {
+    cgmath::Vector2,
+    nested::{
+        editors::ObjCommander,
+        repr_tree::{Context, ReprTree, ReprTreeExt},
+        edit_tree::{EditTree}
+    },
+    nested_tty::{
+        DisplaySegment, TTYApplication,
+        TerminalCompositor, TerminalStyle, TerminalView,
+        TerminalAtom, TerminalEvent
+    },
+    r3vi::{
+        buffer::{singleton::*, vec::*},
+        view::{port::UpdateTask, list::*}
+    },
+    std::sync::{Arc, RwLock},
+};
+
+#[async_std::main]
+async fn main() {
+    /* setup context & create Editor-Tree
+     */
+    let ctx = Arc::new(RwLock::new(Context::new()));
+
+    nested::editors::char::init_ctx( ctx.clone() );
+    nested::editors::digit::init_ctx( ctx.clone() );
+    nested::editors::integer::init_ctx( ctx.clone() );
+    nested::editors::list::init_ctx( ctx.clone() );
+
+    nested_tty::setup_edittree_hook(&ctx);
+
+    /* structure of Repr-Tree
+     *
+     *   === Repr-Tree ===
+     *
+     *        <Digit 10>
+     *         /   |     \
+     *        /    |        \
+     *       /     |          \
+     *     u64   EditTree     Char
+     *           - Editor         \
+     *           - Display        EditTree
+     *         /     |    \      - Editor
+     *        /      |     \     - Display
+     *      TTY  PixelBuf  SDF  /    |     \
+     *                         /     |      \
+     *                       TTY  PixelBuf  SDF
+     */
+    let mut rt_digit = ReprTree::new_arc( Context::parse(&ctx, "<Digit 16>") );
+
+    /* add initial representation
+     *  <Digit 16> ~ Char
+     */
+    rt_digit.insert_leaf(
+        Context::parse(&ctx, "Char"),
+        nested::repr_tree::ReprLeaf::from_singleton_buffer( SingletonBuffer::new('5') )
+    );
+
+    /* furthermore, setup projections to and from u8 value,
+     * this synchronizes the buffers 
+     */
+    ctx.read().unwrap().apply_morphism(
+        &rt_digit,
+        &laddertypes::MorphismType {
+            src_type: Context::parse(&ctx, "<Digit 16>~Char"),
+            dst_type: Context::parse(&ctx, "<Digit 16>~ℤ_2^64~machine.UInt64")
+        }
+    );
+    ctx.read().unwrap().apply_morphism(
+        &rt_digit,
+        &laddertypes::MorphismType {
+            src_type: Context::parse(&ctx, "<Digit 16>~Char"),
+            dst_type: Context::parse(&ctx, "<Digit 16>~EditTree")
+        }
+    );
+
+    /* setup terminal
+     */
+    let app = TTYApplication::new({
+        /* event handler
+         */
+        let ctx = ctx.clone();
+        let digit_edittree = rt_digit.edittree( &ctx );
+        move |ev| {
+            digit_edittree.get().write().unwrap().send_cmd_obj(ev.to_repr_tree(&ctx));
+        }
+    });
+
+    /* setup display view routed to `app.port`
+     */
+    let compositor = TerminalCompositor::new(app.port.inner());
+
+    // add some views to the display compositor
+    {
+        let mut comp = compositor.write().unwrap();
+
+        comp.push(
+            nested_tty::make_label("Hello World")
+                .map_item(|p, a| {
+                    a.add_style_back(TerminalStyle::fg_color(((25 * p.x % 255) as u8, 200, 0)))
+                })
+                .offset(Vector2::new(5,0)));
+
+        let label_str = ctx.read().unwrap().type_term_to_str(&rt_digit.read().unwrap().get_type());
+        comp.push(
+            nested_tty::make_label(&label_str)
+            .map_item(|_pt,atom| atom.add_style_front(TerminalStyle::fg_color((90,90,90))))
+            .offset(Vector2::new(1,1)));
+
+        comp.push(rt_digit
+            .edittree( &ctx ).get().read().unwrap()
+            .display_view()
+            .offset(Vector2::new(3,2)));
+
+        comp.push(rt_digit
+            .descend(Context::parse(&ctx, "ℤ_2^64~machine.UInt64")).unwrap()
+            .view_u64()
+            .map(|d| nested_tty::make_label(&format!("Digit value={}", d)))
+            .to_grid()
+            .flatten()
+            .offset(Vector2::new(5,3)));
+    }
+
+    /* write the changes in the view of `term_port` to the terminal
+     */
+    app.show().await.expect("output error!");
+}
diff --git a/examples/tty-03-string/Cargo.toml b/examples/tty-03-string/Cargo.toml
new file mode 100644
index 0000000..10763ef
--- /dev/null
+++ b/examples/tty-03-string/Cargo.toml
@@ -0,0 +1,19 @@
+[package]
+name = "tty-03-string"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+laddertypes = { path = "../../../lib-laddertypes" }
+r3vi = { path = "../../../lib-r3vi" }
+nested = { path = "../../lib-nested-core" }
+nested-tty = { path = "../../lib-nested-tty" }
+termion = "*"
+cgmath = "*"
+
+[dependencies.async-std]
+version = "1.9.0"
+features = ["unstable", "attributes"]
+
diff --git a/examples/tty-03-string/README.md b/examples/tty-03-string/README.md
new file mode 100644
index 0000000..85305aa
--- /dev/null
+++ b/examples/tty-03-string/README.md
@@ -0,0 +1,8 @@
+# tty-03-string
+
+Similarly to `tty-02-digit`, a editor is created
+but of type <List Char>.
+The contents of the editor can be retrieved by
+a morphism from the `EditTree` node.
+To demonstrate that, the values are are mapped
+to the TTY-display in different form.
diff --git a/examples/tty-03-string/src/main.rs b/examples/tty-03-string/src/main.rs
new file mode 100644
index 0000000..d5f8ff9
--- /dev/null
+++ b/examples/tty-03-string/src/main.rs
@@ -0,0 +1,168 @@
+//! Similarly to `tty-02-digit`, a editor is created
+//! but of type <List Char>.
+//! The contents of the editor can be retrieved by
+//! a morphism from the `EditTree` node.
+//! To demonstrate that, the values are are mapped
+//! to the TTY-display in different form.
+
+extern crate cgmath;
+extern crate nested;
+extern crate nested_tty;
+extern crate r3vi;
+extern crate termion;
+
+use {
+    cgmath::Vector2,
+    nested::{
+        editors::ObjCommander,
+        repr_tree::{Context, ReprTree, ReprTreeExt},
+        edit_tree::{EditTree}
+    },
+    nested_tty::{
+        DisplaySegment, TTYApplication,
+        TerminalCompositor, TerminalStyle, TerminalView,
+        TerminalAtom, TerminalEvent
+    },
+    r3vi::{
+        buffer::{singleton::*, vec::*},
+        view::{port::UpdateTask, list::*, sequence::SequenceViewExt}
+    },
+    std::sync::{Arc, RwLock},
+};
+
+#[async_std::main]
+async fn main() {
+    /* setup context
+     */
+    let ctx = Arc::new(RwLock::new(Context::new()));
+    nested::editors::char::init_ctx( ctx.clone() );
+    nested::editors::digit::init_ctx( ctx.clone() );
+    nested::editors::integer::init_ctx( ctx.clone() );
+    nested::editors::list::init_ctx( ctx.clone() );
+    nested_tty::setup_edittree_hook(&ctx);
+
+    /* Create a Representation-Tree of type <List Char>
+     */
+    let mut rt_string = ReprTree::from_str(
+        Context::parse(&ctx, "<List Char>~<Vec Char>"),
+        "hello world"
+    );
+
+    /* create EditTree
+     */
+    ctx.read().unwrap().apply_morphism(
+        &rt_string,
+        &laddertypes::MorphismType {
+            src_type: Context::parse(&ctx, "<List~Vec Char>"),
+            dst_type: Context::parse(&ctx, "<List Char> ~ EditTree")
+        }
+    );
+
+    // .. avoid cycle of projections..
+    rt_string.write().unwrap().detach(&ctx);
+
+    /* In order to get access to the values that are modified by the Editor,
+     * we apply a morphism that, given the List of Edit-Trees, extracts
+     * the value from each EditTree and shows them in a ListView.
+     */
+    ctx.read().unwrap().apply_morphism(
+        &rt_string,
+        &laddertypes::MorphismType {
+            src_type: Context::parse(&ctx, "<List Char>~EditTree"),
+            dst_type: Context::parse(&ctx, "<List Char>")
+        }
+    );
+
+    /* Now, get the ListView that serves our char-values.
+     * This view is a projection created by the morphism that was called above.
+     */
+    let mut chars_view = rt_string
+        .read().unwrap()
+        .get_port::<dyn ListView<char>>()
+        .unwrap();
+
+    /* Lets add another morphism which will store the values
+     * of the character-list in a `Vec<char>`
+     */
+    ctx.read().unwrap().apply_morphism(
+        &rt_string,
+        &laddertypes::MorphismType {
+            src_type: Context::parse(&ctx, "<List Char>"),
+            dst_type: Context::parse(&ctx, "<List Char>~<Vec Char>")
+        }
+    );
+
+    /* Access the Vec<char> object (wrapped behind a VecBuffer<char>)
+     * from the ReprTree.
+     */
+    let chars_vec = rt_string
+        .descend(Context::parse(&ctx, "<Vec Char>")).unwrap()
+        .vec_buffer::<char>();
+
+    /* transform `ListView<char>` into a `TerminalView`
+     */
+    let string_view_tty = chars_view
+        .to_sequence()
+        .to_grid_vertical()
+        .map_item(|_pt,c| TerminalAtom::new(*c, TerminalStyle::fg_color((200,10,60))));
+
+    /* setup terminal
+     */
+    let app = TTYApplication::new({
+        let edittree_list = rt_string.edittree(&ctx).clone();
+
+        /* event handler
+         */
+        let ctx = ctx.clone();
+        move |ev| {
+            edittree_list.get().write().unwrap().send_cmd_obj(ev.to_repr_tree(&ctx));
+        }
+    });
+
+    /* Setup the compositor to serve as root-view
+     * by routing it to the `app.port` Viewport,
+     * so it will be displayed on TTY-output.
+     */
+    let compositor = TerminalCompositor::new(app.port.inner());
+
+    /* Now add some views to our compositor
+     */
+    {
+        let mut comp = compositor.write().unwrap();
+
+        let label_str = ctx.read().unwrap().type_term_to_str(&rt_string.read().unwrap().get_type());
+        comp.push(
+            nested_tty::make_label(&label_str)
+                .map_item(|_pt, atom| atom.add_style_front(TerminalStyle::fg_color((90,90,90))))
+                .offset(Vector2::new(1,1)));
+
+        comp.push(
+            rt_string.edittree(&ctx).get()
+                .read().unwrap()
+                .display_view()
+                .offset(Vector2::new(3,2)));
+
+        comp.push(
+            string_view_tty
+                .offset(Vector2::new(5,3)));
+    }
+
+    /* write the changes in the view of `term_port` to the terminal
+     */
+    app.show().await.expect("output error!");
+
+    /* need to call update because changes are applied lazily
+     */
+    chars_vec.get_port().0.update();
+
+    /* Vec<char> to String
+     */
+    let string = chars_vec
+        .get_port()
+        .to_sequence()
+        .get_view().unwrap()
+        //.data.read().unwrap()
+        .iter().collect::<String>();
+
+    eprintln!("value of the editor was: {}\n\n", string);
+}
diff --git a/examples/tty-04-posint/Cargo.toml b/examples/tty-04-posint/Cargo.toml
new file mode 100644
index 0000000..0e4e285
--- /dev/null
+++ b/examples/tty-04-posint/Cargo.toml
@@ -0,0 +1,19 @@
+[package]
+name = "tty-04-posint"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+laddertypes = { path = "../../../lib-laddertypes" }
+r3vi = { path = "../../../lib-r3vi" }
+nested = { path = "../../lib-nested-core" }
+nested-tty = { path = "../../lib-nested-tty" }
+termion = "*"
+cgmath = "*"
+
+[dependencies.async-std]
+version = "1.9.0"
+features = ["unstable", "attributes"]
+
diff --git a/examples/tty-04-posint/README.md b/examples/tty-04-posint/README.md
new file mode 100644
index 0000000..1f85cdd
--- /dev/null
+++ b/examples/tty-04-posint/README.md
@@ -0,0 +1,7 @@
+# tty-04-posint
+
+In the following example, a <List Char> editor
+as before is used, but its data is morphed into
+representing a positional integer which is then
+projected into different radices and displayed
+in different views on screen
diff --git a/examples/tty-04-posint/src/main.rs b/examples/tty-04-posint/src/main.rs
new file mode 100644
index 0000000..4c91ee5
--- /dev/null
+++ b/examples/tty-04-posint/src/main.rs
@@ -0,0 +1,199 @@
+//! In the following example, a <List Char> editor
+//! as before is used, but its data is morphed into
+//! representing a positional integer which is then
+//! projected into different radices and displayed
+//! in different views on screen
+
+extern crate cgmath;
+extern crate nested;
+extern crate nested_tty;
+extern crate r3vi;
+extern crate termion;
+
+use {
+    cgmath::Vector2,
+    nested::{
+        editors::{
+            ObjCommander
+        },
+        repr_tree::{Context, ReprTree, ReprTreeExt, ReprLeaf},
+        edit_tree::{EditTree, TreeNav, TreeCursor}
+    },
+    nested_tty::{
+        DisplaySegment, TTYApplication,
+        TerminalCompositor, TerminalStyle, TerminalView,
+        TerminalAtom, TerminalEvent
+    },
+    r3vi::{
+        buffer::{singleton::*, vec::*},
+        view::{port::UpdateTask, singleton::*, list::*, sequence::*},
+        projection::*
+    },
+    std::sync::{Arc, RwLock},
+};
+
+#[async_std::main]
+async fn main() {
+    /* setup context
+     */
+    let ctx = Arc::new(RwLock::new(Context::new()));
+    nested::editors::char::init_ctx( ctx.clone() );
+    nested::editors::digit::init_ctx( ctx.clone() );
+    nested::editors::integer::init_ctx( ctx.clone() );
+    nested::editors::list::init_ctx( ctx.clone() );
+    nested_tty::setup_edittree_hook(&ctx);
+
+    /* Create a Representation-Tree of type `ℕ`
+     * with a specific representation-path (big-endian hexadecimal string)
+     */
+    let mut rt_int = nested::repr_tree::ReprTree::from_str(
+        /* TYPE */
+        Context::parse(&ctx, "
+              ℕ
+            ~ <PosInt 16 BigEndian>
+            ~ <Seq <Digit 16>>
+            ~ <List <Digit 16>>
+            ~ <List Char>
+            ~ <Vec Char>
+        "),
+
+        /* VALUE */
+        "cff"
+    );
+
+    /* initially copy values from Vec to EditTree...
+     */
+    ctx.read().unwrap().build_repr_tree(
+        &rt_int,
+        Context::parse(&ctx, "ℕ ~ <PosInt 16 BigEndian> ~ <Seq~List <Digit 16>~Char> ~ <Vec Char>"),
+        vec![
+            Context::parse(&ctx, "ℕ ~ <PosInt 16 BigEndian> ~ <Seq~List <Digit 16>> ~ EditTree"),
+            Context::parse(&ctx, "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq~List <Digit 16>> ~ EditTree"),
+        ]);
+
+    fn set_master(
+        ctx: &Arc<RwLock<Context>>,
+        rt: &Arc<RwLock<ReprTree>>,
+        mut leaves: Vec< laddertypes::TypeTerm >,
+        master_idx: usize
+    ) {
+        eprintln!("set master to {}", master_idx);
+        if master_idx < leaves.len() {
+            let master = leaves.remove( master_idx );
+            rt.write().unwrap().detach( &ctx );
+            ctx.read().unwrap().build_repr_tree(
+                rt,
+                master,
+                leaves
+            );
+        }
+    }
+
+    let editor_types = vec![
+         Context::parse(&ctx,
+             "ℕ ~ <PosInt 16 BigEndian> ~ <Seq~List <Digit 16>> ~ EditTree"),
+         Context::parse(&ctx,
+             "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq~List <Digit 16>> ~ EditTree"),
+         Context::parse(&ctx,
+             "ℕ ~ <PosInt 16 BigEndian> ~ EditTree"),
+         Context::parse(&ctx,
+             "ℕ ~ <PosInt 8 BigEndian> ~ EditTree"),
+         Context::parse(&ctx,
+             "ℕ ~ <PosInt 2 BigEndian> ~ EditTree"),
+    ];
+
+    set_master(&ctx, &rt_int, editor_types.clone(), 0);
+
+    /* list of editors
+     */
+    let mut list_editor = nested::editors::list::ListEditor::new(ctx.clone(), Context::parse(&ctx, "<Seq Char>"));
+
+    // add all desired editors to the list
+    for leaf in editor_types.iter() {
+        let et =  
+            rt_int
+                .descend(leaf.clone()).unwrap()
+                .edittree(&ctx).get();
+        et.write().unwrap().goto(TreeCursor::none());
+        list_editor.data.push(et);
+    }
+
+    let mut edittree = list_editor.into_node(SingletonBuffer::new(0).get_port());
+
+    /* cursors are a bit screwed initially so fix them up
+     * TODO: how to fix this generally?
+     */
+    edittree.goto(TreeCursor{
+        leaf_mode: nested::editors::list::ListCursorMode::Insert,
+        tree_addr: vec![0,0]
+    });
+    let edittree = Arc::new(RwLock::new(edittree));
+ 
+    /* setup terminal
+     */
+    let app = TTYApplication::new({
+        /* event handler
+         */
+        let ctx = ctx.clone();
+        let rt_int = rt_int.clone();
+        let last_idx = RwLock::new(0);
+        let editor_types = editor_types.clone();
+        move |ev| {
+            let cur = edittree.read().unwrap().get_cursor();
+            if cur.tree_addr.len() > 0 {
+                let mut li = last_idx.write().unwrap();
+                let ci = cur.tree_addr[0];
+
+                if *li != ci {
+                    eprintln!("----------------------------------");
+                    set_master(
+                        &ctx,
+                        &rt_int,
+                        editor_types.clone(),
+                        ci as usize
+                    );
+                    *li = ci;
+                }
+            }
+
+            edittree.write().unwrap().send_cmd_obj(ev.to_repr_tree(&ctx));
+        }
+    });
+
+    /* Setup the compositor to serve as root-view
+     * by routing it to the `app.port` Viewport,
+     * so it will be displayed on TTY-output.
+     */
+    let compositor = TerminalCompositor::new(app.port.inner());
+
+    /* Now add some views to our compositor
+     */
+    {
+        let mut comp = compositor.write().unwrap();
+
+        fn show_edit_tree( ctx: &Arc<RwLock<Context>>, comp: &mut TerminalCompositor, rt: &Arc<RwLock<ReprTree>>, y: i16 )
+        {
+            let rt_edittree = rt.descend(Context::parse(&ctx, "EditTree")).expect("descend");
+            let halo_type = rt_edittree.read().unwrap().get_halo_type().clone();
+            let edittree = rt_edittree.edittree( &ctx );
+
+            comp.push(  nested_tty::make_label( &ctx.read().unwrap().type_term_to_str(&halo_type) ) 
+                .map_item(|_pt, atom| atom.add_style_front(TerminalStyle::fg_color((90,90,90))))
+                .offset(Vector2::new(1,y)));
+
+            comp.push(  edittree.get().read().unwrap().display_view()
+                .offset(Vector2::new(1,y+1)));
+        }
+
+        let mut y = 1;
+        for t in editor_types.iter() {
+            show_edit_tree(&ctx, &mut comp, &rt_int.descend(t.clone()).expect(""), y);
+            y += 3;
+        }
+    }
+
+    /* write the changes in the view of `term_port` to the terminal
+     */
+    app.show().await.expect("output error!");
+}
+
diff --git a/lib-nested-core/Cargo.toml b/lib-nested-core/Cargo.toml
new file mode 100644
index 0000000..0805fce
--- /dev/null
+++ b/lib-nested-core/Cargo.toml
@@ -0,0 +1,11 @@
+[package]
+authors = ["Michael Sippel <micha@fragmental.art>"]
+edition = "2018"
+name = "nested"
+version = "0.1.0"
+
+[dependencies]
+r3vi = { path = "../../lib-r3vi" }
+laddertypes = { path = "../../lib-laddertypes" }
+cgmath = { version = "0.18.0", features = ["serde"]  }
+
diff --git a/nested/src/tree/addr.rs b/lib-nested-core/src/edit_tree/addr.rs
similarity index 100%
rename from nested/src/tree/addr.rs
rename to lib-nested-core/src/edit_tree/addr.rs
diff --git a/nested/src/tree/cursor.rs b/lib-nested-core/src/edit_tree/cursor.rs
similarity index 100%
rename from nested/src/tree/cursor.rs
rename to lib-nested-core/src/edit_tree/cursor.rs
diff --git a/lib-nested-core/src/edit_tree/diagnostics.rs b/lib-nested-core/src/edit_tree/diagnostics.rs
new file mode 100644
index 0000000..4b39a1f
--- /dev/null
+++ b/lib-nested-core/src/edit_tree/diagnostics.rs
@@ -0,0 +1,24 @@
+use {
+    r3vi::{
+        view::{OuterViewPort, sequence::*},
+        buffer::{vec::*, index_hashmap::*}
+    },
+    crate::{
+        repr_tree::ReprTree
+    },
+    std::sync::{Arc, RwLock},
+    cgmath::Point2
+};
+
+#[derive(Clone)]
+pub struct Message {
+    pub addr: Vec<usize>,
+    pub disp: Arc<RwLock<ReprTree>>
+}
+
+pub trait Diagnostics {
+    fn get_msg_port(&self) -> OuterViewPort<dyn SequenceView<Item = Message>> {
+        VecBuffer::new().get_port().to_sequence()
+    }
+}
+
diff --git a/nested/src/tree/mod.rs b/lib-nested-core/src/edit_tree/mod.rs
similarity index 83%
rename from nested/src/tree/mod.rs
rename to lib-nested-core/src/edit_tree/mod.rs
index 71e40c8..92e0411 100644
--- a/nested/src/tree/mod.rs
+++ b/lib-nested-core/src/edit_tree/mod.rs
@@ -3,12 +3,13 @@ pub mod cursor;
 pub mod nav;
 pub mod node;
 pub mod treetype;
+pub mod diagnostics;
 
 pub use {
     addr::TreeAddr,
     cursor::TreeCursor,
     nav::{TreeNav, TreeNavResult, TreeHeightOp},
     treetype::{TreeType},
-    node::NestedNode
+    node::EditTree
 };
 
diff --git a/nested/src/tree/nav.rs b/lib-nested-core/src/edit_tree/nav.rs
similarity index 74%
rename from nested/src/tree/nav.rs
rename to lib-nested-core/src/edit_tree/nav.rs
index 9d85cdd..a8dc371 100644
--- a/nested/src/tree/nav.rs
+++ b/lib-nested-core/src/edit_tree/nav.rs
@@ -15,8 +15,7 @@ use {
     },
     crate::{
         editors::list::ListCursorMode,
-        tree::TreeCursor,
-        terminal::{TerminalView, TerminalProjections, make_label}
+        edit_tree::TreeCursor
     },
     cgmath::Vector2,
 };
@@ -27,9 +26,19 @@ pub enum TreeNavResult { Continue, Exit }
 #[derive(Clone, Copy, Eq, PartialEq, Debug)]
 pub enum TreeHeightOp { P, Q, Max }
 
+#[derive(Clone, Copy, Debug)]
+pub enum TreeNavCmd {
+    pxev, nexd, up, dn,
+    qpxev, qnexd, dup, qdn,
+
+    dn_pxev,
+    up_nexd,
+    pxev_dn_qnexd
+}
+
 pub trait TreeNav {
     /* CORE
-    */
+     */
     fn get_cursor(&self) -> TreeCursor {
         TreeCursor::default()
     }
@@ -150,35 +159,6 @@ pub trait TreeNav {
         }
     }
 
-    fn get_cursor_widget(&self) -> OuterViewPort<dyn TerminalView> {
-        VecBuffer::with_data(
-            vec![
-                make_label("@").with_fg_color((150, 80,230)),
-                self.get_addr_view()
-                    .map(|i|
-                        make_label(&format!("{}", i)).with_fg_color((0, 100, 20)))
-                    .separate(make_label(".").with_fg_color((150, 80,230)))
-                    .to_grid_horizontal()
-                    .flatten(),
-                make_label(":").with_fg_color((150, 80,230)),
-                self.get_mode_view()
-                    .map(|mode| {
-                        make_label(
-                            match mode {
-                                ListCursorMode::Insert => "INSERT",
-                                ListCursorMode::Select => "SELECT"
-                            })
-                            .with_fg_color((200, 200, 20))
-                    })
-                    .to_grid()
-                    .flatten(),
-                make_label(":").with_fg_color((150, 80,230))
-            ]
-        ).get_port()
-            .to_sequence()
-            .to_grid_horizontal()
-            .flatten()
-    }
 }
 
 
diff --git a/lib-nested-core/src/edit_tree/node.rs b/lib-nested-core/src/edit_tree/node.rs
new file mode 100644
index 0000000..8b5a8a6
--- /dev/null
+++ b/lib-nested-core/src/edit_tree/node.rs
@@ -0,0 +1,228 @@
+use {
+    std::{sync::{Arc, RwLock}, any::Any},
+    cgmath::{Vector2, Point2},
+    r3vi::{
+        view::{View, ViewPort, OuterViewPort, AnyOuterViewPort, singleton::*, sequence::*},
+        buffer::{singleton::*, vec::*}
+    },
+    laddertypes::{TypeTerm},
+    crate::{
+        repr_tree::{ReprTree, Context},
+        edit_tree::{TreeNav, TreeCursor, TreeNavResult, TreeHeightOp, diagnostics::{Diagnostics, Message}},
+        editors::{list::{ListCursorMode}, ObjCommander}
+    }
+};
+
+#[derive(Clone)]
+pub struct EdittreeDisplay {
+    /// display view
+    pub view: Arc<RwLock<ReprTree>>,
+
+    /// diagnostics
+    pub diag: Option< OuterViewPort<dyn SequenceView<Item = Message>> >,
+
+    /// depth
+    pub depth: OuterViewPort<dyn SingletonView<Item = usize>>,
+}
+
+#[derive(Clone)]
+pub struct EdittreeControl {
+    /// abstract editor
+    pub editor: SingletonBuffer<
+                    Option< Arc<dyn Any + Send + Sync> >
+                >,
+
+    pub spillbuf: Arc<RwLock<
+                    Vec< Arc<RwLock< EditTree >> >
+                  >>,
+
+    /// commander & navigation
+    pub cmd: SingletonBuffer<
+                 Option< Arc<RwLock<dyn ObjCommander + Send + Sync>> >
+             >,    /// abstract data view
+
+    pub close_char: SingletonBuffer< Option< char > >,
+
+    // could be replaced by cmd when TreeNav -CmdObjects are used
+    pub tree_nav: SingletonBuffer<
+                      Option< Arc<RwLock<dyn TreeNav + Send + Sync>> >
+                  >,    
+}
+
+#[derive(Clone)]
+pub struct EditTree {
+    /// context
+    pub ctx: Arc<RwLock<Context>>,
+
+    /// viewports for terminal display
+    pub disp: EdittreeDisplay,
+
+    /// editor & commander objects
+    pub ctrl: EdittreeControl
+}
+
+impl EditTree {
+    pub fn new(ctx: Arc<RwLock<Context>>, depth: OuterViewPort<dyn SingletonView<Item = usize>>) -> Self {
+        EditTree {
+            disp: EdittreeDisplay {
+                view: ReprTree::new_arc(Context::parse(&ctx, "Display")),
+                diag: None,
+                depth,
+            },
+            ctrl: EdittreeControl {
+                editor: SingletonBuffer::new(None),
+                spillbuf: Arc::new(RwLock::new(Vec::new())),
+                cmd: SingletonBuffer::new(None),
+                close_char: SingletonBuffer::new(None),
+                tree_nav: SingletonBuffer::new(None),
+            },
+            ctx
+        }
+    }
+
+    pub fn set_editor(mut self, editor: Arc<dyn Any + Send + Sync>) -> Self {
+        self.ctrl.editor.set(Some(editor));
+        self
+    }
+
+    pub fn set_cmd(mut self, cmd: Arc<RwLock<dyn ObjCommander + Send + Sync>>) -> Self {
+        self.ctrl.cmd.set(Some(cmd));
+        self
+    }
+
+    pub fn set_nav(mut self, nav: Arc<RwLock<dyn TreeNav + Send + Sync>>) -> Self {
+        self.ctrl.tree_nav.set(Some(nav));
+        self
+    }
+
+    pub fn set_diag(mut self, diag: OuterViewPort<dyn SequenceView<Item = Message>>) -> Self {
+        self.disp.diag = Some(diag);
+        self
+    }
+
+    //\\//\\
+
+    pub fn get_diag(&self) -> OuterViewPort<dyn SequenceView<Item = Message>> {
+        self.disp.diag.clone().unwrap_or(ViewPort::new().into_outer())
+    }
+
+    pub fn get_edit<T: Send + Sync + 'static>(&self) -> Option<Arc<RwLock<T>>> {
+        if let Some(edit) = self.ctrl.editor.get() {
+            if let Ok(edit) = edit.downcast::<RwLock<T>>() {
+                Some(edit)
+            } else {
+                None
+            }
+        } else {
+            None
+        }
+    }
+}
+
+/*
+impl TreeType for NestedNode {
+    fn get_type(&self, addr: &TreeAddr) -> TypeLadder {
+        if let Some(editor) = self.editor {
+            editor.read().unwrap().get_type(addr)
+        } else {
+            vec![]
+        }
+    }
+}
+*/
+
+impl TreeNav for EditTree {
+    fn get_cursor(&self) -> TreeCursor {
+        if let Some(tn) = self.ctrl.tree_nav.get() {
+            tn.read().unwrap().get_cursor()
+        } else {
+            TreeCursor::default()
+        }
+    }
+
+    fn get_addr_view(&self) -> OuterViewPort<dyn SequenceView<Item = isize>> {
+        if let Some(tn) = self.ctrl.tree_nav.get() {
+            tn.read().unwrap().get_addr_view()
+        } else {
+            OuterViewPort::default()
+        }
+    }
+
+    fn get_mode_view(&self) -> OuterViewPort<dyn SingletonView<Item = ListCursorMode>> {
+        if let Some(tn) = self.ctrl.tree_nav.get() {
+            tn.read().unwrap().get_mode_view()
+        } else {
+            OuterViewPort::default()
+        }        
+    }
+
+    fn get_cursor_warp(&self) -> TreeCursor {
+        if let Some(tn) = self.ctrl.tree_nav.get() {
+            tn.read().unwrap().get_cursor_warp()
+        } else {
+            TreeCursor::default()
+        }
+    }
+
+    fn get_height(&self, op: &TreeHeightOp) -> usize {
+        if let Some(tn) = self.ctrl.tree_nav.get() {
+            tn.read().unwrap().get_height( op )
+        } else {
+            0
+        }
+    }
+
+    fn goby(&mut self, direction: Vector2<isize>) -> TreeNavResult {
+        if let Some(tn) = self.ctrl.tree_nav.get() {
+            tn.write().unwrap().goby(direction)
+        } else {
+            TreeNavResult::Exit
+        }
+    }
+
+    fn goto(&mut self, new_cursor: TreeCursor) -> TreeNavResult {
+        if let Some(tn) = self.ctrl.tree_nav.get() {
+            tn.write().unwrap().goto(new_cursor)
+        } else {
+            TreeNavResult::Exit
+        }
+    }
+}
+
+use crate::edit_tree::nav::TreeNavCmd;
+
+impl ObjCommander for EditTree {
+    fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult {
+
+        if cmd_obj.read().unwrap().get_type() == &Context::parse(&self.ctx, "TreeNavCmd") {
+            if let Some(cmd) = cmd_obj.read().unwrap().get_view::<dyn SingletonView<Item = TreeNavCmd>>() {
+                match cmd.get() {
+                    TreeNavCmd::pxev => self.pxev(),
+                    TreeNavCmd::nexd => self.nexd(),
+                    TreeNavCmd::qpxev => self.qpxev(),
+                    TreeNavCmd::qnexd => self.qnexd(),
+
+                    TreeNavCmd::up => self.up(),
+                    TreeNavCmd::dn => self.dn(),
+
+                    _ => TreeNavResult::Continue
+                }
+            } else {
+                TreeNavResult::Exit
+            }
+        } else if let Some(cmd) = self.ctrl.cmd.get() {
+            // todo: filter out tree-nav cmds and send them to tree_nav
+            cmd.write().unwrap().send_cmd_obj(cmd_obj)
+        } else {
+            TreeNavResult::Exit
+        }
+    }
+}
+
+
+impl Diagnostics for EditTree {
+    fn get_msg_port(&self) -> OuterViewPort<dyn SequenceView<Item = Message>> {
+        self.get_diag()
+    }
+}
+
diff --git a/nested/src/tree/treetype.rs b/lib-nested-core/src/edit_tree/treetype.rs
similarity index 85%
rename from nested/src/tree/treetype.rs
rename to lib-nested-core/src/edit_tree/treetype.rs
index 9f66849..c3ad118 100644
--- a/nested/src/tree/treetype.rs
+++ b/lib-nested-core/src/edit_tree/treetype.rs
@@ -2,7 +2,7 @@
 use {
     laddertypes::{TypeTerm, TypeID},
     crate::{
-        tree::{TreeAddr}
+        edit_tree::{TreeAddr}
     }
 };
 
diff --git a/lib-nested-core/src/editors/char/mod.rs b/lib-nested-core/src/editors/char/mod.rs
new file mode 100644
index 0000000..f9f97c0
--- /dev/null
+++ b/lib-nested-core/src/editors/char/mod.rs
@@ -0,0 +1,149 @@
+use {
+    r3vi::{
+        view::{
+            OuterViewPort,
+            singleton::*,
+            port::UpdateTask
+        },
+        buffer::singleton::*
+    },
+    laddertypes::{TypeTerm},
+    crate::{
+        repr_tree::{Context, ReprTree, ReprLeaf, ReprTreeExt, GenericReprTreeMorphism},
+        edit_tree::{EditTree, TreeNavResult},
+        editors::ObjCommander,
+    },
+    std::sync::Arc,
+    std::sync::RwLock
+};
+
+pub fn init_ctx( ctx: Arc<RwLock<Context>> ) {
+
+    let char_morph_to_edittree = GenericReprTreeMorphism::new(
+        Context::parse(&ctx, "Char"),
+        Context::parse(&ctx, "Char~EditTree"),
+        {
+            let ctx = ctx.clone();
+            move |rt, σ| {
+                {
+                    let mut b = rt.write().unwrap().singleton_buffer::<char>();
+                    if let Some(buf) = b {
+                        // buffer already exists
+                    } else {
+                        // create char buffer
+                        rt.write().unwrap().insert_leaf(
+                            vec![].into_iter(),
+                            ReprLeaf::from_singleton_buffer(SingletonBuffer::new('\0'))
+                        );
+                    }
+                }
+            
+                let char_buf = rt.singleton_buffer::<char>();
+                let mut edittree = CharEditor::new_edit_tree(
+                    ctx.clone(),
+                    char_buf,
+                    SingletonBuffer::<usize>::new(0).get_port()
+                );
+
+                rt.insert_leaf(
+                        Context::parse(&ctx, "EditTree"),
+                        ReprLeaf::from_singleton_buffer(
+                            SingletonBuffer::new(
+                                Arc::new(RwLock::new(edittree))
+                            )
+                        )
+                );
+
+                ctx.read().unwrap().setup_edittree(rt);
+            }
+        }
+    );
+
+    let char_morph_from_edittree = GenericReprTreeMorphism::new(
+        Context::parse(&ctx, "Char~EditTree"),
+        Context::parse(&ctx, "Char"),
+        {
+            let ctx = ctx.clone();
+            move |rt, σ|
+            {
+                let mut b = rt
+                   .descend(Context::parse(&ctx, "EditTree")).unwrap()
+                   .view_singleton::<Arc<RwLock<EditTree>>>();
+
+                rt.attach_leaf_to(
+                    Context::parse(&ctx, "Char"),
+                    b.map(|x|
+                        x.read().unwrap()
+                            .get_edit::<CharEditor>().unwrap()
+                            .read().unwrap()
+                            .get())
+                );
+            }
+        });
+    ctx.write().unwrap().morphisms.add_morphism( char_morph_to_edittree );
+    ctx.write().unwrap().morphisms.add_morphism( char_morph_from_edittree );
+}
+
+pub struct CharEditor {
+    ctx: Arc<RwLock<Context>>,
+    data: SingletonBuffer<char>
+}
+
+impl ObjCommander for CharEditor {
+    fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult {
+        let cmd_obj = cmd_obj.read().unwrap();
+        let cmd_type = cmd_obj.get_type().clone();
+
+        if cmd_type == Context::parse(&self.ctx, "Char") {
+            if let Some(cmd_view) = cmd_obj.get_view::<dyn SingletonView<Item = char>>() {
+                let value = cmd_view.get();
+
+                if self.ctx.read().unwrap().meta_chars.contains(&value) {
+                    TreeNavResult::Exit
+                } else {
+                    self.data.set(value);
+                    TreeNavResult::Continue
+                }
+            } else {
+                TreeNavResult::Exit
+            }
+        } else {
+            TreeNavResult::Exit
+        }
+    }
+}
+
+impl CharEditor {
+    pub fn new(ctx: Arc<RwLock<Context>>) -> Self {
+        CharEditor {
+            ctx,
+            data: SingletonBuffer::new('\0')
+        }
+    }
+
+    pub fn get_port(&self) -> OuterViewPort<dyn SingletonView<Item = char>> {
+        self.data.get_port()
+    }
+
+    pub fn get(&self) -> char {
+        self.get_port().get_view().unwrap().get()
+    }
+
+    pub fn new_edit_tree(
+        ctx0: Arc<RwLock<Context>>,
+        data: SingletonBuffer<char>,
+        depth: OuterViewPort<dyn SingletonView<Item = usize>>
+    ) -> EditTree {
+        //let data = SingletonBuffer::new('\0');
+        let ctx = ctx0.clone();
+        let editor = Arc::new(RwLock::new(CharEditor{ ctx, data: data.clone() }));
+
+        EditTree::new(
+            ctx0.clone(),
+            depth
+        )
+            .set_cmd( editor.clone() )
+            .set_editor( editor.clone() )
+    }
+}
+
diff --git a/lib-nested-core/src/editors/digit/cmd.rs b/lib-nested-core/src/editors/digit/cmd.rs
new file mode 100644
index 0000000..ae56f9f
--- /dev/null
+++ b/lib-nested-core/src/editors/digit/cmd.rs
@@ -0,0 +1,52 @@
+
+use {
+    r3vi::view::singleton::SingletonView,
+    crate::{
+        repr_tree::{ReprTree, Context},
+        edit_tree::{TreeNav, TreeNavResult},
+        editors::{ObjCommander, digit::DigitEditor}
+    },
+
+    std::sync::{Arc, RwLock}
+};
+
+impl ObjCommander for DigitEditor {
+    fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult {
+        let cmd_obj = cmd_obj.read().unwrap();
+        let cmd_type = cmd_obj.get_type().clone();
+
+        if cmd_type == Context::parse(&self.ctx, "Char") {
+            if let Some(cmd_view) = cmd_obj.get_view::<dyn SingletonView<Item = char>>() {
+                let c = cmd_view.get();
+
+                self.msg.clear();
+
+                if self.ctx.read().unwrap().meta_chars.contains(&c) {
+                    return TreeNavResult::Exit;
+
+                } else if c.to_digit(self.radix).is_none() {
+                    /* in case the character c is not in the range of digit-chars,
+                       add a message to the diagnostics view
+                     */
+/*
+                    let message = IndexBuffer::from_iter(vec![
+                        (Point2::new(1, 0), make_label("invalid digit '")),
+                        (Point2::new(2, 0), make_label(&format!("{}", c))
+                         .map_item(|_p,a| a.add_style_back(TerminalStyle::fg_color((140,140,250))))),
+                        (Point2::new(3, 0), make_label("'"))
+                    ]);
+
+                    self.msg.push(crate::diagnostics::make_error(message.get_port().flatten()));
+*/
+
+                    self.data.set(c);
+                } else {
+                    self.data.set(c);
+                }
+            }
+        }
+
+        TreeNavResult::Continue
+    }
+}
+
diff --git a/lib-nested-core/src/editors/digit/ctx.rs b/lib-nested-core/src/editors/digit/ctx.rs
new file mode 100644
index 0000000..f78b962
--- /dev/null
+++ b/lib-nested-core/src/editors/digit/ctx.rs
@@ -0,0 +1,205 @@
+
+use {
+    laddertypes::TypeTerm,
+    r3vi::{
+        buffer::singleton::SingletonBuffer,
+        view::{
+            AnyOuterViewPort,
+            singleton::*
+        }
+    },
+    crate::{
+        repr_tree::{Context, ReprTree, ReprTreeExt, ReprLeaf, GenericReprTreeMorphism},
+        editors::digit::DigitEditor,
+    },
+    std::sync::{Arc, RwLock}
+};
+
+pub fn init_ctx( ctx: Arc<RwLock<Context>> ) {
+    // todo: proper scoping of Radix variable
+    ctx.write().unwrap().add_varname("Radix");
+
+    let digit_make_edittree = GenericReprTreeMorphism::new(
+        Context::parse(&ctx, "<Digit Radix>"),
+        Context::parse(&ctx, "<Digit Radix>~EditTree"),
+        {
+                let ctx = ctx.clone();
+                move |src_rt, σ| {
+                    let radix =
+                        match σ.get( &laddertypes::TypeID::Var(ctx.read().unwrap().get_var_typeid("Radix").unwrap()) ) {
+                            Some(TypeTerm::Num(n)) => *n as u32,
+                            _ => 0
+                        };
+
+                    let char_buf = SingletonBuffer::<char>::new('?');
+
+                    /* Create EditTree object
+                     */
+                    let mut edittree = DigitEditor::new(
+                        ctx.clone(),
+                        radix,
+                        char_buf
+                    ).into_node(
+                        r3vi::buffer::singleton::SingletonBuffer::<usize>::new(0).get_port()
+                    );
+
+                    src_rt.write().unwrap()
+                        .insert_branch(
+                            ReprTree::from_singleton_buffer(
+                                Context::parse(&ctx, "EditTree"),
+                                SingletonBuffer::new(Arc::new(RwLock::new(edittree)))
+                            )
+                        );
+
+                    ctx.read().unwrap().setup_edittree( src_rt );
+                }
+        }
+    );
+
+    let digit_morph_char_to_edittree = GenericReprTreeMorphism::new(
+        Context::parse(&ctx, "<Digit Radix>~Char"),
+        Context::parse(&ctx, "<Digit Radix>~EditTree"),
+
+        {
+                let ctx = ctx.clone();
+                move |src_rt, σ| {
+                    let radix =
+                        match σ.get( &laddertypes::TypeID::Var(ctx.read().unwrap().get_var_typeid("Radix").unwrap()) ) {
+                            Some(TypeTerm::Num(n)) => *n as u32,
+                            _ => 0
+                        };
+
+                    /* Create EditTree object
+                     */
+                    let mut edittree = DigitEditor::new(
+                        ctx.clone(),
+                        radix,
+                        src_rt
+                            .descend( Context::parse(&ctx, "Char") ).unwrap()
+                            .singleton_buffer::<char>()
+                    ).into_node(
+                        r3vi::buffer::singleton::SingletonBuffer::<usize>::new(0).get_port()
+                    );
+
+                    src_rt.write().unwrap()
+                        .insert_branch(
+                            ReprTree::from_singleton_buffer(
+                                Context::parse(&ctx, "EditTree"),
+                                SingletonBuffer::new(Arc::new(RwLock::new(edittree)))
+                            )
+                        );
+
+                    ctx.read().unwrap().setup_edittree( src_rt );
+                }
+        }
+    );
+
+    let digit_morph_char_from_edittree = GenericReprTreeMorphism::new(
+        Context::parse(&ctx, "<Digit Radix>~EditTree"),
+        Context::parse(&ctx, "<Digit Radix>~Char"),
+
+        {
+            let ctx = ctx.clone();
+            move |src_rt, σ| {
+                let edittree = src_rt.edittree( &ctx );
+                let port =
+                        edittree
+                            .get()
+                            .read().unwrap()
+                            .get_edit::<DigitEditor>().unwrap()
+                            .read().unwrap()
+                            .get_char_port();
+
+                    src_rt.insert_leaf(
+                        Context::parse(&ctx, "Char"),
+                        ReprLeaf::from_view( port )
+                    )
+            }
+        }
+    );
+
+    let digit_morph_char_to_u64 = GenericReprTreeMorphism::new(
+        Context::parse(&ctx, "<Digit Radix>~Char"),
+        Context::parse(&ctx, "<Digit Radix>~ℤ_2^64~machine.UInt64"),
+
+        {
+            let ctx = ctx.clone();
+            move |rt: &mut Arc<RwLock<ReprTree>>, σ: &std::collections::HashMap<laddertypes::TypeID, TypeTerm>| {
+                    /* infer radix from type
+                     */
+                    let radix_typeid = ctx.read().unwrap().get_var_typeid("Radix").unwrap();
+                    let radix =
+                        match σ.get( &laddertypes::TypeID::Var(radix_typeid) ) {
+                            Some(TypeTerm::Num(n)) => (*n) as u32,
+                            x => {
+                                eprintln!("invalid radix {:?}", x);
+                                0
+                            }
+                        };
+
+                    if radix <= 16 {
+                        if let Some(src_rt) = rt.descend(Context::parse(&ctx, "Char")) {
+                            /* insert projected view into ReprTree
+                             */
+                            let u64_view = 
+                                    src_rt.view_char()
+                                        .map(move |c| c.to_digit(radix).unwrap_or(0) as u64);
+
+                            rt.write().unwrap().attach_leaf_to::<dyn SingletonView<Item = u64>>(
+                                Context::parse(&ctx, "ℤ_2^64~machine.UInt64").get_lnf_vec().into_iter(),
+                                u64_view
+                            );
+                        } else {
+                            eprintln!("could not find required source representation: <Digit {}>~Char", radix);
+                        }
+                    } else {
+                        eprintln!("radix too large ({})", radix);
+                    }
+            }
+        }
+    );
+
+
+    let digit_morph_u64_to_char = GenericReprTreeMorphism::new(
+        Context::parse(&ctx, "<Digit Radix>~ℤ_2^64~machine.UInt64"),
+        Context::parse(&ctx, "<Digit Radix>~Char"),
+        {
+            let ctx = ctx.clone();
+            move |rt: &mut Arc<RwLock<ReprTree>>, σ: &std::collections::HashMap<laddertypes::TypeID, TypeTerm>| {
+                /* infer radix from type
+                 */
+                let radix  =
+                    match σ.get( &laddertypes::TypeID::Var(ctx.read().unwrap().get_var_typeid("Radix").unwrap()) ) {
+                       Some(TypeTerm::Num(n)) => (*n) as u32,
+                        _ => 0
+                    };
+
+                if radix <= 16 {
+                    /* insert projected view into ReprTree
+                     */
+                    let char_view = 
+                        rt.descend(Context::parse(&ctx, "ℤ_2^64~machine.UInt64"))
+                            .unwrap()
+                            .view_u64()
+                            .map(move |digit| char::from_digit((digit%radix as u64) as u32, radix).unwrap_or('?'));
+
+                    rt.write().unwrap().attach_leaf_to::<dyn SingletonView<Item = char>>(
+                        Context::parse(&ctx, "Char").get_lnf_vec().into_iter(),
+                        char_view
+                    );
+                } else {
+                    eprintln!("radix too large ({})", radix);
+                }
+            }
+        }
+    );
+
+
+    ctx.write().unwrap().morphisms.add_morphism( digit_make_edittree );
+    ctx.write().unwrap().morphisms.add_morphism( digit_morph_char_to_edittree );
+    ctx.write().unwrap().morphisms.add_morphism( digit_morph_char_from_edittree );
+    ctx.write().unwrap().morphisms.add_morphism( digit_morph_char_to_u64 );
+    ctx.write().unwrap().morphisms.add_morphism( digit_morph_u64_to_char );
+}
+
+
diff --git a/lib-nested-core/src/editors/digit/editor.rs b/lib-nested-core/src/editors/digit/editor.rs
new file mode 100644
index 0000000..2f80d5d
--- /dev/null
+++ b/lib-nested-core/src/editors/digit/editor.rs
@@ -0,0 +1,98 @@
+
+use {
+    laddertypes::TypeTerm,
+    r3vi::{
+        view::{OuterViewPort,singleton::*},
+        buffer::{singleton::*, vec::*}
+    },
+    crate::{
+        repr_tree::{ReprTree, Context},
+        edit_tree::{
+            EditTree,
+            diagnostics::Message
+        }
+    },
+
+    std::sync::{Arc, RwLock}
+};
+
+
+pub struct DigitEditor {
+    pub(super) ctx: Arc<RwLock<Context>>,
+    pub(super) radix: u32,
+    pub(super) data: SingletonBuffer<char>,
+    pub(super) msg: VecBuffer<Message>,
+}
+
+
+impl DigitEditor {
+    pub fn new(ctx: Arc<RwLock<Context>>, radix: u32, data: SingletonBuffer<char>) -> Self {
+        DigitEditor {
+            ctx,
+            radix,
+            data,
+            msg: VecBuffer::new(),
+        }
+    }
+
+    pub fn into_node(self, depth: OuterViewPort<dyn SingletonView<Item = usize>>) -> EditTree { 
+      //  let data = self.get_data();        
+        let editor = Arc::new(RwLock::new(self));
+        let ed = editor.write().unwrap();
+        let r = ed.radix;
+
+        EditTree::new(ed.ctx.clone(), depth)
+            .set_editor(editor.clone())
+            .set_cmd(editor.clone())
+            .set_diag(
+                ed.msg.get_port().to_sequence()
+            )
+    }
+
+    pub fn attach_to(&mut self, source: OuterViewPort<dyn SingletonView<Item = u32>>) {
+        /*
+        source.add_observer(
+            Arc::new(NotifyFnObserver::new(|_msg| {
+                self.data.set( source.get() )
+            }))
+        );
+        */
+    }
+
+    pub fn get_char_port(&self) -> OuterViewPort<dyn SingletonView<Item = char>> {
+        self.data.get_port()
+    }
+
+    pub fn get_data_port(&self) -> OuterViewPort<dyn SingletonView<Item = Result<u32, char>>> {
+        let radix = self.radix;
+        self.data.get_port().map(move |c|
+            if let Some(d) = c.to_digit(radix) {
+                Ok(d)
+            } else {
+                Err(c)
+            }
+        )
+    }
+
+    pub fn get_type(&self) -> TypeTerm {
+        TypeTerm::TypeID(self.ctx.read().unwrap().get_typeid("Digit").unwrap())
+    }
+
+    pub fn get_char(&self) -> char {
+        self.data.get()
+    }
+
+/*
+    pub fn get_data(&self) -> Arc<RwLock<ReprTree>> {
+        ReprTree::ascend(
+            &ReprTree::from_view(
+                self.ctx.read().unwrap().type_term_from_str("<Seq u32>").unwrap(),
+                self.get_data_port()
+            ),
+            self.get_type()
+        )
+    }
+    */
+}
+
+
diff --git a/lib-nested-core/src/editors/digit/mod.rs b/lib-nested-core/src/editors/digit/mod.rs
new file mode 100644
index 0000000..980db26
--- /dev/null
+++ b/lib-nested-core/src/editors/digit/mod.rs
@@ -0,0 +1,8 @@
+
+pub mod ctx;
+pub mod cmd;
+pub mod editor;
+
+pub use editor::DigitEditor;
+pub use ctx::init_ctx;
+
diff --git a/nested/src/editors/integer/add.rs b/lib-nested-core/src/editors/integer/add.rs
similarity index 100%
rename from nested/src/editors/integer/add.rs
rename to lib-nested-core/src/editors/integer/add.rs
diff --git a/lib-nested-core/src/editors/integer/ctx.rs b/lib-nested-core/src/editors/integer/ctx.rs
new file mode 100644
index 0000000..1165543
--- /dev/null
+++ b/lib-nested-core/src/editors/integer/ctx.rs
@@ -0,0 +1,302 @@
+
+use {
+    r3vi::{
+        view::{OuterViewPort, singleton::*, list::*},
+        buffer::singleton::SingletonBuffer
+    },
+    laddertypes::{TypeTerm, MorphismType},
+    crate::{
+        repr_tree::{ReprTree, ReprTreeExt, ReprLeaf, Context, GenericReprTreeMorphism},
+        editors::{
+            list::*,
+            integer::*
+        },
+    },
+    std::sync::{Arc, RwLock}
+};
+
+pub fn init_ctx(ctx: Arc<RwLock<Context>>) {
+    // TODO: proper scoping
+    ctx.write().unwrap().add_varname("SrcRadix");
+    ctx.write().unwrap().add_varname("DstRadix");
+
+
+    let posint_seq_morph_big_to_little = GenericReprTreeMorphism::new(
+        Context::parse(&ctx, "ℕ ~ <PosInt Radix BigEndian>
+                ~ <Seq <Digit Radix> ~ ℤ_2^64 ~ machine.UInt64 >"),
+        Context::parse(&ctx, "ℕ ~ <PosInt Radix LittleEndian>
+                ~ <Seq <Digit Radix> ~ ℤ_2^64 ~ machine.UInt64 >"),
+        {
+            let ctx = ctx.clone();
+            move |src_rt, σ| {
+                let src_digits = src_rt
+                    .descend(Context::parse(&ctx, "
+                          <PosInt Radix BigEndian>
+                        ~ <Seq <Digit Radix> ~ ℤ_2^64 ~ machine.UInt64 >
+                        ")
+                        .apply_substitution(&|k|σ.get(k).cloned())
+                        .clone()
+                    ).expect("cant descend")
+                       .view_seq::< u64 >();
+
+                src_rt.attach_leaf_to(Context::parse(&ctx, "
+                          <PosInt Radix LittleEndian>
+                        ~ <Seq <Digit Radix> ~ ℤ_2^64 ~ machine.UInt64 >
+                    ").apply_substitution(&|k|σ.get(k).cloned()).clone(),
+                    src_digits.reverse()
+                );            
+            }
+        }
+    );
+
+    let posint_list_morph_big_to_little = GenericReprTreeMorphism::new(
+        Context::parse(&ctx, "ℕ ~ <PosInt Radix BigEndian>
+                ~ <Seq~List <Digit Radix> ~ ℤ_2^64 ~ machine.UInt64 >"),
+        Context::parse(&ctx, "ℕ ~ <PosInt Radix LittleEndian>
+                ~ <Seq~List <Digit Radix> ~ ℤ_2^64 ~ machine.UInt64 >"),
+        {
+            let ctx = ctx.clone();
+            move |src_rt, σ| {
+                let src_digits = src_rt
+                    .descend(Context::parse(&ctx, "
+                          <PosInt Radix BigEndian>
+                        ~ <Seq~List <Digit Radix> ~ ℤ_2^64 ~ machine.UInt64 >
+                        ")
+                        .apply_substitution(&|k|σ.get(k).cloned())
+                        .clone()
+                    ).expect("cant descend")
+                       .view_list::< u64 >();
+
+                src_rt.attach_leaf_to(Context::parse(&ctx, "
+                          <PosInt Radix LittleEndian>
+                        ~ <Seq~List <Digit Radix> ~ ℤ_2^64 ~ machine.UInt64 >
+                    ").apply_substitution(&|k|σ.get(k).cloned()).clone(),
+                    src_digits.reverse()
+                );            
+            }
+        }
+    );
+
+    let posint_list_morph_little_to_big = GenericReprTreeMorphism::new(
+        Context::parse(&ctx, "ℕ ~ <PosInt Radix LittleEndian>
+                ~ <Seq~List <Digit Radix> ~ ℤ_2^64 ~ machine.UInt64 >"),
+        Context::parse(&ctx, "ℕ ~ <PosInt Radix BigEndian>
+                ~ <Seq~List <Digit Radix> ~ ℤ_2^64 ~ machine.UInt64 >"),
+        {
+            let ctx = ctx.clone();
+            move |src_rt, σ| {
+                let src_digits = src_rt
+                    .descend(Context::parse(&ctx, "
+                          <PosInt Radix LittleEndian>
+                        ~ <Seq~List <Digit Radix> ~ ℤ_2^64 ~ machine.UInt64 >
+                        ")
+                        .apply_substitution(&|k|σ.get(k).cloned())
+                        .clone()
+                    ).expect("cant descend")
+                       .view_list::< u64 >();
+
+                src_rt.attach_leaf_to(Context::parse(&ctx, "
+                          <PosInt Radix BigEndian>
+                        ~ <Seq~List <Digit Radix> ~ ℤ_2^64 ~ machine.UInt64 >
+                    ").apply_substitution(&|k|σ.get(k).cloned()).clone(),
+                    src_digits.reverse()
+                );            
+            }
+        }
+    );
+
+
+    let posint_list_morph_radix = GenericReprTreeMorphism::new(
+        Context::parse(&ctx, "
+              ℕ
+            ~ <PosInt SrcRadix LittleEndian>
+            ~ <Seq   <Digit SrcRadix>>
+            ~ <List  <Digit SrcRadix>
+                   ~ ℤ_2^64
+                   ~ machine.UInt64>
+        "),
+        Context::parse(&ctx, "
+              ℕ
+            ~ <PosInt DstRadix LittleEndian>
+            ~ <Seq   <Digit DstRadix>>
+            ~ <List  <Digit DstRadix>
+                   ~ ℤ_2^64
+                   ~ machine.UInt64>
+        "),
+        {
+            let ctx = ctx.clone();
+            move |src_rt, σ| {
+                let src_radix = match σ.get(&laddertypes::TypeID::Var(
+                    ctx.read().unwrap().get_var_typeid("SrcRadix").unwrap()
+                )) {
+                    Some(laddertypes::TypeTerm::Num(n)) => *n as u64,
+                    _ => 0
+                };
+
+                let dst_radix = match σ.get(&laddertypes::TypeID::Var(
+                    ctx.read().unwrap().get_var_typeid("DstRadix").unwrap()
+                )) {
+                    Some(laddertypes::TypeTerm::Num(n)) => *n as u64,
+                    _ => 0
+                };
+
+                let src_digits_rt = src_rt.descend(Context::parse(&ctx, "
+                           <PosInt SrcRadix LittleEndian>
+                         ~ <Seq <Digit SrcRadix>>
+                         ~ <List <Digit SrcRadix>
+                                 ~ ℤ_2^64
+                                 ~ machine.UInt64 >
+                    ").apply_substitution(&|k|σ.get(k).cloned()).clone()
+                ).expect("cant descend repr tree");
+
+                let dst_digits_port =
+                    src_digits_rt.view_list::<u64>()
+                        .to_sequence()
+                        .to_positional_uint( src_radix )
+                        .transform_radix( dst_radix )
+                        .to_list();
+
+                src_rt.attach_leaf_to(
+                    Context::parse(&ctx, "
+                        <PosInt DstRadix LittleEndian>
+                        ~ <Seq <Digit DstRadix> >
+                        ~ <List <Digit DstRadix>
+                                ~ ℤ_2^64
+                                ~ machine.UInt64 >
+                    ").apply_substitution(&|k|σ.get(k).cloned()).clone(),
+                    dst_digits_port
+                );
+            }
+            
+        }
+    );
+
+    let posint_list_morph_from_u64 = GenericReprTreeMorphism::new(
+        Context::parse(&ctx, "ℕ ~ machine.UInt64"),
+        Context::parse(&ctx, "ℕ ~ <PosInt 0 LittleEndian> ~ <Seq~List <Digit 0>~ℤ_2^64~machine.UInt64>"),
+        {
+            let ctx = ctx.clone();
+            move |rt, σ| {
+                let digits = rt
+                    .descend(Context::parse(&ctx, "ℕ ~ machine.UInt64")).unwrap()
+                    .view_u64()
+                    .to_sequence()
+                    .to_list();
+
+                rt.attach_leaf_to(
+                    Context::parse(&ctx, "ℕ ~ <PosInt 0 LittleEndian> ~ <Seq~List <Digit 0>~ℤ_2^64~machine.UInt64>"),
+                    digits
+                );
+            }
+        }
+    );
+    let posint_list_morph_to_u64 = GenericReprTreeMorphism::new(
+        Context::parse(&ctx, "ℕ ~ <PosInt 0 LittleEndian> ~ <Seq~List <Digit 0>~ℤ_2^64~machine.UInt64> ~ <Vec machine.UInt64>"),
+        Context::parse(&ctx, "ℕ ~ machine.UInt64"),
+        {
+            let ctx = ctx.clone();
+            move |rt, σ| {
+                let u64_view = rt
+                    .descend(Context::parse(&ctx, "ℕ ~ <PosInt 0 LittleEndian> ~ <Seq~List <Digit 0>~ℤ_2^64~machine.UInt64> ~ <Vec machine.UInt64>")).unwrap()
+                    .get_port::< RwLock<Vec< u64 >> >().unwrap()
+                    .to_singleton()
+                    .map(|digits| {
+                        digits.get(0).cloned().unwrap_or(0)
+                    });
+
+                rt.attach_leaf_to(
+                    Context::parse(&ctx, "ℕ ~ machine.UInt64"),
+                    u64_view
+                );
+            }
+        }
+    );
+
+    let posint_make_edittree = GenericReprTreeMorphism::new(
+        Context::parse(&ctx, "ℕ ~ <PosInt Radix BigEndian> ~ <Seq~List <Digit Radix>> ~ EditTree"),
+        Context::parse(&ctx, "ℕ ~ <PosInt Radix BigEndian> ~ EditTree"),
+        {
+            let ctx = ctx.clone();
+            move |src_rt, σ| {
+                let mut list_edittree = src_rt.descend(
+                    Context::parse(&ctx, "ℕ ~ <PosInt Radix BigEndian> ~ <Seq~List <Digit Radix>>")
+                        .apply_substitution(&|x| σ.get(x).cloned()).clone()
+                    )
+                    .unwrap()
+                    .edittree( &ctx )
+                    .get().clone()
+                    .read().unwrap()
+                    .clone();
+
+                // clear display
+                list_edittree.disp.view = ReprTree::new_arc(Context::parse(&ctx, "Display"));
+
+                src_rt.insert_leaf(
+                    Context::parse(&ctx, "<PosInt Radix BigEndian> ~ EditTree")
+                           .apply_substitution(&|x| σ.get(x).cloned()).clone(),
+                    ReprLeaf::from_singleton_buffer(
+                        SingletonBuffer::new(
+                            Arc::new(RwLock::new(list_edittree))
+                        )
+                    )
+                );
+
+                ctx.read().unwrap().setup_edittree(
+                    &src_rt.descend(
+                        Context::parse(&ctx, "<PosInt Radix BigEndian>")
+                            .apply_substitution(&|x| σ.get(x).cloned()).clone()
+                    ).unwrap()
+                );
+            }
+        }
+    );
+
+    let posint_edittree_to_list = GenericReprTreeMorphism::new(
+        Context::parse(&ctx, "ℕ ~ <PosInt Radix BigEndian> ~ EditTree"),
+        Context::parse(&ctx, "ℕ ~ <PosInt Radix BigEndian> ~ <Seq~List <Digit Radix>> ~ EditTree"),
+        {
+            let ctx = ctx.clone();
+            move |src_rt, σ| {
+                let mut list_edittree = src_rt.descend(
+                    Context::parse(&ctx, "ℕ ~ <PosInt Radix BigEndian>")
+                        .apply_substitution(&|x| σ.get(x).cloned()).clone())
+                    .unwrap()
+                    .edittree( &ctx )
+                    .get().clone()
+                    .read().unwrap()
+                    .clone();
+
+                // clear display
+                list_edittree.disp.view = ReprTree::new_arc(Context::parse(&ctx, "Display"));
+
+                src_rt.insert_leaf(
+                    Context::parse(&ctx, "<PosInt Radix BigEndian> ~ <Seq~List <Digit Radix>>~EditTree")
+                           .apply_substitution(&|x| σ.get(x).cloned()).clone(),
+                    ReprLeaf::from_singleton_buffer(
+                        SingletonBuffer::new(
+                            Arc::new(RwLock::new(list_edittree))
+                        )
+                    )
+                );
+
+                ctx.read().unwrap().setup_edittree(
+                    &src_rt.descend(
+                        Context::parse(&ctx, "<PosInt Radix BigEndian> ~ <Seq~List <Digit Radix>>")
+                            .apply_substitution(&|x| σ.get(x).cloned()).clone()
+                    ).unwrap()
+                );
+            }
+        }
+    );
+
+    ctx.write().unwrap().morphisms.add_morphism( posint_make_edittree );
+    ctx.write().unwrap().morphisms.add_morphism( posint_edittree_to_list );
+
+    ctx.write().unwrap().morphisms.add_morphism( posint_seq_morph_big_to_little );
+    ctx.write().unwrap().morphisms.add_morphism( posint_list_morph_big_to_little );
+    ctx.write().unwrap().morphisms.add_morphism( posint_list_morph_little_to_big );    
+    ctx.write().unwrap().morphisms.add_morphism( posint_list_morph_radix );
+    ctx.write().unwrap().morphisms.add_morphism( posint_list_morph_from_u64 );
+    ctx.write().unwrap().morphisms.add_morphism( posint_list_morph_to_u64 );
+}
+
diff --git a/lib-nested-core/src/editors/integer/editor.rs b/lib-nested-core/src/editors/integer/editor.rs
new file mode 100644
index 0000000..4fdfe23
--- /dev/null
+++ b/lib-nested-core/src/editors/integer/editor.rs
@@ -0,0 +1,102 @@
+use {
+    r3vi::{
+        view::{
+            OuterViewPort,
+            singleton::*,
+        },
+        buffer::{
+            singleton::*,
+            vec::*,
+            index_hashmap::*
+        }
+    },
+    laddertypes::{TypeTerm},
+    crate::{
+        editors::{
+            digit::DigitEditor,
+            list::{ListCmd},
+            ObjCommander
+        },
+        repr_tree::{Context, ReprTree},
+        edit_tree::{EditTree, TreeNav, TreeNavResult, TreeCursor, diagnostics::{Message}},
+    },
+    std::sync::Arc,
+    std::sync::RwLock,
+    std::iter::FromIterator,
+    cgmath::{Point2}
+};
+
+pub struct PosIntEditor {
+    radix: u32,
+    digits: EditTree,
+
+    // todo: endianness
+}
+
+impl PosIntEditor {
+    pub fn new(ctx: Arc<RwLock<Context>>, radix: u32) -> Self {
+        PosIntEditor {
+            radix,
+            digits: EditTree::new(
+                ctx,
+                r3vi::buffer::singleton::SingletonBuffer::new(0).get_port()
+            )
+        }
+    }
+
+    pub fn from_u64(ctx: Arc<RwLock<Context>>, radix: u32, value: u64) -> Self {
+        let mut edit = PosIntEditor::new(ctx, radix);
+        edit.set_value_u64( value );
+        edit
+    }
+
+    pub fn set_value_u64(&mut self, mut value: u64) {
+        self.digits.send_cmd_obj(ListCmd::Clear.into_repr_tree(&self.digits.ctx));
+
+        while value > 0 {
+            let digit_val = (value % self.radix as u64) as u32;
+            value /= self.radix as u64;
+
+            // if BigEndian
+            self.digits.goto(TreeCursor::home());
+
+            self.digits.send_cmd_obj(ReprTree::from_char(&self.digits.ctx, char::from_digit(digit_val, self.radix).expect("invalid digit"))); 
+        }
+        self.digits.goto(TreeCursor::none());
+    }
+
+    pub fn into_node(self) -> EditTree {
+        self.digits
+    }
+
+/*
+    pub fn get_data_port(&self) -> OuterViewPort<dyn SequenceView<Item = u32>> {
+        let radix = self.radix;
+        self.digits
+            .get_data_port()
+            .filter_map(move |digit_editor| {
+                digit_editor.read().unwrap().data.get()?.to_digit(radix)
+            })
+    }
+
+    pub fn get_value(&self) -> u32 {
+        let mut value = 0;
+        let mut weight = 1;
+        for digit_value in self
+            .get_data_port()
+            .get_view()
+            .unwrap()
+            .iter()
+            .collect::<Vec<_>>()
+            .into_iter()
+            .rev()
+        {
+            value += digit_value * weight;
+            weight *= self.radix;
+        }
+
+        value
+}
+*/
+}
+
diff --git a/lib-nested-core/src/editors/integer/mod.rs b/lib-nested-core/src/editors/integer/mod.rs
new file mode 100644
index 0000000..c0d59d4
--- /dev/null
+++ b/lib-nested-core/src/editors/integer/mod.rs
@@ -0,0 +1,150 @@
+pub mod add;
+pub mod editor;
+pub mod radix;
+pub mod ctx;
+
+pub use {
+    add::Add,
+    editor::PosIntEditor,
+    radix::RadixProjection,
+    ctx::init_ctx
+};
+
+//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
+
+use {
+    r3vi::{
+        view::{
+            View, ViewPort, OuterViewPort,
+            Observer,
+            ObserverBroadcast,
+            sequence::*
+        }
+    },
+    crate::{
+        editors::integer::radix::{
+            PosIntProjections
+        }
+    },
+    std::sync::{Arc, RwLock}
+};
+
+pub trait PositionalUInt : SequenceView<Item = u64> {
+    fn get_radix(&self) -> u64;
+    fn get_value(&self) -> u64 {
+        let mut val = 0;
+        let mut r = 1;
+        for i in 0..self.len().unwrap_or(0) {
+            if let Some(digit_val) = self.get(&i) {
+                val += r * digit_val;
+                r *= self.get_radix();
+            }
+        }
+
+        val  
+    }
+}
+
+impl<V: PositionalUInt> PositionalUInt for RwLock<V> {
+    fn get_radix(&self) -> u64 {
+        self.read().unwrap().get_radix()
+    }
+}
+
+struct PosUIntFromDigits {
+    radix: u64,
+    src_digits: Option<Arc<dyn SequenceView<Item = u64>>>,
+    cast: Arc<RwLock<ObserverBroadcast<dyn PositionalUInt>>>
+}
+
+impl View for PosUIntFromDigits {
+    type Msg = usize;
+}
+
+impl SequenceView for PosUIntFromDigits {
+    type Item = u64;
+
+    fn get(&self, idx: &usize) -> Option<u64> {
+        self.src_digits.get(idx)
+    }
+
+    fn len(&self) -> Option<usize> {
+        self.src_digits.len()
+    }
+}
+
+impl PositionalUInt for PosUIntFromDigits {
+    fn get_radix(&self) -> u64 {
+        self.radix
+    }
+}
+
+impl Observer<dyn SequenceView<Item = u64>> for PosUIntFromDigits {
+    fn reset(&mut self, new_src: Option<Arc<dyn SequenceView<Item = u64>>>) {
+        self.src_digits = new_src;
+//        self.cast.write().unwrap().notify(0);
+    }
+
+    fn notify(&mut self, idx: &usize) {
+        self.cast.write().unwrap().notify(idx);
+    }
+}
+
+//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
+
+pub trait DigitSeqProjection {
+    fn to_positional_uint(&self, radix: u64) -> OuterViewPort<dyn PositionalUInt>;
+}
+
+impl DigitSeqProjection for OuterViewPort<dyn SequenceView<Item = u64>> {
+    fn to_positional_uint(&self, radix: u64) -> OuterViewPort<dyn PositionalUInt> {
+        let port = ViewPort::new();
+        port.add_update_hook(Arc::new(self.0.clone()));
+
+        let proj = Arc::new(RwLock::new(PosUIntFromDigits {
+            radix,
+            src_digits: None,
+            cast: port.inner().get_broadcast()
+        }));
+
+        self.add_observer(proj.clone());
+        port.set_view(Some(proj));
+        port.into_outer()
+    }
+}
+
+//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
+
+struct PosUIntToDigits {
+    src: Option<Arc<dyn PositionalUInt>>,
+    cast: Arc<RwLock<ObserverBroadcast<dyn SequenceView<Item = u64>>>>
+}
+
+impl View for PosUIntToDigits {
+    type Msg = usize;
+}
+
+impl SequenceView for PosUIntToDigits {
+    type Item = u64;
+
+    fn get(&self, idx: &usize) -> Option<u64> {
+        self.src.get(idx)
+    }
+
+    fn len(&self) -> Option<usize> {
+        self.src.len()
+    }
+}
+
+impl Observer<dyn PositionalUInt> for PosUIntToDigits {
+    fn reset(&mut self, view: Option<Arc<dyn PositionalUInt>>) {
+        self.src = view;
+//        self.cast.notify_all();
+    }
+
+    fn notify(&mut self, idx: &usize) {
+        self.cast.notify(idx);
+    }
+}
+
+
diff --git a/lib-nested-core/src/editors/integer/radix.rs b/lib-nested-core/src/editors/integer/radix.rs
new file mode 100644
index 0000000..685452b
--- /dev/null
+++ b/lib-nested-core/src/editors/integer/radix.rs
@@ -0,0 +1,152 @@
+use {
+    r3vi::{
+        view::{
+            View, ViewPort,
+            InnerViewPort, Observer, OuterViewPort,
+            ObserverBroadcast,
+            sequence::*,
+            list::*
+        },
+        buffer::{vec::*}
+    },
+    crate::{
+        editors::integer::{
+            PositionalUInt
+        },
+        repr_tree::{ReprTree, ReprLeaf}
+    },
+    std::sync::{Arc, RwLock},
+};
+
+//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
+
+pub trait PosIntProjections {
+    fn transform_radix(&self, dst_radix: u64) -> OuterViewPort<dyn SequenceView<Item = u64>>;
+//    fn to_digits(&self) -> OuterViewPort<dyn SequenceView<Item = usize>>;
+}
+
+impl PosIntProjections for OuterViewPort<dyn PositionalUInt> {
+    fn transform_radix(&self, dst_radix: u64) -> OuterViewPort<dyn SequenceView<Item = u64>> {
+        let port = ViewPort::<dyn SequenceView<Item = u64>>::new();
+        port.add_update_hook(Arc::new(self.0.clone()));
+
+//        let mut vec_port = ViewPort::new();
+        let proj = Arc::new(RwLock::new(RadixProjection {
+            src: None,
+            dst_radix,
+            dst_digits: VecBuffer::new(),
+            cast: port.inner().get_broadcast()
+        }));
+
+        self.add_observer(proj.clone());
+        port.set_view(Some(proj as Arc<dyn SequenceView<Item = u64>>));
+        port.into_outer()
+    }
+/*
+    fn to_digits(&self) -> OuterViewPort<dyn SequenceView<Item = usize>> {
+        let port = ViewPort::new();
+        port.add_update_hook(Arc::new(self.0.clone()));
+        let proj = Arc::new(RwLock::new(PosUIntToDigits {
+            src: None,
+            cast: port.inner().get_broadcast()
+        }));
+        self.add_observer(proj.clone());
+        port.inner().set_view(Some(proj));
+        port.into_outer()
+    }
+    */
+}
+
+//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
+
+pub struct RadixProjection {
+    src: Option<Arc<dyn PositionalUInt>>,
+    dst_radix: u64,
+    dst_digits: VecBuffer<u64>,
+    cast: Arc<RwLock<ObserverBroadcast<dyn SequenceView<Item = u64>>>>
+}
+
+impl View for RadixProjection {
+    type Msg = usize;
+}
+
+impl SequenceView for RadixProjection {
+    type Item = u64;
+
+    fn get(&self, idx: &usize) -> Option<u64> {
+        if *idx < self.dst_digits.len() {
+            Some(self.dst_digits.get(*idx))
+        } else {
+            None
+        }
+    }
+
+    fn len(&self) -> Option<usize> {
+        Some(self.dst_digits.len())
+    }
+}
+
+impl PositionalUInt for RadixProjection {
+    fn get_radix(&self) -> u64 {
+        self.dst_radix
+    }
+}
+
+impl Observer< dyn PositionalUInt > for RadixProjection {
+    fn reset(&mut self, view: Option<Arc<dyn PositionalUInt>>) {
+        self.src = view;
+        self.update();
+    }
+
+    fn notify(&mut self, idx: &usize) {
+        self.update();
+        // self.update_digit(idx)
+    }
+}
+
+impl RadixProjection {
+    /// recalculate everything
+    fn update(&mut self) {
+//       let mut dst = self.dst_digits;
+        let old_len = self.dst_digits.len();
+        self.dst_digits.clear();
+
+        if let Some(src) = self.src.as_ref() {
+            let mut val = src.get_value();
+            if val == 0 {
+                self.dst_digits.push(0);
+            } else {
+                if self.dst_radix == 0 {
+                    self.dst_digits.push(val);
+                } else {            
+                    while val > 0 {
+                        self.dst_digits.push(val % self.dst_radix);
+                        val /= self.dst_radix;
+                    }
+                }
+            }
+        }
+
+        let new_len = self.dst_digits.len();
+        for i in 0 .. usize::max(old_len, new_len) {
+             self.cast.write().unwrap().notify(&i);
+        }
+    }
+
+    fn _update_dst_digit(&mut self, _idx: usize) {
+        /*
+                let v = 0; // calculate new digit value
+
+                // which src-digits are responsible?
+
+                if idx < self.dst_digits.len() {
+                    self.dst_digits.get_mut(idx) = v;
+                } else if idx == self.dst_digits.len() {
+                    self.dst_digits.push(v);
+                } else {
+                    // error
+                }
+        */
+    }
+}
+
diff --git a/nested/src/editors/list/cmd.rs b/lib-nested-core/src/editors/list/cmd.rs
similarity index 89%
rename from nested/src/editors/list/cmd.rs
rename to lib-nested-core/src/editors/list/cmd.rs
index 74c7fee..bbdd19c 100644
--- a/nested/src/editors/list/cmd.rs
+++ b/lib-nested-core/src/editors/list/cmd.rs
@@ -3,10 +3,9 @@ use {
         view::{singleton::*}
     },
     crate::{
-        editors::list::{ListEditor, ListCursor, ListCursorMode},
-        type_system::{Context, ReprTree},
-        tree::{NestedNode, TreeNav, TreeNavResult, TreeCursor},
-        commander::{ObjCommander}
+        editors::{list::{ListEditor, ListCursor, ListCursorMode}, ObjCommander},
+        repr_tree::{Context, ReprTree},
+        edit_tree::{EditTree, TreeNav, TreeNavResult, TreeCursor},
     },
     std::sync::{Arc, RwLock}
 };
@@ -23,11 +22,11 @@ pub enum ListCmd {
 }
 
 impl ListCmd {
+    // note: cant use Into becaue of ctx (maybe global typedict?)
     pub fn into_repr_tree(self, ctx: &Arc<RwLock<Context>>) -> Arc<RwLock<ReprTree>> {
-        let buf = r3vi::buffer::singleton::SingletonBuffer::new(self);
-        ReprTree::new_leaf(
-            Context::parse(ctx, "ListCmd"),
-            buf.get_port().into()
+        ReprTree::from_singleton_buffer(
+            Context::parse(ctx, "ListCmd"),            
+            r3vi::buffer::singleton::SingletonBuffer::new(self)
         )
     }
 }
@@ -36,7 +35,7 @@ impl ObjCommander for ListEditor {
     fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult {
         let cmd_repr = cmd_obj.read().unwrap();
 
-        if let Some(view) = cmd_repr.get_view::<dyn SingletonView<Item = NestedNode>>() {
+        if let Some(view) = cmd_repr.get_view::<dyn SingletonView<Item = EditTree>>() {
             let node = view.get();
             let cur = self.cursor.get();
 
@@ -58,7 +57,6 @@ impl ObjCommander for ListEditor {
         }
 
         else if let Some(cmd) = cmd_repr.get_view::<dyn SingletonView<Item = ListCmd>>() {
-            eprintln!("pty-list-editor some list cmmd");
 
             let cur = self.cursor.get();
             drop(cmd_repr);
@@ -77,7 +75,6 @@ impl ObjCommander for ListEditor {
                                     
                                     match cmd.get() {
                                         ListCmd::DeletePxev => {
-                                            eprintln!("SELECT: delete pxev");
                                             if idx > 0
                                                 && item_cur.tree_addr.iter().fold(
                                                     true,
@@ -119,7 +116,6 @@ impl ObjCommander for ListEditor {
                                         }
                                     }
                                 } else {
-                                    eprintln!("ptylist: no item");
                                     TreeNavResult::Exit
                                 }
                             },
@@ -127,7 +123,6 @@ impl ObjCommander for ListEditor {
                             ListCursorMode::Insert => {
                                 match cmd.get() {
                                     ListCmd::DeletePxev => {
-                                        eprintln!("INSERT: delete pxev");
                                         self.delete_pxev();
                                         TreeNavResult::Continue
                                     }
@@ -150,7 +145,6 @@ impl ObjCommander for ListEditor {
                             }
                         }
                     } else {
-                        eprintln!("ptylist: cursor has no idx");
                         TreeNavResult::Exit
                     }
                 }
diff --git a/lib-nested-core/src/editors/list/ctx.rs b/lib-nested-core/src/editors/list/ctx.rs
new file mode 100644
index 0000000..0d38e7a
--- /dev/null
+++ b/lib-nested-core/src/editors/list/ctx.rs
@@ -0,0 +1,135 @@
+use {
+    r3vi::{
+        view::{
+            ViewPort, port::UpdateTask,
+            OuterViewPort, Observer,
+            singleton::*,
+            list::*
+        },
+        buffer::{singleton::*, vec::*}
+    },
+    laddertypes::{TypeTerm},
+    crate::{
+        repr_tree::{Context, ReprTree, ReprLeaf, ReprTreeExt, GenericReprTreeMorphism},
+        edit_tree::{EditTree},
+        editors::{
+            char::{CharEditor},
+            list::{ListEditor}
+        }
+    },
+    std::sync::{Arc, RwLock}
+};
+
+//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
+
+pub fn init_ctx(ctx: Arc<RwLock<Context>>) {
+    ctx.write().unwrap().add_varname("Item");
+
+    let list_morph_editsetup1 = GenericReprTreeMorphism::new(
+        Context::parse(&ctx, "<List Item>~<List EditTree>~<Vec EditTree>"),
+        Context::parse(&ctx, "<List Item>~EditTree"),
+        {
+            let ctx = ctx.clone();
+            move |src_rt, σ| {
+                let item_id = laddertypes::TypeID::Var( ctx.read().unwrap().get_var_typeid("Item").unwrap() );
+                if let Some( item_type ) = σ.get( &item_id ) {
+                    let mut item_vec_rt = src_rt
+                        .descend(
+                            Context::parse(&ctx, "<List Item~EditTree>~<Vec EditTree>")
+                                .apply_substitution(&|id| σ.get(id).cloned()).clone()
+                        )
+                        .expect("cant descend src repr");
+
+                    let item_vec_buffer = item_vec_rt.vec_buffer::< Arc<RwLock<EditTree>> >();
+
+                    let mut list_editor = ListEditor::with_data(ctx.clone(), item_type.clone(), item_vec_buffer);
+                    let edittree_list = list_editor.into_node(
+                        SingletonBuffer::<usize>::new(0).get_port()
+                    );
+                    src_rt.insert_leaf(
+                        Context::parse(&ctx, "<List Item> ~ EditTree")
+                            .apply_substitution(&|id| σ.get(id).cloned()).clone(),
+
+                        ReprLeaf::from_singleton_buffer(
+                            SingletonBuffer::new(Arc::new(RwLock::new(edittree_list)))
+                        )
+                    );
+
+                    ctx.read().unwrap().setup_edittree( &src_rt );
+                } else {
+                    eprintln!("no item type");
+                }
+            }
+        }
+    );
+
+    let list_morph_editsetup3 = GenericReprTreeMorphism::new(
+        Context::parse(&ctx, "<List Item> ~ EditTree"),
+        Context::parse(&ctx, "<List Item> ~ <List EditTree>"),
+        {
+            let ctx = ctx.clone();
+            move |src_rt, σ| {
+                let edittree = src_rt.edittree( &ctx );
+                let list_edit = edittree.get().read().unwrap().get_edit::< ListEditor >().unwrap();
+                let edittree_items = list_edit.read().unwrap().data.get_port().to_list();
+
+                eprintln!("edittree_items.len() = {:?}", edittree_items.get_view().unwrap().len());
+
+                src_rt.attach_leaf_to(
+                    Context::parse(&ctx, "<List Item> ~ <List EditTree>")
+                        .apply_substitution(&|x| σ.get(x).cloned()).clone(),
+                    edittree_items
+                );
+            }
+        }
+    );
+
+    let list_morph_to_vec_char = GenericReprTreeMorphism::new(
+        Context::parse(&ctx, "<List Char>"),
+        Context::parse(&ctx, "<List Char>~<Vec Char>"),
+        {
+            let ctx = ctx.clone();
+            move |src_rt, σ| {
+                src_rt.attach_leaf_to(
+                    Context::parse(&ctx, "<Vec Char>"),
+                    src_rt.view_list::<char>()
+                );
+            }
+        }
+    );
+
+    let list_morph_from_vec_char = GenericReprTreeMorphism::new(
+        Context::parse(&ctx, "<List Char>~<Vec Char>"),
+        Context::parse(&ctx, "<List Char>"),
+        {
+            let ctx = ctx.clone();
+            move |src_rt, σ| {
+                let src_port = src_rt.descend(Context::parse(&ctx, "<List Char>~<Vec Char>")).expect("descend")
+                    .get_port::<RwLock<Vec<char>>>().unwrap();
+
+                src_rt.attach_leaf_to( Context::parse(&ctx, "<List Char>"), src_port.to_list() );
+            }
+        }
+    );
+
+
+    let list_morph_to_vec_edittree = GenericReprTreeMorphism::new(
+        Context::parse(&ctx, "<List EditTree>"),
+        Context::parse(&ctx, "<List EditTree> ~ <Vec EditTree>"),
+
+        {
+            let ctx = ctx.clone();
+            move |src_rt, σ| {
+                let list_port = src_rt.get_port::<dyn ListView< Arc<RwLock<EditTree>> >>().unwrap();
+                src_rt.attach_leaf_to( Context::parse(&ctx, "<Vec EditTree>"), list_port );
+            }
+        }
+    );
+
+    ctx.write().unwrap().morphisms.add_morphism( list_morph_editsetup1 );
+    ctx.write().unwrap().morphisms.add_morphism( list_morph_editsetup3 );
+    ctx.write().unwrap().morphisms.add_morphism( list_morph_from_vec_char );
+    ctx.write().unwrap().morphisms.add_morphism( list_morph_to_vec_char );
+    ctx.write().unwrap().morphisms.add_morphism( list_morph_to_vec_edittree );
+}
+
diff --git a/nested/src/editors/list/cursor.rs b/lib-nested-core/src/editors/list/cursor.rs
similarity index 100%
rename from nested/src/editors/list/cursor.rs
rename to lib-nested-core/src/editors/list/cursor.rs
diff --git a/nested/src/editors/list/editor.rs b/lib-nested-core/src/editors/list/editor.rs
similarity index 80%
rename from nested/src/editors/list/editor.rs
rename to lib-nested-core/src/editors/list/editor.rs
index 31c1f1b..6773891 100644
--- a/nested/src/editors/list/editor.rs
+++ b/lib-nested-core/src/editors/list/editor.rs
@@ -1,15 +1,14 @@
 use {
     r3vi::{
-        view::{ViewPort, OuterViewPort, singleton::*, sequence::*},
-        buffer::{singleton::*, vec::*}
+        view::{OuterViewPort, singleton::*, sequence::*},
+        buffer::{singleton::*, vec::*},
+        projection::*
     },
     laddertypes::{TypeTerm},
     crate::{
-        type_system::{Context, ReprTree},
-        editors::list::{ListCursor, ListCursorMode, ListCmd},
-        tree::{NestedNode, TreeNav, TreeCursor},
-        diagnostics::Diagnostics,
-        commander::ObjCommander
+        repr_tree::{Context, ReprTree},
+        edit_tree::{EditTree, TreeNav, TreeCursor, diagnostics::Diagnostics},
+        editors::{list::{ListCursor, ListCursorMode, ListCmd}, ObjCommander},
     },
     std::sync::{Arc, RwLock}
 };
@@ -17,31 +16,42 @@ use {
 //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
 
 pub struct ListEditor {
-    pub(super) cursor: SingletonBuffer<ListCursor>,
+    pub cursor: SingletonBuffer<ListCursor>,
 
     // todo: (?) remove RwLock<..> around NestedNode ??
-    pub data: VecBuffer< Arc<RwLock<NestedNode>> >,
+    pub data: VecBuffer< Arc<RwLock<EditTree>> >,
 
-    pub spillbuf: Arc<RwLock<Vec<Arc<RwLock<NestedNode>>>>>,
+    pub spillbuf: Arc<RwLock<Vec<Arc<RwLock<EditTree>>>>>,
 
     pub(super) addr_port: OuterViewPort<dyn SequenceView<Item = isize>>,
     pub(super) mode_port: OuterViewPort<dyn SingletonView<Item = ListCursorMode>>,
 
     depth: OuterViewPort<dyn SingletonView<Item = usize>>,
 
-    pub(crate) ctx: Arc<RwLock<Context>>,
+    pub ctx: Arc<RwLock<Context>>,
 
     /// item type
-    pub(super) typ: TypeTerm,
+    pub typ: TypeTerm,
 }
 
 impl ListEditor {
     pub fn new(
+       ctx: Arc<RwLock<Context>>,
+       typ: TypeTerm 
+    ) -> Self {
+        Self::with_data(
+            ctx,
+            typ,
+            VecBuffer::new()
+        )
+    }
+
+    pub fn with_data(
         ctx: Arc<RwLock<Context>>,
         typ: TypeTerm,
+        data: VecBuffer<Arc<RwLock<EditTree>>>
     ) -> Self {
         let cursor = SingletonBuffer::new(ListCursor::default());
-        let data : VecBuffer<Arc<RwLock<NestedNode>>> = VecBuffer::new();
 
         ListEditor {
             mode_port: cursor
@@ -57,7 +67,6 @@ impl ListEditor {
                                     if idx >= 0 && idx < data.len() as isize {
                                         data.get(idx as usize).read().unwrap().get_mode_view()
                                     } else {
-                                        eprintln!("ListEditor::mode_port invalid cursor idx");
                                         ip
                                     }
                                 } else {
@@ -103,8 +112,7 @@ impl ListEditor {
         }
     }
 
-    pub fn into_node(mut self, depth: OuterViewPort<dyn SingletonView<Item = usize>>) -> NestedNode {
-        let data = self.get_data();
+    pub fn into_node(mut self, depth: OuterViewPort<dyn SingletonView<Item = usize>>) -> EditTree {
         let ctx = self.ctx.clone();
 
         self.depth = depth.clone();
@@ -112,31 +120,24 @@ impl ListEditor {
 
         let e = editor.read().unwrap();
 
-        let mut node = NestedNode::new(ctx, data, depth)
+        let mut node = EditTree::new(ctx, depth)
             .set_editor(editor.clone())
             .set_nav(editor.clone())
             .set_cmd(editor.clone())
-            .set_diag(e
-                      .get_data_port()
+            .set_diag(e.get_data_port()
                       .enumerate()
-                      .map(
-                          |(idx, item_editor)| {
-                              let idx = *idx;
-                              item_editor
-                                  .get_msg_port()
-                                  .map(
-                                      move |msg| {
-                                          let mut msg = msg.clone();
-                                          msg.addr.insert(0, idx);
-                                          msg
-                                      }
-                                  )
-                          }
-                      )
-                      .flatten()
-            );
+                      .map(|(idx, item_editor)| {
+                          let idx = *idx;
+                          item_editor.get_msg_port()
+                              .map(move |msg| {
+                                  let mut msg = msg.clone();
+                                  msg.addr.insert(0, idx);
+                                  msg
+                              })
+                          })
+                      .flatten());
 
-        node.spillbuf = e.spillbuf.clone();
+        node.ctrl.spillbuf = e.spillbuf.clone();
         node
     }
 
@@ -155,12 +156,12 @@ impl ListEditor {
         self.cursor.get_port()
     }
 
-    pub fn get_data_port(&self) -> OuterViewPort<dyn SequenceView<Item = NestedNode>> {
-        self.data.get_port().to_sequence().map(
+    pub fn get_data_port(&self) -> OuterViewPort<dyn SequenceView<Item = EditTree>> {
+        self.data.get_port().to_list().map(
             |x| x.read().unwrap().clone()
-        )
+        ).to_sequence()
     }
-
+/*
     pub fn get_data(&self) -> Arc<RwLock<ReprTree>> {
         let data_view = self.get_data_port();
         ReprTree::new_leaf(
@@ -168,8 +169,8 @@ impl ListEditor {
             data_view.into()
         )
     }
-
-    pub fn get_item(&self) -> Option<NestedNode> {
+*/
+    pub fn get_item(&self) -> Option<EditTree> {
         if let Some(idx) = self.cursor.get().idx {
             let idx = crate::utils::modulo(idx as isize, self.data.len() as isize) as usize;
             if idx < self.data.len() {
@@ -182,7 +183,7 @@ impl ListEditor {
         }
     }
 
-    pub fn get_item_mut(&mut self) -> Option<MutableVecAccess<Arc<RwLock<NestedNode>>>> {
+    pub fn get_item_mut(&mut self) -> Option<MutableVecAccess<Arc<RwLock<EditTree>>>> {
         if let Some(idx) = self.cursor.get().idx {
             let idx = crate::utils::modulo(idx as isize, self.data.len() as isize) as usize;
             if idx < self.data.len() {
@@ -233,10 +234,8 @@ impl ListEditor {
     }
 
     /// insert a new element
-    pub fn insert(&mut self, item: Arc<RwLock<NestedNode>>) {
-        eprintln!("list insert");
-
-        item.read().unwrap().depth.0.set_view(
+    pub fn insert(&mut self, item: Arc<RwLock<EditTree>>) {
+        item.read().unwrap().disp.depth.0.set_view(
             self.depth.map(|d| d+1).get_view()
         );
 
@@ -248,7 +247,6 @@ impl ListEditor {
                     if self.is_listlist() {
                         cur.mode = ListCursorMode::Select;
                     } else {
-                        eprintln!("list insert: is not a listlist ({:?})", self.typ);
                         item.write().unwrap().goto(TreeCursor::none());
                         cur.idx = Some(idx + 1);
                     }
@@ -264,13 +262,11 @@ impl ListEditor {
 
             self.cursor.set(cur);
         } else {
-            //eprintln!("insert: no cursor");
         }
     }
 
     /// split the list off at the current cursor position and return the second half
     pub fn split(&mut self) {
-        eprintln!("split");
         let cur = self.cursor.get();
         if let Some(idx) = cur.idx {
             let idx = idx as usize;
@@ -305,7 +301,6 @@ impl ListEditor {
     }
 
     pub fn listlist_split(&mut self) {
-        eprintln!("listlist split");
         let cur = self.get_cursor();
 
         if let Some(mut item) = self.get_item().clone() {
@@ -317,22 +312,29 @@ impl ListEditor {
                 self.set_leaf_mode(ListCursorMode::Insert);
                 self.nexd();
 
-                let mut b = item.spillbuf.write().unwrap();
-                let mut tail_node = Context::make_node(&self.ctx, self.typ.clone(), self.depth.map(|d| d+1)).unwrap();
+                let mut b = item.ctrl.spillbuf.write().unwrap();
+
+                let rt = ReprTree::new_arc(self.typ.clone());
+                let mut et = self.ctx.read().unwrap().setup_edittree(&rt);
+
+                if let Some(edittree) = et.as_mut(){
+
+                let mut tail_node = edittree.get();
+                let mut tail_node = tail_node.write().unwrap();
                 tail_node.goto(TreeCursor::home());
 
                 for node in b.iter() {
-                    eprintln!("splid :send to tail node");
                     tail_node
                         .send_cmd_obj(
-                            ReprTree::new_leaf(
-                                Context::parse(&self.ctx, "NestedNode"),
-                                SingletonBuffer::<NestedNode>::new(
+                            ReprTree::from_singleton_buffer(
+                                Context::parse(&self.ctx, "EditTree"),
+                                SingletonBuffer::<EditTree>::new(
                                     node.read().unwrap().clone()
-                                ).get_port().into()
+                                )
                             )
                         );
                 }
+
                 b.clear();
                 drop(b);
                 drop(item);
@@ -341,11 +343,14 @@ impl ListEditor {
                 if cur.tree_addr.len() > 1 {
                     tail_node.dn();
                 }
+                drop(tail_node);
 
                 self.insert(
-                    Arc::new(RwLock::new(tail_node))
+                    edittree.value.read().unwrap().clone()
                 );
 
+                }
+
             } else {
                 self.up();
                 self.listlist_split();
@@ -376,14 +381,14 @@ impl ListEditor {
 
             let old_cur = pxv_editor.get_cursor();
 
-            let data = cur_editor.spillbuf.read().unwrap();
+            let data = cur_editor.ctrl.spillbuf.read().unwrap();
             for x in data.iter() {
                 pxv_editor.send_cmd_obj(
-                    ReprTree::new_leaf(
-                        Context::parse(&self.ctx, "NestedNode"),
-                        SingletonBuffer::<NestedNode>::new(
+                    ReprTree::from_singleton_buffer(
+                        Context::parse(&self.ctx, "EditTree"),
+                        SingletonBuffer::<EditTree>::new(
                             x.read().unwrap().clone()
-                        ).get_port().into()
+                        )
                     )
                 );
             }
@@ -434,15 +439,15 @@ impl ListEditor {
                 leaf_mode: ListCursorMode::Insert
             });
  
-            let data = nxd_editor.spillbuf.read().unwrap();
+            let data = nxd_editor.ctrl.spillbuf.read().unwrap();
 
             for x in data.iter() {
                 cur_editor.send_cmd_obj(
-                    ReprTree::new_leaf(
-                        Context::parse(&self.ctx, "NestedNode"),
-                        SingletonBuffer::<NestedNode>::new(
+                    ReprTree::from_singleton_buffer(
+                        Context::parse(&self.ctx, "EditTree"),
+                        SingletonBuffer::<EditTree>::new(
                             x.read().unwrap().clone()
-                        ).get_port().into()
+                        )
                     )
                 );
             }
diff --git a/nested/src/editors/list/mod.rs b/lib-nested-core/src/editors/list/mod.rs
similarity index 77%
rename from nested/src/editors/list/mod.rs
rename to lib-nested-core/src/editors/list/mod.rs
index c929369..b788aae 100644
--- a/nested/src/editors/list/mod.rs
+++ b/lib-nested-core/src/editors/list/mod.rs
@@ -1,10 +1,8 @@
 
-
 pub mod cursor;
 pub mod editor;
 pub mod nav;
 pub mod segment;
-pub mod pty_editor;
 pub mod cmd;
 pub mod ctx;
 
@@ -12,7 +10,6 @@ pub use {
     cursor::{ListCursor, ListCursorMode},
     editor::ListEditor,
     segment::{ListSegment, ListSegmentSequence},
-    pty_editor::{PTYListStyle, PTYListController},
     cmd::ListCmd,
     ctx::init_ctx
 };
diff --git a/nested/src/editors/list/nav.rs b/lib-nested-core/src/editors/list/nav.rs
similarity index 96%
rename from nested/src/editors/list/nav.rs
rename to lib-nested-core/src/editors/list/nav.rs
index 31d0cc2..b92cc8f 100644
--- a/nested/src/editors/list/nav.rs
+++ b/lib-nested-core/src/editors/list/nav.rs
@@ -11,7 +11,7 @@ use {
             ListCursor, ListCursorMode,
             editor::ListEditor
         },
-        tree::{TreeCursor, TreeNav, TreeNavResult, TreeHeightOp}
+        edit_tree::{TreeCursor, TreeNav, TreeNavResult, TreeHeightOp}
     },
     cgmath::Vector2
 };
@@ -195,7 +195,6 @@ impl TreeNav for ListEditor {
                     TreeNavResult::Exit
                 } else if direction.y > 0 {
                     // dn
-                    eprintln!("dn: data.len() = {}", self.data.len());
                     self.cursor.set(ListCursor {
                         mode: if self.data.len() > 0 { cur.leaf_mode } else { ListCursorMode::Insert },
                         idx: Some(0)
@@ -367,7 +366,6 @@ impl TreeNav for ListEditor {
                                                 depth as isize - 1
                                             };
 
-                                        eprintln!("<- LEFT CROSS: pxv_height = {}, cur_height = {}, dist_from_ground = {}, n_steps_down = {}", pxv_height, cur_height, dist_from_ground, n_steps_down);
                                         new_addr.push( cur.tree_addr[0] - 1 );
                                         for _i in 0..n_steps_down {
                                             new_addr.push( -1 );
@@ -387,7 +385,6 @@ impl TreeNav for ListEditor {
                                                 depth as isize - 1
                                             };
 
-                                        eprintln!("-> RIGHT CROSS: cur_height = {}, nxd_height = {}, dist_from_ground = {}, n_steps_down = {}", cur_height, nxd_height, dist_from_ground, n_steps_down);
                                         new_addr.push( cur.tree_addr[0] + 1 );
                                         for _i in 0..n_steps_down {
                                             new_addr.push( 0 );
@@ -396,7 +393,6 @@ impl TreeNav for ListEditor {
 
                                     drop(cur_item);
 
-                                    eprintln!("CROSS: goto {:?}", new_addr);
                                     cur.tree_addr = new_addr;
                                     self.goto(cur)
                                 } else {
diff --git a/nested/src/editors/list/segment.rs b/lib-nested-core/src/editors/list/segment.rs
similarity index 70%
rename from nested/src/editors/list/segment.rs
rename to lib-nested-core/src/editors/list/segment.rs
index 4ae0368..4cd495b 100644
--- a/nested/src/editors/list/segment.rs
+++ b/lib-nested-core/src/editors/list/segment.rs
@@ -9,10 +9,7 @@ use {
     },
     crate::{
         editors::list::{ListCursor, ListCursorMode},
-        terminal::{TerminalView, TerminalStyle, make_label},
-        tree::{NestedNode, TreeNav},
-        utils::color::{bg_style_from_depth, fg_style_from_depth},
-        PtySegment
+        edit_tree::{EditTree}
     },
     std::sync::Arc,
     std::sync::RwLock,
@@ -21,46 +18,13 @@ use {
 pub enum ListSegment {
     InsertCursor,
     Item {
-        editor: NestedNode,
+        editor: EditTree,
         cur_dist: isize,
     }
 }
 
-impl PtySegment for ListSegment {
-    fn pty_view(&self) -> OuterViewPort<dyn TerminalView> {
-        match self {
-            ListSegment::InsertCursor => {
-                make_label("|")
-                    .map_item(move |_pt, atom| {
-                     atom.add_style_front(TerminalStyle::fg_color((150,80,230)))
-                        .add_style_front(TerminalStyle::bold(true))
-                    })
-            }
-            ListSegment::Item{ editor, cur_dist } => {
-                let e = editor.clone();
-                let cur_dist = *cur_dist;
-                editor.get_view().map_item(move |_pt, atom| {
-                    let c = e.get_cursor();
-                    let cur_depth = c.tree_addr.len();
-                    let select =
-                        if cur_dist == 0 {
-                            cur_depth
-                        } else {
-                            usize::MAX
-                        };
-                    
-                    atom
-                        .add_style_back(bg_style_from_depth(select))
-                        .add_style_back(TerminalStyle::bold(select==1))
-                        .add_style_back(fg_style_from_depth(e.depth.get_view().get()))
-                })
-            }
-        }
-    }
-}
-
 pub struct ListSegmentSequence {
-    data: Arc<dyn SequenceView<Item = NestedNode>>,
+    data: Arc<dyn SequenceView<Item = EditTree>>,
     cursor: Arc<dyn SingletonView<Item = ListCursor>>,
 
     cur_cursor: ListCursor,
@@ -78,11 +42,12 @@ impl SequenceView for ListSegmentSequence {
     type Item = ListSegment;
 
     fn len(&self) -> Option<usize> {
+        let l = self.data.len()?;
         match self.cur_cursor.mode {
             ListCursorMode::Insert => {
-                Some(self.data.len()? + if self.cur_cursor.idx.is_some() { 1 } else { 0 })
+                Some(l + if self.cur_cursor.idx.is_some() { 1 } else { 0 })
             }
-            _ => self.data.len(),
+            _ => Some(l),
         }
     }
 
@@ -124,7 +89,7 @@ impl SequenceView for ListSegmentSequence {
 impl ListSegmentSequence {
     pub fn new(
         cursor_port: OuterViewPort<dyn SingletonView<Item = ListCursor>>,
-        data_port: OuterViewPort<dyn SequenceView<Item = NestedNode>>,
+        data_port: OuterViewPort<dyn SequenceView<Item = EditTree>>,
     ) -> Arc<RwLock<Self>> {
         let out_port = ViewPort::new();
         let mut proj_helper = ProjectionHelper::new(out_port.update_hooks.clone());
diff --git a/nested/src/commander.rs b/lib-nested-core/src/editors/mod.rs
similarity index 57%
rename from nested/src/commander.rs
rename to lib-nested-core/src/editors/mod.rs
index fdbeaee..4de5274 100644
--- a/nested/src/commander.rs
+++ b/lib-nested-core/src/editors/mod.rs
@@ -1,4 +1,14 @@
 
+pub mod list;
+//pub mod product;
+//pub mod sum;
+
+pub mod char;
+pub mod digit;
+pub mod integer;
+//pub mod typeterm;
+
+
 pub trait Commander {
     type Cmd;
 
@@ -7,11 +17,12 @@ pub trait Commander {
 
 use std::sync::{Arc, RwLock};
 use crate::{
-    type_system::ReprTree,
-    tree::{nav::TreeNavResult}
+    repr_tree::ReprTree,
+    edit_tree::nav::TreeNavResult
 };
 
 pub trait ObjCommander {
     fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult;
 }
 
+
diff --git a/nested/src/editors/product/editor.rs b/lib-nested-core/src/editors/product/editor.rs
similarity index 98%
rename from nested/src/editors/product/editor.rs
rename to lib-nested-core/src/editors/product/editor.rs
index d3bdd9a..80acc24 100644
--- a/nested/src/editors/product/editor.rs
+++ b/lib-nested-core/src/editors/product/editor.rs
@@ -12,10 +12,6 @@ use {
     laddertypes::{TypeTerm},
     crate::{
         type_system::{Context},
-        terminal::{
-            TerminalEditor, TerminalEditorResult,
-            TerminalEvent, TerminalView
-        },
         editors::{
             list::ListCursorMode,
             product::{
diff --git a/nested/src/editors/product/mod.rs b/lib-nested-core/src/editors/product/mod.rs
similarity index 100%
rename from nested/src/editors/product/mod.rs
rename to lib-nested-core/src/editors/product/mod.rs
diff --git a/nested/src/editors/product/nav.rs b/lib-nested-core/src/editors/product/nav.rs
similarity index 100%
rename from nested/src/editors/product/nav.rs
rename to lib-nested-core/src/editors/product/nav.rs
diff --git a/nested/src/editors/product/segment.rs b/lib-nested-core/src/editors/product/segment.rs
similarity index 96%
rename from nested/src/editors/product/segment.rs
rename to lib-nested-core/src/editors/product/segment.rs
index 0b223f5..a9c9318 100644
--- a/nested/src/editors/product/segment.rs
+++ b/lib-nested-core/src/editors/product/segment.rs
@@ -19,7 +19,10 @@ use {
 
 #[derive(Clone)]
 pub enum ProductEditorSegment {
+    /// Terminal Node, i.e. literal, immutable string
     T( String, usize ),
+
+    /// Nonterminal Node, i.e. sub-editor for type t
     N {
         t: TypeTerm,
         editor: Option<NestedNode>,
diff --git a/nested/src/editors/sum/editor.rs b/lib-nested-core/src/editors/sum/editor.rs
similarity index 84%
rename from nested/src/editors/sum/editor.rs
rename to lib-nested-core/src/editors/sum/editor.rs
index 14b7798..b995da5 100644
--- a/nested/src/editors/sum/editor.rs
+++ b/lib-nested-core/src/editors/sum/editor.rs
@@ -8,14 +8,9 @@ use {
     },
     laddertypes::{TypeTerm},
     crate::{
-        terminal::TerminalView,
-        editors::list::ListCursorMode,
-        type_system::{Context, ReprTree},
-        tree::{TreeNav, TreeCursor, TreeNavResult},
-        diagnostics::{Diagnostics, Message},
-        tree::NestedNode,
-        commander::{ObjCommander},
-        PtySegment
+        editors::{list::ListCursorMode, ObjCommander},
+        repr_tree::{Context, ReprTree},
+        edit_tree::{TreeNav, TreeCursor, TreeNavResult, diagnostics::{Diagnostics, Message}, NestedNode},
     },
     cgmath::{Vector2},
     std::sync::{Arc, RwLock}
@@ -28,7 +23,7 @@ pub struct SumEditor {
     addr_port: ViewPort< dyn SequenceView<Item = isize> >,
     mode_port: ViewPort< dyn SingletonView<Item = ListCursorMode> >,
 
-    port: ViewPort< dyn TerminalView >,
+//    port: ViewPort< dyn TerminalView >,
     diag_port: ViewPort< dyn SequenceView<Item = Message> >
 }
 
@@ -36,12 +31,12 @@ impl SumEditor {
     pub fn new(
         editors: Vec< NestedNode >
     ) -> Self {
-        let port = ViewPort::new();
+//        let port = ViewPort::new();
 
         SumEditor {
             cur: 0,
             editors,
-            port,
+//            port,
             diag_port: ViewPort::new(),
 
 
@@ -55,15 +50,15 @@ impl SumEditor {
     }
 
     pub fn into_node(self, ctx: Arc<RwLock<Context>>) -> NestedNode {
-        let view = self.pty_view();
+//        let view = self.pty_view();
         let editor = Arc::new(RwLock::new(self));
 
         NestedNode::new(
             ctx.clone(),
-            ReprTree::new_arc(TypeTerm::TypeID(ctx.read().unwrap().get_typeid("Sum").unwrap())),
+//            ReprTree::new_arc(TypeTerm::TypeID(ctx.read().unwrap().get_typeid("Sum").unwrap())),
             r3vi::buffer::singleton::SingletonBuffer::new(0).get_port()
         )
-            .set_view(view)
+//            .set_view(view)
             .set_editor(editor.clone())
             .set_cmd(editor.clone())
             .set_nav(editor.clone())
@@ -76,6 +71,7 @@ impl SumEditor {
 
     pub fn select(&mut self, idx: usize) {
         self.cur = idx;
+/* FIXME
 
         let tv = self.editors[ self.cur ].get_view();
         tv.add_observer( self.port.get_cast() );
@@ -100,6 +96,7 @@ impl SumEditor {
         self.mode_port.update_hooks.write().unwrap().clear();
         self.mode_port.add_update_hook( Arc::new(dv.0.clone()) );
         self.mode_port.set_view( Some(dv.get_view_arc()) );
+  */
     }
 }
 
@@ -129,12 +126,6 @@ impl TreeNav for SumEditor {
     }
 }
 
-impl PtySegment for SumEditor {
-    fn pty_view(&self) -> OuterViewPort<dyn TerminalView> {
-        self.port.outer()
-    }
-}
-
 impl ObjCommander for SumEditor {
     fn send_cmd_obj(&mut self, obj: Arc<RwLock<ReprTree>>) -> TreeNavResult {
         self.editors[ self.cur ].send_cmd_obj( obj )
diff --git a/nested/src/editors/sum/mod.rs b/lib-nested-core/src/editors/sum/mod.rs
similarity index 100%
rename from nested/src/editors/sum/mod.rs
rename to lib-nested-core/src/editors/sum/mod.rs
diff --git a/nested/src/editors/typeterm/cmd.rs b/lib-nested-core/src/editors/typeterm/cmd.rs
similarity index 97%
rename from nested/src/editors/typeterm/cmd.rs
rename to lib-nested-core/src/editors/typeterm/cmd.rs
index e219cc8..4420115 100644
--- a/nested/src/editors/typeterm/cmd.rs
+++ b/lib-nested-core/src/editors/typeterm/cmd.rs
@@ -3,10 +3,9 @@ use {
         view::{singleton::*}
     },
     crate::{
-        type_system::{Context, ReprTree},
-        editors::{list::{ListEditor, ListCmd, ListCursorMode}},
-        tree::{NestedNode, TreeNav, TreeNavResult, TreeCursor},
-        commander::ObjCommander
+        repr_tree::{Context, ReprTree},
+        edit_tree::{NestedNode, TreeNav, TreeNavResult, TreeCursor},
+        editors::{list::{ListEditor, ListCmd, ListCursorMode}, ObjCommander},
     },
     std::{sync::{Arc, RwLock}},
 
@@ -241,7 +240,6 @@ impl ObjCommander for TypeTermEditor {
                                 self.set_state( State::Ladder );
                             }
                         } else {
-                            eprintln!("ERROR");
                         }
                     } else {
                         self.set_state( State::AnySymbol );
diff --git a/nested/src/editors/typeterm/ctx.rs b/lib-nested-core/src/editors/typeterm/ctx.rs
similarity index 94%
rename from nested/src/editors/typeterm/ctx.rs
rename to lib-nested-core/src/editors/typeterm/ctx.rs
index 4ad5b55..00d851e 100644
--- a/nested/src/editors/typeterm/ctx.rs
+++ b/lib-nested-core/src/editors/typeterm/ctx.rs
@@ -4,13 +4,11 @@ use {
     },
     laddertypes::{TypeTerm},
     crate::{
-        type_system::{Context, MorphismTypePattern},
-        terminal::{TerminalStyle, TerminalProjections},
+        repr_tree::{Context, MorphismType},
         editors::{
-            list::{PTYListStyle, PTYListController, ListEditor, ListSegmentSequence},
+            list::{ListEditor, ListSegmentSequence},
             typeterm::{State, TypeTermEditor}
-        },
-        PtySegment
+        }
     },
     std::{sync::{Arc, RwLock}},
     cgmath::{Point2}
@@ -27,8 +25,9 @@ pub fn init_ctx(ctx: &mut Context) {
     ctx.add_list_typename("Type::App".into()); // = <T1 T2 ...>
     ctx.add_list_typename("Type::Ladder".into()); // = T1~T2~...
 
+/*
     ctx.add_morphism(
-        MorphismTypePattern { src_tyid: ctx.get_typeid("List"), dst_tyid: ctx.get_typeid("Type").unwrap() },
+        MorphismType { src_tyid: Context::parse(&ctx, "<List T>"), dst_tyid: Context::parse(&ctx, "Type") },
         Arc::new(move |node, _dst_type:_| {
             let ctx : Arc<RwLock<Context>> = Arc::new(RwLock::new(Context::with_parent(Some(node.ctx.clone()))));
             ctx.write().unwrap().meta_chars.push('~');
@@ -36,7 +35,8 @@ pub fn init_ctx(ctx: &mut Context) {
             let new_node = TypeTermEditor::with_node( ctx, node.clone(), State::Any );
             Some(new_node)
         }));
-
+    */
+/*
     ctx.add_morphism(
         MorphismTypePattern { src_tyid: ctx.get_typeid("List"), dst_tyid: ctx.get_typeid("Type::Ladder").unwrap() },
         Arc::new(|mut node, _dst_type: _| {
@@ -140,5 +140,6 @@ pub fn init_ctx(ctx: &mut Context) {
         |ctx: Arc<RwLock<Context>>, _ty: TypeTerm, depth: OuterViewPort<dyn SingletonView<Item = usize>>| {
             Some(TypeTermEditor::new_node(ctx, depth))
         }));
+    */
 }
 
diff --git a/nested/src/editors/typeterm/mod.rs b/lib-nested-core/src/editors/typeterm/mod.rs
similarity index 94%
rename from nested/src/editors/typeterm/mod.rs
rename to lib-nested-core/src/editors/typeterm/mod.rs
index d15cbb4..abaaaab 100644
--- a/nested/src/editors/typeterm/mod.rs
+++ b/lib-nested-core/src/editors/typeterm/mod.rs
@@ -11,10 +11,9 @@ use {
     },
     laddertypes::{TypeID, TypeTerm},
     crate::{
-        type_system::{Context, ReprTree},
-        editors::{list::{ListCursorMode, ListEditor, ListCmd}},
-        tree::{NestedNode, TreeNav, TreeNavResult, TreeCursor},
-        commander::ObjCommander
+        repr_tree::{Context, ReprTree},
+        edit_tree::{NestedNode, TreeNav, TreeNavResult, TreeCursor},
+        editors::{list::{ListCursorMode, ListEditor, ListCmd}, ObjCommander},
     },
     std::{sync::{Arc, RwLock}}
 };
@@ -169,8 +168,8 @@ impl TypeTermEditor {
 
         node.goto(TreeCursor::home());
 
-        let _editor = node.editor.get();
-        self.close_char.set(node.close_char.get());
+        let _editor = node.edit.editor.get();
+        self.close_char.set(node.edit.close_char.get());
         self.cur_node.set(node);
         self.state = new_state;
     }
@@ -205,9 +204,9 @@ impl TypeTermEditor {
             cur_node: SingletonBuffer::new(cur_node.clone()),
             close_char: SingletonBuffer::new(None),
             spillbuf: Arc::new(RwLock::new(Vec::new())),
-            depth: cur_node.depth.clone()
+            depth: cur_node.disp.depth.clone()
         };
-
+/* FIXME
         let view = editor.cur_node
             .get_port()
             .map(|node| {
@@ -215,24 +214,25 @@ impl TypeTermEditor {
             })
             .to_grid()
             .flatten();
-        let _cc = editor.cur_node.get().close_char;
+        */
+        let _cc = editor.cur_node.get().edit.close_char;
         let editor = Arc::new(RwLock::new(editor));
 
-        let mut super_node = NestedNode::new(ctx, data, cur_node.depth)
-            .set_view(view)
+        let mut super_node = NestedNode::new(ctx, data, cur_node.disp.depth)
+//            .set_view(view)
             .set_nav(editor.clone())
             .set_cmd(editor.clone())
             .set_editor(editor.clone());
 
-        editor.write().unwrap().close_char = super_node.close_char.clone();
-        super_node.spillbuf = editor.read().unwrap().spillbuf.clone();
+        editor.write().unwrap().close_char = super_node.edit.close_char.clone();
+        super_node.edit.spillbuf = editor.read().unwrap().spillbuf.clone();
 
         super_node
     }
 
     fn forward_spill(&mut self) {
         let node = self.cur_node.get();
-        let mut buf = node.spillbuf.write().unwrap();
+        let mut buf = node.edit.spillbuf.write().unwrap();
         for n in buf.iter() {
             self.spillbuf.write().unwrap().push(n.clone());
         }
@@ -285,7 +285,6 @@ impl TypeTermEditor {
     }
 
     pub fn normalize_empty(&mut self) {
-        eprintln!("normalize singleton");
         let subladder_list_node = self.cur_node.get().clone();
         let subladder_list_edit = subladder_list_node.get_edit::<ListEditor>().unwrap();
 
@@ -298,7 +297,6 @@ impl TypeTermEditor {
     /* unwrap a ladder if it only contains one element
      */
     pub fn normalize_singleton(&mut self) {
-        eprintln!("normalize singleton");
 
         if self.state == State::Ladder {           
             let subladder_list_node = self.cur_node.get().clone();
@@ -362,7 +360,6 @@ impl TypeTermEditor {
     /* replace with new list-node (ladder/app) with self as first element
      */
      pub(super) fn morph_to_list(&mut self, state: State) {
-        eprintln!("morph into ladder");
 
         let mut old_node = self.cur_node.get().clone();
 
@@ -374,7 +371,7 @@ impl TypeTermEditor {
          * that has same state & child-node as current node.
          */
         let old_edit_node = TypeTermEditor::new_node( self.ctx.clone(), SingletonBuffer::new(0).get_port() );
-        old_node.depth.0.set_view( old_edit_node.depth.map(|x|x).get_view() );
+        old_node.disp.depth.0.set_view( old_edit_node.disp.depth.map(|x|x).get_view() );
         
         let old_edit_clone = old_edit_node.get_edit::<TypeTermEditor>().unwrap();
         old_edit_clone.write().unwrap().set_state( self.state );
diff --git a/nested/src/editors/typeterm/nav.rs b/lib-nested-core/src/editors/typeterm/nav.rs
similarity index 94%
rename from nested/src/editors/typeterm/nav.rs
rename to lib-nested-core/src/editors/typeterm/nav.rs
index 6fb7bf1..b4f2175 100644
--- a/nested/src/editors/typeterm/nav.rs
+++ b/lib-nested-core/src/editors/typeterm/nav.rs
@@ -7,7 +7,7 @@ use {
         }
     },
     crate::{
-        tree::{TreeNav, TreeCursor, TreeNavResult, TreeHeightOp},
+        edit_tree::{TreeNav, TreeCursor, TreeNavResult, TreeHeightOp},
         editors::{typeterm::TypeTermEditor, list::ListCursorMode}
     },
     cgmath::Vector2
diff --git a/lib-nested-core/src/lib.rs b/lib-nested-core/src/lib.rs
new file mode 100644
index 0000000..b942062
--- /dev/null
+++ b/lib-nested-core/src/lib.rs
@@ -0,0 +1,8 @@
+
+#![feature(trait_upcasting)]
+
+pub mod repr_tree;
+pub mod edit_tree;
+pub mod editors;
+pub mod utils;
+
diff --git a/lib-nested-core/src/repr_tree/context.rs b/lib-nested-core/src/repr_tree/context.rs
new file mode 100644
index 0000000..b592ae0
--- /dev/null
+++ b/lib-nested-core/src/repr_tree/context.rs
@@ -0,0 +1,274 @@
+use {
+    r3vi::{view::{OuterViewPort, singleton::*}, buffer::{singleton::*}},
+    laddertypes::{TypeDict, TypeTerm, TypeID, MorphismType, MorphismBase, Morphism},
+    crate::{
+        repr_tree::{ReprTree, ReprTreeExt, GenericReprTreeMorphism},
+        edit_tree::EditTree
+    },
+    std::{
+        collections::HashMap,
+        sync::{Arc, RwLock},
+    }
+};
+
+//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
+
+pub static TYPEID_edittree : TypeID = TypeID::Fun(0);
+pub static TYPEID_char : TypeID = TypeID::Fun(1);
+pub static TYPEID_u64  : TypeID = TypeID::Fun(2);
+pub static TYPEID_list : TypeID = TypeID::Fun(3);
+pub static TYPEID_vec : TypeID = TypeID::Fun(4);
+
+//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
+
+#[derive(Clone)]
+pub struct Context {
+    /// assigns a name to every type
+    pub type_dict: Arc<RwLock<TypeDict>>,
+
+    pub morphisms: laddertypes::morphism::MorphismBase< GenericReprTreeMorphism >,
+
+    /// named vertices of the graph
+    nodes: HashMap< String, Arc<RwLock<ReprTree>> >,
+
+    /// todo: beautify
+    /// types that can be edited as lists
+    /// do we really need this?
+    pub list_types: Vec< TypeID >,
+    pub meta_chars: Vec< char >,
+
+    edittree_hook: Arc< dyn Fn(&mut EditTree, TypeTerm) + Send +Sync +'static >,
+
+    /// recursion
+    parent: Option<Arc<RwLock<Context>>>,
+}
+
+//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
+
+impl Context {
+    pub fn with_parent(
+        parent: Option<Arc<RwLock<Context>>>
+    ) -> Self {
+        Context {
+            type_dict: match parent.as_ref() {
+                Some(p) => p.read().unwrap().type_dict.clone(),
+                None => {
+                    let mut dict = TypeDict::new();
+                    assert_eq!( TYPEID_edittree, dict.add_typename("EditTree".into()) );
+                    assert_eq!( TYPEID_char, dict.add_typename("Char".into()) );
+                    assert_eq!( TYPEID_u64, dict.add_typename("machine.UInt64".into()) );
+                    assert_eq!( TYPEID_list, dict.add_typename("List".into()) );
+                    assert_eq!( TYPEID_vec, dict.add_typename("Vec".into()) );
+
+                    Arc::new(RwLock::new(dict))
+                }
+            },
+            morphisms: MorphismBase::new( TYPEID_list ),
+            nodes: HashMap::new(),
+            list_types: match parent.as_ref() {
+                Some(p) => p.read().unwrap().list_types.clone(),
+                None => Vec::new()
+            },
+            meta_chars: match parent.as_ref() {
+                Some(p) => p.read().unwrap().meta_chars.clone(),
+                None => Vec::new()
+            },
+            parent,
+            edittree_hook: Arc::new(|_et, _t| {})
+        }
+    }
+
+    pub fn new() -> Self {
+        Context::with_parent(None)
+    }
+
+    pub fn set_edittree_hook(&mut self, hook: Arc< dyn Fn(&mut EditTree, TypeTerm) + Send +Sync +'static >) {
+        self.edittree_hook = hook;
+    }
+
+    pub fn depth(&self) -> usize {
+        if let Some(parent) = self.parent.as_ref() {
+            parent.read().unwrap().depth() + 1
+        } else {
+            0
+        }
+    }
+
+    pub fn apply_morphism( &self, rt: &Arc<RwLock<ReprTree>>, ty: &MorphismType ) {
+        if let Some(path)
+            = self.morphisms.find_morphism_path( ty.clone().normalize() )
+        {
+            let mut path = path.into_iter();
+            if let Some(mut src_type) = path.next() {
+                for dst_type in path {
+                   if let Some(( m, mut τ, σ )) =
+                       self.morphisms.find_morphism_with_subtyping(
+                        &laddertypes::MorphismType {
+                            src_type: src_type.clone(),
+                            dst_type: dst_type.clone()
+                        }
+                    ) {
+                        let mut rt = rt.descend( τ ).expect("descend src repr");
+                        (m.setup_projection)( &mut rt, &σ );
+                    }
+
+                    src_type = dst_type;
+                }
+            }
+        } else {
+            eprintln!("no path found");
+        }    
+    }
+
+    pub fn build_repr_tree(
+        &self,
+        rt: &Arc<RwLock<ReprTree>>,
+        root: TypeTerm,
+        leaves: Vec< TypeTerm >
+    ) {
+        let mut st_problem = laddertypes::steiner_tree::PathApproxSteinerTreeSolver::new(
+            root,
+            leaves
+        );
+
+        if let Some( steiner_tree ) = st_problem.solve( &self.morphisms ) {
+            for morphism_type in steiner_tree.into_edges() {
+                eprintln!("--> apply morph to {}", self.type_term_to_str(&morphism_type.dst_type));
+                if let Some(( morphism, mut τ, σ )) =
+                    self.morphisms.find_morphism_with_subtyping( &morphism_type )
+                {
+                    let mut rt = rt.descend( τ ).expect("descend src repr");
+                    (morphism.setup_projection)( &mut rt, &σ );
+                }
+            }
+        } else {
+            eprintln!("could not find steiner tree to build the requested repr tree");
+        }
+    }
+
+    pub fn make_repr(ctx: &Arc<RwLock<Self>>, t: &TypeTerm) -> Arc<RwLock<ReprTree>> {
+        let rt = Arc::new(RwLock::new(ReprTree::new( TypeTerm::unit() )));
+        ctx.read().unwrap().apply_morphism( &rt, &MorphismType{ src_type: TypeTerm::unit(), dst_type: t.clone() } );
+        rt
+    }
+
+    pub fn parse(ctx: &Arc<RwLock<Self>>, s: &str) -> TypeTerm {
+        ctx.read().unwrap().type_term_from_str(s).expect("could not parse type term")
+    }
+
+    pub fn add_typename(&mut self, tn: &str) -> TypeID {
+        self.type_dict.write().unwrap().add_typename(tn.to_string())
+    }
+
+    pub fn add_varname(&mut self, vn: &str) -> TypeID {
+        self.type_dict.write().unwrap().add_varname(vn.to_string())
+    }
+
+    pub fn add_synonym(&mut self, new: &str, old: &str) {
+        self.type_dict.write().unwrap().add_synonym(new.to_string(), old.to_string());
+    }
+
+    pub fn add_list_typename(&mut self, tn: &str) {
+        let tid = self.add_typename(tn);
+        self.list_types.push( tid );
+    }
+
+    pub fn is_list_type(&self, t: &TypeTerm) -> bool {
+        match t {
+            TypeTerm::TypeID(id) => {
+                self.list_types.contains(id)
+            }
+            TypeTerm::Ladder(args) |
+            TypeTerm::App(args) => {
+                if args.len() > 0 {
+                    if self.is_list_type(&args[0]) {
+                        true
+                    } else {
+                        false
+                    }
+                } else {
+                    false
+                }
+            }
+            _ => false
+        }
+    }
+
+    pub fn get_typeid(&self, tn: &str) -> Option<TypeID> {
+        self.type_dict.read().unwrap().get_typeid(&tn.into())
+    }
+
+    pub fn get_fun_typeid(&self, tn: &str) -> Option<u64> {
+        match self.get_typeid(tn) {
+            Some(TypeID::Fun(x)) => Some(x),
+            _ => None
+        }
+    }
+
+    pub fn get_typename(&self, tid: &TypeID) -> Option<String> {
+        self.type_dict.read().unwrap().get_typename(tid)
+    }
+
+    pub fn get_var_typeid(&self, tn: &str) -> Option<u64> {
+        match self.get_typeid(tn) {
+            Some(TypeID::Var(x)) => Some(x),
+            _ => None
+        }
+    }
+
+    pub fn type_term_from_str(&self, tn: &str) -> Result<TypeTerm, laddertypes::parser::ParseError> {
+        self.type_dict.write().unwrap().parse(&tn)
+    }
+
+    pub fn type_term_to_str(&self, t: &TypeTerm) -> String {
+        self.type_dict.read().unwrap().unparse(&t)
+    }
+
+    /// adds an object without any representations
+    pub fn add_obj(ctx: Arc<RwLock<Context>>, name: String, typename: &str) {
+        let type_tag = ctx.read().unwrap()
+            .type_dict.write().unwrap()
+            .parse(typename).unwrap();
+/*
+        if let Some(node) = Context::make_node(&ctx, type_tag, SingletonBuffer::new(0).get_port()) {
+            ctx.write().unwrap().nodes.insert(name, node);
+        }
+*/
+    }
+
+    pub fn get_obj(&self, name: &String) -> Option< Arc<RwLock<ReprTree>> > {
+        if let Some(obj) = self.nodes.get(name) {
+            Some(obj.clone())
+        } else if let Some(parent) = self.parent.as_ref() {
+            parent.read().unwrap().get_obj(name)
+        } else {
+            None
+        }
+    }
+
+    pub fn setup_edittree(
+        &self,
+        rt: &Arc<RwLock<ReprTree>>
+    ) -> Option<SingletonBuffer<Arc<RwLock<EditTree>>>> {
+        if let Some(new_edittree) =
+            rt.descend(self.type_term_from_str("EditTree").unwrap())
+        {
+            let typ = rt.read().unwrap().get_type().clone();
+            let buf = new_edittree.singleton_buffer::<Arc<RwLock<EditTree>>>();
+            (*self.edittree_hook)(
+                &mut *buf.get().write().unwrap(),
+                typ
+            );
+            Some(buf)
+        } else {
+            eprintln!("cant find edit tree repr {} ~Ψ~ {}",
+                self.type_term_to_str(rt.read().unwrap().get_halo_type()),
+                self.type_term_to_str(rt.read().unwrap().get_type())
+            );
+            None
+        }
+    }
+}
+
+//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
+
diff --git a/lib-nested-core/src/repr_tree/leaf.rs b/lib-nested-core/src/repr_tree/leaf.rs
new file mode 100644
index 0000000..6a12440
--- /dev/null
+++ b/lib-nested-core/src/repr_tree/leaf.rs
@@ -0,0 +1,216 @@
+use {
+    r3vi::{
+        view::{
+            ViewPort, OuterViewPort,
+            AnyViewPort, AnyInnerViewPort, AnyOuterViewPort,
+            port::UpdateTask,
+            View, Observer,
+            singleton::*,
+            sequence::*,
+            list::*
+        },
+        buffer::{singleton::*, vec::*}
+    },
+    laddertypes::{TypeTerm},
+    std::{
+        collections::HashMap,
+        sync::{Arc, RwLock},
+        any::Any
+    },
+};
+
+//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
+
+#[derive(Clone)]
+pub struct ReprLeaf {
+    out_port: AnyViewPort,
+    in_port: AnyInnerViewPort,
+    data: Option< Arc<dyn Any + Send + Sync> >,
+
+    /// keepalive for the observer that updates the buffer from in_port
+    keepalive: Option<Arc<dyn Any + Send + Sync>>,
+    in_keepalive: Option<Arc<dyn Any + Send + Sync>>,
+}
+
+//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
+
+impl ReprLeaf {
+    pub fn from_view<V>( src_port: OuterViewPort<V> ) -> Self
+    where V: View + ?Sized + 'static,
+        V::Msg: Clone
+    {
+        let mut in_port = ViewPort::<V>::new();
+        let in_keepalive = in_port.attach_to(src_port);
+
+        let mut out_port = ViewPort::<V>::new();
+        let out_keepalive = out_port.attach_to(in_port.outer());
+
+        ReprLeaf {
+            keepalive: Some(out_keepalive),
+            in_keepalive: Some(in_keepalive),
+            in_port: in_port.inner().into(),
+            out_port: out_port.into(),
+            data: None, 
+        }
+    }
+
+    pub fn detach<V>(&mut self)
+    where V: View + ?Sized + 'static,
+         V::Msg: Clone
+    {
+        self.keepalive = None;
+        self.in_keepalive = None;
+
+        let ip = self.in_port.clone()
+            .downcast::<V>().ok()
+            .unwrap();
+        ip.0.detach();
+
+        if self.data.is_none() {
+            let mut op = self.out_port.clone()
+                .downcast::<V>().ok()
+                .unwrap();
+
+            op.detach();
+            self.keepalive = Some(op.attach_to(ip.0.outer()));
+        }
+    }
+
+    pub fn detach_vec<Item>(&mut self)
+    where Item: Clone + Send + Sync + 'static
+    {
+        self.keepalive = None;
+        self.in_keepalive = None;
+
+        let ip = self.in_port.clone()
+            .downcast::<dyn ListView<Item>>().ok()
+            .unwrap();
+
+        ip.0.detach();
+
+        if let Some(data) = self.data.as_mut() {
+            let mut op = self.out_port.clone()
+                .downcast::<RwLock<Vec<Item>>>().ok()
+                .unwrap();
+            op.detach();
+
+            let data = data.clone().downcast::< RwLock<Vec<Item>> >().ok().unwrap();
+            let buffer = VecBuffer::with_data_arc_port(data, op.inner());
+            self.keepalive = Some(buffer.attach_to(ip.0.outer()))
+        }
+    }
+
+    pub fn attach_to<V>(&mut self, src_port: OuterViewPort<V>)
+    where V: View + ?Sized + 'static,
+        V::Msg: Clone
+    {
+        self.in_keepalive = Some(self.in_port.clone()
+            .downcast::<V>().ok().unwrap()
+            .0.attach_to( src_port ));
+    }
+
+    pub fn from_singleton_buffer<T>( buffer: SingletonBuffer<T> ) -> Self
+    where T: Clone + Send + Sync + 'static
+    {
+        let in_port = ViewPort::<dyn SingletonView<Item = T>>::new();
+        ReprLeaf {
+            in_keepalive: None,
+            keepalive: Some(buffer.attach_to(in_port.outer())),
+            in_port: in_port.inner().into(),
+            out_port: buffer.get_port().0.into(),
+            data: Some(buffer.into_inner())
+        }
+    }
+
+    pub fn from_vec_buffer<T>( buffer: VecBuffer<T> ) -> Self
+    where T: Clone + Send + Sync + 'static
+    {
+        let in_port = ViewPort::< dyn ListView<T> >::new();
+        ReprLeaf {
+            in_keepalive: None,
+            keepalive: Some(buffer.attach_to(in_port.outer())),
+            in_port: in_port.inner().into(),
+            out_port: buffer.get_port().0.into(),
+            data: Some(buffer.into_inner())
+        }
+    }
+
+    pub fn as_singleton_buffer<T>(&mut self) -> Option<SingletonBuffer<T>>
+    where T: Clone + Send + Sync + 'static
+    {
+        let sgl_port = self.get_port::< dyn SingletonView<Item = T> >().unwrap().0;
+
+        let data_arc =
+            if let Some(data) = self.data.as_ref() {
+                data.clone().downcast::<RwLock<T>>().ok()
+            } else {
+                sgl_port.update();
+                let value = sgl_port.outer().get_view().unwrap().get();
+                eprintln!("make new data ARC from old value");
+                Some(Arc::new(RwLock::new( value )))
+            };
+
+        if let Some(data_arc) = data_arc {
+            self.data = Some(data_arc.clone() as Arc<dyn Any + Send + Sync>);
+            let buf = SingletonBuffer {
+                value: data_arc,
+                port: sgl_port.inner()
+            };
+            self.keepalive = Some(buf.attach_to(
+                self.in_port.0.clone()
+                    .downcast::<dyn SingletonView<Item = T>>()
+                    .ok().unwrap()
+                    .outer()
+            ));
+            Some(buf)
+        } else {
+            None
+        }
+    }
+
+    pub fn as_vec_buffer<T>(&mut self) -> Option<VecBuffer<T>>
+    where T: Clone + Send + Sync + 'static
+    {
+        let vec_port = self.get_port::< RwLock<Vec<T>> >().unwrap().0;
+
+        let data_arc =
+            if let Some(data) = self.data.as_ref() {
+                data.clone().downcast::<RwLock<Vec<T>>>().ok()
+            } else {
+                vec_port.update();
+                if let Some(value) = vec_port.outer().get_view() {
+                    let value = value.read().unwrap().clone();
+                    eprintln!("make new data ARC from old VECTOR-value");
+                    Some(Arc::new(RwLock::new( value )))
+                } else {
+                    eprintln!("no data vec");
+                    Some(Arc::new(RwLock::new( Vec::new() )))
+//                    None
+                }
+            };
+
+        if let Some(data_arc) = data_arc {
+            self.data = Some(data_arc.clone() as Arc<dyn Any + Send + Sync>);
+            let buf = VecBuffer::with_data_arc_port(data_arc, vec_port.inner());
+            self.keepalive = Some(buf.attach_to(
+                self.in_port.0.clone()
+                    .downcast::< dyn ListView<T> >()
+                    .ok().unwrap()
+                    .outer()
+            ));
+            Some(buf)
+        } else {
+            None
+        }
+    }
+
+    pub fn get_port<V>(&self) -> Option<OuterViewPort<V>>
+    where V: View + ?Sized + 'static,
+        V::Msg: Clone
+    {
+        self.out_port.clone().downcast::<V>().ok().map(|p| p.outer())
+    }
+}
+
+//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
+
diff --git a/lib-nested-core/src/repr_tree/mod.rs b/lib-nested-core/src/repr_tree/mod.rs
new file mode 100644
index 0000000..8af48f8
--- /dev/null
+++ b/lib-nested-core/src/repr_tree/mod.rs
@@ -0,0 +1,145 @@
+pub mod node;
+pub mod leaf;
+pub mod context;
+pub mod morphism;
+
+#[cfg(test)]
+mod tests;
+
+pub use {
+    context::{Context},
+    leaf::ReprLeaf,
+    node::ReprTree,
+    morphism::{GenericReprTreeMorphism}
+};
+
+use {
+    r3vi::{
+        view::{
+            ViewPort, OuterViewPort,
+            AnyViewPort, AnyInnerViewPort, AnyOuterViewPort,
+            port::UpdateTask,
+            View, Observer,
+            singleton::*,
+            sequence::*,
+            list::*
+        },
+        buffer::{singleton::*, vec::*}
+    },
+    laddertypes::{TypeTerm},
+    std::{
+        collections::HashMap,
+        sync::{Arc, RwLock},
+        any::Any
+    },
+};
+
+//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
+
+pub trait ReprTreeExt {
+    fn get_type(&self) -> TypeTerm;
+
+    fn insert_leaf(&mut self, type_ladder: impl Into<TypeTerm>, leaf: ReprLeaf);
+    fn insert_branch(&mut self, repr: Arc<RwLock<ReprTree>>);
+    fn create_branch(&mut self, rung: impl Into<TypeTerm>);
+    fn descend(&self, target_type: impl Into<TypeTerm>) -> Option<Arc<RwLock<ReprTree>>>;
+
+    fn attach_leaf_to<V: View + ?Sized + 'static>(&self, t: impl Into<TypeTerm>, v: OuterViewPort<V>) where V::Msg: Clone;
+    fn get_port<V: View + ?Sized + 'static>(&self) -> Option<OuterViewPort<V>> where V::Msg: Clone;
+
+    fn view_char(&self) -> OuterViewPort<dyn SingletonView<Item = char>>;
+    fn view_u8(&self) -> OuterViewPort<dyn SingletonView<Item = u8>>;
+    fn view_u64(&self) -> OuterViewPort<dyn SingletonView<Item = u64>>;
+    fn view_usize(&self) -> OuterViewPort<dyn SingletonView<Item = usize>>;
+
+    fn view_singleton<T: Send + Sync + 'static>(&self) -> OuterViewPort<dyn SingletonView<Item = T>>;
+    fn view_seq<T: Send + Sync + 'static>(&self) -> OuterViewPort<dyn SequenceView<Item = T>>;
+    fn view_list<T: Clone + Send + Sync + 'static>(&self) -> OuterViewPort<dyn ListView<T>>;
+
+    fn singleton_buffer<T: Clone + Send + Sync + 'static>(&self) -> SingletonBuffer<T>;
+    fn vec_buffer<T: Clone + Send + Sync + 'static>(&self) -> VecBuffer<T>;
+
+    fn edittree(&self, ctx: &Arc<RwLock<Context>>) -> SingletonBuffer< Arc<RwLock<crate::edit_tree::EditTree>> > {
+        self.descend(Context::parse(&ctx, "EditTree")).unwrap()
+            .singleton_buffer()
+    }
+}
+
+impl ReprTreeExt for Arc<RwLock<ReprTree>> {
+    fn get_type(&self) -> TypeTerm {
+        self.read().unwrap().get_type().clone()
+    }
+
+    fn insert_leaf(&mut self, type_ladder: impl Into<TypeTerm>, leaf: ReprLeaf) {
+        self.write().unwrap().insert_leaf(type_ladder.into().get_lnf_vec().into_iter(), leaf)
+    }
+
+    fn insert_branch(&mut self, repr: Arc<RwLock<ReprTree>>) {
+        self.write().unwrap().insert_branch(repr)
+    }
+
+    fn create_branch(&mut self, rung: impl Into<TypeTerm>) {
+        let mut lnf = rung.into().get_lnf_vec().into_iter();
+        if let Some(rung) = lnf.next() {
+            let mut parent = ReprTree::new_arc( rung );
+            self.insert_branch( parent.clone() );
+
+            for rung in lnf {
+                let r = ReprTree::new_arc( rung );
+                parent.insert_branch(r.clone());
+                parent = r;
+            }
+        }
+    }
+
+    fn get_port<V: View + ?Sized + 'static>(&self) -> Option<OuterViewPort<V>> where V::Msg: Clone {
+        self.read().unwrap().get_port::<V>()
+    }
+
+    fn attach_leaf_to<V: View + ?Sized + 'static>(&self, type_ladder: impl Into<TypeTerm>, v: OuterViewPort<V>) where V::Msg: Clone {
+        self.write().unwrap().attach_leaf_to::<V>(type_ladder.into().get_lnf_vec().into_iter(), v)
+    }
+
+    fn descend(&self, target_type: impl Into<TypeTerm>) -> Option<Arc<RwLock<ReprTree>>> {
+        ReprTree::descend( self, target_type )
+    }
+
+    fn view_char(&self) -> OuterViewPort<dyn SingletonView<Item = char>> {
+        self.read().unwrap().view_char()
+    }
+
+    fn view_u8(&self) -> OuterViewPort<dyn SingletonView<Item = u8>> {
+        self.read().unwrap().view_u8()
+    }
+
+    fn view_u64(&self) -> OuterViewPort<dyn SingletonView<Item = u64>> {
+        self.read().unwrap().view_u64()
+    }
+
+    fn view_usize(&self) -> OuterViewPort<dyn SingletonView<Item = usize>> {
+        self.read().unwrap().view_usize()
+    }
+
+    fn view_singleton<T: Send + Sync + 'static>(&self) -> OuterViewPort<dyn SingletonView<Item = T>> {
+        self.read().unwrap().view_singleton::<T>()
+    }
+
+    fn view_seq<T: Send + Sync + 'static>(&self) -> OuterViewPort<dyn SequenceView<Item = T>> {
+        self.read().unwrap().view_seq::<T>()
+    }
+
+    fn view_list<T: Clone + Send + Sync + 'static>(&self) -> OuterViewPort<dyn ListView<T>> {
+        self.read().unwrap().view_list::<T>()
+    }
+
+    fn singleton_buffer<T: Clone + Send + Sync + 'static>(&self) -> SingletonBuffer<T> {
+        self.write().unwrap().singleton_buffer::<T>().expect("")
+    }
+
+    fn vec_buffer<T: Clone + Send + Sync + 'static>(&self) -> VecBuffer<T> {
+        self.write().unwrap().vec_buffer::<T>().expect("")
+    }
+}
+
+//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
+
diff --git a/lib-nested-core/src/repr_tree/morphism.rs b/lib-nested-core/src/repr_tree/morphism.rs
new file mode 100644
index 0000000..fe59b6f
--- /dev/null
+++ b/lib-nested-core/src/repr_tree/morphism.rs
@@ -0,0 +1,207 @@
+use {
+    laddertypes::{TypeTerm, TypeID, morphism::Morphism},
+    r3vi::view::{AnyOuterViewPort, port::*, list::*},
+    crate::{
+        repr_tree::{
+            ReprTree, ReprTreeExt, ReprLeaf,
+            context::{*}
+        },
+    },
+    std::{
+        sync::{Arc, RwLock},
+        collections::HashMap
+    }
+};
+
+pub use laddertypes::morphism::MorphismType;
+
+//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
+
+#[derive(Clone)]
+pub struct GenericReprTreeMorphism {
+    pub(super) morph_type: MorphismType,
+    pub(super) setup_projection: Arc<
+        dyn Fn( &mut Arc<RwLock<ReprTree>>, &HashMap<TypeID, TypeTerm> )
+//            -> Result< ReprLeaf, () >
+        + Send + Sync
+    >
+}
+
+impl Morphism for GenericReprTreeMorphism {
+    fn get_type(&self) -> MorphismType {
+        self.morph_type.clone()
+    }
+
+    fn list_map_morphism(&self, list_typeid: TypeID) -> Option< GenericReprTreeMorphism > {
+        self.into_list_map_dyn(list_typeid)
+    }
+}
+
+impl GenericReprTreeMorphism {
+    pub fn new(
+        src_type: TypeTerm,
+        dst_type: TypeTerm,
+
+        setup: impl Fn( &mut Arc<RwLock<ReprTree>>, &HashMap<TypeID, TypeTerm> )
+                + Send + Sync + 'static
+    ) -> Self {
+        GenericReprTreeMorphism {
+            morph_type: MorphismType {
+                src_type, dst_type
+            }.normalize(),
+
+            setup_projection: Arc::new(setup)
+        }
+    }
+
+    pub fn into_list_map< SrcItem, DstItem >(&self, list_typeid: TypeID)
+    -> GenericReprTreeMorphism
+    where
+        SrcItem: Clone + Send + Sync + 'static,
+        DstItem: Clone + Send + Sync + 'static
+    {
+        let mut lst_map_type = MorphismType {
+            src_type: TypeTerm::App(vec![
+                TypeTerm::TypeID(list_typeid),
+                self.morph_type.src_type.clone()
+            ]),
+            dst_type: TypeTerm::App(vec![
+                TypeTerm::TypeID(list_typeid),
+                self.morph_type.dst_type.clone()
+            ])
+        }.normalize();
+
+        let item_morph = self.clone();
+
+        GenericReprTreeMorphism{
+            morph_type: lst_map_type.clone(),
+            setup_projection: Arc::new(move |repr_tree, subst| {
+                let mut lst_map_type = lst_map_type.clone();
+                lst_map_type.src_type.apply_substitution( &|x| subst.get(x).cloned() );
+                lst_map_type.dst_type.apply_substitution( &|x| subst.get(x).cloned() );
+
+                eprintln!(
+                    "lst map type :  {:?}", lst_map_type
+                );
+
+                let src_port = repr_tree
+                    .descend( lst_map_type.src_type.clone() )
+                    .expect("descend src seq")
+                    .view_list::<SrcItem>();
+
+                let subst = subst.clone();
+                let item_morph = item_morph.clone();
+
+                let dst_view = src_port.map(
+                        move |x| {
+                            let mut item_ladder = item_morph.morph_type.src_type.clone().get_lnf_vec();
+                            let mut item_rt = ReprTree::from_singleton_buffer(
+                                item_ladder.remove( item_ladder.len() - 1 ),
+                                r3vi::buffer::singleton::SingletonBuffer::new(x.clone())
+                            );
+
+                            // TODO: required?
+                            while item_ladder.len() > 0 {
+                                let mut n = ReprTree::new_arc( item_ladder.remove( item_ladder.len() - 1) );
+                                n.insert_branch( item_rt );
+                                item_rt = n;
+                            }
+
+                            (item_morph.setup_projection)( &mut item_rt, &subst );
+                            item_rt.descend( item_morph.morph_type.dst_type.clone() ).expect("descend to item rt")
+                                .view_singleton::< DstItem >()
+                                .get_view().unwrap()
+                                .get()
+                        }
+                );
+
+                repr_tree.attach_leaf_to(
+                    lst_map_type.dst_type.clone(),
+                    dst_view as r3vi::view::OuterViewPort::< dyn r3vi::view::list::ListView<DstItem> >
+                );
+            })
+        }
+    }
+
+    pub fn into_list_map_dyn(&self, typeid_list: TypeID)
+    -> Option< GenericReprTreeMorphism >
+    {        
+        let src_item_type_lnf = self.morph_type.src_type.clone().get_lnf_vec();
+        let dst_item_type_lnf = self.morph_type.dst_type.clone().get_lnf_vec();
+
+        eprintln!("into list map dyn");
+
+        if src_item_type_lnf.last() == Some(&TypeTerm::TypeID(TYPEID_char)) &&
+           dst_item_type_lnf.last() == Some(&TypeTerm::TypeID(TYPEID_char))
+        {
+            Some( self.into_list_map::< char, char >(TYPEID_list) )
+        }
+        else if src_item_type_lnf.last() == Some(&TypeTerm::TypeID(TYPEID_u64)) &&
+           dst_item_type_lnf.last() == Some(&TypeTerm::TypeID(TYPEID_u64))
+        {
+            Some( self.into_list_map::< u64, u64 >(TYPEID_list) )
+        }
+        else if src_item_type_lnf.last() == Some(&TypeTerm::TypeID(TYPEID_char)) &&
+           dst_item_type_lnf.last() == Some(&TypeTerm::TypeID(TYPEID_u64))
+        {
+            Some( self.into_list_map::< char, u64 >(TYPEID_list) )
+        }
+        else if src_item_type_lnf.last() == Some(&TypeTerm::TypeID(TYPEID_u64)) &&
+                dst_item_type_lnf.last() == Some(&TypeTerm::TypeID(TYPEID_char))
+        {
+            Some( self.into_list_map::< u64, char >(TYPEID_list) )
+        }
+        else if src_item_type_lnf.last() == Some(&TypeTerm::TypeID(TYPEID_char)) &&
+                dst_item_type_lnf.last() == Some(&TypeTerm::TypeID(TYPEID_edittree))
+        {
+            Some( self.into_list_map::< char, Arc<RwLock<crate::edit_tree::EditTree>> >(TYPEID_list) )
+        }
+        else if src_item_type_lnf.last() == Some(&TypeTerm::TypeID(TYPEID_edittree)) &&
+                dst_item_type_lnf.last() == Some(&TypeTerm::TypeID(TYPEID_char))
+        {
+            Some( self.into_list_map::< Arc<RwLock<crate::edit_tree::EditTree>>, char >(TYPEID_list) )
+        }
+/*
+        else if src_item_type_lnf.last() == Some(&TypeTerm::App(vec![ TypeTerm::TypeID(typeid_list), TypeTerm::TypeID(typeid_char) ])) &&
+                dst_item_type_lnf.last() == Some(&TypeTerm::App(vec![ TypeTerm::TypeID(typeid_list), TypeTerm::TypeID(typeid_char) ]))
+        {
+            Some( self.into_list_map::< char, char >(typeid_list) )
+        }
+        else if src_item_type_lnf.last() == Some(&TypeTerm::App(vec![ TypeTerm::TypeID(typeid_list), TypeTerm::TypeID(typeid_u64) ])) &&
+                dst_item_type_lnf.last() == Some(&TypeTerm::App(vec![ TypeTerm::TypeID(typeid_list), TypeTerm::TypeID(typeid_u64) ]))
+        {
+            Some( self.into_list_map::< u64, u64 >(typeid_list) )
+        }
+        else if src_item_type_lnf.last() == Some(&TypeTerm::App(vec![ TypeTerm::TypeID(typeid_list), TypeTerm::TypeID(typeid_char) ])) &&
+                dst_item_type_lnf.last() == Some(&TypeTerm::App(vec![ TypeTerm::TypeID(typeid_list), TypeTerm::TypeID(typeid_u64) ]))
+        {
+            Some( self.into_list_map::< OuterViewPort<dyn ListView<char>>, OuterViewPort<dyn ListView<u64>> >(typeid_list) )
+        }
+        else if src_item_type_lnf.last() == Some(&TypeTerm::App(vec![ TypeTerm::TypeID(typeid_list), TypeTerm::TypeID(typeid_u64) ])) &&
+                dst_item_type_lnf.last() == Some(&TypeTerm::App(vec![ TypeTerm::TypeID(typeid_list), TypeTerm::TypeID(typeid_char) ]))
+        {
+            Some( self.into_list_map::< OuterViewPort<dyn ListView<u64>>, OuterViewPort<dyn ListView<char>> >(typeid_list) )
+        }
+*/
+        else
+        {
+            eprintln!("no list map type for {:?}", dst_item_type_lnf.last());
+            None
+        }
+    }
+}
+
+//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
+/*
+impl MorphismType {
+    pub fn to_str(&self, ctx: &Context) -> String {
+        format!("{:?} -> {:?}",
+                if let Some(t) = self.src_type.as_ref() {
+                    ctx.type_dict.read().unwrap().unparse(t)
+                } else {
+                    "None".into()
+                },
+                ctx.type_dict.read().unwrap().unparse(&self.dst_type))
+    }
+}
+*/
diff --git a/lib-nested-core/src/repr_tree/node.rs b/lib-nested-core/src/repr_tree/node.rs
new file mode 100644
index 0000000..bc51906
--- /dev/null
+++ b/lib-nested-core/src/repr_tree/node.rs
@@ -0,0 +1,453 @@
+
+
+use {
+    r3vi::{
+        view::{
+            ViewPort, OuterViewPort,
+            AnyViewPort, AnyInnerViewPort, AnyOuterViewPort,
+            port::UpdateTask,
+            View, Observer,
+            singleton::*,
+            sequence::*,
+            list::*
+        },
+        buffer::{singleton::*, vec::*}
+    },
+    laddertypes::{TypeTerm, TypeID},
+    std::{
+        collections::HashMap,
+        sync::{Arc, RwLock},
+        any::Any
+    },
+    super::{Context, ReprLeaf, ReprTreeExt, context::{TYPEID_list, TYPEID_vec, TYPEID_char, TYPEID_u64, TYPEID_edittree}}
+};
+
+//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
+
+#[derive(Clone)]
+pub struct ReprTree {
+    halo: TypeTerm,
+    type_tag: TypeTerm,
+    branches: HashMap<TypeTerm, Arc<RwLock<ReprTree>>>,
+    leaf: Option< ReprLeaf >
+}
+
+//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
+
+impl std::fmt::Debug for ReprTree {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        writeln!(f, "| type: {:?}", self.type_tag)?;
+
+        for (_k,x) in self.branches.iter() {
+            writeln!(f, "|--> child: {:?}", x)?;
+        }
+        writeln!(f, "");
+
+        Ok(())
+    }
+}
+
+//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
+
+impl ReprTree {
+    pub fn new(type_tag: impl Into<TypeTerm>) -> Self {
+        let type_tag = type_tag.into();
+
+        assert!(type_tag.is_flat());
+        
+        ReprTree {
+            halo: TypeTerm::unit(),
+            type_tag: type_tag.clone(),
+            branches: HashMap::new(),
+            leaf: None
+        }
+    }
+
+    pub fn new_arc(type_tag: impl Into<TypeTerm>) -> Arc<RwLock<Self>> {
+        Arc::new(RwLock::new(Self::new(type_tag)))
+    }
+
+    pub fn get_type(&self) -> &TypeTerm {
+        &self.type_tag
+    }
+
+    pub fn set_halo(&mut self, halo_type: impl Into<TypeTerm>) {
+        self.halo = halo_type.into();
+        for (branch_type, branch) in self.branches.iter() {
+            branch.write().unwrap().set_halo( TypeTerm::Ladder(vec![
+                    self.halo.clone(),
+                    self.type_tag.clone()
+                ]).normalize()
+            );
+        }
+    }
+
+    pub fn get_halo_type(&self) -> &TypeTerm {
+        &self.halo
+    }
+
+    pub fn get_leaf_types(&self) -> Vec< TypeTerm > {
+        let mut leaf_types = Vec::new();
+        if self.leaf.is_some() {
+            leaf_types.push( self.get_type().clone() );
+        }
+        for (branch_type, branch) in self.branches.iter() {
+            for t in branch.read().unwrap().get_leaf_types() {
+                leaf_types.push(TypeTerm::Ladder(vec![
+                    self.get_type().clone(),
+                    t
+                ]).normalize())
+            }
+        }
+        leaf_types
+    }
+
+    pub fn insert_branch(&mut self, repr: Arc<RwLock<ReprTree>>) {
+        let branch_type = repr.read().unwrap().get_type().clone();
+
+        assert!(branch_type.is_flat());
+
+        repr.write().unwrap().set_halo( TypeTerm::Ladder(vec![
+            self.halo.clone(),
+            self.type_tag.clone()
+        ]).normalize() );
+
+        self.branches.insert(branch_type, repr.clone());
+    }
+
+    pub fn from_char(ctx: &Arc<RwLock<Context>>, c: char ) -> Arc<RwLock<Self>> {
+        ReprTree::from_singleton_buffer(
+            Context::parse(ctx, "Char"),
+            SingletonBuffer::new(c)
+        )
+    }
+
+    pub fn from_view<V>( type_tag: impl Into<TypeTerm>, view: OuterViewPort<V> ) -> Arc<RwLock<Self>>
+    where V: View + ?Sized + 'static,
+        V::Msg: Clone
+    {
+        let mut rt = ReprTree::new(type_tag);
+        rt.leaf = Some(ReprLeaf::from_view(view));
+        Arc::new(RwLock::new(rt))
+    }
+
+    pub fn from_singleton_buffer<T>( type_tag: impl Into<TypeTerm>, buf: SingletonBuffer<T> ) -> Arc<RwLock<Self>>
+    where T: Clone + Send + Sync + 'static
+    {
+        let mut rt = ReprTree::new(type_tag);
+        rt.leaf = Some(ReprLeaf::from_singleton_buffer(buf));
+        Arc::new(RwLock::new(rt))
+    }
+
+    pub fn from_str(
+        type_tag: impl Into<TypeTerm>,
+        val: &str
+    ) -> Arc<RwLock<Self>> {
+        let mut lnf = type_tag.into().get_lnf_vec();
+
+        let mut rt = ReprTree::from_vec_buffer(
+            lnf.pop().unwrap(),
+            VecBuffer::with_data( val.chars().collect() )
+        );
+
+        while let Some(t) = lnf.pop() {
+            let mut new_rt = ReprTree::new_arc(t);
+            new_rt.insert_branch(rt);
+            rt = new_rt;
+        }
+
+        rt
+    }
+
+    pub fn from_vec_buffer<T>( type_tag: impl Into<TypeTerm>, buf: VecBuffer<T> ) -> Arc<RwLock<Self>>
+    where T: Clone + Send + Sync + 'static
+    {
+        let mut rt = ReprTree::new(type_tag);
+        rt.leaf = Some(ReprLeaf::from_vec_buffer(buf));
+        Arc::new(RwLock::new(rt))
+    }
+
+    pub fn attach_to<V>(
+        &mut self,
+        src_port: OuterViewPort<V>
+    )
+    where V: View + ?Sized + 'static,
+        V::Msg: Clone
+    {
+        if let Some(leaf) = self.leaf.as_mut() {
+            leaf.attach_to(src_port);
+        } else {
+            eprintln!("cant attach branch without leaf");
+        }
+    }
+
+    /// find, and if necessary, create corresponding path in repr-tree.
+    /// Attach src_port to input of that node
+    pub fn attach_leaf_to<V>(
+        &mut self,
+        mut type_ladder: impl Iterator<Item = TypeTerm>,
+        src_port: OuterViewPort<V>
+    )
+    where V: View + ?Sized + 'static,
+        V::Msg: Clone
+    {
+        while let Some(rung_type) = type_ladder.next() {
+            if &rung_type != self.get_type() { 
+                if let Some(next_repr) = self.branches.get(&rung_type) {
+                    next_repr.write().unwrap().attach_leaf_to(type_ladder, src_port);
+                } else {
+                    let mut next_repr = ReprTree::new(rung_type.clone());
+                    next_repr.attach_leaf_to(type_ladder, src_port);
+                    self.insert_branch(Arc::new(RwLock::new(next_repr)));
+                }
+                return;
+            }
+        }
+
+        if let Some(leaf) = self.leaf.as_mut() {
+            leaf.attach_to(src_port);
+        } else {
+            if self.type_tag == TypeTerm::App(vec![
+                TypeTerm::TypeID(TYPEID_vec),
+                TypeTerm::TypeID(TYPEID_edittree)
+            ]) {
+                let mut leaf = ReprLeaf::from_vec_buffer(
+                    VecBuffer::<
+                        Arc<RwLock<crate::edit_tree::EditTree>>
+                    >::new()
+                );
+
+                leaf.attach_to(src_port);
+                self.leaf = Some(leaf);
+            }           
+            else if self.type_tag == TypeTerm::App(vec![
+                TypeTerm::TypeID(TYPEID_vec),
+                TypeTerm::TypeID(TYPEID_char)
+            ]) {
+                let mut leaf = ReprLeaf::from_vec_buffer(
+                    VecBuffer::<char>::new()
+                );
+
+                leaf.attach_to(src_port);
+                self.leaf = Some(leaf);
+            }
+            else if self.type_tag == TypeTerm::App(vec![
+                TypeTerm::TypeID(TYPEID_vec),
+                TypeTerm::TypeID(TYPEID_u64)
+            ]) {
+                let mut leaf = ReprLeaf::from_vec_buffer(
+                    VecBuffer::<u64>::new()
+                );
+
+                leaf.attach_to(src_port);
+                self.leaf = Some(leaf);
+            } else {
+                self.leaf = Some(ReprLeaf::from_view(src_port));
+            }
+        }
+    }
+
+    pub fn detach(&mut self, ctx: &Arc<RwLock<Context>>) {
+        if let Some(leaf) = self.leaf.as_mut() {
+            if self.type_tag ==
+                TypeTerm::TypeID(TYPEID_edittree)
+            {
+                leaf.detach::< dyn SingletonView<
+                    Item = Arc<RwLock< crate::edit_tree::EditTree >>
+                > >();
+            }
+            else if self.type_tag ==
+                TypeTerm::TypeID(TYPEID_char)
+            {
+                leaf.detach::< dyn SingletonView<Item = char> >();
+            }
+            else if self.type_tag == TypeTerm::TypeID(TYPEID_u64)
+            {
+                leaf.detach::< dyn SingletonView<Item = u64> >();
+            }
+            else if self.type_tag == TypeTerm::App(vec![
+                TypeTerm::TypeID(TYPEID_vec),
+                TypeTerm::TypeID(TYPEID_edittree),
+            ]) {
+                leaf.detach_vec::<
+                    Arc<RwLock< crate::edit_tree::EditTree >>
+                >();
+            }
+            else if self.type_tag == TypeTerm::App(vec![
+                TypeTerm::TypeID(TYPEID_vec),
+                TypeTerm::TypeID(TYPEID_char),
+            ]) {
+                leaf.detach_vec::< char >();
+            }
+            else if self.type_tag == TypeTerm::App(vec![
+                TypeTerm::TypeID(TYPEID_vec),
+                TypeTerm::TypeID(TYPEID_u64),
+            ]) {
+                leaf.detach_vec::< u64 >();
+            }
+            else if self.type_tag == TypeTerm::App(vec![
+                TypeTerm::TypeID(TYPEID_list),
+                TypeTerm::TypeID(TYPEID_edittree),
+            ]) {
+                leaf.detach::< dyn ListView<Arc<RwLock<crate::edit_tree::EditTree>>> >();
+            }
+            else if self.type_tag == TypeTerm::App(vec![
+                TypeTerm::TypeID(TYPEID_list),
+                TypeTerm::TypeID(TYPEID_char),
+            ]) {
+                leaf.detach::< dyn ListView<char> >();
+            }
+            else if self.type_tag == TypeTerm::App(vec![
+                TypeTerm::TypeID(TYPEID_list),
+                TypeTerm::TypeID(TYPEID_u64),
+            ]) {
+                leaf.detach::< dyn ListView<u64> >();
+            }
+            else {
+                eprintln!("cant detach type {}", ctx.read().unwrap().type_term_to_str(&self.type_tag));
+            }
+        }
+
+        for (t,b) in self.branches.iter_mut() {
+            b.write().unwrap().detach(&ctx);
+        }
+    }
+
+    pub fn insert_leaf(
+        &mut self,
+        mut type_ladder: impl Iterator<Item = TypeTerm>,
+        leaf: ReprLeaf
+    ) {
+        while let Some(type_term) = type_ladder.next() {
+            if &type_term != self.get_type() {
+                if let Some(next_repr) = self.branches.get(&type_term) {
+                    next_repr.write().unwrap().insert_leaf(type_ladder, leaf.clone());
+                } else {
+                    let mut next_repr = ReprTree::new(type_term.clone());
+                    next_repr.insert_leaf(type_ladder, leaf.clone());
+                    self.insert_branch(Arc::new(RwLock::new(next_repr)));
+                }
+                return;
+            }
+        }
+
+        self.leaf = Some(leaf);
+    }
+
+    //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
+
+    pub fn descend_one(&self, dst_type: impl Into<TypeTerm>) -> Option<Arc<RwLock<ReprTree>>> {
+        let dst_type = dst_type.into();
+        assert!( dst_type.is_flat() );
+        self.branches.get(&dst_type).cloned()
+    }
+
+    pub fn descend_ladder(rt: &Arc<RwLock<Self>>, mut repr_ladder: impl Iterator<Item = TypeTerm>) -> Option<Arc<RwLock<ReprTree>>> {
+        if let Some(first) = repr_ladder.next() {
+            let rt = rt.read().unwrap();
+            repr_ladder.fold(
+                rt.descend_one(first),
+                |s, t| s?.descend(t))
+        } else {
+            Some(rt.clone())
+        }
+    }
+
+    pub fn descend(rt: &Arc<RwLock<Self>>, dst_type: impl Into<TypeTerm>) -> Option<Arc<RwLock<ReprTree>>> {
+        let mut lnf = dst_type.into().get_lnf_vec();
+        if lnf.len() > 0 {
+            if lnf[0] == rt.get_type() {
+                lnf.remove(0);
+            }
+            ReprTree::descend_ladder(rt, lnf.into_iter())
+        } else {
+            Some(rt.clone())
+        }
+    }
+
+    pub fn ascend(rt: &Arc<RwLock<Self>>, type_term: impl Into<TypeTerm>) -> Arc<RwLock<ReprTree>> {
+        let mut n = Self::new(type_term);
+        n.insert_branch(rt.clone());
+        Arc::new(RwLock::new(n))
+    }
+
+    //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
+
+    pub fn singleton_buffer<T: Clone + Send + Sync + 'static>(&mut self) -> Option<SingletonBuffer<T>> {
+        if let Some(leaf) = self.leaf.as_mut() {
+            leaf.as_singleton_buffer::<T>()
+        } else {
+            // create new singleton buffer
+            /*
+            // default value??
+            let buf = SingletonBuffer::<T>::default();
+            self.leaf = Some(ReprLeaf::from_singleton_buffer(buf.clone()));
+            Some(buf)
+            */
+            None
+        }
+    }
+
+    pub fn vec_buffer<T: Clone + Send + Sync + 'static>(&mut self) -> Option<VecBuffer<T>> {
+        if let Some(leaf) = self.leaf.as_mut() {
+            leaf.as_vec_buffer::<T>()
+        } else {
+            None
+        }
+    }
+
+    //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
+
+    pub fn get_port<V: View + ?Sized + 'static>(&self) -> Option<OuterViewPort<V>>
+    where
+        V::Msg: Clone,
+    {
+        if let Some(leaf) = self.leaf.as_ref() {
+            leaf.get_port::<V>()
+        } else {
+            None
+        }
+    }
+
+    pub fn get_view<V: View + ?Sized + 'static>(&self) -> Option<Arc<V>>
+    where
+        V::Msg: Clone,
+    {
+        self.get_port::<V>()?
+            .get_view()
+    }
+
+    //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
+
+    pub fn view_singleton<T: 'static>(&self) -> OuterViewPort<dyn SingletonView<Item = T>> {
+        self.get_port::<dyn SingletonView<Item = T>>().expect("no singleton-view available")
+    }
+
+    pub fn view_seq<T: 'static>(&self) -> OuterViewPort<dyn SequenceView<Item = T>> {
+        self.get_port::<dyn SequenceView<Item = T>>().expect("no sequence-view available")
+    }
+
+    pub fn view_list<T: Clone + Send + Sync + 'static>(&self) -> OuterViewPort<dyn ListView<T>> {
+        self.get_port::<dyn ListView<T>>().expect("no list-view available")
+    }
+
+    pub fn view_char(&self) -> OuterViewPort<dyn SingletonView<Item = char>> {
+        self.get_port::<dyn SingletonView<Item = char>>().expect("no char-view available")
+    }
+
+    pub fn view_u8(&self) -> OuterViewPort<dyn SingletonView<Item = u8>> {
+        self.get_port::<dyn SingletonView<Item = u8>>().expect("no u8-view available")
+    }
+
+    pub fn view_u64(&self) -> OuterViewPort<dyn SingletonView<Item = u64>> {
+        self.get_port::<dyn SingletonView<Item = u64>>().expect("no u64-view available")
+    }
+
+    pub fn view_usize(&self) -> OuterViewPort<dyn SingletonView<Item = usize>> {
+        self.get_port::<dyn SingletonView<Item = usize>>().expect("no usize-view available")
+    }
+}
+
+//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
+
+
diff --git a/lib-nested-core/src/repr_tree/tests.rs b/lib-nested-core/src/repr_tree/tests.rs
new file mode 100644
index 0000000..8663cb7
--- /dev/null
+++ b/lib-nested-core/src/repr_tree/tests.rs
@@ -0,0 +1,198 @@
+
+use {
+    r3vi::{
+        buffer::singleton::{
+            SingletonBuffer
+        },
+        view::port::UpdateTask
+    },
+    crate::{
+        repr_tree::{Context, ReprTreeExt, ReprTree, ReprLeaf}
+    },
+    std::sync::{Arc, RwLock}
+};
+
+#[test]
+fn halo_type() {
+    let ctx = Arc::new(RwLock::new(Context::new()));
+
+    let mut rt1 = ReprTree::new_arc(Context::parse(&ctx, "ℕ"));
+    let mut rt2 = ReprTree::new_arc(Context::parse(&ctx, "<PosInt 10 BigEndian>"));
+    rt1.insert_branch( rt2.clone() );
+    assert_eq!( rt2.read().unwrap().get_halo_type(), &Context::parse(&ctx, "ℕ") );
+    
+    let mut rt3 = ReprTree::new_arc(Context::parse(&ctx, "<Seq <Digit 10>>"));
+    rt2.insert_branch( rt3.clone() );
+    assert_eq!( rt3.read().unwrap().get_halo_type(), &Context::parse(&ctx, "ℕ~<PosInt 10 BigEndian>") );
+
+    let rt4 = ReprTree::new_arc(Context::parse(&ctx, "<List <Digit 10>>"));
+    rt3.insert_branch( rt4.clone() );
+    assert_eq!( rt4.read().unwrap().get_halo_type(), &Context::parse(&ctx, "ℕ~<PosInt 10 BigEndian>~<Seq <Digit 10>>") );
+
+    
+    let mut r = ReprTree::new_arc(Context::parse(&ctx, "ℕ"));
+    r.create_branch(Context::parse(&ctx, "<PosInt 10 BigEndian>~<Seq <Digit 10>>"));
+    assert_eq!( r.descend(Context::parse(&ctx, "<PosInt 10 BigEndian>")).unwrap().read().unwrap().get_halo_type(), &Context::parse(&ctx, "ℕ") );
+    assert_eq!( r.descend(Context::parse(&ctx, "<PosInt 10 BigEndian>~<Seq <Digit 10>>")).unwrap().read().unwrap().get_halo_type(), &Context::parse(&ctx, "ℕ~<PosInt 10 BigEndian>") );
+}
+
+#[test]
+fn char_view() {
+    let ctx = Arc::new(RwLock::new(Context::new()));
+    crate::editors::digit::init_ctx( ctx.clone() );
+
+    let mut rt_digit = ReprTree::new_arc( Context::parse(&ctx, "<Digit 16>") );
+    rt_digit.insert_leaf(
+        Context::parse(&ctx, "Char"),
+        ReprLeaf::from_singleton_buffer( SingletonBuffer::new('5') )
+    );
+
+    //<><><><>
+    let mut digit_char_buffer = rt_digit
+        .descend( Context::parse(&ctx, "Char") ).unwrap()
+        .singleton_buffer::<char>();
+
+    assert_eq!( digit_char_buffer.get(), '5' );
+    //<><><><>
+
+    let digit_char_view = rt_digit
+        .descend(Context::parse(&ctx, "Char")).unwrap()
+        .view_char();
+
+    assert_eq!( digit_char_view.get_view().unwrap().get(), '5' );
+
+
+    //<><><><>
+    // `Char-view` is correctly coupled to `char-buffer`
+    digit_char_buffer.set('2');
+    assert_eq!( digit_char_view.get_view().unwrap().get(), '2' );
+}
+
+#[test]
+fn digit_projection_char_to_u64() {
+    let ctx = Arc::new(RwLock::new(Context::new()));
+    crate::editors::digit::init_ctx( ctx.clone() );
+
+    let mut rt_digit = ReprTree::new_arc( Context::parse(&ctx, "<Digit 16>") );
+
+    rt_digit.insert_leaf(
+        Context::parse(&ctx, "Char"),
+        ReprLeaf::from_singleton_buffer( SingletonBuffer::new('5') )
+    );
+
+    //<><><><>
+    // add another representation
+ 
+    ctx.read().unwrap().apply_morphism(
+        rt_digit.clone(),
+        &laddertypes::MorphismType {
+            src_type: Context::parse(&ctx, "<Digit 16>~Char"),
+            dst_type: Context::parse(&ctx, "<Digit 16>~ℤ_2^64~machine.UInt64")
+        }
+    );
+
+    let digit_u64_view = rt_digit
+        .descend(Context::parse(&ctx, "ℤ_2^64~machine.UInt64")).unwrap()
+        .view_u64();
+
+    assert_eq!( digit_u64_view.get_view().unwrap().get(), 5 as u64 );
+
+
+    // projection behaves accordingly , when buffer is changed
+
+    let mut digit_char_buffer = rt_digit
+        .descend( Context::parse(&ctx, "Char") ).unwrap()
+        .singleton_buffer::<char>();
+
+    digit_char_buffer.set('2');
+    assert_eq!( digit_u64_view.get_view().unwrap().get(), 2 as u64 );
+}
+
+#[test]
+fn digit_projection_u64_to_char() {
+    let ctx = Arc::new(RwLock::new(Context::new()));
+    crate::editors::digit::init_ctx( ctx.clone() );
+
+    let mut rt_digit = ReprTree::new_arc( Context::parse(&ctx, "<Digit 16>") );
+
+    rt_digit.insert_leaf(
+        Context::parse(&ctx, "ℤ_2^64~machine.UInt64"),
+        ReprLeaf::from_singleton_buffer( SingletonBuffer::new(5 as u64) )
+    );
+
+    //<><><><>
+    // add another representation
+ 
+    ctx.read().unwrap().apply_morphism(
+        rt_digit.clone(),
+        &laddertypes::MorphismType {
+            src_type: Context::parse(&ctx, "<Digit 16>~ℤ_2^64~machine.UInt64"),
+            dst_type: Context::parse(&ctx, "<Digit 16>~Char")
+        }
+    );
+
+    let digit_u64_view = rt_digit
+        .descend(Context::parse(&ctx, "Char")).unwrap()
+        .view_char();
+
+    assert_eq!( digit_u64_view.get_view().unwrap().get(), '5' );
+}
+
+
+#[test]
+fn char_buffered_projection() {
+    let ctx = Arc::new(RwLock::new(Context::new()));
+    crate::editors::digit::init_ctx( ctx.clone() );
+
+    let mut rt_digit = ReprTree::new_arc( Context::parse(&ctx, "<Digit 16>") );
+
+    rt_digit.insert_leaf(
+        Context::parse(&ctx, "ℤ_2^64~machine.UInt64"),
+        ReprLeaf::from_singleton_buffer( SingletonBuffer::new(8 as u64) )
+    );
+
+    let mut digit_u64_buffer = rt_digit
+        .descend(Context::parse(&ctx, "ℤ_2^64~machine.UInt64")).unwrap()
+        .singleton_buffer::<u64>();
+
+    assert_eq!( digit_u64_buffer.get(), 8 );
+
+    rt_digit.insert_leaf(
+        Context::parse(&ctx, "Char"),
+        ReprLeaf::from_singleton_buffer( SingletonBuffer::new('5') )
+    );
+
+    let digit_char_buf = rt_digit
+        .descend(Context::parse(&ctx, "Char")).unwrap()
+        .singleton_buffer::<char>();
+    let digit_char_view = rt_digit
+        .descend(Context::parse(&ctx, "Char")).unwrap()
+        .view_char();
+
+    // before setting up the morphism, char-view remains as initialized
+    assert_eq!( digit_char_buf.get(), '5' );
+    assert_eq!( digit_char_view.get_view().unwrap().get(), '5' );
+
+    // now we attach the char-repr to the u64-repr
+    ctx.read().unwrap().apply_morphism(
+        rt_digit.clone(),
+        &laddertypes::MorphismType {
+            src_type: Context::parse(&ctx, "<Digit 16>~ℤ_2^64~machine.UInt64"),
+            dst_type: Context::parse(&ctx, "<Digit 16>~Char")
+        }
+    );
+
+    // char buffer and view should now follow the u64-buffer
+    assert_eq!( digit_char_view.get_view().unwrap().get(), '8' );
+    assert_eq!( digit_char_buf.get(), '8' );
+
+    // now u64-buffer changes, and char-buffer should change accordingly
+    digit_u64_buffer.set(3);
+    assert_eq!( digit_u64_buffer.get(), 3 );
+
+    // char buffer should follow
+    digit_char_view.0.update();
+    assert_eq!( digit_char_buf.get(), '3' );
+    assert_eq!( digit_char_view.get_view().unwrap().get(), '3' ); 
+}
+
diff --git a/lib-nested-core/src/utils/mod.rs b/lib-nested-core/src/utils/mod.rs
new file mode 100644
index 0000000..f97b6e5
--- /dev/null
+++ b/lib-nested-core/src/utils/mod.rs
@@ -0,0 +1,2 @@
+pub mod modulo;
+pub use modulo::modulo;
diff --git a/nested/src/utils/modulo.rs b/lib-nested-core/src/utils/modulo.rs
similarity index 100%
rename from nested/src/utils/modulo.rs
rename to lib-nested-core/src/utils/modulo.rs
diff --git a/nested/Cargo.toml b/lib-nested-tty/Cargo.toml
similarity index 58%
rename from nested/Cargo.toml
rename to lib-nested-tty/Cargo.toml
index 8814165..0e5b412 100644
--- a/nested/Cargo.toml
+++ b/lib-nested-tty/Cargo.toml
@@ -1,24 +1,23 @@
 [package]
 authors = ["Michael Sippel <micha@fragmental.art>"]
-edition = "2018"
-name = "nested"
+name = "nested-tty"
 version = "0.1.0"
+edition = "2018"
 
 [dependencies]
-#r3vi = { git = "https://git.exobiont.de/senvas/lib-r3vi.git" }
 r3vi = { path = "../../lib-r3vi" }
 laddertypes = { path = "../../lib-laddertypes" }
-no_deadlocks = "*"
+nested = { path = "../lib-nested-core" }
 cgmath = { version = "0.18.0", features = ["serde"] }
-termion = "2.0.1"
+serde = { version = "1.0", features = ["serde_derive"] }
+termion = "2.0.3"
 vte = "0.10.1"
 ansi_colours = "1.0"
-signal-hook = "0.3.1"
-signal-hook-async-std = "0.2.0"
-serde = { version = "1.0", features = ["derive"] }
-bincode = "1.3.3"
-serde_json = "*"
+signal-hook = "*"
+signal-hook-async-std = "*"
 
 [dependencies.async-std]
 version = "1.9.0"
 features = ["unstable", "attributes"]
+
+
diff --git a/nested/src/terminal/ansi_parser.rs b/lib-nested-tty/src/ansi_parser.rs
similarity index 99%
rename from nested/src/terminal/ansi_parser.rs
rename to lib-nested-tty/src/ansi_parser.rs
index 669ee06..399bf15 100644
--- a/nested/src/terminal/ansi_parser.rs
+++ b/lib-nested-tty/src/ansi_parser.rs
@@ -10,7 +10,8 @@ use {
         projection::projection_helper::ProjectionHelper,
     },
     crate::{
-        terminal::{TerminalAtom, TerminalStyle, TerminalView},
+        atom::{TerminalAtom, TerminalStyle},
+        TerminalView,
     },
     cgmath::{Point2, Vector2},
     std::io::Read,
diff --git a/nested/src/terminal/atom.rs b/lib-nested-tty/src/atom/mod.rs
similarity index 93%
rename from nested/src/terminal/atom.rs
rename to lib-nested-tty/src/atom/mod.rs
index 2cd4d29..0bc55f1 100644
--- a/nested/src/terminal/atom.rs
+++ b/lib-nested-tty/src/atom/mod.rs
@@ -1,7 +1,7 @@
-use {
-    super::TerminalStyle,
-    serde::{Deserialize, Serialize},
-};
+pub mod style;
+pub use style::TerminalStyle;
+
+use serde::{Deserialize, Serialize};
 
 #[derive(Clone, Copy, Serialize, Deserialize, Debug)]
 pub struct TerminalAtom {
diff --git a/nested/src/terminal/style.rs b/lib-nested-tty/src/atom/style.rs
similarity index 100%
rename from nested/src/terminal/style.rs
rename to lib-nested-tty/src/atom/style.rs
diff --git a/nested/src/terminal/compositor.rs b/lib-nested-tty/src/compositor.rs
similarity index 97%
rename from nested/src/terminal/compositor.rs
rename to lib-nested-tty/src/compositor.rs
index d8a53e4..e0774d6 100644
--- a/nested/src/terminal/compositor.rs
+++ b/lib-nested-tty/src/compositor.rs
@@ -6,7 +6,7 @@ use {
         },
         projection::projection_helper::*,
     },
-    crate::{terminal::{TerminalAtom, TerminalView}},
+    crate::{TerminalAtom, TerminalView},
     cgmath::Point2,
     std::sync::Arc,
     std::sync::RwLock,
diff --git a/nested/src/utils/color.rs b/lib-nested-tty/src/edit_tree/color.rs
similarity index 96%
rename from nested/src/utils/color.rs
rename to lib-nested-tty/src/edit_tree/color.rs
index 532a7fe..42f36fc 100644
--- a/nested/src/utils/color.rs
+++ b/lib-nested-tty/src/edit_tree/color.rs
@@ -1,5 +1,5 @@
 use {
-    crate::terminal::TerminalStyle,
+    crate::atom::TerminalStyle,
 };
 
 pub fn bg_style_from_depth(depth: usize) -> TerminalStyle {
diff --git a/lib-nested-tty/src/edit_tree/cursor_widget.rs b/lib-nested-tty/src/edit_tree/cursor_widget.rs
new file mode 100644
index 0000000..2504428
--- /dev/null
+++ b/lib-nested-tty/src/edit_tree/cursor_widget.rs
@@ -0,0 +1,33 @@
+
+impl TreeNav {
+    fn get_cursor_widget(&self) -> OuterViewPort<dyn TerminalView> {
+        VecBuffer::with_data(
+            vec![
+                make_label("@").with_fg_color((150, 80,230)),
+                self.get_addr_view()
+                    .map(|i|
+                        make_label(&format!("{}", i)).with_fg_color((0, 100, 20)))
+                    .separate(make_label(".").with_fg_color((150, 80,230)))
+                    .to_grid_horizontal()
+                    .flatten(),
+                make_label(":").with_fg_color((150, 80,230)),
+                self.get_mode_view()
+                    .map(|mode| {
+                        make_label(
+                            match mode {
+                                ListCursorMode::Insert => "INSERT",
+                                ListCursorMode::Select => "SELECT"
+                            })
+                            .with_fg_color((200, 200, 20))
+                    })
+                    .to_grid()
+                    .flatten(),
+                make_label(":").with_fg_color((150, 80,230))
+            ]
+        ).get_port()
+            .to_sequence()
+            .to_grid_horizontal()
+            .flatten()
+    }
+}
+
diff --git a/nested/src/diagnostics.rs b/lib-nested-tty/src/edit_tree/diagnostics.rs
similarity index 82%
rename from nested/src/diagnostics.rs
rename to lib-nested-tty/src/edit_tree/diagnostics.rs
index c1230c5..6ffad73 100644
--- a/nested/src/diagnostics.rs
+++ b/lib-nested-tty/src/edit_tree/diagnostics.rs
@@ -1,27 +1,3 @@
-use {
-    r3vi::{
-        view::{OuterViewPort, sequence::*},
-        buffer::{vec::*, index_hashmap::*}
-    },
-    crate::{
-        terminal::{
-            TerminalView, TerminalStyle, make_label
-        }
-    },
-    cgmath::Point2
-};
-
-#[derive(Clone)]
-pub struct Message {
-    pub addr: Vec<usize>,
-    pub port: OuterViewPort<dyn TerminalView>
-}
-
-pub trait Diagnostics {
-    fn get_msg_port(&self) -> OuterViewPort<dyn SequenceView<Item = Message>> {
-        VecBuffer::new().get_port().to_sequence()
-    }
-}
 
 pub fn make_error(msg: OuterViewPort<dyn TerminalView>) -> Message {
     let mut mb = IndexBuffer::new();
diff --git a/lib-nested-tty/src/edit_tree/keymap.rs b/lib-nested-tty/src/edit_tree/keymap.rs
new file mode 100644
index 0000000..09a3609
--- /dev/null
+++ b/lib-nested-tty/src/edit_tree/keymap.rs
@@ -0,0 +1,110 @@
+use {
+    termion::event::{Event, Key},
+    r3vi::{
+        buffer::singleton::*
+    },
+    nested::{
+        repr_tree::{Context, ReprTree},
+        editors::list::ListCmd,
+        edit_tree::nav::TreeNavCmd
+    },
+    crate::{
+        TerminalEvent
+    },
+    std::sync::{Arc, RwLock}
+};
+
+fn neo2_treenav_keymap( key: &Key ) -> Option<TreeNavCmd> {
+    match key {
+        Key::Ctrl(c) => {
+            match c {
+
+                // left hand
+                'l' => Some(TreeNavCmd::up),
+                'i' => Some(TreeNavCmd::qnexd),
+                'a' => Some(TreeNavCmd::dn),
+                'e' => Some(TreeNavCmd::pxev),
+
+                // right hand
+                'n' => Some(TreeNavCmd::nexd),
+                'r' => Some(TreeNavCmd::dn_pxev),
+                't' => Some(TreeNavCmd::qnexd),
+                'g' => Some(TreeNavCmd::up_nexd),
+
+                _ => None
+            }
+        }
+        _ => None
+    }
+}
+
+fn universal_treenav_keymap( key: &Key ) -> Option<TreeNavCmd> {
+    match key {    
+        Key::Left => Some(TreeNavCmd::pxev),
+        Key::Right => Some(TreeNavCmd::nexd),
+        Key::Up => Some(TreeNavCmd::up),
+        Key::Down => Some(TreeNavCmd::dn),
+        Key::Home => Some(TreeNavCmd::qpxev),
+        Key::End => Some(TreeNavCmd::qnexd),
+        Key::PageUp => Some(TreeNavCmd::up_nexd),
+        Key::PageDown => Some(TreeNavCmd::pxev_dn_qnexd),
+        _ => None
+    }
+}
+
+fn tty_list_keymap( key: &Key ) -> Option<ListCmd> {
+    match key {
+//      Key::Char('\t') => Some( ListCmd::ToggleLeafMode ),
+
+        Key::Backspace => Some( ListCmd::DeletePxev ),
+        Key::Delete => Some( ListCmd::DeleteNexd ),
+
+        _ => None
+    }
+}
+
+impl TerminalEvent {
+    pub fn to_repr_tree( &self, ctx: &Arc<RwLock<Context>> ) -> Arc<RwLock<ReprTree>> {
+        match self {
+            TerminalEvent::Input(Event::Key(key)) => {
+                if let Some(tree_nav_cmd) = neo2_treenav_keymap(key) {
+                    ReprTree::from_singleton_buffer(
+                        Context::parse(&ctx, "TreeNavCmd"),
+                        SingletonBuffer::new(tree_nav_cmd)
+                    )
+                } else if let Some(tree_nav_cmd) = universal_treenav_keymap(key) {
+                    ReprTree::from_singleton_buffer(
+                        Context::parse(&ctx, "TreeNavCmd"),
+                        SingletonBuffer::new(tree_nav_cmd)
+                    )
+                } else {
+                    if let Some(list_cmd) = tty_list_keymap(key) {
+                        ReprTree::from_singleton_buffer(
+                            Context::parse(&ctx, "ListCmd"),
+                            SingletonBuffer::new(list_cmd)
+                        )
+                    } else {
+                        match key {
+                            Key::Char(c) => {
+                                ReprTree::from_char(&ctx, *c)
+                            }
+                            _ => {
+                                ReprTree::from_singleton_buffer(
+                                    Context::parse(&ctx, "TerminalEvent"),
+                                    SingletonBuffer::new(self.clone())
+                                )
+                            }
+                        }
+                    }
+                }
+            }
+            _ => {
+                ReprTree::from_singleton_buffer(
+                    Context::parse(&ctx, "TerminalEvent"),
+                    SingletonBuffer::new(self.clone())
+                )
+            }
+        }
+    }
+}
+
diff --git a/lib-nested-tty/src/edit_tree/mod.rs b/lib-nested-tty/src/edit_tree/mod.rs
new file mode 100644
index 0000000..fdf1de4
--- /dev/null
+++ b/lib-nested-tty/src/edit_tree/mod.rs
@@ -0,0 +1,4 @@
+
+pub mod color;
+pub mod keymap;
+
diff --git a/lib-nested-tty/src/editors/char.rs b/lib-nested-tty/src/editors/char.rs
new file mode 100644
index 0000000..e69de29
diff --git a/nested/src/editors/list/pty_editor.rs b/lib-nested-tty/src/editors/list.rs
similarity index 57%
rename from nested/src/editors/list/pty_editor.rs
rename to lib-nested-tty/src/editors/list.rs
index 829aef4..e55172c 100644
--- a/nested/src/editors/list/pty_editor.rs
+++ b/lib-nested-tty/src/editors/list.rs
@@ -3,13 +3,17 @@ use {
         view::{ViewPort, OuterViewPort, sequence::*},
         projection::decorate_sequence::*,
     },
-    crate::{
-        type_system::{Context, ReprTree},
+    nested::{
+        repr_tree::{Context, ReprTree},
         editors::list::*,
-        terminal::{TerminalEvent, TerminalView, make_label},
-        tree::{TreeCursor, TreeNav, TreeNavResult},
-        tree::NestedNode,
-        PtySegment
+        edit_tree::{TreeCursor, TreeNav, TreeNavResult, EditTree},
+        repr_tree::{ReprTreeExt, ReprLeaf}
+    },
+    crate::{
+        DisplaySegment,
+        TerminalStyle,
+        TerminalEvent, TerminalView, make_label,
+        edit_tree::color::{bg_style_from_depth, fg_style_from_depth}
     },
     std::sync::{Arc, RwLock},
     termion::event::{Event, Key}
@@ -17,6 +21,41 @@ use {
 
 //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
 
+impl DisplaySegment for ListSegment {
+    fn display_view(&self) -> OuterViewPort<dyn TerminalView> {
+        match self {
+            ListSegment::InsertCursor => {
+                make_label("|")
+                    .map_item(move |_pt, atom| {
+                     atom.add_style_front(TerminalStyle::fg_color((150,80,230)))
+                        .add_style_front(TerminalStyle::bold(true))
+                    })
+            }
+            ListSegment::Item{ editor, cur_dist } => {
+                let e = editor.clone();
+                let cur_dist = *cur_dist;
+                editor.display_view().map_item(move |_pt, atom| {
+                    let c = e.get_cursor();
+                    let cur_depth = c.tree_addr.len();
+                    let select =
+                        if cur_dist == 0 {
+                            cur_depth
+                        } else {
+                            usize::MAX
+                        };
+                    
+                    atom
+                        .add_style_back(bg_style_from_depth(select))
+                        .add_style_back(TerminalStyle::bold(select==1))
+                        .add_style_back(fg_style_from_depth(e.disp.depth.get_view().get()))
+                })
+            }
+        }
+    }
+}
+
+//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
+
 pub struct PTYListStyle {
     style: (String, String, String)
 }
@@ -34,7 +73,7 @@ impl PTYListStyle {
             editor.get_data_port()
         );
         let se = seg_seq.read().unwrap();
-        se.get_view().map(move |segment| segment.pty_view())
+        se.get_view().map(move |segment| segment.display_view())
     }
 
     pub fn pty_view(&self, editor: &ListEditor) -> OuterViewPort<dyn TerminalView> {
@@ -42,24 +81,28 @@ impl PTYListStyle {
             editor.get_cursor_port(),
             editor.get_data_port()
         );
-        let seg_seq = seg_seq.read().unwrap();
+
+        let seg_seq0 = seg_seq.read().unwrap();
+        let seg_seq = seg_seq0.get_view();
+        drop(seg_seq0);
 
         seg_seq
-            .get_view()
-            .map(move |segment| segment.pty_view())
+            .map(move |segment| segment.display_view())
             .separate(make_label(&self.style.1))
             .wrap(make_label(&self.style.0), make_label(&self.style.2))
             .to_grid_horizontal()
             .flatten()
     }
 
-    pub fn for_node(node: &mut NestedNode, style: (&str, &str, &str)) {
-        node.view = Some(
-            Self::new(style)
-                .pty_view(
-                    &node.get_edit::<ListEditor>().unwrap().read().unwrap()
-                )
-        );
+    pub fn for_node(node: &mut EditTree, style: (&str, &str, &str)) {
+        let editor = node.get_edit::<ListEditor>().unwrap();
+        let editor = editor.read().unwrap();
+        let pty_view = Self::new(style).pty_view(&editor);
+        node.disp.view
+            .attach_leaf_to(
+                Context::parse(&node.ctx, "TerminalView"),
+                pty_view
+            );
     }
 }
 
@@ -94,10 +137,11 @@ impl PTYListController {
     }
 
     pub fn for_node(
-        node: &mut NestedNode,
+        node: &mut EditTree,
         split_char: Option<char>,
         close_char: Option<char>
     ) {
+/*
         {
             let ctx = node.ctx.as_ref();
             let mut ctx = ctx.write().unwrap();
@@ -109,15 +153,15 @@ impl PTYListController {
                 ctx.meta_chars.push(*c);
             }
         }
-        
+*/
         let editor = node.get_edit::<ListEditor>().unwrap();
-        let controller = Arc::new(RwLock::new(PTYListController::from_editor( editor, split_char, close_char, node.depth.clone() )));
+        let controller = Arc::new(RwLock::new(PTYListController::from_editor( editor, split_char, close_char, node.disp.depth.clone() )));
 
-        node.cmd.set(Some(controller.clone()));
-        node.close_char.set(close_char);
+        node.ctrl.cmd.set(Some(controller.clone()));
+        node.ctrl.close_char.set(close_char);
     }
 
-    pub fn get_data_port(&self) -> OuterViewPort<dyn SequenceView<Item = NestedNode>> {
+    pub fn get_data_port(&self) -> OuterViewPort<dyn SequenceView<Item = EditTree>> {
         self.editor.read().unwrap().get_data_port()
     }
 
@@ -125,31 +169,38 @@ impl PTYListController {
         self.editor.write().unwrap().clear();
     }
 
-    pub fn get_item(&self) -> Option<NestedNode> {
+    pub fn get_item(&self) -> Option<EditTree> {
         self.editor.read().unwrap().get_item()
     }
 
-    pub fn handle_term_event(&mut self, event: &TerminalEvent, _cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult {
+    pub fn handle_term_event(&mut self, event: &TerminalEvent, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult {
         let mut e = self.editor.write().unwrap();
         match event {
             TerminalEvent::Input(Event::Key(Key::Insert)) => {
                 e.toggle_leaf_mode();
                 TreeNavResult::Continue
             }
-            _  => TreeNavResult::Continue
-        }        
+            TerminalEvent::Input(Event::Key(Key::Char(c))) => {
+                let ctx = e.ctx.clone();
+                drop(e);
+                self.handle_any_event(
+                    ReprTree::from_char(&ctx, *c)
+                )
+            }
+            _ => TreeNavResult::Continue
+        }
     }
 
     pub fn handle_meta_char(&mut self, c: char, child_close_char: Option<char>) -> TreeNavResult {
-        eprintln!("handle meta char: got '{}', child_close={:?}, self.close={:?}, split={:?}", c, child_close_char, self.close_char, self.split_char);
+//        eprintln!("handle meta char: got '{}', child_close={:?}, self.close={:?}, split={:?}", c, child_close_char, self.close_char, self.split_char);
         let mut e = self.editor.write().unwrap();
         let cur = e.cursor.get();
-        
+
         if Some(c) == self.split_char
 //            || Some(c) == child_close_char
         {
             e.listlist_split();
-            eprintln!("done listlist split");
+ //           eprintln!("done listlist split");
             TreeNavResult::Continue
         } else if Some(c) == child_close_char {
             e.goto(TreeCursor::none());
@@ -171,23 +222,47 @@ impl PTYListController {
 
         match cur.mode {
             ListCursorMode::Insert => {
-                let mut new_edit = Context::make_node(&e.ctx, e.typ.clone(), self.depth.map(|d| d+1)).unwrap();
-                new_edit.goto(TreeCursor::home());
+                let rt = ReprTree::new_arc(e.typ.clone());
 
-                match new_edit.send_cmd_obj(cmd_obj.clone()) {
-                    TreeNavResult::Continue => {
-                        e.insert(Arc::new(RwLock::new(new_edit.clone())));
-                        TreeNavResult::Continue
+                let src_ladder = laddertypes::TypeTerm::Ladder(vec![
+                    rt.read().unwrap().get_type().clone()
+                ]);
+                let dst_ladder = laddertypes::TypeTerm::Ladder(vec![
+                    rt.read().unwrap().get_type().clone(),
+                    ctx.type_term_from_str("EditTree").expect("")
+                ]);
+                ctx.apply_morphism(
+                    &rt,
+                    &laddertypes::MorphismType {
+                        src_type: src_ladder,
+                        dst_type: dst_ladder
                     }
-                    TreeNavResult::Exit => {
-                        TreeNavResult::Exit
+                );
+
+                let new_edittree = ctx.setup_edittree( &rt );
+
+                if let Some(new_edittree) = new_edittree {
+                    let mut ne = new_edittree.get();
+                    let mut ne = ne.write().unwrap();
+                    match ne.send_cmd_obj(cmd_obj.clone()) {
+                        TreeNavResult::Continue => {
+                            drop(ne);
+                            e.insert(new_edittree.value.read().unwrap().clone());
+                            TreeNavResult::Continue
+                        }
+                        TreeNavResult::Exit => {
+                            TreeNavResult::Exit
+                        }
                     }
+                } else {
+                    panic!("cant get edit tree");
+                    TreeNavResult::Continue
                 }
             },
             ListCursorMode::Select => {
                 if let Some(item) = e.get_item_mut() {
                     let res = item.write().unwrap().send_cmd_obj(cmd_obj.clone());
-                    let child_close_char = item.read().unwrap().close_char.get();
+                    let child_close_char = item.read().unwrap().ctrl.close_char.get();
 
                    match res {
                         TreeNavResult::Continue => TreeNavResult::Continue,
@@ -218,7 +293,7 @@ impl PTYListController {
 }
 
 use r3vi::view::singleton::SingletonView;
-use crate::commander::ObjCommander;
+use nested::editors::ObjCommander;
 
 impl ObjCommander for PTYListController {
     fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult {
@@ -226,7 +301,7 @@ impl ObjCommander for PTYListController {
         let cmd_type = cmd_obj.read().unwrap().get_type().clone();
 
         if cmd_type == Context::parse(&e.ctx, "ListCmd").into()
-        || cmd_type == Context::parse(&e.ctx, "NestedNode").into()
+        || cmd_type == Context::parse(&e.ctx, "EditTree").into()
         {
             e.send_cmd_obj( cmd_obj )
         }
diff --git a/lib-nested-tty/src/editors/mod.rs b/lib-nested-tty/src/editors/mod.rs
new file mode 100644
index 0000000..669aab7
--- /dev/null
+++ b/lib-nested-tty/src/editors/mod.rs
@@ -0,0 +1,85 @@
+
+pub mod list;
+
+use {
+    nested::{
+        edit_tree::{EditTree},
+        repr_tree::{ReprTree, Context}
+    },
+    r3vi::{
+        view::{singleton::*, sequence::*},
+        projection::decorate_sequence::*
+    },
+    crate::{
+        make_label,
+        DisplaySegment,
+        atom::{TerminalAtom, TerminalStyle}
+    }
+};
+
+pub fn edittree_make_char_view(
+    node: EditTree
+) -> EditTree {
+    node.disp.view
+        .write().unwrap()
+        .insert_branch(ReprTree::from_view(
+            Context::parse(&node.ctx, "TerminalView"),
+            node.get_edit::< nested::editors::char::CharEditor >()
+                .unwrap()
+                .read()
+                .unwrap()
+                .get_port()
+                .map(move |c| TerminalAtom::from(if c == '\0' { ' ' } else { c }))
+                .to_grid()
+        ));
+
+    node
+}
+
+pub fn edittree_make_digit_view(
+    node: EditTree
+) -> EditTree {
+    node.disp.view
+        .write().unwrap()
+        .insert_branch(ReprTree::from_view(
+            Context::parse(&node.ctx, "TerminalView"),
+            node.get_edit::< nested::editors::digit::DigitEditor >()
+                .unwrap()
+                .read()
+                .unwrap()
+                .get_data_port()
+                .map(move |digit|
+                    match digit {
+                        Ok(digit) => TerminalAtom::new( char::from_digit(digit, 16).unwrap_or('?'), TerminalStyle::fg_color((220, 220, 0)) ),
+                        Err(c) => TerminalAtom::new( c, TerminalStyle::fg_color((220, 0, 0)) )
+                    }
+                )
+                .to_grid()
+        ));
+
+    node
+}
+
+/*
+pub fn edittree_make_seq_view(
+    mut node: EditTree
+) -> EditTree {
+    node.disp.view
+        .write().unwrap()
+        .insert_branch(ReprTree::new_leaf(
+            Context::parse(&node.ctx, "TerminalView"),
+            node.get_edit::< nested::editors::list::ListEditor >()
+                .unwrap()
+                .read().unwrap()
+                .get_data_port()
+                .map(move |item_edittree|
+                    edittree_make_tty_view( item_edittree ).display_view()
+                )
+                .wrap(make_label("("), make_label(")"))
+                .to_grid_horizontal()
+                .flatten()
+                .into()
+        ));
+    node
+}
+*/
diff --git a/lib-nested-tty/src/editors/product.rs b/lib-nested-tty/src/editors/product.rs
new file mode 100644
index 0000000..e69de29
diff --git a/lib-nested-tty/src/editors/singleton.rs b/lib-nested-tty/src/editors/singleton.rs
new file mode 100644
index 0000000..e69de29
diff --git a/lib-nested-tty/src/editors/sum.rs b/lib-nested-tty/src/editors/sum.rs
new file mode 100644
index 0000000..626f249
--- /dev/null
+++ b/lib-nested-tty/src/editors/sum.rs
@@ -0,0 +1,8 @@
+
+
+impl PtySegment for SumEditor {
+    fn pty_view(&self) -> OuterViewPort<dyn TerminalView> {
+        self.port.outer()
+    }
+}
+
diff --git a/lib-nested-tty/src/lib.rs b/lib-nested-tty/src/lib.rs
new file mode 100644
index 0000000..0e12095
--- /dev/null
+++ b/lib-nested-tty/src/lib.rs
@@ -0,0 +1,180 @@
+
+#![feature(trait_alias)]
+
+// <<<<>>>><<>><><<>><<< * >>><<>><><<>><<<<>>>> \\
+
+pub mod atom;
+
+pub mod compositor;
+pub mod ansi_parser;
+
+pub mod terminal;
+pub mod tty_application;
+
+pub mod editors;
+pub mod edit_tree;
+//pub mod widgets;
+
+// <<<<>>>><<>><><<>><<< * >>><<>><><<>><<<<>>>> \\
+
+pub use {
+    atom::{TerminalAtom, TerminalStyle},
+    terminal::{Terminal, TerminalEvent},
+    tty_application::TTYApplication,
+    compositor::TerminalCompositor,
+};
+
+use r3vi::view::grid::*;
+
+// <<<<>>>><<>><><<>><<< * >>><<>><><<>><<<<>>>> \\
+
+pub trait TerminalView = GridView<Item = TerminalAtom>;
+
+// <<<<>>>><<>><><<>><<< * >>><<>><><<>><<<<>>>> \\
+
+use r3vi::view::OuterViewPort;
+
+pub trait DisplaySegment {
+    fn display_view(&self) -> OuterViewPort<dyn TerminalView>;
+}
+
+
+use nested::repr_tree::{Context, ReprTreeExt};
+use std::sync::{Arc, RwLock};
+
+impl DisplaySegment for nested::edit_tree::EditTree {
+    fn display_view(&self) -> OuterViewPort<dyn TerminalView> {
+        if let Some( tv_repr ) = self.disp.view
+            .descend( Context::parse(&self.ctx, "TerminalView") )
+        {
+            if let Some(port) = 
+            tv_repr
+                .read().unwrap()
+                .get_port::<dyn TerminalView>() {
+                    port
+                }
+                
+                else {
+                make_label("# could not get ViewPort #")
+            }
+        } else {
+            make_label("# No TTY View available #")
+            .map_item(|_p,a| a.add_style_back(TerminalStyle::fg_color((220, 30, 30))))
+        }
+    }
+}
+
+//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
+
+use {
+    r3vi::{
+       buffer::vec::*,
+    },
+    cgmath::Point2,
+};
+
+pub fn make_label(s: &str) -> OuterViewPort<dyn TerminalView> {
+    let label = VecBuffer::with_data(s.chars().collect());
+
+    let v = label.get_port()
+        .to_sequence()
+        .map(|c| TerminalAtom::from(c))
+        .to_index()
+        .map_key(
+            |idx| Point2::new(*idx as i16, 0),
+            |pt| if pt.y == 0 { Some(pt.x as usize) } else { None },
+        );
+
+    v
+}
+
+//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
+
+pub trait TerminalProjections {
+    fn with_style(&self, style: TerminalStyle) -> OuterViewPort<dyn TerminalView>;
+    fn with_fg_color(&self, col: (u8, u8, u8)) -> OuterViewPort<dyn TerminalView>;
+    fn with_bg_color(&self, col: (u8, u8, u8)) -> OuterViewPort<dyn TerminalView>;
+}
+
+impl TerminalProjections for OuterViewPort<dyn TerminalView> {
+    fn with_style(&self, style: TerminalStyle) -> OuterViewPort<dyn TerminalView> {
+        self.map_item(
+            move |_idx, a|
+            a.add_style_front(style)
+        )
+    }
+
+    fn with_fg_color(&self, col: (u8, u8, u8)) -> OuterViewPort<dyn TerminalView> {
+        self.with_style(TerminalStyle::fg_color(col))
+    }
+
+    fn with_bg_color(&self, col: (u8, u8, u8)) -> OuterViewPort<dyn TerminalView> {
+        self.with_style(TerminalStyle::bg_color(col))
+    }
+}
+
+
+//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
+
+pub fn setup_edittree_hook(ctx: &Arc<RwLock<Context>>) {
+
+    let char_type = Context::parse(&ctx, "Char");
+    let digit_type = Context::parse(&ctx, "<Digit Radix>");
+    let list_type = Context::parse(&ctx, "<List Item>");
+    let posint_bin_type = Context::parse(&ctx, "<PosInt 2 BigEndian>");
+    let posint_oct_type = Context::parse(&ctx, "<PosInt 8 BigEndian>");
+    let posint_dec_type = Context::parse(&ctx, "<PosInt 10 BigEndian>");
+    let posint_hex_type = Context::parse(&ctx, "<PosInt 16 BigEndian>");
+    let item_tyid = ctx.read().unwrap().get_var_typeid("Item").unwrap();
+
+    ctx.write().unwrap().meta_chars.push(',');
+    ctx.write().unwrap().meta_chars.push('\"');
+    ctx.write().unwrap().meta_chars.push('}');
+
+    // Define a hook which is executed when a new editTree of type `t` is created.
+    // this will setup the display and navigation elements of the editor.
+    // It provides the necessary bridge to the rendering- & input-backend.
+    ctx.write().unwrap().set_edittree_hook(
+        Arc::new(
+            move |et: &mut nested::edit_tree::EditTree, t: laddertypes::TypeTerm| {
+                if let Ok(σ) = laddertypes::unify(&t, &char_type.clone()) {
+                    *et = crate::editors::edittree_make_char_view(et.clone());
+                }
+                else if let Ok(σ) = laddertypes::unify(&t, &digit_type) {
+                    *et = crate::editors::edittree_make_digit_view(et.clone());
+                }
+                else if let Ok(σ) = laddertypes::unify(&t, &posint_bin_type) {
+                    crate::editors::list::PTYListStyle::for_node( &mut *et, ("0b", "", ""));
+                    crate::editors::list::PTYListController::for_node( &mut *et, None, None );
+                }                
+                else if let Ok(σ) = laddertypes::unify(&t, &posint_oct_type) {
+                    crate::editors::list::PTYListStyle::for_node( &mut *et, ("0o", "", ""));
+                    crate::editors::list::PTYListController::for_node( &mut *et, None, None );
+                }
+                else if let Ok(σ) = laddertypes::unify(&t, &posint_dec_type) {
+                    crate::editors::list::PTYListStyle::for_node( &mut *et, ("0d", "", ""));
+                    crate::editors::list::PTYListController::for_node( &mut *et, None, None );
+                }
+                else if let Ok(σ) = laddertypes::unify(&t, &posint_hex_type) {
+                    crate::editors::list::PTYListStyle::for_node( &mut *et, ("0x", "", ""));
+                    crate::editors::list::PTYListController::for_node( &mut *et, None, None );
+                }
+                else if let Ok(σ) = laddertypes::unify(&t, &list_type) {
+                    let item_type = σ.get( &laddertypes::TypeID::Var(item_tyid) ).unwrap();
+
+                    // choose style based on element type
+                    if *item_type == char_type {
+                        crate::editors::list::PTYListStyle::for_node( &mut *et, ("\"", "", "\""));
+                        crate::editors::list::PTYListController::for_node( &mut *et, None, Some('\"') );
+                    } else {
+                        crate::editors::list::PTYListStyle::for_node( &mut *et, ("{", ", ", "}"));
+                        crate::editors::list::PTYListController::for_node( &mut *et, Some(','), Some('}') );
+                    }
+                    //*et = nested_tty::editors::edittree_make_list_edit(et.clone());
+                }
+            }
+        )
+    );
+
+}
+
diff --git a/nested/src/terminal/terminal.rs b/lib-nested-tty/src/terminal.rs
similarity index 98%
rename from nested/src/terminal/terminal.rs
rename to lib-nested-tty/src/terminal.rs
index c03e588..4cfa510 100644
--- a/nested/src/terminal/terminal.rs
+++ b/lib-nested-tty/src/terminal.rs
@@ -7,7 +7,8 @@ use {
             index::*,
         }
     },
-    super::{TerminalStyle, TerminalView},
+    crate::atom::{TerminalStyle},
+    crate::{TerminalView},
     async_std::{stream::StreamExt, task},
     cgmath::{Point2, Vector2},
     signal_hook,
@@ -24,7 +25,7 @@ use {
     },
 };
 
-#[derive(PartialEq, Eq, Clone)]
+#[derive(PartialEq, Eq, Clone, Debug)]
 pub enum TerminalEvent {
     Resize(Vector2<i16>),
     Input(termion::event::Event),
diff --git a/lib-nested-tty/src/tty_application.rs b/lib-nested-tty/src/tty_application.rs
new file mode 100644
index 0000000..aade2bb
--- /dev/null
+++ b/lib-nested-tty/src/tty_application.rs
@@ -0,0 +1,71 @@
+use {
+    cgmath::Vector2,
+    nested::{
+        edit_tree::EditTree,
+        repr_tree::{Context, ReprTree},
+    },
+    crate::{
+        terminal::TermOutWriter, DisplaySegment, Terminal, TerminalAtom, TerminalCompositor,
+        TerminalEvent, TerminalStyle, TerminalView,
+    },
+    r3vi::{
+        buffer::singleton::*,
+        view::{port::UpdateTask, singleton::*, ViewPort},
+    },
+    std::sync::{Arc, Mutex, RwLock},
+    termion::event::{Event, Key},
+};
+
+pub struct TTYApplication {
+    pub port: ViewPort<dyn TerminalView>,
+    term_writer: Arc<TermOutWriter>,
+}
+
+impl TTYApplication {
+    pub fn new(event_handler: impl Fn(TerminalEvent) + Send + Sync + 'static) -> Self {
+        let port = ViewPort::new();
+        let portmutex = Mutex::new(());
+        let term = Terminal::new(port.outer());
+        let term_writer = term.get_writer();
+
+        async_std::task::spawn(TTYApplication::event_loop(term, port.clone(), Arc::new(event_handler)));
+        async_std::task::spawn(TTYApplication::update_loop(port.clone()));
+
+        TTYApplication {
+            port,
+            term_writer,
+        }
+    }
+
+    /* this task handles all terminal events (e.g. key press, resize)
+     */
+    async fn event_loop(mut term: Terminal, port: ViewPort<dyn TerminalView>, event_handler: Arc<dyn Fn(TerminalEvent) + Send + Sync>) {
+        loop {
+            let ev = term.next_event().await;
+            if ev == TerminalEvent::Input(Event::Key(Key::Ctrl('d'))) {
+                break;
+            }
+
+            event_handler( ev );
+            port.update();
+        }
+    }
+
+    /* this task will continuously pull forward
+     * all notifications which are influencing
+     * the view in `term_port`
+     */
+    async fn update_loop(port: ViewPort<dyn TerminalView>) {
+        loop {
+            port.update();
+            async_std::task::sleep(std::time::Duration::from_millis(50)).await;
+        }
+    }
+
+    /* write the changes in the view of `term_port` to the terminal
+     */
+    pub async fn show(&self) -> Result<(), std::io::Error> {
+        self.term_writer.show().await
+    }
+}
+
diff --git a/nested/src/terminal/widgets/ascii_box.rs b/lib-nested-tty/src/widgets/ascii_box.rs
similarity index 100%
rename from nested/src/terminal/widgets/ascii_box.rs
rename to lib-nested-tty/src/widgets/ascii_box.rs
diff --git a/nested/src/terminal/widgets/mod.rs b/lib-nested-tty/src/widgets/mod.rs
similarity index 100%
rename from nested/src/terminal/widgets/mod.rs
rename to lib-nested-tty/src/widgets/mod.rs
diff --git a/nested/src/terminal/widgets/monstera.rs b/lib-nested-tty/src/widgets/monstera.rs
similarity index 100%
rename from nested/src/terminal/widgets/monstera.rs
rename to lib-nested-tty/src/widgets/monstera.rs
diff --git a/nested/src/terminal/widgets/plot.rs b/lib-nested-tty/src/widgets/plot.rs
similarity index 100%
rename from nested/src/terminal/widgets/plot.rs
rename to lib-nested-tty/src/widgets/plot.rs
diff --git a/math/fib/Cargo.toml b/math/fib/Cargo.toml
deleted file mode 100644
index 7f4efbb..0000000
--- a/math/fib/Cargo.toml
+++ /dev/null
@@ -1,9 +0,0 @@
-[package]
-name = "fib"
-version = "0.1.0"
-edition = "2018"
-
-# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
-
-[dependencies]
-nested = { path = "../../nested" }
diff --git a/math/fib/src/main.rs b/math/fib/src/main.rs
deleted file mode 100644
index b528448..0000000
--- a/math/fib/src/main.rs
+++ /dev/null
@@ -1,62 +0,0 @@
-use std::{
-    fs::File,
-    io::{Read, Write},
-    os::unix::io::FromRawFd,
-};
-
-fn fib(n: u64) -> u64 {
-    let mut y = 0;
-    let mut y1 = 1;
-    let mut y2 = 0;
-
-    for _ in 0..n {
-        y = y1 + y2;
-        y2 = y1;
-        y1 = y;
-    }
-
-    y
-}
-
-fn main() {
-    nested::magic_header();
-
-    eprintln!("            Fibonacci Sequence");
-
-    nested::magic_header();
-
-    eprintln!(
-        "
-interface (Sequence ℕ) 0 1"
-    );
-
-    let mut f0 = unsafe { File::from_raw_fd(0) };
-    eprintln!(
-        "
->0: n
-  ( ℕ )
-  ( MachineInt )
-  ( MachineWord )
-  ( Stream MachineSyllab )
-"
-    );
-
-    let mut f1 = unsafe { File::from_raw_fd(1) };
-    eprintln!(
-        "
-<1: n'th fibonacci number
-  ( ℕ )
-  ( MachineInt )
-  ( MachineWord )
-  ( Stream MachineSyllab )
-"
-    );
-
-    nested::magic_header();
-
-    let mut bytes = [0 as u8; 8];
-    f0.read_exact(&mut bytes).expect("");
-    let n = u64::from_le_bytes(bytes);
-    bytes = fib(n).to_le_bytes();
-    f1.write(&bytes).expect("");
-}
diff --git a/math/int2str/Cargo.toml b/math/int2str/Cargo.toml
deleted file mode 100644
index cdac039..0000000
--- a/math/int2str/Cargo.toml
+++ /dev/null
@@ -1,9 +0,0 @@
-[package]
-name = "int2str"
-version = "0.1.0"
-edition = "2018"
-
-# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
-
-[dependencies]
-nested = { path = "../../nested" }
diff --git a/math/int2str/src/main.rs b/math/int2str/src/main.rs
deleted file mode 100644
index 00cc669..0000000
--- a/math/int2str/src/main.rs
+++ /dev/null
@@ -1,36 +0,0 @@
-use std::{fs::File, io::Read, os::unix::io::FromRawFd};
-
-fn main() {
-    nested::magic_header();
-    eprintln!("     Human-readably Print MachineInt");
-    nested::magic_header();
-
-    let mut f0 = unsafe { File::from_raw_fd(0) };
-    eprintln!(
-        "
->0:
-  ( ℕ )
-  ( MachineInt )
-  ( MachineWord )
-  ( Stream MachineSyllab )
-"
-    );
-
-    eprintln!(
-        "
-<1:
-  ( ℕ )
-  ( PositionalInt 10 BigEndian )
-  ( Sequence ( Digit 10 ) )
-  ( Sequence UTF-8-Char )
-  ( Stream UTF-8-Char )
-  ( Stream MachineSyllab )
-"
-    );
-
-    nested::magic_header();
-
-    let mut bytes = [0 as u8; 8];
-    f0.read_exact(&mut bytes).expect("");
-    println!("{}", u64::from_le_bytes(bytes));
-}
diff --git a/math/radix_transform/src/main.rs b/math/radix_transform/src/main.rs
deleted file mode 100644
index b1b48ff..0000000
--- a/math/radix_transform/src/main.rs
+++ /dev/null
@@ -1,137 +0,0 @@
-use nested::{
-    core::{TypeDict, ViewPort},
-    integer::RadixProjection,
-    vec::VecBuffer,
-};
-
-#[async_std::main]
-async fn main() {
-    let mut td = TypeDict::new();
-    for tn in vec![
-        "MachineWord",
-        "MachineInt",
-        "MachineSyllab",
-        "Vec",
-        "Stream",
-        "Json",
-        "Sequence",
-        "UTF-8-Char",
-        "PositionalInt",
-        "Digit",
-        "LittleEndian",
-        "BigEndian",
-        "DiffStream",
-        "ℕ",
-        "$src_radix",
-        "$dst_radix",
-    ] {
-        td.add_typename(tn.into());
-    }
-
-    let radix_types = vec![
-        td.type_term_from_str("( ℕ )").unwrap(),
-        td.type_term_from_str("( PositionalInt 10 LittleEndian )")
-            .unwrap(),
-        td.type_term_from_str("( Sequence ( Digit 10 ) )").unwrap(),
-        td.type_term_from_str("( Sequence UTF-8-Char )").unwrap(),
-        td.type_term_from_str("( Sequence MachineSyllab )").unwrap(),
-    ];
-
-    let src_types = vec![
-        td.type_term_from_str("( ℕ )").unwrap(),
-        td.type_term_from_str("( PositionalInt $src_radix LittleEndian )")
-            .unwrap(),
-        td.type_term_from_str("( Sequence ( Digit $src_radix ) )")
-            .unwrap(),
-        td.type_term_from_str("( Sequence MachineInt )").unwrap(),
-        td.type_term_from_str("( DiffStream ( Vec MachineInt ) )")
-            .unwrap(),
-        td.type_term_from_str("( Json )").unwrap(),
-        td.type_term_from_str("( Stream UTF-8-Char )").unwrap(),
-        td.type_term_from_str("( Stream MachineSyllab )").unwrap(),
-    ];
-
-    let dst_types = vec![
-        td.type_term_from_str("( ℕ )").unwrap(),
-        td.type_term_from_str("( PositionalInt $dst_radix LittleEndian )")
-            .unwrap(),
-        td.type_term_from_str("( Sequence ( Digit $dst_radix ) )")
-            .unwrap(),
-        td.type_term_from_str("( Sequence MachineInt )").unwrap(),
-        td.type_term_from_str("( DiffStream ( Vec MachineInt ) )")
-            .unwrap(),
-        td.type_term_from_str("( Json )").unwrap(),
-        td.type_term_from_str("( Stream UTF-8-Char )").unwrap(),
-        td.type_term_from_str("( Stream MachineSyllab )").unwrap(),
-    ];
-
-    nested::magic_header();
-    eprintln!("    Convert Radix of Positional Integer");
-    nested::magic_header();
-
-    eprintln!("\n$1: src_radix");
-    for t in radix_types.iter() {
-        eprintln!("  {}", td.type_term_to_str(t));
-    }
-
-    eprintln!("\n$2: dst_radix");
-    for t in radix_types.iter() {
-        eprintln!("  {}", td.type_term_to_str(t));
-    }
-
-    eprintln!("\n>0: n");
-    for t in src_types.iter() {
-        eprintln!("  {}", td.type_term_to_str(t));
-    }
-
-    eprintln!("\n<1: n");
-    for t in dst_types.iter() {
-        eprintln!("  {}", td.type_term_to_str(t));
-    }
-
-    nested::magic_header();
-
-    let mut args = std::env::args();
-    args.next().expect("Arg $0 missing!");
-
-    let src_radix_str = args.next().expect("Arg $1 required!");
-    let dst_radix_str = args.next().expect("Arg $2 required!");
-
-    let src_radix = usize::from_str_radix(&src_radix_str, 10).expect("could not parse src_radix");
-    let dst_radix = usize::from_str_radix(&dst_radix_str, 10).expect("could not parse dst_radix");
-
-    assert!(src_radix > 1);
-    assert!(dst_radix > 1);
-
-    let src_digits_port = ViewPort::new();
-    let dst_digits_port = ViewPort::new();
-
-    let mut src_digits = VecBuffer::<usize>::new(src_digits_port.inner());
-
-    let _proj = RadixProjection::new(
-        src_radix,
-        dst_radix,
-        src_digits_port.outer().to_sequence(),
-        dst_digits_port.inner(),
-    );
-
-    // output dst digits
-    let writer = {
-        use std::os::unix::io::FromRawFd;
-
-        dst_digits_port
-            .outer()
-            .serialize_json(unsafe { std::fs::File::from_raw_fd(1) })
-    };
-
-    // start reading src digits
-    {
-        use async_std::os::unix::io::FromRawFd;
-
-        src_digits
-            .from_json(unsafe { async_std::fs::File::from_raw_fd(0) })
-            .await;
-    }
-
-    drop(writer);
-}
diff --git a/math/str2int/Cargo.toml b/math/str2int/Cargo.toml
deleted file mode 100644
index b85bed6..0000000
--- a/math/str2int/Cargo.toml
+++ /dev/null
@@ -1,9 +0,0 @@
-[package]
-name = "str2int"
-version = "0.1.0"
-edition = "2018"
-
-# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
-
-[dependencies]
-nested = { path = "../../nested" }
diff --git a/math/str2int/src/main.rs b/math/str2int/src/main.rs
deleted file mode 100644
index fa900b5..0000000
--- a/math/str2int/src/main.rs
+++ /dev/null
@@ -1,69 +0,0 @@
-use std::{
-    fs::File,
-    io::{Read, Write},
-    os::unix::io::FromRawFd,
-};
-
-fn main() {
-    nested::magic_header();
-    eprintln!("       Parse MachineInt from String");
-    nested::magic_header();
-
-    eprintln!(
-        "
-$1: radix
-  ( ℕ )
-  ( PositionalInt 10 BigEndian )
-  ( Sequence ( Digit 10 ) )
-  ( Sequence UTF-8-Char )
-  ( Sequence MachineSyllab )
-"
-    );
-
-    eprintln!(
-        "
->0: n
-  ( ℕ )
-  ( PositionalInt $radix BigEndian )
-  ( Sequence ( Digit $radix ) )
-  ( Sequence UTF-8-Char )
-  ( Stream UTF-8-Char )
-  ( Stream MachineSyllab )
-"
-    );
-
-    eprintln!(
-        "
-<1: n
-  ( ℕ )
-  ( MachineInt )
-  ( MachineWord )
-  ( Stream MachineSyllab )
-"
-    );
-
-    nested::magic_header();
-
-    let mut f0 = unsafe { File::from_raw_fd(0) };
-    let mut f1 = unsafe { File::from_raw_fd(1) };
-
-    let mut args = std::env::args();
-    args.next().expect("Arg $0 missing!");
-
-    let radix_str = args.next().expect("Arg $1 required!");
-
-    let radix = u32::from_str_radix(&radix_str, 10).expect("could not parse radix");
-    if radix > 16 {
-        panic!("invalid radix! (radix<=16 required)");
-    }
-
-    let mut chars = Vec::new();
-    f0.read_to_end(&mut chars).expect("");
-    chars.retain(|c| (*c as char).is_alphanumeric());
-    f1.write(
-        &u64::from_str_radix(&String::from_utf8_lossy(&chars), radix)
-            .unwrap()
-            .to_le_bytes(),
-    )
-    .expect("");
-}
diff --git a/nested/src/editors/char/mod.rs b/nested/src/editors/char/mod.rs
deleted file mode 100644
index 2521cb1..0000000
--- a/nested/src/editors/char/mod.rs
+++ /dev/null
@@ -1,102 +0,0 @@
-use {
-    r3vi::{
-        view::{
-            OuterViewPort,
-            singleton::*,
-        },
-        buffer::singleton::*
-    },
-    laddertypes::{TypeTerm},
-    crate::{
-        type_system::{Context, ReprTree},
-        terminal::{TerminalAtom},
-        tree::{NestedNode, TreeNavResult},
-        commander::{ObjCommander}
-    },
-    std::sync::Arc,
-    std::sync::RwLock
-};
-
-pub fn init_ctx( ctx: &mut Context ) {
-    ctx.add_node_ctor(
-        "Char",
-        Arc::new(|ctx: Arc<RwLock<Context>>, _ty: TypeTerm, depth: OuterViewPort<dyn SingletonView<Item = usize>>| {
-            Some(CharEditor::new_node(ctx, depth))
-        }));
-}
-
-pub struct CharEditor {
-    ctx: Arc<RwLock<Context>>,
-    data: SingletonBuffer<char>
-}
-
-impl ObjCommander for CharEditor {
-    fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult {
-        let cmd_obj = cmd_obj.read().unwrap();
-        let cmd_type = cmd_obj.get_type().clone();
-
-        if cmd_type == Context::parse(&self.ctx, "Char") {
-            if let Some(cmd_view) = cmd_obj.get_view::<dyn SingletonView<Item = char>>() {
-                let value = cmd_view.get();
-
-                if self.ctx.read().unwrap().meta_chars.contains(&value) {
-                    TreeNavResult::Exit
-                } else {
-                    self.data.set(value);
-                    TreeNavResult::Continue
-                }
-            } else {
-                TreeNavResult::Exit
-            }
-        } else {
-            TreeNavResult::Exit   
-        }
-    }
-}
-
-impl CharEditor {
-    pub fn new(ctx: Arc<RwLock<Context>>) -> Self {
-        CharEditor {
-            ctx,
-            data: SingletonBuffer::new('\0')
-        }
-    }
-
-    pub fn get_port(&self) -> OuterViewPort<dyn SingletonView<Item = char>> {
-        self.data.get_port()
-    }
-
-    pub fn get(&self) -> char {
-        self.get_port().get_view().unwrap().get()
-    }
-
-    pub fn new_node(ctx0: Arc<RwLock<Context>>, depth: OuterViewPort<dyn SingletonView<Item = usize>>) -> NestedNode {
-        let data = SingletonBuffer::new('\0');
-        let ctx = ctx0.clone();
-        let editor = Arc::new(RwLock::new(CharEditor{ ctx, data: data.clone() }));
-
-        NestedNode::new(
-            ctx0.clone(),
-            ReprTree::new_leaf(
-                ctx0.read().unwrap().type_term_from_str("Char").unwrap(),
-                data.get_port().into()
-            ),
-            depth
-        )
-            .set_view(data
-                      .get_port()
-                      .map(move |c| TerminalAtom::from(if c == '\0' { ' ' } else { c }))
-                      .to_grid()
-            )
-            .set_cmd( editor.clone() )
-            .set_editor( editor.clone() )
-    }
-}
-/*
-use crate::StringGen;
-impl StringGen for CharEditor {
-    fn get_string(&self)  -> String {
-        String::from(self.get())
-    }
-}
-*/
diff --git a/nested/src/editors/integer/ctx.rs b/nested/src/editors/integer/ctx.rs
deleted file mode 100644
index 99c9aa7..0000000
--- a/nested/src/editors/integer/ctx.rs
+++ /dev/null
@@ -1,139 +0,0 @@
-
-use {
-    r3vi::{
-        view::{OuterViewPort, singleton::*}
-    },
-    laddertypes::{TypeTerm},
-    crate::{
-        type_system::{Context},
-        editors::{
-            list::*,
-            integer::*
-        },
-        type_system::{MorphismTypePattern},
-    },
-    std::sync::{Arc, RwLock}
-};
-
-pub fn init_ctx(ctx: &mut Context) {
-    ctx.add_typename("MachineInt".into());
-    ctx.add_typename("u32".into());
-    ctx.add_typename("u64".into());
-    ctx.add_typename("LittleEndian".into());
-    ctx.add_typename("BigEndian".into());
-
-    ctx.add_node_ctor(
-        "Digit", Arc::new(
-            |ctx: Arc<RwLock<Context>>, ty: TypeTerm, depth: OuterViewPort<dyn SingletonView<Item = usize>>| {
-                match ty {
-                    TypeTerm::App(args) => {
-                        if args.len() > 1 {
-                            match args[1] {
-                                TypeTerm::Num(radix) => {
-                                    let node = DigitEditor::new(ctx.clone(), radix as u32).into_node(depth);
-                                    Some(
-                                        node
-                                    )
-                                },
-                                _ => None
-                            }
-                        } else {
-                            None
-                        }
-                    }
-                    _ => None
-                }
-            }
-        )
-    );
-
-    ctx.add_list_typename("PosInt".into());
-    let pattern = MorphismTypePattern {
-        src_tyid: ctx.get_typeid("List"),
-        dst_tyid: ctx.get_typeid("PosInt").unwrap()
-    };
-    ctx.add_morphism(pattern,
-        Arc::new(
-            |mut node, dst_type| {
-                // todo: check src_type parameter to be ( Digit radix )
-
-                match dst_type {
-                    TypeTerm::App(args) => {
-                        if args.len() > 1 {
-                            match args[1] {
-                                TypeTerm::Num(_radix) => {
-                                    PTYListController::for_node(
-                                        &mut node,
-                                        Some(','),
-                                        None,
-                                    );
-
-                                    PTYListStyle::for_node(
-                                        &mut node,
-                                        ("0d", "", "")
-                                    );
-
-                                    Some(node)
-                                },
-                                _ => None
-                            }
-                        } else {
-                            None
-                        }
-                    }
-                    _ => None
-                }
-            }
-        )
-    );
-
-    ctx.add_node_ctor(
-        "PosInt", Arc::new(
-            |ctx0: Arc<RwLock<Context>>, dst_typ: TypeTerm, depth: OuterViewPort<dyn SingletonView<Item = usize>>| {
-                match dst_typ.clone() {
-                    TypeTerm::App(args) => {
-                        if args.len() > 1 {
-                            match args[1] {
-                                TypeTerm::Num(radix) => {
-                                    let ctx = ctx0.read().unwrap();
-                                    let mut node = Context::make_node(
-                                        &ctx0,
-                                        TypeTerm::App(vec![
-                                            TypeTerm::TypeID(ctx.get_typeid("List").unwrap()),
-                                            TypeTerm::TypeID(
-                                                ctx.get_typeid("Digit").unwrap()
-                                            )
-                                                .num_arg(radix)
-                                                .clone()
-                                                .into()
-                                        ]),
-                                        depth.map(|d| d+1)
-                                    ).unwrap();
-
-                                    node = node.morph(dst_typ);
-
-                                    Some(node)
-                                }
-                                _ => None
-                            }
-                        } else {
-                            None
-                        }
-                    }
-                    _ => None
-                }
-            }
-        )
-    );
-    
-    ctx.add_typename("Date".into());
-    ctx.add_typename("ISO-8601".into());
-    ctx.add_typename("TimeSince".into());
-    ctx.add_typename("UnixEpoch".into());
-    ctx.add_typename("AnnoDomini".into());
-    ctx.add_typename("Epoch".into());
-    ctx.add_typename("Duration".into());
-    ctx.add_typename("Seconds".into());
-    ctx.add_typename("ℕ".into());
-}
-
diff --git a/nested/src/editors/integer/editor.rs b/nested/src/editors/integer/editor.rs
deleted file mode 100644
index 3e11b34..0000000
--- a/nested/src/editors/integer/editor.rs
+++ /dev/null
@@ -1,239 +0,0 @@
-use {
-    r3vi::{
-        view::{
-            OuterViewPort,
-            singleton::*,
-        },
-        buffer::{
-            singleton::*,
-            vec::*,
-            index_hashmap::*
-        }
-    },
-    laddertypes::{TypeTerm},
-    crate::{
-        type_system::{Context, ReprTree},
-        editors::list::{ListCmd, PTYListController, PTYListStyle},
-        terminal::{
-            TerminalAtom, TerminalStyle, make_label
-        },
-        diagnostics::{Message},
-        tree::{NestedNode, TreeNav, TreeNavResult, TreeCursor},
-        commander::ObjCommander
-    },
-    std::sync::Arc,
-    std::sync::RwLock,
-    std::iter::FromIterator,
-    cgmath::{Point2}
-};
-
-//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
-
-pub struct DigitEditor {
-    ctx: Arc<RwLock<Context>>,
-    radix: u32,
-    data: SingletonBuffer<Option<char>>,
-    msg: VecBuffer<Message>,
-}
-
-impl ObjCommander for DigitEditor {
-    fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult {
-        let cmd_obj = cmd_obj.read().unwrap();
-        let cmd_type = cmd_obj.get_type().clone();
-
-        if cmd_type == Context::parse(&self.ctx, "Char") {
-            if let Some(cmd_view) = cmd_obj.get_view::<dyn SingletonView<Item = char>>() {
-                let c = cmd_view.get();
-
-                self.msg.clear();
-
-                if self.ctx.read().unwrap().meta_chars.contains(&c) {
-                    eprintln!("digitedit: meta char");
-                    return TreeNavResult::Exit;
-
-                } else if c.to_digit(self.radix).is_none() {
-                    /* in case the character c is not in the range of digit-chars,
-                       add a message to the diagnostics view
-                     */
-
-                    let message = IndexBuffer::from_iter(vec![
-                        (Point2::new(1, 0), make_label("invalid digit '")),
-                        (Point2::new(2, 0), make_label(&format!("{}", c))
-                         .map_item(|_p,a| a.add_style_back(TerminalStyle::fg_color((140,140,250))))),
-                        (Point2::new(3, 0), make_label("'"))
-                    ]);
-
-                    self.msg.push(crate::diagnostics::make_error(message.get_port().flatten()));
-                    self.data.set(Some(c));
-                } else {
-                    self.data.set(Some(c));
-                }
-            }
-        }
-
-        TreeNavResult::Continue
-    }
-}
-
-impl DigitEditor {
-    pub fn new(ctx: Arc<RwLock<Context>>, radix: u32) -> Self {
-        DigitEditor {
-            ctx,
-            radix,
-            data: SingletonBuffer::new(None),
-            msg: VecBuffer::new(),
-        }
-    }
-
-    pub fn into_node(self, depth: OuterViewPort<dyn SingletonView<Item = usize>>) -> NestedNode {
-        let data = self.get_data();        
-        let editor = Arc::new(RwLock::new(self));
-        let ed = editor.write().unwrap();
-        let r = ed.radix;
-
-        NestedNode::new(ed.ctx.clone(), data, depth)
-            .set_cmd(editor.clone())
-            .set_view(
-                ed.data
-                    .get_port()
-                    .map(move |c| {
-                        TerminalAtom::new(
-                            c.unwrap_or('?'),
-                            if c.unwrap_or('?').to_digit(r).is_some() {
-                                TerminalStyle::fg_color((90, 160, 90))
-                            } else {
-                                //TerminalStyle::bg_color((90, 10, 10))
-                                TerminalStyle::fg_color((200, 40, 40))
-                            },
-                        )
-                    })
-                    .to_grid()
-            )
-            .set_diag(
-                ed.msg.get_port().to_sequence()
-            )
-    }
-
-    pub fn get_data_port(&self) -> OuterViewPort<dyn SingletonView<Item = Option<u32>>> {
-        let radix = self.radix;
-        self.data.get_port().map(move |c| c?.to_digit(radix))
-    }
-
-    pub fn get_type(&self) -> TypeTerm {
-        TypeTerm::TypeID(self.ctx.read().unwrap().get_typeid("Digit").unwrap())
-    }
-
-    pub fn get_data(&self) -> Arc<RwLock<ReprTree>> {
-        ReprTree::ascend(
-            &ReprTree::new_leaf(
-                self.ctx.read().unwrap().type_term_from_str("<Seq u32>").unwrap(),
-                self.get_data_port().into()
-            ),
-            self.get_type()
-        )
-    }
-}
-
-
-pub struct PosIntEditor {
-    radix: u32,
-    digits: NestedNode,
-
-    // todo: endianness
-}
-
-impl PosIntEditor {
-    pub fn new(ctx: Arc<RwLock<Context>>, radix: u32) -> Self {
-        let mut node = Context::make_node(
-            &ctx,
-            Context::parse(&ctx, format!("<List <Digit {}>>", radix).as_str()),
-            r3vi::buffer::singleton::SingletonBuffer::new(0).get_port()
-        ).unwrap();
-
-        // Set Type
-        node.data = ReprTree::ascend(
-            &node.data.clone(),
-            TypeTerm::App(vec![
-                TypeTerm::TypeID(ctx.read().unwrap().get_typeid("PosInt").unwrap()),
-                TypeTerm::Num(radix as i64).into(),
-                TypeTerm::TypeID(ctx.read().unwrap().get_typeid("BigEndian").unwrap())
-            ]
-        ));
-
-        PTYListController::for_node( &mut node, Some(' '), None );
-        PTYListStyle::for_node( &mut node,
-            (
-                match radix {
-                    2 => "0b".into(),
-                    8 => "0o".into(),
-                    10 => "0d".into(),
-                    16 => "0x".into(),
-                    _ => "".into()
-                },
-                "".into(),
-                "".into()
-            )
-        );
-
-        PosIntEditor {
-            radix,
-            digits: node
-        }
-    }
-
-    pub fn from_u64(ctx: Arc<RwLock<Context>>, radix: u32, value: u64) -> Self {
-        let mut edit = PosIntEditor::new(ctx, radix);
-        edit.set_value_u64( value );
-        edit
-    }
-
-    pub fn set_value_u64(&mut self, mut value: u64) {
-        self.digits.send_cmd_obj(ListCmd::Clear.into_repr_tree(&self.digits.ctx));
-
-        while value > 0 {
-            let digit_val = (value % self.radix as u64) as u32;
-            value /= self.radix as u64;
-
-            // if BigEndian
-            self.digits.goto(TreeCursor::home());
-
-            self.digits.send_cmd_obj(ReprTree::from_char(&self.digits.ctx, char::from_digit(digit_val, self.radix).expect("invalid digit"))); 
-        }
-        self.digits.goto(TreeCursor::none());
-    }
-
-    pub fn into_node(self) -> NestedNode {
-        self.digits
-    }
-
-/*
-    pub fn get_data_port(&self) -> OuterViewPort<dyn SequenceView<Item = u32>> {
-        let radix = self.radix;
-        self.digits
-            .get_data_port()
-            .filter_map(move |digit_editor| {
-                digit_editor.read().unwrap().data.get()?.to_digit(radix)
-            })
-    }
-
-    pub fn get_value(&self) -> u32 {
-        let mut value = 0;
-        let mut weight = 1;
-        for digit_value in self
-            .get_data_port()
-            .get_view()
-            .unwrap()
-            .iter()
-            .collect::<Vec<_>>()
-            .into_iter()
-            .rev()
-        {
-            value += digit_value * weight;
-            weight *= self.radix;
-        }
-
-        value
-}
-*/
-}
-
diff --git a/nested/src/editors/integer/mod.rs b/nested/src/editors/integer/mod.rs
deleted file mode 100644
index bdbf565..0000000
--- a/nested/src/editors/integer/mod.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-pub mod add;
-pub mod editor;
-pub mod radix;
-pub mod ctx;
-
-pub use {
-    add::Add,
-    editor::{DigitEditor, PosIntEditor},
-    radix::RadixProjection,
-    ctx::init_ctx
-};
-
diff --git a/nested/src/editors/integer/radix.rs b/nested/src/editors/integer/radix.rs
deleted file mode 100644
index bcc12da..0000000
--- a/nested/src/editors/integer/radix.rs
+++ /dev/null
@@ -1,101 +0,0 @@
-use {
-    r3vi::{
-        view::{
-            InnerViewPort, Observer, OuterViewPort,
-            sequence::*,
-        },
-        buffer::{vec::*}
-    },
-    std::sync::{Arc, RwLock},
-};
-
-pub struct RadixProjection {
-    src_radix: usize,
-    dst_radix: usize,
-    src_digits: Option<Arc<dyn SequenceView<Item = usize>>>,
-    dst_digits: RwLock<VecBuffer<usize>>,
-}
-
-impl RadixProjection {
-    pub fn new(
-        // static parameters
-        //---
-        src_radix: usize,
-        dst_radix: usize,
-        //---
-
-        // dynamic parameters
-        //---
-        // input
-        src_digits: OuterViewPort<dyn SequenceView<Item = usize>>,
-        // output
-        dst_digits: InnerViewPort<RwLock<Vec<usize>>>,
-        //---
-    ) -> Arc<RwLock<Self>> {
-        dst_digits.0.add_update_hook(Arc::new(src_digits.0.clone()));
-        let proj = Arc::new(RwLock::new(RadixProjection {
-            src_radix,
-            dst_radix,
-            src_digits: None,
-            dst_digits: RwLock::new(VecBuffer::with_port(dst_digits)),
-        }));
-        src_digits.add_observer(proj.clone());
-        proj
-    }
-
-    fn machine_int(&self) -> usize {
-        let mut val = 0;
-        let mut r = 1;
-        for i in 0..self.src_digits.len().unwrap_or(0) {
-            val += r * self.src_digits.get(&i).unwrap();
-            r *= self.src_radix;
-        }
-
-        val
-    }
-
-    // recalculate everything
-    fn update(&self) {
-        let mut dst = self.dst_digits.write().unwrap();
-        dst.clear();
-
-        let mut val = self.machine_int();
-
-        while val > 0 {
-            dst.push(val % self.dst_radix);
-            val /= self.dst_radix;
-        }
-    }
-
-    fn _update_dst_digit(&mut self, _idx: usize) {
-        /*
-                let v = 0; // calculate new digit value
-
-                // which src-digits are responsible?
-
-                if idx < self.dst_digits.len() {
-                    self.dst_digits.get_mut(idx) = v;
-                } else if idx == self.dst_digits.len() {
-                    self.dst_digits.push(v);
-                } else {
-                    // error
-                }
-        */
-    }
-}
-
-impl Observer<dyn SequenceView<Item = usize>> for RadixProjection {
-    fn reset(&mut self, view: Option<Arc<dyn SequenceView<Item = usize>>>) {
-        self.src_digits = view;
-    }
-
-    fn notify(&mut self, _idx: &usize) {
-        // todo:
-        // src digit i changed.
-        // which dst-digits does it affect?
-        // update dst-digit j:
-
-        // ...but for now the easy way
-        self.update();
-    }
-}
diff --git a/nested/src/editors/list/ctx.rs b/nested/src/editors/list/ctx.rs
deleted file mode 100644
index 91474f0..0000000
--- a/nested/src/editors/list/ctx.rs
+++ /dev/null
@@ -1,41 +0,0 @@
-use {
-    r3vi::{view::{OuterViewPort, singleton::*}},
-    laddertypes::{TypeTerm},
-    crate::{
-        type_system::{Context},
-        editors::list::{ListEditor, PTYListController, PTYListStyle}
-    },
-    std::sync::{Arc, RwLock}
-};
-
-//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
-
-pub fn init_ctx(ctx: &mut Context) {
-    ctx.add_typename("ListCmd".into());
-    ctx.add_list_typename("List".into());
-
-    ctx.add_node_ctor(
-        "List", Arc::new(
-            |ctx: Arc<RwLock<Context>>, ty: TypeTerm, depth: OuterViewPort<dyn SingletonView<Item = usize>>| {
-                match ty {
-                    TypeTerm::App(args) => {
-                        if args.len() > 1 {
-                            let typ = args[1].clone();
-
-                            let mut node = ListEditor::new(ctx.clone(), typ).into_node(depth);
-
-                            PTYListController::for_node( &mut node, Some(','), Some('}') );
-                            PTYListStyle::for_node( &mut node, ("{",", ","}") );
-
-                            Some(node)
-                        } else {
-                            None
-                        }
-                    }
-                    _ => None
-                }
-            }
-        )
-    );
-}
-
diff --git a/nested/src/editors/mod.rs b/nested/src/editors/mod.rs
deleted file mode 100644
index a93800c..0000000
--- a/nested/src/editors/mod.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-
-pub mod list;
-pub mod product;
-pub mod sum;
-
-pub mod char;
-pub mod integer;
-pub mod typeterm;
-
diff --git a/nested/src/lib.rs b/nested/src/lib.rs
deleted file mode 100644
index c81e77d..0000000
--- a/nested/src/lib.rs
+++ /dev/null
@@ -1,34 +0,0 @@
-#![feature(trait_alias)]
-
-pub mod terminal;
-
-pub mod utils;
-pub mod editors;
-pub mod tree;
-pub mod type_system;
-
-pub mod diagnostics;
-pub mod commander;
-//pub mod product;
-//pub mod sum;
-//pub mod list;
-
-pub fn magic_header() {
-    eprintln!("<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>");
-}
-
-/*
-pub trait StringGen {
-    fn get_string(&self) -> String;    
-}
-
-use crate::{tree::{TreeNav}, diagnostics::Diagnostics, terminal::TerminalView, core::{OuterViewPort}};
- */
-
-use r3vi::view::OuterViewPort;
-use crate::terminal::TerminalView;
-
-pub trait PtySegment {
-    fn pty_view(&self) -> OuterViewPort<dyn TerminalView>;
-}
-
diff --git a/nested/src/terminal/mod.rs b/nested/src/terminal/mod.rs
deleted file mode 100644
index 61e41b2..0000000
--- a/nested/src/terminal/mod.rs
+++ /dev/null
@@ -1,80 +0,0 @@
-pub mod ansi_parser;
-pub mod atom;
-pub mod compositor;
-pub mod style;
-pub mod terminal;
-pub mod widgets;
-
-pub use {
-    atom::TerminalAtom,
-    compositor::TerminalCompositor,
-    style::TerminalStyle,
-    terminal::{Terminal, TerminalEvent},
-};
-
-use r3vi::view::grid::*;
-
-//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
-
-pub trait TerminalView = GridView<Item = TerminalAtom>;
-
-//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
-
-pub enum TerminalEditorResult {
-    Continue,
-    Exit,
-}
-
-pub trait TerminalEditor {
-    fn get_term_view(&self) -> OuterViewPort<dyn TerminalView>;
-    fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult;
-}
-
-//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
-
-use {
-    r3vi::{
-        view::{OuterViewPort},
-        buffer::vec::*,
-    },
-    cgmath::Point2,
-};
-
-pub fn make_label(s: &str) -> OuterViewPort<dyn TerminalView> {
-    let label = VecBuffer::with_data(s.chars().collect());
-
-    let v = label.get_port()
-        .to_sequence()
-        .map(|c| TerminalAtom::from(c))
-        .to_index()
-        .map_key(
-            |idx| Point2::new(*idx as i16, 0),
-            |pt| if pt.y == 0 { Some(pt.x as usize) } else { None },
-        );
-
-    v
-}
-
-pub trait TerminalProjections {
-    fn with_style(&self, style: TerminalStyle) -> OuterViewPort<dyn TerminalView>;
-    fn with_fg_color(&self, col: (u8, u8, u8)) -> OuterViewPort<dyn TerminalView>;
-    fn with_bg_color(&self, col: (u8, u8, u8)) -> OuterViewPort<dyn TerminalView>;
-}
-
-impl TerminalProjections for OuterViewPort<dyn TerminalView> {
-    fn with_style(&self, style: TerminalStyle) -> OuterViewPort<dyn TerminalView> {
-        self.map_item(
-            move |_idx, a|
-            a.add_style_front(style)
-        )
-    }
-
-    fn with_fg_color(&self, col: (u8, u8, u8)) -> OuterViewPort<dyn TerminalView> {
-        self.with_style(TerminalStyle::fg_color(col))
-    }
-
-    fn with_bg_color(&self, col: (u8, u8, u8)) -> OuterViewPort<dyn TerminalView> {
-        self.with_style(TerminalStyle::bg_color(col))
-    }
-}
-
diff --git a/nested/src/tree/node.rs b/nested/src/tree/node.rs
deleted file mode 100644
index 1406c96..0000000
--- a/nested/src/tree/node.rs
+++ /dev/null
@@ -1,343 +0,0 @@
-use {
-    std::{sync::{Arc, RwLock}, any::Any},
-    cgmath::{Vector2, Point2},
-    r3vi::{
-        view::{View, ViewPort, OuterViewPort, AnyOuterViewPort, singleton::*, sequence::*},
-        buffer::{singleton::*}
-    },
-    laddertypes::{TypeTerm},
-    crate::{
-        type_system::{ReprTree, Context},
-        terminal::{TerminalView, TerminalEvent, TerminalEditor, TerminalEditorResult, TerminalAtom},
-        diagnostics::{Diagnostics, Message},
-        tree::{TreeNav, TreeCursor, TreeNavResult, TreeHeightOp},
-        editors::list::{ListCursorMode},
-        commander::ObjCommander,
-    }
-};
-
-/* TODO: refactoring proposal
-
-struct NestedNodeDisplay {
-    /// display view
-    pub view: Option< OuterViewPort<dyn TerminalView> >,
-
-    /// diagnostics
-    pub diag: Option< OuterViewPort<dyn SequenceView<Item = Message>> >,
-
-    /// depth
-    pub depth: SingletonBuffer< usize >,    
-}
-
-struct NestedNodeEdit {
-    /// abstract editor
-    pub editor: SingletonBuffer<
-                    Option< Arc<dyn Any + Send + Sync> >
-    >,
-
-    pub spillbuf: VecBuffer< NestedNode >,
-
-    /// commander & navigation
-    pub cmd: SingletonBuffer<
-                 Option< Arc<RwLock<dyn ObjCommander + Send + Sync>> >
-             >,
-    pub close_char: SingletonBuffer< Option< char > >,
-
-    // could be replaced by cmd when TreeNav -CmdObjects are used
-    pub tree_nav: SingletonBuffer<
-                      Option< Arc<RwLock<dyn TreeNav + Send + Sync>> >
-                  >,    
-}
-
-pub struct NewNestedNode {
-    /// context
-    pub ctx: Arc<RwLock<Context>>,
-
-    /// abstract data view
-    pub data: Arc<RwLock<ReprTree>>,
-
-    /// viewports for terminal display
-    pub disp: NestedNodeDisplay,
-
-    /// editor & commander objects
-    pub edit: NestedNodeEdit
-}
-
-*/
-
-#[derive(Clone)]
-pub struct NestedNode {    
-    /// context
-    pub ctx: Arc<RwLock<Context>>,
-
-    /// abstract data view
-    pub data: Arc<RwLock<ReprTree>>,
-
-    /// display view
-    pub view: Option< OuterViewPort<dyn TerminalView> >,
-
-    /// diagnostics
-    pub diag: Option< OuterViewPort<dyn SequenceView<Item = Message>> >,
-
-    /// depth
-    pub depth: OuterViewPort< dyn SingletonView<Item = usize> >,
-
-    /// abstract editor
-    pub editor: SingletonBuffer<
-                    Option< Arc<dyn Any + Send + Sync> >
-                >,
-
-    pub spillbuf: Arc<RwLock<Vec<Arc<RwLock<NestedNode>>>>>,
-
-    /// commander & navigation
-    pub cmd: SingletonBuffer<
-                 Option< Arc<RwLock<dyn ObjCommander + Send + Sync>> >
-             >,
-    pub close_char: SingletonBuffer<
-                        Option< char >
-                    >,
-    pub tree_nav: SingletonBuffer<
-                      Option< Arc<RwLock<dyn TreeNav + Send + Sync>> >
-                  >,
-}
-
-impl NestedNode {
-    pub fn new(ctx: Arc<RwLock<Context>>, data: Arc<RwLock<ReprTree>>, depth: OuterViewPort<dyn SingletonView<Item = usize>>) -> Self {
-        NestedNode {
-            ctx,
-            data,
-            view: None,
-            diag: None,
-            depth,
-            editor: SingletonBuffer::new(None),
-            spillbuf: Arc::new(RwLock::new(Vec::new())),
-            cmd: SingletonBuffer::new(None),
-            close_char: SingletonBuffer::new(None),
-            tree_nav: SingletonBuffer::new(None)
-        }
-    }
-
-    /* TODO: move into separate file/module
-    */
-    pub fn from_char(ctx: Arc<RwLock<Context>>, c: char) -> NestedNode {
-        let buf = r3vi::buffer::singleton::SingletonBuffer::<char>::new(c);
-
-        NestedNode::new(
-            ctx.clone(),
-            ReprTree::new_leaf(
-                Context::parse(&ctx, "Char"),
-                buf.get_port().into()
-            ),
-            SingletonBuffer::new(0).get_port()
-        )
-            .set_view(buf.get_port()
-                      .map(|c| TerminalAtom::from(c))
-                      .to_index()
-                      .map_key(
-                          |_x| {
-                              Point2::new(0, 0)
-                          },
-                          |p| {
-                              if *p == Point2::new(0,0) { Some(()) } else { None }
-                          })
-            )
-            .set_editor(Arc::new(RwLock::new(buf)))
-    }
-
-    
-    //\\//\\
-
-    pub fn morph(self, ty: TypeTerm) -> NestedNode {
-        Context::morph_node(self, ty)
-    }
-
-    pub fn get_type(&self) -> TypeTerm {
-        self.data.read().unwrap().get_type().clone()
-    }
-
-    //\\//\\
-    
-    pub fn set_editor(mut self, editor: Arc<dyn Any + Send + Sync>) -> Self {
-        self.editor.set(Some(editor));
-        self
-    }
-
-    pub fn set_view(mut self, view: OuterViewPort<dyn TerminalView>) -> Self {
-        self.view = Some(view);
-        self
-    }
-
-    pub fn set_cmd(mut self, cmd: Arc<RwLock<dyn ObjCommander + Send + Sync>>) -> Self {
-        self.cmd.set(Some(cmd));
-        self
-    }
-
-    pub fn set_nav(mut self, nav: Arc<RwLock<dyn TreeNav + Send + Sync>>) -> Self {
-        self.tree_nav.set(Some(nav));
-        self
-    }
-
-    pub fn set_diag(mut self, diag: OuterViewPort<dyn SequenceView<Item = Message>>) -> Self {
-        self.diag = Some(diag);
-        self
-    }
-
-    //\\//\\
-
-    pub fn get_diag(&self) -> OuterViewPort<dyn SequenceView<Item = Message>> {
-        self.diag.clone().unwrap_or(ViewPort::new().into_outer())
-    }
-
-    pub fn get_view(&self) -> OuterViewPort<dyn TerminalView> {
-        self.view.clone().unwrap_or(ViewPort::new().into_outer())
-    }
-    
-    pub fn get_data_port<'a, V: View + ?Sized + 'static>(&'a self, type_str: impl Iterator<Item = &'a str>) -> Option<OuterViewPort<V>>
-    where V::Msg: Clone {
-        let ctx = self.ctx.clone();
-        let type_ladder = type_str.map(|s| Context::parse(&ctx, s));
-
-        let repr_tree = ReprTree::descend_ladder(&self.data, type_ladder)?;
-        repr_tree.clone().read().unwrap()
-            .get_port::<V>().clone()
-    }
-
-    pub fn get_data_view<'a, V: View + ?Sized + 'static>(&'a self, type_str: impl Iterator<Item = &'a str>) -> Option<Arc<V>>
-    where V::Msg: Clone {
-        self.get_data_port::<V>(type_str)?.get_view()
-    }
-
-    /* TODO
-    pub fn get_seq_view<'a, T: Clone>(&self, type_str: impl Iterator<Item = &'a str>) -> Option<OuterViewPort<dyn SingletonView<Item = T>>> {
-        self.get_data_view::<dyn SequenceView<Item = NestedNode>>(type_str)
-            .unwrap()
-            .map({
-                move |node| {
-                    node.get_data_view::<dyn SingletonView<Item = T>>().get()
-                }
-            })
-    }
-     */
-    
-    pub fn get_edit<T: Send + Sync + 'static>(&self) -> Option<Arc<RwLock<T>>> {
-        if let Some(edit) = self.editor.get() {
-            if let Ok(edit) = edit.downcast::<RwLock<T>>() {
-                Some(edit)
-            } else {
-                None
-            }
-        } else {
-            None
-        }
-    }
-}
-
-/*
-impl TreeType for NestedNode {
-    fn get_type(&self, addr: &TreeAddr) -> TypeLadder {
-        if let Some(editor) = self.editor {
-            editor.read().unwrap().get_type(addr)
-        } else {
-            vec![]
-        }
-    }
-}
- */
-
-/* TODO: remove that at some point
-*/
-impl TerminalEditor for NestedNode {
-    fn get_term_view(&self) -> OuterViewPort<dyn TerminalView> {
-        self.get_view()
-    }
-
-    fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult {
-        let buf = SingletonBuffer::new(event.clone());
-
-        if let Some(cmd) = self.cmd.get() {
-            cmd.write().unwrap().send_cmd_obj(
-                ReprTree::new_leaf(
-                    self.ctx.read().unwrap().type_term_from_str("TerminalEvent").unwrap(),
-                    AnyOuterViewPort::from(buf.get_port())
-                ));
-        }
-
-        TerminalEditorResult::Continue
-    }
-}
-
-impl TreeNav for NestedNode {
-    fn get_cursor(&self) -> TreeCursor {
-        if let Some(tn) = self.tree_nav.get() {
-            tn.read().unwrap().get_cursor()
-        } else {
-            TreeCursor::default()
-        }
-    }
-
-    fn get_addr_view(&self) -> OuterViewPort<dyn SequenceView<Item = isize>> {
-        if let Some(tn) = self.tree_nav.get() {
-            tn.read().unwrap().get_addr_view()
-        } else {
-            OuterViewPort::default()
-        }
-    }
-
-    fn get_mode_view(&self) -> OuterViewPort<dyn SingletonView<Item = ListCursorMode>> {
-        if let Some(tn) = self.tree_nav.get() {
-            tn.read().unwrap().get_mode_view()
-        } else {
-            OuterViewPort::default()
-        }        
-    }
-
-    fn get_cursor_warp(&self) -> TreeCursor {
-        if let Some(tn) = self.tree_nav.get() {
-            tn.read().unwrap().get_cursor_warp()
-        } else {
-            TreeCursor::default()
-        }
-    }
-
-    fn get_height(&self, op: &TreeHeightOp) -> usize {
-        if let Some(tn) = self.tree_nav.get() {
-            tn.read().unwrap().get_height( op )
-        } else {
-            0
-        }
-    }
-
-    fn goby(&mut self, direction: Vector2<isize>) -> TreeNavResult {
-        if let Some(tn) = self.tree_nav.get() {
-            tn.write().unwrap().goby(direction)
-        } else {
-            TreeNavResult::Exit
-        }
-    }
-
-    fn goto(&mut self, new_cursor: TreeCursor) -> TreeNavResult {
-        if let Some(tn) = self.tree_nav.get() {
-            tn.write().unwrap().goto(new_cursor)
-        } else {
-            TreeNavResult::Exit
-        }
-    }
-}
-
-impl ObjCommander for NestedNode {
-    fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult {
-        if let Some(cmd) = self.cmd.get() {
-            // todo: filter out tree-nav cmds and send them to tree_nav
-            cmd.write().unwrap().send_cmd_obj(cmd_obj)
-        } else {
-            TreeNavResult::Exit
-        }
-    }
-}
-
-impl Diagnostics for NestedNode {
-    fn get_msg_port(&self) -> OuterViewPort<dyn SequenceView<Item = Message>> {
-        self.get_diag()
-    }
-}
-
diff --git a/nested/src/type_system/context.rs b/nested/src/type_system/context.rs
deleted file mode 100644
index bf4f8c4..0000000
--- a/nested/src/type_system/context.rs
+++ /dev/null
@@ -1,433 +0,0 @@
-use {
-    r3vi::{view::{OuterViewPort, singleton::*}, buffer::{singleton::*}},
-    laddertypes::{TypeDict, TypeTerm, TypeID},
-    crate::{
-        type_system::{ReprTree},
-        tree::NestedNode
-    },
-    std::{
-        collections::HashMap,
-        sync::{Arc, RwLock},
-    }
-};
-
-//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
-
-#[derive(Clone, Copy, Hash, PartialEq, Eq)]
-pub enum MorphismMode {
-    /// Isomorphism
-    /// e.g. `( PositionalInteger 10 BigEndian ) <~> ( PositionalInteger 16 LittleEndian )`
-    Iso,
-
-    /// Monomorphism, i.e. injective functions,
-    /// upcast-view, downcast-control, semantic gain
-    /// e.g. `( Sequence ( Digit 16 ) ) ~> ( PositionalInteger 16 LittleEndian )`
-    Mono,
-
-    /// Epimorphsim, i.e. surjective functions,
-    /// upcast-control, downcast-view, possible loss of entropy
-    /// e.g. `( Ascii ) ~> ( Digit 16 )`
-    Epi,
-
-    /// Any other function
-    Any,
-}
-
-#[derive(Clone, Hash, PartialEq, Eq, Debug)]
-pub struct MorphismType {
-//    pub mode: MorphismMode,
-    pub src_type: Option<TypeTerm>,
-    pub dst_type: TypeTerm,
-}
-
-#[derive(Clone, Hash, Eq, PartialEq)]
-pub struct MorphismTypePattern {
-    pub src_tyid: Option<TypeID>,
-    pub dst_tyid: TypeID
-}
-
-impl MorphismType {
-    pub fn to_str(&self, ctx: &Context) -> String {
-        format!("{:?} -> {:?}",
-                if let Some(t) = self.src_type.as_ref() {
-                    ctx.type_term_to_str(t)
-                } else {
-                    "None".into()
-                },
-                ctx.type_term_to_str(&self.dst_type))
-    }
-}
-
-impl MorphismTypePattern {
-    pub fn to_str(&self, ctx: &Context) -> String {
-        format!("{:?} -> {:?}",
-                if let Some(t) = self.src_tyid.as_ref() {
-                    ctx.type_term_to_str(&TypeTerm::TypeID(t.clone()))
-                } else {
-                    "None".into()
-                },
-                ctx.type_term_to_str(&TypeTerm::TypeID(self.dst_tyid.clone())))
-    }
-}
-
-impl From<MorphismType> for MorphismTypePattern {    
-    fn from(value: MorphismType) -> MorphismTypePattern {
-        fn strip( x: &TypeTerm ) -> TypeID {
-            match x {
-                TypeTerm::TypeID(id) => id.clone(),
-                TypeTerm::App(args) => strip(&args[0]),
-                TypeTerm::Ladder(args) => strip(&args[0]),
-                    _ => unreachable!()
-            }
-        }
-
-        MorphismTypePattern {
-            src_tyid: value.src_type.map(|x| strip(&x)),
-            dst_tyid: strip(&value.dst_type)
-        }
-    }
-}
-
-//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
-
-#[derive(Clone)]
-pub struct Context {
-    /// assigns a name to every type
-    pub type_dict: Arc<RwLock<TypeDict>>,
-
-    /// named vertices of the graph
-    nodes: HashMap< String, NestedNode >,
-
-    /// todo: beautify
-    /// types that can be edited as lists
-    pub list_types: Vec< TypeID >,
-    pub meta_chars: Vec< char >,
-
-    /// graph constructors
-    /// TODO: move into separate struct MorphismMap or something
-    morphisms: HashMap<
-                   MorphismTypePattern,
-                   Arc<
-                           dyn Fn( NestedNode, TypeTerm ) -> Option<NestedNode>
-                           + Send + Sync
-                   >
-               >,
-
-    /// recursion
-    parent: Option<Arc<RwLock<Context>>>,
-}
-
-impl Default for Context {
-    fn default() -> Context {
-        let mut ctx = Context::new();
-
-        ctx.add_list_typename("Sequence");
-        ctx.add_synonym("Seq", "Sequence");
-        ctx.add_list_typename("SepSeq");
-        ctx.add_typename("NestedNode");
-        ctx.add_typename("TerminalEvent");
-        
-        crate::editors::list::init_ctx( &mut ctx );
-        crate::editors::char::init_ctx( &mut ctx );
-        crate::editors::integer::init_ctx( &mut ctx );
-        crate::editors::typeterm::init_ctx( &mut ctx );
-
-        ctx
-    }
-}
-
-impl Context {
-    pub fn with_parent(parent: Option<Arc<RwLock<Context>>>) -> Self {
-        Context {
-            type_dict: match parent.as_ref() {
-                Some(p) => p.read().unwrap().type_dict.clone(),
-                None => Arc::new(RwLock::new(TypeDict::new()))
-            },
-            morphisms: HashMap::new(),
-            nodes: HashMap::new(),
-            list_types: match parent.as_ref() {
-                Some(p) => p.read().unwrap().list_types.clone(),
-                None => Vec::new()
-            },
-            meta_chars: match parent.as_ref() {
-                Some(p) => p.read().unwrap().meta_chars.clone(),
-                None => Vec::new()
-            },
-            parent,
-        }
-    }
-
-    pub fn new() -> Self {
-        Context::with_parent(None)
-    }
-
-    pub fn depth(&self) -> usize {
-        if let Some(parent) = self.parent.as_ref() {
-            parent.read().unwrap().depth() + 1
-        } else {
-            0
-        }
-    }
-
-    pub fn parse(ctx: &Arc<RwLock<Self>>, s: &str) -> TypeTerm {
-        ctx.read().unwrap().type_term_from_str(s).expect("could not parse type term")
-    }
-
-    pub fn add_typename(&mut self, tn: &str) -> TypeID {
-        self.type_dict.write().unwrap().add_typename(tn.to_string())
-    }
-
-    pub fn add_varname(&mut self, vn: &str) -> TypeID {
-        self.type_dict.write().unwrap().add_varname(vn.to_string())
-    }
-
-    pub fn add_synonym(&mut self, new: &str, old: &str) {
-        self.type_dict.write().unwrap().add_synonym(new.to_string(), old.to_string());
-    }
-
-    pub fn add_list_typename(&mut self, tn: &str) {
-        let tid = self.add_typename(tn);
-        self.list_types.push( tid );
-    }
-
-    pub fn is_list_type(&self, t: &TypeTerm) -> bool {
-        match t {
-            TypeTerm::TypeID(id) => {
-                self.list_types.contains(id)
-            }
-            TypeTerm::Ladder(args) |
-            TypeTerm::App(args) => {
-                if args.len() > 0 {
-                    if self.is_list_type(&args[0]) {
-                        true
-                    } else {
-                        false
-                    }
-                } else {
-                    false
-                }
-            }
-            _ => false
-        }
-    }
-
-    pub fn get_typeid(&self, tn: &str) -> Option<TypeID> {
-        self.type_dict.read().unwrap().get_typeid(&tn.into())
-    }
-
-    pub fn get_fun_typeid(&self, tn: &str) -> Option<u64> {
-        match self.get_typeid(tn) {
-            Some(TypeID::Fun(x)) => Some(x),
-            _ => None
-        }
-    }
-
-    pub fn get_typename(&self, tid: &TypeID) -> Option<String> {
-        self.type_dict.read().unwrap().get_typename(tid)
-    }
-
-    pub fn get_var_typeid(&self, tn: &str) -> Option<u64> {
-        match self.get_typeid(tn) {
-            Some(TypeID::Var(x)) => Some(x),
-            _ => None
-        }
-    }
-
-    pub fn type_term_from_str(&self, tn: &str) -> Result<TypeTerm, laddertypes::parser::ParseError> {
-        self.type_dict.write().unwrap().parse(&tn)
-    }
-
-    pub fn type_term_to_str(&self, t: &TypeTerm) -> String {
-        self.type_dict.read().unwrap().unparse(&t)
-    }
-
-    pub fn add_node_ctor(&mut self, tn: &str, mk_editor: Arc<dyn Fn(Arc<RwLock<Self>>, TypeTerm, OuterViewPort<dyn SingletonView<Item = usize>>) -> Option<NestedNode> + Send + Sync>) {
-        let dict = self.type_dict.clone();
-        let mut dict = dict.write().unwrap();
-
-        let tyid =
-            if let Some(tyid) = dict.get_typeid(&tn.into()) {
-                tyid
-            } else {
-                dict.add_typename(tn.into())
-            };
-
-        let morphism_pattern = MorphismTypePattern {
-            src_tyid: None,
-            dst_tyid: tyid
-        };
-
-        drop(dict);
-
-        self.add_morphism(morphism_pattern, Arc::new(move |node, dst_type| {
-            mk_editor(node.ctx.clone(), dst_type, node.depth)
-        }));
-    }
-
-    pub fn add_morphism(
-        &mut self,
-        morph_type_pattern: MorphismTypePattern,
-        morph_fn: Arc<
-                     dyn Fn( NestedNode, TypeTerm ) -> Option<NestedNode>
-                     + Send + Sync
-                  >
-    ) {
-        self.morphisms.insert(morph_type_pattern, morph_fn);
-    }
-
-    pub fn get_morphism(&self, ty: MorphismType) -> Option<Arc<dyn Fn(NestedNode, TypeTerm) -> Option<NestedNode> + Send + Sync>> {
-        let pattern = MorphismTypePattern::from(ty.clone());
-
-        if let Some(morphism) = self.morphisms.get( &pattern ) {
-            Some(morphism.clone())
-        } else {
-            self.parent.as_ref()?
-                .read().unwrap()
-                .get_morphism(ty)
-        }
-    }
-
-    pub fn make_node(ctx: &Arc<RwLock<Self>>, type_term: TypeTerm, depth: OuterViewPort<dyn SingletonView<Item = usize>>) -> Option<NestedNode> {
-        let mk_node = ctx.read().unwrap().get_morphism(MorphismType {
-            src_type: None,
-            dst_type: type_term.clone()
-        }).expect(&format!("morphism {}", ctx.read().unwrap().type_term_to_str(&type_term)));
-
-        /* create new context per node ?? too heavy.. whats the reason? TODO */
-
-        let new_ctx = Arc::new(RwLock::new(Context::with_parent(Some(ctx.clone()))));
-
-        mk_node(
-            NestedNode::new(new_ctx, ReprTree::new_arc(type_term.clone()), depth),
-            type_term
-        )
-    }
-
-    pub fn morph_node(mut node: NestedNode, dst_type: TypeTerm) -> NestedNode {
-        let src_type = node.data.read().unwrap().get_type().clone();
-        let pattern = MorphismType { src_type: Some(src_type), dst_type: dst_type.clone() };
-
-        /* it is not univesally true to always use ascend.
-         */
-        node.data =
-            ReprTree::ascend(
-                &node.data,
-                dst_type.clone()
-            );
-
-        let m = node.ctx.read().unwrap().get_morphism(pattern.clone());
-        if let Some(transform) = m {
-            if let Some(new_node) = transform(node.clone(), dst_type) {
-                new_node
-            } else {
-                node.clone()
-            }
-        } else {
-            eprintln!("could not find morphism {}", pattern.to_str(&node.ctx.read().unwrap()));
-            node
-        }
-    }
-
-    /// adds an object without any representations
-    pub fn add_obj(ctx: Arc<RwLock<Context>>, name: String, typename: &str) {
-        let type_tag = ctx.read().unwrap()
-            .type_dict.write().unwrap()
-            .parse(typename).unwrap();
-
-        if let Some(node) = Context::make_node(&ctx, type_tag, SingletonBuffer::new(0).get_port()) {
-            ctx.write().unwrap().nodes.insert(name, node);
-        }
-    }
-
-    pub fn get_obj(&self, name: &String) -> Option<NestedNode> {
-        if let Some(obj) = self.nodes.get(name) {
-            Some(obj.clone())
-        } else if let Some(parent) = self.parent.as_ref() {
-            parent.read().unwrap().get_obj(name)
-        } else {
-            None
-        }
-    }
-
-/*
-    pub fn get_obj_port<'a, V: View + ?Sized + 'static>(
-        &self,
-        name: &str,
-        type_ladder: impl Iterator<Item = &'a str>,
-    ) -> Option<OuterViewPort<V>>
-    where
-        V::Msg: Clone,
-    {
-        self.get_obj(&name.into())?
-            .downcast_ladder(type_ladder.map(|tn| self.type_dict.type_term_from_str(tn).unwrap()))?
-            .get_port()
-    }
-
-    pub fn insert_repr<'a>(
-        &mut self,
-        name: &str,
-        type_ladder: impl Iterator<Item = &'a str>,
-        port: AnyOuterViewPort,
-    ) {
-        self.get_obj(&name.to_string())
-            .unwrap()
-            .repr
-            .write()
-            .unwrap()
-            .insert_leaf(
-                type_ladder.map(|tn| self.type_dict.type_term_from_str(tn).unwrap()),
-                port,
-            );
-    }
-
-    pub fn epi_cast(&mut self, name: &str, typename: &str) {
-        let dst_type = self.type_dict.type_term_from_str(typename).unwrap();
-        let old_obj = self.objects.get(&name.to_string()).unwrap().clone();
-        let new_obj = if let Some(ctor) = self.morphism_constructors.get(&MorphismType {
-            mode: MorphismMode::Epi,
-            src_type: old_obj.type_tag.clone(),
-            dst_type: dst_type.clone(),
-        }) {
-            ctor(old_obj.clone())
-        } else {
-            Arc::new(RwLock::new(ReprTree::new(dst_type)))
-        };
-
-        new_obj
-            .repr
-            .write()
-            .unwrap()
-            .insert_branch(old_obj.type_tag, old_obj.repr);
-
-        self.objects.insert(name.to_string(), new_obj);
-    }
-
-    pub fn mono_view<'a, V: View + ?Sized + 'static>(
-        &mut self,
-        name: &str,
-        type_ladder: impl Iterator<Item = &'a str>,
-    ) -> Option<OuterViewPort<V>>
-    where
-        V::Msg: Clone,
-    {
-        if let Some(p) = self.get_obj_port(name, type_ladder) {
-            Some(p)
-        } else {
-            // todo : add repr with morphism constructor (if one exists)
-            /*
-            if let Some(ctor) = self.morphism_constructors.get(
-                &MorphismType {
-                    mode: MorphismMode::Mono,
-                    src_type: old_obj.type_tag.clone(),
-                    dst_type:
-                }
-            )
-            */
-            None
-        }
-}
-    */
-}
-
-//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
-
diff --git a/nested/src/type_system/mod.rs b/nested/src/type_system/mod.rs
deleted file mode 100644
index 6d52a5b..0000000
--- a/nested/src/type_system/mod.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-pub mod context;
-pub mod repr_tree;
-
-pub use {
-    context::{Context, MorphismMode, MorphismType, MorphismTypePattern},
-    repr_tree::ReprTree
-};
-
diff --git a/nested/src/type_system/repr_tree.rs b/nested/src/type_system/repr_tree.rs
deleted file mode 100644
index 611565c..0000000
--- a/nested/src/type_system/repr_tree.rs
+++ /dev/null
@@ -1,235 +0,0 @@
-use {
-    r3vi::view::{AnyOuterViewPort, OuterViewPort, View},
-    laddertypes::{TypeTerm},
-    crate::{
-        type_system::{Context}
-    },
-    std::{
-        collections::HashMap,
-        sync::{Arc, RwLock},
-    },
-};
-
-//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
-
-#[derive(Clone)]
-pub struct ReprTree {
-    type_tag: TypeTerm,
-    port: Option<AnyOuterViewPort>,
-    branches: HashMap<TypeTerm, Arc<RwLock<ReprTree>>>,
-}
-
-impl std::fmt::Debug for ReprTree {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        write!(f, "type: {:?}", self.type_tag)?;
-
-        for (_k,x) in self.branches.iter() {
-            write!(f, "child: {:?}", x)?;
-        }
-
-        Ok(())
-    }
-}
-
-impl ReprTree {
-    pub fn new(type_tag: impl Into<TypeTerm>) -> Self {
-        ReprTree {
-            type_tag: type_tag.into(),
-            port: None,
-            branches: HashMap::new(),
-        }
-    }
-
-    pub fn new_arc(type_tag: impl Into<TypeTerm>) -> Arc<RwLock<Self>> {
-        Arc::new(RwLock::new(Self::new(type_tag)))
-    }
-
-    pub fn get_type(&self) -> &TypeTerm {
-        &self.type_tag
-    }
-
-    pub fn from_char(ctx: &Arc<RwLock<Context>>, c: char) -> Arc<RwLock<Self>> {
-        let buf = r3vi::buffer::singleton::SingletonBuffer::<char>::new(c);
-        ReprTree::new_leaf(
-            Context::parse(ctx, "Char"),
-            buf.get_port().into()
-        )
-    }
-
-    pub fn new_leaf(type_tag: impl Into<TypeTerm>, port: AnyOuterViewPort) -> Arc<RwLock<Self>> {
-        let mut tree = ReprTree::new(type_tag.into());
-        tree.insert_leaf(vec![].into_iter(), port);
-        Arc::new(RwLock::new(tree))
-    }
-
-    pub fn insert_branch(&mut self, repr: Arc<RwLock<ReprTree>>) {
-        self.branches.insert(repr.clone().read().unwrap().type_tag.clone(), repr.clone());
-    }
-
-    pub fn insert_leaf(
-        &mut self,
-        mut type_ladder: impl Iterator<Item = TypeTerm>,
-        port: AnyOuterViewPort,
-    ) {
-        if let Some(type_term) = type_ladder.next() {
-            if let Some(next_repr) = self.branches.get(&type_term) {
-                next_repr.write().unwrap().insert_leaf(type_ladder, port);
-            } else {
-                let mut next_repr = ReprTree::new(type_term.clone());
-                next_repr.insert_leaf(type_ladder, port);
-                self.insert_branch(Arc::new(RwLock::new(next_repr)));
-            }
-        } else {
-            self.port = Some(port);
-        }
-    }
-
-    //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
-
-    pub fn get_port<V: View + ?Sized + 'static>(&self) -> Option<OuterViewPort<V>>
-    where
-        V::Msg: Clone,
-    {
-        Some(
-            self.port
-                .clone()?
-                .downcast::<V>()
-                .ok()?
-        )
-    }
-
-    pub fn get_view<V: View + ?Sized + 'static>(&self) -> Option<Arc<V>>
-    where
-        V::Msg: Clone,
-    {
-            self.get_port::<V>()?
-                .get_view()
-    }
-
-    pub fn descend(&self, dst_type: impl Into<TypeTerm>) -> Option<Arc<RwLock<ReprTree>>> {
-        self.branches.get(&dst_type.into()).cloned()
-    }
-
-    pub fn descend_ladder(rt: &Arc<RwLock<Self>>, mut repr_ladder: impl Iterator<Item = TypeTerm>) -> Option<Arc<RwLock<ReprTree>>> {
-        if let Some(first) = repr_ladder.next() {
-            let rt = rt.read().unwrap();
-            repr_ladder.fold(
-                rt.descend(first),
-                |s, t| s?.read().unwrap().descend(t))
-        } else {
-            Some(rt.clone())
-        }
-    }
-
-    pub fn ascend(rt: &Arc<RwLock<Self>>, type_term: impl Into<TypeTerm>) -> Arc<RwLock<ReprTree>> {
-        let mut n = Self::new(type_term);
-        n.insert_branch(rt.clone());
-        Arc::new(RwLock::new(n))
-    }
-
-/*
-    pub fn add_iso_repr(
-        &self,
-        type_ladder: impl Iterator<Item = TypeTerm>,
-        morphism_constructors: &HashMap<MorphismType, Box<dyn Fn(Object) -> Object>>,
-    ) {
-        let mut cur_repr = self.repr.clone();
-
-        for dst_type in type_ladder {
-            if let Some(next_repr) = self.repr.read().unwrap().branches.get(&dst_type) {
-                // go deeper
-                cur_repr = next_repr.clone();
-            } else {
-                // search for morphism constructor and insert new repr
-                let mut obj = None;
-
-                for src_type in cur_repr.read().unwrap().branches.keys() {
-                    if let Some(ctor) = morphism_constructors.get(&MorphismType {
-                        mode: MorphismMode::Iso,
-                        src_type: src_type.clone(),
-                        dst_type: dst_type.clone(),
-                    }) {
-                        let new_obj = ctor(Object {
-                            type_tag: src_type.clone(),
-                            repr: cur_repr
-                                .read()
-                                .unwrap()
-                                .branches
-                                .get(&src_type)
-                                .unwrap()
-                                .clone(),
-                        });
-
-                        assert!(new_obj.type_tag == dst_type);
-
-                        obj = Some(new_obj);
-                        break;
-                    }
-                }
-
-                if let Some(obj) = obj {
-                    cur_repr
-                        .write()
-                        .unwrap()
-                        .insert_branch(obj.type_tag, obj.repr);
-                } else {
-                    panic!("could not find matching isomorphism!");
-                }
-            }
-        }
-    }
-
-    pub fn add_mono_repr<'a>(
-        &self,
-        type_ladder: impl Iterator<Item = TypeTerm>,
-        morphism_constructors: &HashMap<MorphismType, Box<dyn Fn(Object) -> Object>>,
-    ) {
-        let mut cur_type = self.type_tag.clone();
-        let mut cur_repr = self.repr.clone();   
-
-        for dst_type in type_ladder {
-            if let Some(next_repr) = self.repr.read().unwrap().branches.get(&dst_type) {
-                // go deeper
-                cur_type = dst_type;
-                cur_repr = next_repr.clone();
-            } else {
-                if let Some(constructor) = morphism_constructors.get(&MorphismType {
-                    mode: MorphismMode::Mono,
-                    src_type: cur_type.clone(),
-                    dst_type: dst_type.clone(),
-                }) {
-                    let new_obj = constructor(Object {
-                        type_tag: cur_type.clone(),
-                        repr: cur_repr
-                            .read()
-                            .unwrap()
-                            .branches
-                            .get(&cur_type)
-                            .unwrap()
-                            .clone(),
-                    });
-
-                    assert!(new_obj.type_tag == dst_type);
-                    cur_repr
-                        .write()
-                        .unwrap()
-                        .insert_branch(new_obj.type_tag.clone(), new_obj.repr.clone());
-
-                    cur_type = new_obj.type_tag;
-                    cur_repr = new_obj.repr;
-                }
-            }
-        }
-    }
-
-    // replace with higher-level type in which self is a repr branch
-    pub fn epi_cast<'a>(
-        &self,
-        _type_ladder: impl Iterator<Item = TypeTerm>,
-        _morphism_constructors: &HashMap<MorphismType, Box<dyn Fn(Object) -> Object>>,
-    ) {
-        // todo        
-}
-    */
-}
-
diff --git a/nested/src/utils/bimap.rs b/nested/src/utils/bimap.rs
deleted file mode 100644
index 8bd41b6..0000000
--- a/nested/src/utils/bimap.rs
+++ /dev/null
@@ -1,24 +0,0 @@
-use std::{collections::HashMap, hash::Hash};
-
-//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
-
-pub struct Bimap<V: Eq + Hash, Λ: Eq + Hash> {
-    pub mλ: HashMap<V, Λ>,
-    pub my: HashMap<Λ, V>,
-}
-
-impl<V: Eq + Hash + Clone, Λ: Eq + Hash + Clone> Bimap<V, Λ> {
-    pub fn new() -> Self {
-        Bimap {
-            mλ: HashMap::new(),
-            my: HashMap::new(),
-        }
-    }
-
-    pub fn insert(&mut self, y: V, λ: Λ) {
-        self.mλ.insert(y.clone(), λ.clone());
-        self.my.insert(λ, y);
-    }
-}
-
-//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
diff --git a/nested/src/utils/mod.rs b/nested/src/utils/mod.rs
deleted file mode 100644
index fe10469..0000000
--- a/nested/src/utils/mod.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-pub mod bimap;
-pub mod modulo;
-pub mod color;
-
-pub use modulo::modulo;
-pub use bimap::Bimap;
diff --git a/terminal/ansi_parser/Cargo.toml b/srv-pty-capture/Cargo.toml
similarity index 71%
rename from terminal/ansi_parser/Cargo.toml
rename to srv-pty-capture/Cargo.toml
index 2b1ca1d..3453d45 100644
--- a/terminal/ansi_parser/Cargo.toml
+++ b/srv-pty-capture/Cargo.toml
@@ -1,11 +1,12 @@
 [package]
 authors = ["Michael Sippel <micha@fragmental.art>"]
-name = "ansi_parser"
+name = "srv-pty-capture"
 version = "0.1.0"
 edition = "2018"
 
 [dependencies]
-nested = { path = "../../nested" }
+nested = { path = "../lib-nested-core" }
+nested-tty = { path = "../lib-nested-tty" }
 cgmath = { version = "0.18.0", features = ["serde"] }
 serde = { version = "1.0", features = ["serde_derive"] }
 bincode = "1.3.3"
diff --git a/terminal/ansi_parser/src/main.rs b/srv-pty-capture/src/main.rs
similarity index 99%
rename from terminal/ansi_parser/src/main.rs
rename to srv-pty-capture/src/main.rs
index 0e4d532..5d531ac 100644
--- a/terminal/ansi_parser/src/main.rs
+++ b/srv-pty-capture/src/main.rs
@@ -2,7 +2,7 @@
 
 use {
     cgmath::Point2,
-    nested::terminal::{TerminalAtom, TerminalStyle},
+    nested_tty::{TerminalAtom, TerminalStyle},
     std::{
         fs::File,
         io::{stdin, Read, Write},
diff --git a/terminal/display_server/Cargo.toml b/srv-tty-output/Cargo.toml
similarity index 70%
rename from terminal/display_server/Cargo.toml
rename to srv-tty-output/Cargo.toml
index 4d933da..314e9f5 100644
--- a/terminal/display_server/Cargo.toml
+++ b/srv-tty-output/Cargo.toml
@@ -1,11 +1,12 @@
 [package]
 authors = ["Michael Sippel <micha@fragmental.art>"]
-name = "display_server"
+name = "srv-tty-output"
 version = "0.1.0"
 edition = "2018"
 
 [dependencies]
-nested = { path = "../../nested" }
+nested = { path = "../lib-nested-core" }
+nested-tty  = { path = "../lib-nested-tty" }
 termion = "1.5.5"
 cgmath = { version = "0.18.0", features = ["serde"] }
 serde = { version = "1.0", features = ["serde_derive"] }
diff --git a/terminal/display_server/src/main.rs b/srv-tty-output/src/main.rs
similarity index 97%
rename from terminal/display_server/src/main.rs
rename to srv-tty-output/src/main.rs
index a3f52fc..46f6c6e 100644
--- a/terminal/display_server/src/main.rs
+++ b/srv-tty-output/src/main.rs
@@ -1,6 +1,6 @@
 use {
     cgmath::{Point2, Vector2},
-    nested::terminal::{TerminalAtom, TerminalStyle},
+    nested_tty::{TerminalAtom, TerminalStyle},
     std::io::{stdout, Read, Write},
     termion::raw::IntoRawMode,
 };