diff --git a/nested/src/index/buffer.rs b/nested/src/index/buffer.rs
index e6e53d1..d5f0851 100644
--- a/nested/src/index/buffer.rs
+++ b/nested/src/index/buffer.rs
@@ -4,7 +4,7 @@ use {
         index::{IndexArea, IndexView},
     },
     std::sync::RwLock,
-    std::{collections::HashMap, hash::Hash, sync::Arc},
+    std::{collections::HashMap, hash::Hash, sync::Arc, ops::{Deref, DerefMut}},
 };
 
 pub struct IndexBufferView<Key, Item>(Arc<RwLock<HashMap<Key, Item>>>)
@@ -36,6 +36,7 @@ where
     }
 }
 
+#[derive(Clone)]
 pub struct IndexBuffer<Key, Item>
 where
     Key: Clone + Hash + Eq + Send + Sync + 'static,
@@ -68,6 +69,27 @@ where
         self.port.0.outer()
     }
 
+    pub fn get(&self, key: &Key) -> Option<Item> {
+        self.data.read().unwrap().get(key).cloned()
+    }
+
+    pub fn get_mut(&mut self, key: &Key) -> MutableIndexAccess<Key, Item> {
+        MutableIndexAccess {
+            buf: self.clone(),
+            key: key.clone(),
+            val: self.get(key)
+        }
+    }
+
+    pub fn update(&mut self, key: Key, item: Option<Item>) {
+        if let Some(item) = item {
+            self.data.write().unwrap().insert(key.clone(), item);
+        } else {
+            self.data.write().unwrap().remove(&key);
+        }
+        self.port.notify(&IndexArea::Set(vec![key]));        
+    }
+    
     pub fn insert(&mut self, key: Key, item: Item) {
         self.data.write().unwrap().insert(key.clone(), item);
         self.port.notify(&IndexArea::Set(vec![key]));
@@ -87,3 +109,48 @@ where
         self.port.notify(&IndexArea::Set(vec![key]));
     }
 }
+
+//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
+
+pub struct MutableIndexAccess<Key, Item>
+where
+    Key: Clone + Hash + Eq + Send + Sync + 'static,
+    Item: Clone + Send + Sync + 'static,
+{
+    buf: IndexBuffer<Key, Item>,
+    key: Key,
+    val: Option<Item>,
+}
+
+impl<Key, Item> Deref for MutableIndexAccess<Key, Item>
+where
+    Key: Clone + Hash + Eq + Send + Sync + 'static,
+    Item: Clone + Send + Sync + 'static,
+{
+    type Target = Option<Item>;
+
+    fn deref(&self) -> &Option<Item> {
+        &self.val
+    }
+}
+
+impl<Key, Item> DerefMut for MutableIndexAccess<Key, Item>
+where
+    Key: Clone + Hash + Eq + Send + Sync + 'static,
+    Item: Clone + Send + Sync + 'static,
+{
+    fn deref_mut(&mut self) -> &mut Self::Target {
+        &mut self.val
+    }
+}
+
+impl<Key, Item> Drop for MutableIndexAccess<Key, Item>
+where
+    Key: Clone + Hash + Eq + Send + Sync + 'static,
+    Item: Clone + Send + Sync + 'static,
+{
+    fn drop(&mut self) {
+        self.buf.update(self.key.clone(), self.val.clone());
+    }
+}
+
diff --git a/nested/src/make_editor.rs b/nested/src/make_editor.rs
index ad4a1ed..b489164 100644
--- a/nested/src/make_editor.rs
+++ b/nested/src/make_editor.rs
@@ -10,7 +10,7 @@ use {
         product::editor::ProductEditor,
         char_editor::CharEditor
     },
-    cgmath::Vector2,
+    cgmath::{Vector2, Point2},
     std::sync::{Arc, RwLock},
 };
 
@@ -90,26 +90,46 @@ pub fn make_editor(ctx: Arc<RwLock<Context>>, t: &TypeLadder, depth: usize) -> A
 
     } else if t[0] == c.type_term_from_str("( RGB )").unwrap() {
         Arc::new(RwLock::new(ProductEditor::new(depth, ctx.clone())
-                             .with_t("{ r: ")
-                             .with_n( vec![ ctx.read().unwrap().type_term_from_str("( PosInt 16 BigEndian )").unwrap() ] )
-                             .with_t(", g: ")
-                             .with_n( vec![ ctx.read().unwrap().type_term_from_str("( PosInt 16 BigEndian )").unwrap() ] )
-                             .with_t(", b: ")
-                             .with_n( vec![ ctx.read().unwrap().type_term_from_str("( PosInt 16 BigEndian )").unwrap() ] )
-                             .with_t(" }")
+                             .with_t(Point2::new(0, 0), "{")
+                             .with_t(Point2::new(1, 1), "r: ")
+                             .with_n(Point2::new(2, 1), vec![ ctx.read().unwrap().type_term_from_str("( PosInt 16 BigEndian )").unwrap() ] )
+                             .with_t(Point2::new(1, 2), "g: ")
+                             .with_n(Point2::new(2, 2), vec![ ctx.read().unwrap().type_term_from_str("( PosInt 16 BigEndian )").unwrap() ] )
+                             .with_t(Point2::new(1, 3), "b: ")
+                             .with_n(Point2::new(2, 3), vec![ ctx.read().unwrap().type_term_from_str("( PosInt 16 BigEndian )").unwrap() ] )
+                             .with_t(Point2::new(0, 4), " }")
         )) as Arc<RwLock<dyn TerminalTreeEditor + Send + Sync>>
 
     } else if t[0] == c.type_term_from_str("( Vec3i )").unwrap() {
         Arc::new(RwLock::new(ProductEditor::new(depth, ctx.clone())
-                             .with_t("{ x: ")
-                             .with_n( vec![ ctx.read().unwrap().type_term_from_str("( PosInt 10 BigEndian )").unwrap() ] )
-                             .with_t(", y: ")
-                             .with_n( vec![ ctx.read().unwrap().type_term_from_str("( PosInt 10 BigEndian )").unwrap() ] )
-                             .with_t(", z: ")
-                             .with_n( vec![ ctx.read().unwrap().type_term_from_str("( PosInt 10 BigEndian )").unwrap() ] )
-                             .with_t(" }")
+                             .with_t(Point2::new(0, 0), "{")
+                             .with_t(Point2::new(1, 1), "x: ")
+                             .with_n(Point2::new(2, 1), vec![ ctx.read().unwrap().type_term_from_str("( PosInt 10 BigEndian )").unwrap() ] )
+                             .with_t(Point2::new(1, 2), "y: ")
+                             .with_n(Point2::new(2, 2), vec![ ctx.read().unwrap().type_term_from_str("( PosInt 10 BigEndian )").unwrap() ] )
+                             .with_t(Point2::new(1, 3), "z: ")
+                             .with_n(Point2::new(2, 3), vec![ ctx.read().unwrap().type_term_from_str("( PosInt 10 BigEndian )").unwrap() ] )
+                             .with_t(Point2::new(0, 4), " }")
         )) as Arc<RwLock<dyn TerminalTreeEditor + Send + Sync>>
 
+    } else if t[0] == c.type_term_from_str("( Json )").unwrap() {
+        Arc::new(RwLock::new(
+            PTYListEditor::<dyn TerminalTreeEditor + Send + Sync>::new(
+                Box::new({
+                    let ctx = ctx.clone();
+                    move || {
+                        Arc::new(RwLock::new(ProductEditor::new(depth, ctx.clone())
+                                             .with_n(Point2::new(0, 0), vec![ ctx.read().unwrap().type_term_from_str("( String )").unwrap() ] )
+                                             .with_t(Point2::new(1, 0), ": ")
+                                             .with_n(Point2::new(2, 0), vec![ ctx.read().unwrap().type_term_from_str("( Json )").unwrap() ] )
+                        )) as Arc<RwLock<dyn TerminalTreeEditor + Send + Sync>>
+                    }
+                }),
+                SeqDecorStyle::VerticalSexpr,
+                depth
+            )
+        )) as Arc<RwLock<dyn TerminalTreeEditor + Send + Sync>>
+            
     } else if t[0] == c.type_term_from_str("( List Term )").unwrap() {
         Arc::new(RwLock::new(
             PTYListEditor::<dyn TerminalTreeEditor + Send + Sync>::new(
@@ -126,10 +146,15 @@ pub fn make_editor(ctx: Arc<RwLock<Context>>, t: &TypeLadder, depth: usize) -> A
 
     } else { // else: term
         Arc::new(RwLock::new(
-            ProductEditor::new(depth, ctx.clone())
-                .with_n( vec![ c.type_term_from_str("( List Char )").unwrap() ] )
-                .with_n( vec![ c.type_term_from_str("( List Term )").unwrap() ] )
-        )) as Arc<RwLock<dyn TerminalTreeEditor + Send + Sync>>
+            PTYListEditor::new(
+                Box::new(|| {
+                    Arc::new(RwLock::new(CharEditor::new()))
+                }),
+                SeqDecorStyle::DoubleQuote,
+                depth
+            )
+        ))
+
     }
 }
 
diff --git a/nested/src/product/editor.rs b/nested/src/product/editor.rs
index d3fce6d..d1e75a8 100644
--- a/nested/src/product/editor.rs
+++ b/nested/src/product/editor.rs
@@ -8,19 +8,21 @@ use {
         sequence::{SequenceView},
         tree_nav::{TreeNav, TerminalTreeEditor, TreeNavResult},
         vec::{VecBuffer, MutableVecAccess},
+        index::{buffer::{IndexBuffer, MutableIndexAccess}, IndexView},
         list::ListCursorMode,
         product::{segment::ProductEditorSegment},
         make_editor::make_editor
     },
-    cgmath::Vector2,
+    cgmath::{Vector2, Point2},
     std::sync::{Arc, RwLock},
     termion::event::{Event, Key},
+    std::ops::{Deref, DerefMut}
 };
 
 pub struct ProductEditor {
-    segments: VecBuffer<ProductEditorSegment>,
-    pub(super) n_indices: Vec<usize>,
-    
+    segments: IndexBuffer<Point2<i16>, ProductEditorSegment>,
+    pub(super) n_indices: Vec<Point2<i16>>,
+
     pub(super) ctx: Arc<RwLock<Context>>,    
     pub(super) cursor: Option<isize>,
     pub(super) depth: usize,
@@ -29,7 +31,7 @@ pub struct ProductEditor {
 impl ProductEditor {
     pub fn new(depth: usize, ctx: Arc<RwLock<Context>>) -> Self {
         ProductEditor {
-            segments: VecBuffer::new(),
+            segments: IndexBuffer::new(),
             n_indices: Vec::new(),
             ctx,
             cursor: None,
@@ -37,53 +39,52 @@ impl ProductEditor {
         }
     }
     
-    pub fn with_t(mut self, t: &str) -> Self {
-        self.segments.push(ProductEditorSegment::T(t.to_string(), self.depth));
+    pub fn with_t(mut self, pos: Point2<i16>, t: &str) -> Self {
+        self.segments.insert(pos, ProductEditorSegment::T(t.to_string(), self.depth));
         self
     }
 
-    pub fn with_n(mut self, n: TypeLadder) -> Self {
-        let elem_idx = self.segments.len();
-        self.segments.push(ProductEditorSegment::N{
+    pub fn with_n(mut self, pos: Point2<i16>, n: TypeLadder) -> Self {
+        self.segments.insert(pos, ProductEditorSegment::N{
             t: n,
             editor: None,
             cur_depth: 0
         });
-        self.n_indices.push(elem_idx);
+        self.n_indices.push(pos);
         self
     }
 
-    pub fn get_editor_element(&self, mut idx: isize) -> Option<ProductEditorSegment> {
+    pub fn get_editor_segment(&self, mut idx: isize) -> ProductEditorSegment {
         idx = crate::modulo(idx, self.n_indices.len() as isize);
-        if let Some(i) = self.n_indices.get(idx as usize) {
-            Some(self.segments.get(*i))
+        if let Some(pos) = self.n_indices.get(idx as usize) {
+            self.segments.get(pos).unwrap()
         } else {
-            None
+            unreachable!()
         }
     }
 
-    pub fn get_editor_element_mut(&mut self, mut idx: isize) -> Option<MutableVecAccess<ProductEditorSegment>> {
+    pub fn get_editor_segment_mut(&mut self, mut idx: isize) -> MutableIndexAccess<Point2<i16>, ProductEditorSegment> {
         idx = crate::modulo(idx, self.n_indices.len() as isize);
-        if let Some(i) = self.n_indices.get(idx as usize) {
-            Some(self.segments.get_mut(*i))
+        if let Some(pos) = self.n_indices.get(idx as usize) {
+            self.segments.get_mut(pos)
         } else {
-            None
+            unreachable!()
         }
     }
 
-    pub fn get_cur_element(&self) -> Option<ProductEditorSegment> {
-        self.get_editor_element(self.cursor?)
+    pub fn get_cur_segment(&self) -> Option<ProductEditorSegment> {
+        Some(self.get_editor_segment(self.cursor?))
     }
 
-    pub fn get_cur_element_mut(&mut self) -> Option<MutableVecAccess<ProductEditorSegment>> {
-        self.get_editor_element_mut(self.cursor?)
+    pub fn get_cur_segment_mut(&mut self) -> Option<MutableIndexAccess<Point2<i16>, ProductEditorSegment>> {
+        Some(self.get_editor_segment_mut(self.cursor?))
     }
 
     pub fn get_editor(&self, idx: isize) -> Option<Arc<RwLock<dyn TerminalTreeEditor + Send + Sync>>> {
-        if let Some(ProductEditorSegment::N{ t: _, editor, cur_depth: _ }) = self.get_editor_element(idx) {
+        if let ProductEditorSegment::N{ t: _, editor, cur_depth: _ } = self.get_editor_segment(idx) {
             editor
         } else {
-            None
+            unreachable!()
         }
     }
 
@@ -103,14 +104,13 @@ impl TerminalEditor for ProductEditor {
         let ctx = self.ctx.clone();
         self.segments
             .get_port()
-            .to_sequence()
-            .map(move |e: &ProductEditorSegment| { e.get_view(ctx.clone()) })
-            .to_grid_horizontal()
+            .map_item(move |_pos, e: &ProductEditorSegment| { e.get_view(ctx.clone()) })
             .flatten()
     }
 
     fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult {
-        if let Some(ProductEditorSegment::N{ t, editor, cur_depth }) = self.get_cur_element_mut().as_deref_mut() {
+        if let Some(mut segment) = self.get_cur_segment_mut().as_deref_mut() {
+            if let Some(ProductEditorSegment::N{ t, editor, cur_depth }) = segment.deref_mut() {
             *cur_depth = self.get_cursor().tree_addr.len();
             if let Some(e) = editor.clone() {
                 let mut ce = e.write().unwrap();
@@ -141,6 +141,9 @@ impl TerminalEditor for ProductEditor {
                 *cur_depth = self.get_cursor().tree_addr.len()+1;
                 x
             }
+            } else {
+                unreachable!()
+            }
         } else {
             TerminalEditorResult::Exit
         }
diff --git a/nested/src/product/nav.rs b/nested/src/product/nav.rs
index 6e4bf64..f831e8e 100644
--- a/nested/src/product/nav.rs
+++ b/nested/src/product/nav.rs
@@ -52,8 +52,8 @@ impl TreeNav for ProductEditor {
     }
 
     fn goto(&mut self, mut c: TreeCursor) -> TreeNavResult {
-        if let Some(mut element) = self.get_cur_element_mut() {
-            if let ProductEditorSegment::N{ t: _t, editor, cur_depth } = element.deref_mut() {
+        if let Some(mut segment) = self.get_cur_segment_mut() {
+            if let Some(ProductEditorSegment::N{ t: _t, editor, cur_depth }) = segment.deref_mut() {
                 if let Some(e) = editor {
                     let mut e = e.write().unwrap();
                     e.goto(TreeCursor::none());
@@ -65,8 +65,8 @@ impl TreeNav for ProductEditor {
         if c.tree_addr.len() > 0 {
             self.cursor = Some(crate::modulo(c.tree_addr.remove(0), self.n_indices.len() as isize));
 
-            if let Some(mut element) = self.get_cur_element_mut() {
-                if let ProductEditorSegment::N{ t: _t, editor, cur_depth } = element.deref_mut() {
+            if let Some(mut element) = self.get_cur_segment_mut() {
+                if let Some(ProductEditorSegment::N{ t: _t, editor, cur_depth }) = element.deref_mut() {
                     if let Some(e) = editor {
                         e.write().unwrap().goto(c.clone());
                     }
@@ -89,8 +89,8 @@ impl TreeNav for ProductEditor {
                 if direction.y > 0 {
                     self.cursor = Some(0);
 
-                    if let Some(mut element) = self.get_cur_element_mut() {
-                        if let ProductEditorSegment::N{ t, editor, cur_depth } = element.deref_mut() {
+                    if let Some(mut element) = self.get_cur_segment_mut() {
+                        if let Some(ProductEditorSegment::N{ t, editor, cur_depth }) = element.deref_mut() {
                             *cur_depth = 1;
                         }
                     }
@@ -106,8 +106,8 @@ impl TreeNav for ProductEditor {
             1 => {
                 if direction.y > 0 {
                     // dn
-                    if let Some(mut element) = self.get_cur_element_mut() {
-                        if let ProductEditorSegment::N{ t, editor, cur_depth } = element.deref_mut() {
+                    if let Some(mut element) = self.get_cur_segment_mut() {
+                        if let Some(ProductEditorSegment::N{ t, editor, cur_depth }) = element.deref_mut() {
                             if let Some(e) = editor {
                                 let mut e = e.write().unwrap();
                                 e.goby(direction);
@@ -125,8 +125,8 @@ impl TreeNav for ProductEditor {
                     TreeNavResult::Continue
                 } else if direction.y < 0 {
                     // up
-                    if let Some(mut element) = self.get_cur_element_mut() {
-                        if let ProductEditorSegment::N{ t, editor, cur_depth } = element.deref_mut() {
+                    if let Some(mut element) = self.get_cur_segment_mut() {
+                        if let Some(ProductEditorSegment::N{ t, editor, cur_depth }) = element.deref_mut() {
                             *cur_depth = 0;
                         }
                     }
@@ -137,14 +137,14 @@ impl TreeNav for ProductEditor {
                     if (cur.tree_addr[0]+direction.x >= 0) &&
                         (cur.tree_addr[0]+direction.x < self.n_indices.len() as isize)
                     {
-                        if let Some(mut element) = self.get_cur_element_mut() {
-                            if let ProductEditorSegment::N{ t, editor, cur_depth } = element.deref_mut() {
+                        if let Some(mut element) = self.get_cur_segment_mut() {
+                            if let Some(ProductEditorSegment::N{ t, editor, cur_depth }) = element.deref_mut() {
                                 *cur_depth = 0;
                             }
                         }
                         self.cursor = Some(cur.tree_addr[0] + direction.x);
-                        if let Some(mut element) = self.get_cur_element_mut() {
-                            if let ProductEditorSegment::N{ t, editor, cur_depth } = element.deref_mut() {
+                        if let Some(mut element) = self.get_cur_segment_mut() {
+                            if let Some(ProductEditorSegment::N{ t, editor, cur_depth }) = element.deref_mut() {
                                 *cur_depth = 1;
                             }
                         }
@@ -156,8 +156,8 @@ impl TreeNav for ProductEditor {
                 }
             }
             depth => {
-                if let Some(mut element) = self.get_cur_element_mut() {
-                    if let ProductEditorSegment::N{ t, editor, cur_depth } = element.deref_mut() {
+                if let Some(mut element) = self.get_cur_segment_mut() {
+                    if let Some(ProductEditorSegment::N{ t, editor, cur_depth }) = element.deref_mut() {
                         if let Some(e) = editor {
                             let mut ce = e.write().unwrap();
                             //\\//\\//\\//\\