Improve handling of nested lists, trees, null and floating point values.

git-svn-id: https://svn.apache.org/repos/asf/tuscany/sca-cpp/trunk@1428191 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/components/chat/xmpp.hpp b/components/chat/xmpp.hpp
index 8817461..31b4ed3 100644
--- a/components/chat/xmpp.hpp
+++ b/components/chat/xmpp.hpp
@@ -51,7 +51,6 @@
     }
 
     ~XMPPRuntime() {
-        debug("chat::~xmppruntime");
         xmpp_shutdown();
     }
 
@@ -79,7 +78,6 @@
     XMPPClient& operator=(const XMPPClient& xc) = delete;
 
     ~XMPPClient() {
-        debug("chat::~xmppclient");
         extern const failable<bool> disconnect(XMPPClient& xc);
         if (!owner)
             return;
diff --git a/components/http/server-test.scm b/components/http/server-test.scm
index 4bbff6e..41d6296 100644
--- a/components/http/server-test.scm
+++ b/components/http/server-test.scm
@@ -22,7 +22,7 @@
 ; ATOMPub test case
 
 (define (get id)
-  (if (nul id)
+  (if (null? id)
     '((feed (title "Sample Feed") (id "123456789") (entry
        (((title "Item") (id "111") (content (item (name "Apple") (currencyCode "USD") (currencySymbol "$") (price 2.99))))
         ((title "Item") (id "222") (content (item (name "Orange") (currencyCode "USD") (currencySymbol "$") (price 3.55))))
diff --git a/components/queue/qpid.hpp b/components/queue/qpid.hpp
index 7736146..076d9f1 100644
--- a/components/queue/qpid.hpp
+++ b/components/queue/qpid.hpp
@@ -68,7 +68,6 @@
     QpidConnection& operator=(const QpidConnection& qc) = delete;
 
     ~QpidConnection() {
-        debug("queue::~qpidonnection");
         if (!owner)
             return;
         c.close();
@@ -109,7 +108,6 @@
     }
 
     ~QpidSession() {
-        debug("queue::~qpidsession");
         if (!owner)
             return;
         s.close();
diff --git a/components/webservice/axis2.hpp b/components/webservice/axis2.hpp
index fd4d1f9..d6d2107 100644
--- a/components/webservice/axis2.hpp
+++ b/components/webservice/axis2.hpp
@@ -72,7 +72,6 @@
     }
 
     ~Axis2Context() {
-        debug("webservice::~axis2context");
         if (!owner || env == NULL)
             return;
         axutil_env_free(env);
diff --git a/configure.ac b/configure.ac
index eb626c7..b0992a5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -119,7 +119,7 @@
 if test "${want_maintainer_mode}" = "true"; then
   cxxflags="${cxxflags} -ggdb -g3 -Werror -Wall -Wextra -Wno-ignored-qualifiers -Wno-strict-aliasing -Winit-self -Wmissing-include-dirs -Wcast-qual -Wcast-align -Wwrite-strings -Wpointer-arith -Waddress -Wredundant-decls -std=c++0x -fmessage-length=0"
   if test "${cxxtype}" = "clang"; then
-    cxxflags="${cxxflags} -O2 -stdlib=libc++ -Qunused-arguments -Wno-return-type-c-linkage"
+    cxxflags="${cxxflags} -O1 -stdlib=libc++ -Qunused-arguments -Wno-return-type-c-linkage"
   else
     cxxflags="${cxxflags} -O2 -Wlogical-op -Wconversion"
   fi
@@ -128,7 +128,7 @@
 else
   cxxflags="${cxxflags} -g -std=c++0x -fmessage-length=0"
   if test "${cxxtype}" = "clang"; then
-    cxxflags="${cxxflags} -O2 -stdlib=libc++ -Qunused-arguments"
+    cxxflags="${cxxflags} -O1 -stdlib=libc++ -Qunused-arguments"
   else
     cxxflags="${cxxflags} -O2"
   fi
diff --git a/kernel/element.hpp b/kernel/element.hpp
index 9ae1e63..d8907c8 100644
--- a/kernel/element.hpp
+++ b/kernel/element.hpp
@@ -228,33 +228,12 @@
 }
 
 /**
- * Returns a selector lambda function which can be used to filter
- * elements against the given element pattern.
- */
-inline const lambda<const bool(const value&)> selector(const list<value>& select) {
-    return [select](const value& v) -> const bool {
-        const lambda<const bool(const list<value>&, const list<value>&)> evalSelect = [&evalSelect](const list<value>& s, const list<value>& v) -> const bool {
-            if (isNil(s))
-                return true;
-            if (isNil(v))
-                return false;
-            if (car(s) != car(v))
-                return false;
-            return evalSelect(cdr(s), cdr(v));
-        };
-        if (!isList(v))
-            return false;
-        return evalSelect(select, v);
-    };
-}
-
-/**
  * Returns the value of the attribute with the given name.
  */
-inline const value attributeValue(const value& name, const value& l) {
+inline const value attributeValue(const value& name, const list<value>& l) {
     const list<value> f = filter<value>([name](const value& v) {
                 return isAttribute(v) && attributeName((list<value>)v) == name;
-           }, list<value>(l));
+           }, l);
     if (isNil(f))
         return nilValue;
     return caddr<value>(car(f));
@@ -263,16 +242,16 @@
 /**
  * Returns child elements with the given name.
  */
-inline const value elementChildren(const value& name, const value& l) {
+inline const list<value> elementChildren(const value& name, const list<value>& l) {
     return filter<value>([name](const value& v) {
                 return isElement(v) && elementName((list<value>)v) == name;
-            }, list<value>(l));
+            }, l);
 }
 
 /**
  * Return the child element with the given name.
  */
-inline const value elementChild(const value& name, const value& l) {
+inline const value elementChild(const value& name, const list<value>& l) {
     const list<value> f = elementChildren(name, l);
     if (isNil(f))
         return nilValue;
diff --git a/kernel/gc.hpp b/kernel/gc.hpp
index 7853c55..2b65132 100644
--- a/kernel/gc.hpp
+++ b/kernel/gc.hpp
@@ -214,7 +214,7 @@
     gc_pool& operator=(const gc_pool& pool) = delete;
 
 private:
-    friend apr_pool_t* pool(const gc_pool& pool) noexcept;
+    friend apr_pool_t* const pool(const gc_pool& pool) noexcept;
     friend class gc_global_pool_t;
     friend class gc_child_pool;
     friend class gc_local_pool;
@@ -226,7 +226,7 @@
 /**
  * Return the APR pool used by a gc_pool.
  */
-inline apr_pool_t* pool(const gc_pool& pool) noexcept {
+inline apr_pool_t* const pool(const gc_pool& pool) noexcept {
     return pool.apr_pool;
 }
 
@@ -242,21 +242,22 @@
     inline gc_pool_stack_t() noexcept : key(mkkey()) {
     }
 
-    inline operator apr_pool_t*() const noexcept {
-        return (apr_pool_t*)pthread_getspecific(key);
+    inline operator apr_pool_t* const () const noexcept {
+        return (apr_pool_t* const )pthread_getspecific(key);
     }
 
-    inline const gc_pool_stack_t& operator=(apr_pool_t* p) noexcept {
-        pthread_setspecific(key, p);
+    const gc_pool_stack_t& operator=(apr_pool_t* const p) noexcept {
+        const int rc = pthread_setspecific(key, p);
+        assertOrFail(rc == 0);
         return *this;
     }
 
 private:
-    pthread_key_t key;
+    const pthread_key_t key;
 
-    pthread_key_t mkkey() {
+    inline const pthread_key_t mkkey() noexcept {
         pthread_key_t k;
-        int rc = pthread_key_create(&k, NULL);
+        const int rc = pthread_key_create(&k, NULL);
         assertOrFail(rc == 0);
         return k;
     }
@@ -278,7 +279,7 @@
 /**
  * Push a pool onto the stack.
  */
-inline apr_pool_t* const gc_push_pool(apr_pool_t* pool) noexcept {
+inline apr_pool_t* const gc_push_pool(apr_pool_t* const pool) noexcept {
     apr_pool_t* const p = gc_pool_stack;
     gc_pool_stack = pool;
     return p;
@@ -287,7 +288,7 @@
 /**
  * Pop a pool from the stack.
  */
-inline apr_pool_t* const gc_pop_pool(apr_pool_t* pool) noexcept {
+inline apr_pool_t* const gc_pop_pool(apr_pool_t* const pool) noexcept {
     apr_pool_t* const p = gc_pool_stack;
     gc_pool_stack = pool;
     return p;
@@ -326,7 +327,7 @@
 private:
     const bool owner;
 
-    apr_pool_t* const mkpool() {
+    inline apr_pool_t* const mkpool() noexcept {
         apr_pool_t* p;
         apr_pool_create(&p, gc_current_pool());
         assertOrFail(p != NULL);
@@ -356,7 +357,7 @@
 private:
     const bool owner;
 
-    apr_pool_t* const mkpool() {
+    inline apr_pool_t* const mkpool() noexcept {
         apr_pool_t* p;
         apr_pool_create(&p, gc_current_pool());
         assertOrFail(p != NULL);
@@ -375,7 +376,7 @@
         gc_push_pool(apr_pool);
     }
 
-    inline gc_scoped_pool(apr_pool_t* p) noexcept : gc_pool(p), prev(gc_current_pool()), owner(false) {
+    inline gc_scoped_pool(apr_pool_t* const p) noexcept : gc_pool(p), prev(gc_current_pool()), owner(false) {
         gc_push_pool(apr_pool);
     }
 
@@ -394,7 +395,7 @@
     apr_pool_t* const prev;
     const bool owner;
 
-    apr_pool_t* const mkpool() {
+    inline apr_pool_t* const mkpool() noexcept {
         apr_pool_t* p;
         apr_pool_create(&p, gc_current_pool());
         assertOrFail(p != NULL);
diff --git a/kernel/kernel-test.cpp b/kernel/kernel-test.cpp
index 0e2a142..4c68975 100644
--- a/kernel/kernel-test.cpp
+++ b/kernel/kernel-test.cpp
@@ -557,11 +557,37 @@
     return true;
 }
 
+const bool testSubst() {
+    assert(subst(1, 9, mklist(1, 2, 1, 3, 1)) == mklist(9, 2, 9, 3, 9));
+    assert(subst<value>(1, 9, mklist<value>(1, 2, 1, 3, 1)) == mklist<value>(9, 2, 9, 3, 9));
+    return true;
+}
+
 const bool testAssoc() {
     const list<list<string> > l = mklist(mklist<string>("x", "X"), mklist<string>("a", "A"), mklist<string>("y", "Y"), mklist<string>("a", "AA"));
     assert(assoc<string>("a", l) == mklist<string>("a", "A"));
     assert(isNil(assoc<string>("z", l)));
 
+    const list<list<string> > l3 = mklist(mklist<string>("x", "X"), mklist<string>("a", "A"), mklist<string>("a", "AA"));
+    assert(delAssoc<string>("y", l) == l3);
+
+    const list<list<string> > l4 = mklist(mklist<string>("x", "X"), mklist<string>("y", "Y"));
+    assert(delAssoc<string>("a", l) == l4);
+
+    const list<list<string> > l5 = mklist(mklist<string>("x", "X"), mklist<string>("a", "A"), mklist<string>("y", "YY"), mklist<string>("a", "AA"));
+    assert(substAssoc<string>("y", mklist<string>("y", "YY"), l) == l5);
+
+    const list<list<string> > l6 = mklist(mklist<string>("x", "X"), mklist<string>("a", "AAA"), mklist<string>("y", "Y"), mklist<string>("a", "AAA"));
+    assert(substAssoc<string>("a", mklist<string>("a", "AAA"), l) == l6);
+
+    const list<list<string> > l7 = mklist(mklist<string>("x", "X"), mklist<string>("a", "A"), mklist<string>("y", "Y"), mklist<string>("a", "AA"), mklist<string>("z", "ZZ"));
+    assert(substAssoc<string>("z", mklist<string>("z", "ZZ"), l) == l);
+    assert(substAssoc<string>("z", mklist<string>("z", "ZZ"), l, true) == l7);
+
+    return true;
+}
+
+const bool testValueAssoc() {
     const list<list<value> > u = mklist(mklist<value>("x", "X"), mklist<value>("a", "A"), mklist<value>("y", "Y"), mklist<value>("a", "AA"));
     assert(assoc<value>("a", u) == mklist<value>("a", "A"));
 
@@ -570,6 +596,50 @@
 
     const list<value> v2 = mklist<value>(mklist<value>("x", "X"), "a", mklist<value>("a", "A"), mklist<value>("y", "Y"), mklist<value>("a", "AA"));
     assert(assoc<value>("a", v2) == mklist<value>("a", "A"));
+
+    const list<value> v3 = mklist<value>(mklist<value>("x", "X"), mklist<value>("a", "A"), mklist<value>("a", "AA"));
+    assert(delAssoc<value>("y", v) == v3);
+
+    const list<value> v4 = mklist<value>(mklist<value>("x", "X"), mklist<value>("y", "Y"));
+    assert(delAssoc<value>("a", v) == v4);
+
+    const list<value> v5 = mklist<value>(mklist<value>("x", "X"), mklist<value>("a", "A"), mklist<value>("y", "YY"), mklist<value>("a", "AA"));
+    assert(substAssoc<value>("y", mklist<value>("y", "YY"), v) == v5);
+
+    const list<value> v6 = mklist<value>(mklist<value>("x", "X"), mklist<value>("a", "AAA"), mklist<value>("y", "Y"), mklist<value>("a", "AAA"));
+    assert(substAssoc<value>("a", mklist<value>("a", "AAA"), v) == v6);
+
+    const list<value> v7 = mklist<value>(mklist<value>("x", "X"), mklist<value>("a", "A"), mklist<value>("y", "Y"), mklist<value>("a", "AA"), mklist<value>("z", "ZZ"));
+    assert(substAssoc<value>("z", mklist<value>("z", "ZZ"), v) == v);
+    assert(substAssoc<value>("z", mklist<value>("z", "ZZ"), v, true) == v7);
+    return true;
+}
+
+const bool testTreeAssoc() {
+    const list<value> tv = mklist<value>(mklist<value>("a", "A"), mklist<value>("b", mklist<value>("ba", "BA"), mklist<value>("bc", "BC"), mklist<value>("bd", mklist<value>("z", "ZZ"), mklist<value>("bda", "BDA"))), mklist<value>("z", "Z"));
+    assert(treeSelectAssoc<value>(mklist<value>("a"), tv) == mklist<value>(mklist<value>("a", "A")));
+    assert(treeSelectAssoc<value>(mklist<value>("b", "bc"), tv) == mklist<value>(mklist<value>("bc", "BC")));
+    assert(treeSelectAssoc<value>(mklist<value>("b", "bx"), tv) == list<value>());
+    assert(treeSelectAssoc<value>(mklist<value>("b", "bd", "bda"), tv) == mklist<value>(mklist<value>("bda", "BDA")));
+    assert(treeSelectAssoc<value>(mklist<value>("bc"), tv) == mklist<value>(mklist<value>("bc", "BC")));
+    assert(treeSelectAssoc<value>(mklist<value>("bda"), tv) == mklist<value>(mklist<value>("bda", "BDA")));
+    assert(treeSelectAssoc<value>(mklist<value>("bd", "bda"), tv) == mklist<value>(mklist<value>("bda", "BDA")));
+    assert(treeSelectAssoc<value>(mklist<value>("bd", "bda", "bdax"), tv) == list<value>());
+    assert(treeSelectAssoc<value>(mklist<value>("z"), tv) == mklist<value>(mklist<value>("z", "ZZ"), mklist<value>("z", "Z")));
+
+    const list<value> tv2 = mklist<value>(mklist<value>("a", "A"), mklist<value>("b", mklist<value>("ba", "BA"), mklist<value>("bc", "BC"), mklist<value>("bd", mklist<value>("bda", "BDA"))));
+    const list<value> tv3 = mklist<value>(mklist<value>("a", "A"), mklist<value>("b", mklist<value>("ba", "BA"), mklist<value>("bc", "BC"), mklist<value>("bd", mklist<value>("z", "ZZ"))), mklist<value>("z", "Z"));
+    assert(treeDelAssoc<value>(mklist<value>("z"), tv) == tv2);
+    assert(treeDelAssoc<value>(mklist<value>("bda"), tv) == tv3);
+    assert(treeDelAssoc<value>(mklist<value>("bd", "bda"), tv) == tv3);
+    assert(treeDelAssoc<value>(mklist<value>("bd", "bda", "bdax"), tv) == tv);
+
+    const list<value> tv4 = mklist<value>(mklist<value>("a", "A"), mklist<value>("b", mklist<value>("ba", "BA"), mklist<value>("bc", "BC"), mklist<value>("bd", mklist<value>("z", "ZZZ"), mklist<value>("bda", "BDA"))), mklist<value>("z", "ZZZ"));
+    const list<value> tv5 = mklist<value>(mklist<value>("a", "A"), mklist<value>("b", mklist<value>("ba", "BA"), mklist<value>("bc", "BC"), mklist<value>("bd", mklist<value>("z", "ZZ"), mklist<value>("bda", "BDAX"))), mklist<value>("z", "Z"));
+    assert(treeSubstAssoc<value>(mklist<value>("z"), mklist<value>("z", "ZZZ"), tv) == tv4);
+    assert(treeSubstAssoc<value>(mklist<value>("bda"), mklist<value>("bda", "BDAX"), tv) == tv5);
+    assert(treeSubstAssoc<value>(mklist<value>("bd", "bda"), mklist<value>("bda", "BDAX"), tv) == tv5);
+    assert(treeSubstAssoc<value>(mklist<value>("bd", "bda", "bdax"), mklist<value>("bda", "BDAX"), tv) == tv);
     return true;
 }
 
@@ -638,7 +708,7 @@
     assert(value(mklist<value>(1, 2)) == value(mklist<value>(1, 2)));
 
     const list<value> v = mklist<value>(mklist<value>("x", "X"), mklist<value>("a", "A"), mklist<value>("y", "Y"));
-    assert(cadr((list<list<value> >)value(v)) == mklist<value>("a", "A"));
+    assert(cadr<value>(value(v)) == mklist<value>("a", "A"));
 
     const value pv(gc_ptr<value>(new (gc_new<value>()) value(1)));
     assert(*(gc_ptr<value>)pv == value(1));
@@ -662,16 +732,16 @@
     return true;
 }
 
-const bool testTree() {
-    const list<value> t = mktree<value>("a", nilListValue, nilListValue);
-    const list<value> ct = constree<value>("d", constree<value>("f", constree<value>("c", constree<value>("e", constree<value>("b", t)))));
-    const list<value> mt = mktree(mklist<value>("d", "f", "c", "e", "b", "a"));
+const bool testBinaryTree() {
+    const list<value> t = mkrbtree<value>("a", nilListValue, nilListValue);
+    const list<value> ct = rbtreeCons<value>("d", rbtreeCons<value>("f", rbtreeCons<value>("c", rbtreeCons<value>("e", rbtreeCons<value>("b", t)))));
+    const list<value> mt = mkrbtree(mklist<value>("d", "f", "c", "e", "b", "a"));
     assert(mt == ct);
     const list<value> l = flatten<value>(mt);
     assert(length(l) == 6);
     assert(car(l) == "a");
     assert(car(reverse(l)) == "f");
-    const list<value> bt = mkbtree<value>(l);
+    const list<value> bt = mkbrbtree<value>(l);
     assert(car(bt) == "c");
     return true;
 }
@@ -680,19 +750,19 @@
     return mklist<value>(c_str(x), c_str(x + x));
 }
 
-const bool testTreeAssoc() {
-    const list<value> t = mktree<value>(lta("a"), nilListValue, nilListValue);
-    const list<value> at = constree<value>(lta("d"), constree<value>(lta("f"), constree<value>(lta("c"), constree<value>(lta("e"), constree<value>(lta("b"), t)))));
+const bool testBinaryTreeAssoc() {
+    const list<value> t = mkrbtree<value>(lta("a"), nilListValue, nilListValue);
+    const list<value> at = rbtreeCons<value>(lta("d"), rbtreeCons<value>(lta("f"), rbtreeCons<value>(lta("c"), rbtreeCons<value>(lta("e"), rbtreeCons<value>(lta("b"), t)))));
     const list<value> l = flatten<value>(at);
     assert(length(l) == 6);
     assert(car(l) == mklist<value>("a", "aa"));
     assert(car(reverse(l)) == mklist<value>("f", "ff"));
-    const list<value> bt = mkbtree<value>(l);
+    const list<value> bt = mkbrbtree<value>(l);
     assert(car(bt) == mklist<value>("c", "cc"));
-    assert(assoctree<value>("a", bt) == mklist<value>("a", "aa"));
-    assert(assoctree<value>("b", bt) == mklist<value>("b", "bb"));
-    assert(assoctree<value>("f", bt) == mklist<value>("f", "ff"));
-    assert(isNil(assoctree<value>("x", bt)));
+    assert(rbtreeAssoc<value>("a", bt) == mklist<value>("a", "aa"));
+    assert(rbtreeAssoc<value>("b", bt) == mklist<value>("b", "bb"));
+    assert(rbtreeAssoc<value>("f", bt) == mklist<value>("f", "ff"));
+    assert(isNil(rbtreeAssoc<value>("x", bt)));
     return true;
 }
 
@@ -893,14 +963,17 @@
     tuscany::testMember();
     tuscany::testReverse();
     tuscany::testListRef();
+    tuscany::testSubst();
     tuscany::testAssoc();
+    tuscany::testValueAssoc();
+    tuscany::testTreeAssoc();
     tuscany::testZip();
     tuscany::testTokenize();
     tuscany::testSeq();
     tuscany::testValue();
     tuscany::testValueGC();
-    tuscany::testTree();
-    tuscany::testTreeAssoc();
+    tuscany::testBinaryTree();
+    tuscany::testBinaryTreeAssoc();
     tuscany::testCppPerf();
     tuscany::testIdMonad();
     tuscany::testMaybeMonad();
diff --git a/kernel/list.hpp b/kernel/list.hpp
index 16a0649..02df2c2 100644
--- a/kernel/list.hpp
+++ b/kernel/list.hpp
@@ -43,16 +43,16 @@
 long countCLists = 0;
 long countELists = 0;
 
-inline const bool resetListCounters() {
+inline const bool resetListCounters() noexcept {
     countLists = countILists = countCLists = countELists = 0;
     return true;
 }
 
-inline const bool checkListCounters() {
+inline const bool checkListCounters() noexcept {
     return countLists == 0;
 }
 
-inline const bool printListCounters() {
+inline const bool printListCounters() noexcept {
     cout << "countLists " << countLists << endl;
     cout << "countELists " << countELists << endl;
     cout << "countILists " << countILists << endl;
@@ -91,19 +91,19 @@
 template<typename T> class list {
 public:
 
-    inline list() : car() {
+    inline list() noexcept : car() {
         debug_inc(countLists);
         debug_inc(countELists);
         debug_watchList();
     }
 
-    inline list(const T& car, const lambda<list<T>()>& cdr) : car(car), cdr(cdr) {
+    inline list(const T& car, const lambda<list<T>()>& cdr) noexcept : car(car), cdr(cdr) {
         debug_inc(countLists);
         debug_inc(countILists);
         debug_watchList();
     }
 
-    inline list(const list& p) : car(p.car), cdr(p.cdr) {
+    inline list(const list& p) noexcept : car(p.car), cdr(p.cdr) {
         debug_inc(countLists);
         debug_inc(countCLists);
 #ifdef WANT_MAINTAINER_WATCH
@@ -113,11 +113,11 @@
 
     list<T>& operator=(const list<T>& p) = delete;
 
-    inline ~list() {
+    inline ~list() noexcept {
         debug_dec(countLists);
     }
 
-    inline const bool operator==(const list<T>& p) const {
+    inline const bool operator==(const list<T>& p) const noexcept {
         if(this == &p)
             return true;
         if(isNil(cdr))
@@ -131,7 +131,7 @@
         return cdr() == p.cdr();
     }
 
-    inline const bool operator<(const list<T>& p) const {
+    inline const bool operator<(const list<T>& p) const noexcept {
         if(this == &p)
             return false;
         if (isNil(cdr))
@@ -145,7 +145,7 @@
         return cdr() < p.cdr();
     }
 
-    inline const bool operator>(const list<T>& p) const {
+    inline const bool operator>(const list<T>& p) const noexcept {
         if(this == &p)
             return false;
         if (isNil(cdr))
@@ -159,24 +159,23 @@
         return cdr() > p.cdr();
     }
 
-    inline const bool operator!=(const list<T>& p) const {
+    inline const bool operator!=(const list<T>& p) const noexcept {
         return !this->operator==(p);
     }
 
-    inline operator const list<list<T> >() const {
+    inline operator const list<list<T> >() const noexcept {
         return (list<list<T> >)T(*this);
     }
 
 private:
 #ifdef WANT_MAINTAINER_WATCH
-    template<typename X> friend const string watchList(const list<X>& p);
+    template<typename X> friend const string watchList(const list<X>& p) noexcept;
     string watch;
 #endif
 
-    template<typename X> friend const bool isNil(const list<X>& p);
-    template<typename X> friend const X car(const list<X>& p);
-    template<typename X> friend const list<X> cdr(const list<X>& p);
-    template<typename X> friend const bool setlist(list<X>& target, const list<X>& l);
+    template<typename X> friend const bool isNil(const list<X>& p) noexcept;
+    template<typename X> friend const X car(const list<X>& p) noexcept;
+    template<typename X> friend const list<X> cdr(const list<X>& p) noexcept;
 
     const T car;
     const lambda<list<T>()> cdr;
@@ -188,7 +187,7 @@
  * Debug utility used to write the contents of a list to a string, easier
  * to watch than the list itself in a debugger.
  */
-template<typename T> inline const string watchList(const list<T>& p) {
+template<typename T> inline const string watchList(const list<T>& p) noexcept {
     if(isNil(p))
         return "()";
     odebugstream os;
@@ -201,21 +200,21 @@
 /**
  * Returns true if the given list is nil.
  */
-template<typename T> inline const bool isNil(const list<T>& p) {
+template<typename T> inline const bool isNil(const list<T>& p) noexcept {
     return isNil(p.cdr);
 }
 
 /**
  * Write a list to an output stream.
  */
-template<typename T> inline ostream& writeHelper(ostream& out, const list<T>& l) {
+template<typename T> inline ostream& writeHelper(ostream& out, const list<T>& l) noexcept {
     if (isNil(l))
         return out;
     out << " " << car(l);
     return writeHelper(out, cdr(l));
 }
 
-template<typename T> inline ostream& operator<<(ostream& out, const list<T>& l) {
+template<typename T> inline ostream& operator<<(ostream& out, const list<T>& l) noexcept {
     if(isNil(l))
         return out << "()";
     out << "(" << car(l);
@@ -226,74 +225,74 @@
 /**
  * Construct a (lazy) list from a value and a lambda function that returns the cdr.
  */
-template<typename T> inline const list<T> cons(const T& car, const lambda<const list<T>()>& cdr) {
+template<typename T> inline const list<T> cons(const T& car, const lambda<const list<T>()>& cdr) noexcept {
     return list<T> (car, cdr);
 }
 
 /**
  * Construct a list from a value and a cdr list.
  */
-template<typename T> inline const list<T> cons(const T& car, const list<T>& cdr) {
+template<typename T> inline const list<T> cons(const T& car, const list<T>& cdr) noexcept {
     return list<T> (car, result(cdr));
 }
 
 /**
  * Cons variations for use with the reduce and reduceRight functions.
  */
-template<typename T> inline const list<T> lcons(const list<T>& cdr, const T& car) {
+template<typename T> inline const list<T> lcons(const list<T>& cdr, const T& car) noexcept {
     return cons<T>(car, cdr);
 }
 
-template<typename T> inline const list<T> rcons(const T& car, const list<T>& cdr) {
+template<typename T> inline const list<T> rcons(const T& car, const list<T>& cdr) noexcept {
     return cons<T>(car, cdr);
 }
 
 /**
  * Construct a list of one value.
  */
-template<typename T> inline const list<T> mklist(const T& car) {
+template<typename T> inline const list<T> mklist(const T& car) noexcept {
     return list<T> (car, result(list<T> ()));
 }
 
 /**
  * Construct a list of two values.
  */
-template<typename T> inline const list<T> mklist(const T& a, const T& b) {
+template<typename T> inline const list<T> mklist(const T& a, const T& b) noexcept {
     return cons(a, mklist(b));
 }
 
 /**
  * Construct a list of three values.
  */
-template<typename T> inline const list<T> mklist(const T& a, const T& b, const T& c) {
+template<typename T> inline const list<T> mklist(const T& a, const T& b, const T& c) noexcept {
     return cons(a, cons(b, mklist(c)));
 }
 
 /**
  * Construct a list of four values.
  */
-template<typename T> inline const list<T> mklist(const T& a, const T& b, const T& c, const T& d) {
+template<typename T> inline const list<T> mklist(const T& a, const T& b, const T& c, const T& d) noexcept {
     return cons(a, cons(b, cons(c, mklist(d))));
 }
 
 /**
  * Construct a list of five values.
  */
-template<typename T> inline const list<T> mklist(const T& a, const T& b, const T& c, const T& d, const T& e) {
+template<typename T> inline const list<T> mklist(const T& a, const T& b, const T& c, const T& d, const T& e) noexcept {
     return cons(a, cons(b, cons(c, cons(d, mklist(e)))));
 }
 
 /**
  * Construct a list of six values.
  */
-template<typename T> inline const list<T> mklist(const T& a, const T& b, const T& c, const T& d, const T& e, const T& f) {
+template<typename T> inline const list<T> mklist(const T& a, const T& b, const T& c, const T& d, const T& e, const T& f) noexcept {
     return cons(a, cons(b, cons(c, cons(d, cons(e, mklist(f))))));
 }
 
 /**
  * Returns the car of a list.
  */
-template<typename T> inline const T car(const list<T>& p) {
+template<typename T> inline const T car(const list<T>& p) noexcept {
     // Abort if trying to access the car of a nil list
     assertOrFail(!isNil(p.cdr));
     return p.car;
@@ -302,105 +301,105 @@
 /**
  * Returns the cdr of a list.
  */
-template<typename T> inline const list<T> cdr(const list<T>& p) {
+template<typename T> inline const list<T> cdr(const list<T>& p) noexcept {
     return p.cdr();
 }
 
 /**
  * Returns the car of the cdr (the 2nd element) of a list.
  */
-template<typename T> inline const T cadr(const list<T>& p) {
+template<typename T> inline const T cadr(const list<T>& p) noexcept {
     return car(cdr(p));
 }
 
 /**
  * Returns the 3rd element of a list.
  */
-template<typename T> inline const T caddr(const list<T>& p) {
+template<typename T> inline const T caddr(const list<T>& p) noexcept {
     return car(cdr(cdr(p)));
 }
 
 /**
  * Returns the 4th element of a list.
  */
-template<typename T> inline const T cadddr(const list<T>& p) {
+template<typename T> inline const T cadddr(const list<T>& p) noexcept {
     return car(cdr(cdr(cdr(p))));
 }
 
 /**
  * Returns the 5th element of a list.
  */
-template<typename T> inline const T caddddr(const list<T>& p) {
+template<typename T> inline const T caddddr(const list<T>& p) noexcept {
     return car(cdr(cdr(cdr(cdr(p)))));
 }
 
 /**
  * Returns the 6th element of a list.
  */
-template<typename T> inline const T cadddddr(const list<T>& p) {
+template<typename T> inline const T cadddddr(const list<T>& p) noexcept {
     return car(cdr(cdr(cdr(cdr(cdr(p))))));
 }
 
 /**
  * Returns the 7th element of a list.
  */
-template<typename T> inline const T caddddddr(const list<T>& p) {
+template<typename T> inline const T caddddddr(const list<T>& p) noexcept {
     return car(cdr(cdr(cdr(cdr(cdr(cdr(p)))))));
 }
 
 /**
  * Returns the 8th element of a list.
  */
-template<typename T> inline const T cadddddddr(const list<T>& p) {
+template<typename T> inline const T cadddddddr(const list<T>& p) noexcept {
     return car(cdr(cdr(cdr(cdr(cdr(cdr(cdr(p))))))));
 }
 
 /**
  * Returns a list of elements from the 3rd to the end of a list.
  */
-template<typename T> inline const list<T> cddr(const list<T>& p) {
+template<typename T> inline const list<T> cddr(const list<T>& p) noexcept {
     return cdr(cdr(p));
 }
 
 /**
  * Returns a list of elements from the 4th to the end of a list.
  */
-template<typename T> inline const list<T> cdddr(const list<T>& p) {
+template<typename T> inline const list<T> cdddr(const list<T>& p) noexcept {
     return cdr(cdr(cdr(p)));
 }
 
 /**
  * Returns a list of elements from the 5th to the end of a list.
  */
-template<typename T> inline const list<T> cddddr(const list<T>& p) {
+template<typename T> inline const list<T> cddddr(const list<T>& p) noexcept {
     return cdr(cdr(cdr(cdr(p))));
 }
 
 /**
  * Returns a list of elements from the 6th to the end of a list.
  */
-template<typename T> inline const list<T> cdddddr(const list<T>& p) {
+template<typename T> inline const list<T> cdddddr(const list<T>& p) noexcept {
     return cdr(cdr(cdr(cdr(cdr(p)))));
 }
 
 /**
  * Returns a list of elements from the 7th to the end of a list.
  */
-template<typename T> inline const list<T> cddddddr(const list<T>& p) {
+template<typename T> inline const list<T> cddddddr(const list<T>& p) noexcept {
     return cdr(cdr(cdr(cdr(cdr(cdr(p))))));
 }
 
 /**
  * Returns a list of elements from the 8th to the end of a list.
  */
-template<typename T> inline const list<T> cdddddddr(const list<T>& p) {
+template<typename T> inline const list<T> cdddddddr(const list<T>& p) noexcept {
     return cdr(cdr(cdr(cdr(cdr(cdr(cdr(p)))))));
 }
 
 /**
  * Returns the length of a list.
  */
-template<typename T> inline const size_t length(const list<T>& p) {
+template<typename T> inline const size_t length(const list<T>& p) noexcept {
     const lambda<size_t(const size_t, const list<T>&)> lengthRef = [&lengthRef](const size_t c, const list<T>& p) -> const size_t {
         if(isNil(p))
             return c;
@@ -412,7 +411,7 @@
 /**
  * Appends a list and a lambda function returning a list.
  */
-template<typename T> inline const list<T> append(const list<T>&a, const lambda<const list<T>()>& fb) {
+template<typename T> inline const list<T> append(const list<T>&a, const lambda<const list<T>()>& fb) noexcept {
     if(isNil(a))
         return fb();
     return cons<T>(car(a), [a, fb]() { return append(cdr(a), fb); });
@@ -421,25 +420,25 @@
 /**
  * Appends two lists.
  */
-template<typename T> inline const list<T> append(const list<T>&a, const list<T>& b) {
+template<typename T> inline const list<T> append(const list<T>&a, const list<T>& b) noexcept {
     return append(a, result(b));
 }
 
 /**
  * Append a value to a list.
  */
-template<typename T> inline const list<T> operator+(const list<T>& l, const T& v) {
+template<typename T> inline const list<T> operator+(const list<T>& l, const T& v) noexcept {
     return append(l, mklist(v));
 }
 
-template<typename T, typename V> const list<T> inline operator+(const list<T>& l, const V& v) {
+template<typename T, typename V> const list<T> inline operator+(const list<T>& l, const V& v) noexcept {
     return append(l, mklist<T>(v));
 }
 
 /**
- * Map a lambda function on a list.
+ * Run a map lambda function on a list.
  */
-template<typename T, typename R> inline const list<R> map(const lambda<const R(const T)>& f, const list<T>& p) {
+template<typename T, typename R> inline const list<R> map(const lambda<const R(const T)>& f, const list<T>& p) noexcept {
     if(isNil(p))
         return list<R> ();
     return cons(f(car(p)), map(f, cdr(p)));
@@ -448,7 +447,7 @@
 /**
  * Run a reduce lambda function on a list.
  */
-template<typename T, typename R> inline const R reduce(const lambda<const R(const R, const T)>& f, const R& initial, const list<T>& p) {
+template<typename T, typename R> inline const R reduce(const lambda<const R(const R, const T)>& f, const R& initial, const list<T>& p) noexcept {
     const lambda<const R(const R&, const list<T>&p)> reduceAccumulate = [f, &reduceAccumulate](const R& acc, const list<T>& p) -> R {
         if(isNil(p))
             return acc;
@@ -457,7 +456,7 @@
     return reduceAccumulate(initial, p);
 }
 
-template<typename T, typename R> inline const R reduceRight(const lambda<const R(const T, const R)>& f, const R& initial, const list<T>& p) {
+template<typename T, typename R> inline const R reduceRight(const lambda<const R(const T, const R)>& f, const R& initial, const list<T>& p) noexcept {
     const lambda<const R(const list<T>&p, const R&)> reduceRightAccumulate = [f, &reduceRightAccumulate](const list<T>& p, const R& acc) -> R {
         if(isNil(p))
             return acc;
@@ -469,7 +468,7 @@
 /**
  * Run a filter lambda function on a list.
  */
-template<typename T> inline const list<T> filter(const lambda<const bool(const T)>& f, const list<T>& p) {
+template<typename T> inline const list<T> filter(const lambda<const bool(const T)>& f, const list<T>& p) noexcept {
     if(isNil(p))
         return list<T> ();
     if(f(car(p))) {
@@ -482,7 +481,7 @@
 /**
  * Returns a list pointing to a member of a list.
  */
-template<typename T> inline const list<T> member(const T& t, const list<T>& p) {
+template<typename T> inline const list<T> member(const T& t, const list<T>& p) noexcept {
     if(isNil(p))
         return list<T> ();
     if(t == car(p))
@@ -493,20 +492,20 @@
 /**
  * Reverse a list.
  */
-template<typename T> inline const list<T> reverseIter(const list<T>& acc, const list<T>& p) {
+template<typename T> inline const list<T> reverseIter(const list<T>& acc, const list<T>& p) noexcept {
     if(isNil(p))
         return acc;
     return reverseIter(cons(car(p), acc), cdr(p));
 }
 
-template<typename T> inline const list<T> reverse(const list<T>& p) {
+template<typename T> inline const list<T> reverse(const list<T>& p) noexcept {
     return reverseIter(list<T> (), p);
 }
 
 /**
  * Returns a sequence of values between the given bounds.
  */
-template<typename T> inline const list<T> seq(const T& start, const T& end) {
+template<typename T> inline const list<T> seq(const T& start, const T& end) noexcept {
     if(start == end)
         return mklist(start);
     if(start < end)
@@ -517,27 +516,62 @@
 /**
  * Returns the i-th element of a list.
  */
-template<typename T> inline const T listRef(const list<T>& l, const size_t i) {
-    if (i == 0)
+template<typename T> inline const T listRef(const list<T>& l, const size_t i) noexcept {
+    if(i == 0)
         return car(l);
     return listRef(cdr(l), i - 1);
 }
 
 /**
+ * Returns the tail of a list, ommiting the first k elements.
+ */
+template<typename T> inline const list<T> listTail(const list<T>& l, const size_t k) noexcept {
+    if(k == 0)
+        return l;
+    if(isNil(l))
+        return l;
+    return listTail(cdr(l), k - 1);
+}
+
+/**
+ * Substitute elements in a list.
+ */
+template<typename T> inline const list<T> subst(const T& o, const T& n, const list<T>& p) noexcept {
+    if(isNil(p))
+        return p;
+    if(o == car(p))
+        return cons<T>(n, subst(o, n, cdr(p)));
+    return cons<T>(car(p), subst(o, n, cdr(p)));
+}
+
+/**
  * Returns the first pair matching a key from a list of key value pairs.
  */
-template<typename T> inline const list<T> assoc(const T& k, const list<list<T> >& p) {
+template<typename T> inline const list<T> assoc(const T& k, const list<list<T> >& p) noexcept {
     if(isNil(p))
-        return list<T> ();
+        return list<T>();
     if(k == car(car(p)))
         return car(p);
     return assoc(k, cdr(p));
 }
 
 /**
+ * Returns the first pair matching a key from a list of key value pairs.
+ * Requires T to support isList and cast to list<T>.
+ */
+template<typename T> inline const list<T> assoc(const T& k, const list<T>& p) noexcept {
+    if(isNil(p))
+        return list<T>();
+    const T c = car(p);
+    if(isList(c) && k == car<T>(c))
+        return c;
+    return assoc(k, cdr(p));
+}
+
+/**
  * Returns a list of lists containing elements from two input lists.
  */
-template<typename T> inline const list<list<T> > zip(const list<T>& a, const list<T>& b) {
+template<typename T> inline const list<list<T> > zip(const list<T>& a, const list<T>& b) noexcept {
     if (isNil(a) || isNil(b))
         return list<list<T> >();
     return cons<list<T> >(mklist<T>(car(a), car(b)), zip(cdr(a), cdr(b)));
@@ -546,22 +580,70 @@
 /**
  * Converts a list of key value pairs to a list containing the list of keys and the list of values.
  */
-template<typename T> inline const list<T> unzipKeys(const list<list<T> >& l) {
+template<typename T> inline const list<T> unzipKeys(const list<list<T> >& l) noexcept {
     if (isNil(l))
         return list<T>();
     return cons(car(car(l)), unzipKeys(cdr(l)));
 }
 
-template<typename T> inline const list<T> unzipValues(const list<list<T> >& l) {
+template<typename T> inline const list<T> unzipValues(const list<list<T> >& l) noexcept {
     if (isNil(l))
         return list<T>();
     return cons(cadr(car(l)), unzipValues(cdr(l)));
 }
 
-template<typename T> inline const list<list<T> > unzip(const list<list<T> >& l) {
+template<typename T> inline const list<list<T> > unzip(const list<list<T> >& l) noexcept {
     return mklist<list<T> >(unzipKeys(l), unzipValues(l));
 }
 
+/**
+ * Delete assocs matching a key from a list of assocs.
+ */
+template<typename T> inline const list<list<T> > delAssoc(const T& k, const list<list<T> >& p) noexcept {
+    if(isNil(p))
+        return p;
+    if(k == car(car(p)))
+        return delAssoc(k, cdr(p));
+    return cons<list<T> >(car(p), delAssoc(k, cdr(p)));
+}
+
+/**
+ * Delete assocs matching a key from a list of assocs.
+ * Requires T to support isList, isAssoc, and cast to list<T>.
+ */
+template<typename T> inline const list<T> delAssoc(const T& k, const list<T>& p) noexcept {
+    if(isNil(p))
+        return p;
+    const T c = car(p);
+    if(isList(c) && k == car<T>(c))
+        return delAssoc(k, cdr(p));
+    return cons<T>(c, delAssoc(k, cdr(p)));
+}
+
+/**
+ * Substitute assocs with matching keys in a list of assocs.
+ */
+template<typename T> inline const list<list<T> > substAssoc(const T& k, const list<T>& n, const list<list<T> >& p, const bool add = false) noexcept {
+    if(isNil(p))
+        return add? mklist<list<T> >(n) : p;
+    if(k == car(car(p)))
+        return cons<list<T> >(n, substAssoc(k, n, cdr(p), false));
+    return cons<list<T> >(car(p), substAssoc(k, n, cdr(p), add));
+}
+
+/**
+ * Substitute assocs with matching keys in a list of assocs.
+ * Requires T to support isList, isAssoc, and cast to list<T>.
+ */
+template<typename T> inline const list<T> substAssoc(const T& k, const list<T>& n, const list<T>& p, const bool add = false) noexcept {
+    if(isNil(p))
+        return add? mklist<T>(n) : p;
+    const T c = car(p);
+    if(isList(c) && k == car<T>(c))
+        return cons<T>(n, substAssoc(k, n, cdr(p), false));
+    return cons<T>(c, substAssoc(k, n, cdr(p), add));
+}
+
 }
 
 #endif /* tuscany_list_hpp */
diff --git a/kernel/stream.hpp b/kernel/stream.hpp
index e59e6a4..a4f4d3c 100644
--- a/kernel/stream.hpp
+++ b/kernel/stream.hpp
@@ -83,7 +83,7 @@
 }
 
 inline ostream& operator<<(ostream& os, const double v) {
-    return os.vprintf("%.10g", v);
+    return os.vprintf("%.16g", v);
 }
 
 inline ostream& operator<<(ostream& os, const void* const v) {
diff --git a/kernel/tree.hpp b/kernel/tree.hpp
index 44af09f..d350879 100644
--- a/kernel/tree.hpp
+++ b/kernel/tree.hpp
@@ -31,54 +31,172 @@
 #include "function.hpp"
 #include "list.hpp"
 #include "monad.hpp"
-#include "value.hpp"
 
 namespace tuscany {
 
 /**
- * Make a tree from a leaf and two branches.
+ * Delete assocs matching a path of keys in a tree of assocs.
+ * The path can be a complete or partial path to an assoc.
+ * Requires T to support isList, isAssoc, and cast to list<T>.
  */
-template<typename T> inline const list<T> mktree(const T& e, const list<T>& left, const list<T>& right) {
+template<typename T> inline const list<T> treeDelAssoc(const list<T>& k, const list<T>& l) noexcept {
+    if (isNil(k) || isNil(l))
+        return l;
+    const list<T> lv = l;
+
+    // If list is an assoc and matches, skip it
+    if (isAssoc(lv)) {
+        if (car<T>(lv) == car(k) && isNil(cdr(k)))
+            return list<T>();
+    }
+
+    // If list element is not an assoc, lookup children and rest of the list
+    const T a = car(lv);
+    if (!isAssoc(a)) {
+        if (!isList(a))
+            return cons<T>(a, treeDelAssoc<T>(k, cdr(lv)));
+        const list<T> da = treeDelAssoc<T>(k, a);
+        return isNil(da)? treeDelAssoc<T>(k, cdr(lv)) : cons<T>(da, treeDelAssoc<T>(k, cdr(lv)));
+    }
+
+    // If we found a match, skip it and lookup children and rest of the list
+    if (car<T>(a) == car(k)) {
+        if (isNil(cdr(k)))
+            return treeDelAssoc<T>(k, cdr(lv));
+        return cons<T>(cons<T>(car<T>(a), treeDelAssoc<T>(cdr(k), cdr<T>(a))), treeDelAssoc<T>(k, cdr(lv)));
+    }
+
+    // No match, lookup children and rest of the list
+    if (isNil(cdr<T>(a)))
+        return cons<T>(a, treeDelAssoc<T>(k, cdr(lv)));
+    if (!isList(cadr<T>(a)))
+        return cons<T>(cons<T>(car<T>(a), cons<T>(cadr<T>(a), treeDelAssoc<T>(k, cddr<T>(a)))), treeDelAssoc<T>(k, cdr(lv)));
+    const list<T> da = treeDelAssoc<T>(k, cadr<T>(a));
+    if (isNil(da))
+        return cons<T>(cons<T>(car<T>(a), treeDelAssoc<T>(k, cddr<T>(a))), treeDelAssoc<T>(k, cdr(lv)));
+    return cons<T>(cons<T>(car<T>(a), cons<T>(da, treeDelAssoc<T>(k, cddr<T>(a)))), treeDelAssoc<T>(k, cdr(lv)));
+}
+
+/**
+ * Substitute assocs matching a path of keys in a tree of assocs.
+ * The path can be a complete or partial path to an assoc.
+ * Requires T to support isList, isAssoc, and cast to list<T>.
+ */
+template<typename T> inline const list<T> treeSubstAssoc(const list<T>& k, const list<T>& n, const list<T>& lv) noexcept {
+    if (isNil(k) || isNil(lv))
+        return lv;
+
+    // If list is an assoc and matches, substitute it
+    if (isAssoc(lv)) {
+        if (car<T>(lv) == car(k) && isNil(cdr(k)))
+            return n;
+    }
+
+    // If list element is not an assoc, lookup children and rest of the list
+    const T a = car(lv);
+    if (!isAssoc(a)) {
+        if (!isList(a))
+            return cons<T>(a, treeSubstAssoc<T>(k, n, cdr(lv)));
+        return cons<T>(treeSubstAssoc<T>(k, n, a), treeSubstAssoc<T>(k, n, cdr(lv)));
+    }
+
+    // If we found a match, substitute it and lookup children and rest of the list
+    if (car<T>(a) == car(k)) {
+        if (isNil(cdr(k)))
+            return cons<T>(n, treeSubstAssoc<T>(k, n, cdr(lv)));
+        return cons<T>(cons<T>(car<T>(a), treeSubstAssoc<T>(cdr(k), n, cdr<T>(a))), treeSubstAssoc<T>(k, n, cdr(lv)));
+    }
+
+    // No match, lookup children and rest of the list
+    if (isNil(cdr<T>(a)))
+        return cons<T>(a, treeSubstAssoc<T>(k, n, cdr(lv)));
+    if (!isList(cadr<T>(a)))
+        return cons<T>(cons<T>(car<T>(a), cons<T>(cadr<T>(a), treeSubstAssoc<T>(k, n, cddr<T>(a)))), treeSubstAssoc<T>(k, n, cdr(lv)));
+    return cons<T>(cons<T>(car<T>(a), cons<T>(treeSubstAssoc<T>(k, n, cadr<T>(a)), treeSubstAssoc<T>(k, n, cddr<T>(a)))), treeSubstAssoc<T>(k, n, cdr(lv)));
+}
+
+/**
+ * Select assocs matching a path of keys in a tree of assocs.
+ * The path can be a complete or partial path to an assoc.
+ * Requires T to support isList, isAssoc, and cast to list<T>.
+ */
+template<typename T> inline const list<T> treeSelectAssoc(const list<T>& k, const list<T>& lv) noexcept {
+    if (isNil(k) || isNil(lv))
+        return list<T>();
+
+    // If list is an assoc and matches, select it
+    if (isAssoc(lv)) {
+        if (car<T>(lv) == car(k) && isNil(cdr(k)))
+            return mklist<T>(lv);
+    }
+
+    // If list element is not an assoc, lookup children and rest of the list
+    const T a = car(lv);
+    if (!isAssoc(a)) {
+        if (!isList(a))
+            return treeSelectAssoc<T>(k, cdr(lv));
+        return append<T>(treeSelectAssoc<T>(k, a), treeSelectAssoc<T>(k, cdr(lv)));
+    }
+
+    // If we found a match, select it and lookup children and rest of the list
+    if (car<T>(a) == car(k)) {
+        if (isNil(cdr(k)))
+            return cons<T>(a, treeSelectAssoc<T>(k, cdr(lv)));
+        return append<T>(treeSelectAssoc<T>(cdr(k), cdr<T>(a)), treeSelectAssoc<T>(k, cdr(lv)));
+    }
+
+    // No match, lookup children and rest of the list
+    if (isNil(cdr<T>(a)))
+        return treeSelectAssoc<T>(k, cdr(lv));
+    if (!isList(cadr<T>(a)))
+        return append<T>(treeSelectAssoc<T>(k, cddr<T>(a)), treeSelectAssoc<T>(k, cdr(lv)));
+    return append<T>(append<T>(treeSelectAssoc<T>(k, cadr<T>(a)), treeSelectAssoc<T>(k, cddr<T>(a))), treeSelectAssoc<T>(k, cdr(lv)));
+}
+
+/**
+ * Make a rooted binary tree from a leaf and two branches.
+ */
+template<typename T> inline const list<T> mkrbtree(const T& e, const list<T>& left, const list<T>& right) {
     return mklist<T>(e, left, right);
 }
 
 /**
- * Find a leaf with the given key in a tree.
+ * Find a leaf with the given key in a rooted binary tree.
  */
-template<typename T> inline const list<T> assoctree(const T& k, const list<T>& tree) {
+template<typename T> inline const list<T> rbtreeAssoc(const T& k, const list<T>& tree) {
     if (isNil(tree))
         return tree;
     if (k == car<T>(car(tree)))
         return car(tree);
     if (k < car<T>(car(tree)))
-        return assoctree<T>(k, cadr(tree));
-    return assoctree<T>(k, caddr(tree));
+        return rbtreeAssoc<T>(k, cadr(tree));
+    return rbtreeAssoc<T>(k, caddr(tree));
 }
 
 /**
- * Construct a new tree from a leaf and a tree.
+ * Construct a new rooted binary tree from a leaf and a tree.
  */
-template<typename T> inline const list<T> constree(const T& e, const list<T>& tree) {
+template<typename T> inline const list<T> rbtreeCons(const T& e, const list<T>& tree) {
     if (isNil(tree))
-        return mktree(e, list<T>(), list<T>());
+        return mkrbtree(e, list<T>(), list<T>());
     if (e == car(tree))
         return tree;
     if (e < car(tree))
-        return mktree<T>(car(tree), constree<T>(e, cadr(tree)), caddr(tree));
-    return mktree<T>(car(tree), cadr(tree), constree<T>(e, caddr(tree)));
+        return mkrbtree<T>(car(tree), rbtreeCons<T>(e, cadr(tree)), caddr(tree));
+    return mkrbtree<T>(car(tree), cadr(tree), rbtreeCons<T>(e, caddr(tree)));
 }
 
 /**
- * Make a tree from an unordered list of leaves.
+ * Make a rooted binary tree from an unordered list of leaves.
  */
-template<typename T> inline const list<T> mktree(const list<T>& l) {
+template<typename T> inline const list<T> mkrbtree(const list<T>& l) {
     if (isNil(l))
         return l;
-    return constree(car(l), mktree(cdr(l)));
+    return rbtreeCons(car(l), mkrbtree(cdr(l)));
 }
 
 /**
- * Convert a tree to an ordered list of leaves.
+ * Convert a rooted binary tree to an ordered list of leaves.
  */
 template<typename T> inline const list<T> flatten(const list<T>& tree) {
     if (isNil(tree))
@@ -87,28 +205,28 @@
 }
 
 /**
- * Sort a list.
+ * Sort a list, using a rooted binary tree.
  */
 template<typename T> inline const list<T> sort(const list<T>& l) {
-    return flatten(mktree(l));
+    return flatten(mkrbtree(l));
 }
 
 /**
- * Make a balanced tree from an ordered list of leaves.
+ * Make a balanced rooted binary tree from an ordered list of leaves.
  */
-template<typename T> inline const list<T> btreeHelper(const list<T>& elements, const size_t n) {
+template<typename T> inline const list<T> brbtreeHelper(const list<T>& elements, const size_t n) {
     if (n == 0)
         return cons<T>(list<T>(), elements);
     const size_t leftSize = (n - 1) / 2; {
-        const list<T> leftResult = btreeHelper<T>(elements, leftSize); {
+        const list<T> leftResult = brbtreeHelper<T>(elements, leftSize); {
             const list<T> leftTree = car(leftResult);
             const list<T> nonLeftElements = cdr(leftResult);
             const size_t rightSize = n - (leftSize + 1); {
                 const T thisEntry = car(nonLeftElements);
-                const list<T> rightResult = btreeHelper<T>(cdr(nonLeftElements), rightSize); {
+                const list<T> rightResult = brbtreeHelper<T>(cdr(nonLeftElements), rightSize); {
                     const list<T> rightTree = car(rightResult);
                     const list<T> remainingElements = cdr(rightResult); {
-                        return cons<T>(mktree<T>(thisEntry, leftTree, rightTree), remainingElements);
+                        return cons<T>(mkrbtree<T>(thisEntry, leftTree, rightTree), remainingElements);
                     }
                 }
             }
@@ -116,8 +234,8 @@
     }
 }
 
-template<typename T> inline const list<T> mkbtree(const list<T>& elements) {
-    return car(btreeHelper<T>(elements, length(elements)));
+template<typename T> inline const list<T> mkbrbtree(const list<T>& elements) {
+    return car(brbtreeHelper<T>(elements, length(elements)));
 }
 
 }
diff --git a/kernel/value.hpp b/kernel/value.hpp
index 60fb290..d5ce340 100644
--- a/kernel/value.hpp
+++ b/kernel/value.hpp
@@ -27,6 +27,7 @@
  */
 
 #include <stdlib.h>
+#include <math.h>
 #include <apr_uuid.h>
 #include <apr_time.h>
 
@@ -184,12 +185,6 @@
         debug_watchValue();
     }
 
-    inline value(const list<list<value> >& l) noexcept : type(value::List), lst(new (gc_new<list<value> >()) list<value>(listOfValues(l))) {
-        debug_inc(countValues);
-        debug_inc(countVValues);
-        debug_watchValue();
-    }
-
     inline value(const double d) noexcept : type(value::Number), num(d) {
         debug_inc(countValues);
         debug_inc(countVValues);
@@ -249,7 +244,8 @@
         case value::String:
             return (v.type == value::Symbol || v.type == value::String) && str == v.str;
         case value::Number:
-            return v.type == value::Number && num == v.num;
+            // Handle double floating point rounding
+            return v.type == value::Number && fabs(num - v.num) < 5e-16;
         case value::Bool:
             return v.type == value::Bool && boo == v.boo;
         case value::Ptr:
@@ -363,33 +359,23 @@
     }
 
     inline operator const list<value>() const noexcept {
+        switch(type) {
+        case value::List:
+            return *lst;
+        default:
+            return nilListValue;
+        }
         return *lst;
     }
 
-    inline operator const list<list<value> >() const noexcept {
-        return listOfListOfValues(*lst);
-    }
-
     inline operator const lvvlambda() const noexcept {
         return func;
     }
 
 private:
-    inline const list<value> listOfValues(const list<list<value> >& l) const noexcept {
-        if (isNil(l))
-            return nilListValue;
-        return cons<value>(car(l), listOfValues(cdr(l)));
-    }
-
-    inline const list<list<value> > listOfListOfValues(const list<value>& l) const noexcept {
-        if (isNil(l))
-            return list<list<value> >();
-        return cons<list<value> >(car(l).type == value::List? list<value>(car(l)) : nilPairValue, listOfListOfValues(cdr(l)));
-    }
-
     friend ostream& operator<<(ostream&, const value&) noexcept;
     friend const value::ValueType type(const value& v) noexcept;
-    friend const bool setvalue(value& target, const value& v);
+    friend const bool setvalue(value& target, const value& v) noexcept;
 
 #ifdef WANT_MAINTAINER_WATCH
     friend const string watchValue(const value& v);
@@ -566,6 +552,13 @@
 }
 
 /**
+ * Returns true if a value is an assoc.
+ */
+inline const bool isAssoc(const value& exp) noexcept {
+    return isList(exp) && !isNil((list<value>)exp) && isSymbol(car<value>(exp));
+}
+
+/**
  * Make a list of values from a list of other things.
  */
 template<typename T> inline const list<value> mkvalues(const list<T>& l) noexcept {
@@ -584,6 +577,24 @@
 }
 
 /**
+ * Convert a list of lists of values to a list of values.
+ */
+inline const list<value> listOfValues(const list<list<value> >& l) noexcept {
+    if (isNil(l))
+        return nilListValue;
+    return cons<value>(car(l), listOfValues(cdr(l)));
+}
+
+/**
+ * Convert a list of values to a list of lists of values.
+ */
+inline const list<list<value> > listOfListOfValues(const list<value>& l) noexcept {
+    if (isNil(l))
+        return list<list<value> >();
+    return cons<list<value> >(type(car(l)) == value::List? list<value>(car(l)) : nilPairValue, listOfListOfValues(cdr(l)));
+}
+
+/**
  * Convert a path string value to a list of values.
  */
 inline const list<string> pathTokens(const char* const p) noexcept {
@@ -638,7 +649,7 @@
 /**
  * Set a value. Use with moderation.
  */
-inline const bool setvalue(value& target, const value& v) {
+inline const bool setvalue(value& target, const value& v) noexcept {
     if (&target == &v)
         return true;
 #ifdef WANT_MAINTAINER_WATCH
diff --git a/modules/atom/atom.hpp b/modules/atom/atom.hpp
index 2f6e688..259769e 100644
--- a/modules/atom/atom.hpp
+++ b/modules/atom/atom.hpp
@@ -45,23 +45,24 @@
  * Convert a list of elements to a list of element values representing an ATOM entry.
  */
 const list<value> entryElementValues(const list<value>& e) {
-    const list<value> lt = filter<value>(selector(mklist<value>(element, "title")), e);
+    const list<value> lt = elementChildren("title", e);
     const list<value> t = nilListValue + element + value("title") + (isNil(lt)? value(emptyString) : elementValue(car(lt)));
 
-    const list<value> li = filter<value>(selector(mklist<value>(element, "id")), e);
+    const list<value> li = elementChildren("id", e);
     const list<value> i = nilListValue + element + value("id") + (isNil(li)? value(emptyString) : elementValue(car(li)));
 
-    const list<value> la = filter<value>(selector(mklist<value>(element, "author")), e);
-    const list<value> lan = isNil(la)? nilListValue : filter<value>(selector(mklist<value>(element, "name")), car(la));
-    const list<value> lae = isNil(la)? nilListValue : filter<value>(selector(mklist<value>(element, "email")), car(la));
+    const list<value> la = elementChildren("author", e);
+    const list<value> lan = isNil(la)? nilListValue : elementChildren("name", car(la));
+    const list<value> lae = isNil(la)? nilListValue : elementChildren("email", car(la));
     const list<value> laa = isNil(lan)? lae : lan;
     const list<value> a = isNil(laa)? nilListValue : mklist<value>(nilListValue + element + value("author") + elementValue(car(laa)));
 
-    const list<value> lu = filter<value>(selector(mklist<value>(element, "updated")), e);
+    const list<value> lu = elementChildren("updated", e);
     const list<value> u = isNil(lu)? nilListValue : mklist<value>(nilListValue + element + value("updated") + elementValue(car(lu)));
 
-    const list<value> lc = filter<value>(selector(mklist<value>(element, "content")), e);
-    const list<value> c = isNil(lc)? nilListValue : mklist<value>(nilListValue + element + value("content") + elementValue(car(lc)));
+    const list<value> lc = elementChildren("content", e);
+    const list<value> c = isNil(lc)? nilListValue : isAttribute(elementValue(car(lc)))? nilListValue :
+        mklist<value>(nilListValue + element + value("content") + elementValue(car(lc)));
 
     return append<value>(append<value>(append<value>(nilListValue + element + entry + value(t) + value(i), a), u), c);
 }
@@ -110,9 +111,9 @@
     const list<value> f = content(xml::readElements(ilist));
     if (isNil(f))
         return mkfailure<list<value> >("Empty feed");
-    const list<value> t = filter<value>(selector(mklist<value>(element, "title")), car(f));
-    const list<value> i = filter<value>(selector(mklist<value>(element, "id")), car(f));
-    const list<value> e = filter<value>(selector(mklist<value>(element, entry)), car(f));
+    const list<value> t = elementChildren("title", car(f));
+    const list<value> i = elementChildren("id", car(f));
+    const list<value> e = elementChildren(entry, car(f));
     return mklist<value>(append<value>(nilListValue + element + feed 
                 + value(nilListValue + element + value("title") + elementValue(car(t)))
                 + value(nilListValue + element + value("id") + elementValue(car(i))),
@@ -182,9 +183,9 @@
  */
 template<typename R> const failable<R> writeATOMFeed(const lambda<const R(const string&, const R)>& reduce, const R& initial, const list<value>& ll) {
     const list<value> l = isNil(ll)? ll : (list<value>)car(ll);
-    const list<value> lt = filter<value>(selector(mklist<value>(element, "title")), l);
+    const list<value> lt = elementChildren("title", l);
     const value t = isNil(lt)? value(emptyString) : elementValue(car(lt));
-    const list<value> li = filter<value>(selector(mklist<value>(element, "id")), l);
+    const list<value> li = elementChildren("id", l);
     const value i = isNil(li)? value(emptyString) : elementValue(car(li));
     const list<value> f = nilListValue
         + element + feed + (nilListValue + attribute + "xmlns" + "http://www.w3.org/2005/Atom")
@@ -192,7 +193,7 @@
         + (nilListValue + element + "id" + i);
 
     // Write ATOM entries
-    const list<value> le = filter<value>(selector(mklist<value>(element, entry)), l);
+    const list<value> le = elementChildren(entry, l);
     if (isNil(le))
         return xml::writeElements<R>(reduce, initial, mklist<value>(f));
 
diff --git a/modules/http/http.hpp b/modules/http/http.hpp
index 1153f61..cd0eb6c 100644
--- a/modules/http/http.hpp
+++ b/modules/http/http.hpp
@@ -87,7 +87,6 @@
             return;
         if (h.h == NULL)
             return;
-        debug(h.h, "http::~CURLSession::cleanup::h");
         curl_easy_cleanup(h.h);
     }
 
@@ -943,7 +942,7 @@
 /**
  * Converts a list of key value pairs to a query string.
  */
-ostringstream& queryString(const list<list<value> > args, ostringstream& os) {
+ostringstream& queryString(const list<value>& args, ostringstream& os) {
     if (isNil(args))
         return os;
     const list<value> arg = car(args);
@@ -956,7 +955,7 @@
     return queryString(cdr(args), os);
 }
 
-const string queryString(const list<list<value> > args) {
+const string queryString(const list<value>& args) {
     ostringstream os;
     return str(queryString(args, os));
 }
diff --git a/modules/http/httpd.hpp b/modules/http/httpd.hpp
index e090c2f..255f0aa 100644
--- a/modules/http/httpd.hpp
+++ b/modules/http/httpd.hpp
@@ -330,13 +330,13 @@
 /**
  * Unescape a list of key of value pairs representing query args.
  */
-const list<value> unescapeArg(const list<value> a) {
-    return mklist<value>(car(a), unescape(cadr(a)));
+const value unescapeArg(const value& a) {
+    return mklist<value>(car<value>(a), unescape(cadr<value>(a)));
 }
 
-const list<list<value> > unescapeArgs(const list<list<value> > args) {
+const list<value> unescapeArgs(const list<value>& args) {
     debug(args, "httpd::unescape::args");
-    const list<list<value> > uargs = map<list<value>, list<value>>(unescapeArg, args);
+    const list<value> uargs = map<value, value>(unescapeArg, args);
     debug(uargs, "httpd::unescape::result");
     return uargs;
 }
@@ -344,7 +344,7 @@
 /**
  * Returns a list of key value pairs from the args in a query string.
  */
-const list<value> queryArg(const string& s) {
+const value queryArg(const string& s) {
     debug(s, "httpd::queryArg::string");
     const list<string> t = tokenize("=", s);
     if (isNil(cdr(t)))
@@ -359,27 +359,27 @@
     return join("&", t);
 }
 
-const list<list<value> > queryArgs(const string& a) {
-    return map<string, list<value>>(queryArg, tokenize("&", fixupQueryArgs(a)));
+const list<value> queryArgs(const string& a) {
+    return map<string, value>(queryArg, tokenize("&", fixupQueryArgs(a)));
 }
 
 /**
  * Returns a list of key value pairs from the args in an HTTP request.
  */
-const list<list<value> > queryArgs(const request_rec* const r) {
+const list<value> queryArgs(const request_rec* const r) {
     if (r->args == NULL)
-        return list<list<value> >();
+        return nilListValue;
     return queryArgs(r->args);
 }
 
 /**
  * Converts the args received in a POST to a list of key value pairs.
  */
-const list<list<value> > postArgs(const list<value>& a) {
+const list<value> postArgs(const list<value>& a) {
     if (isNil(a))
-        return list<list<value> >();
+        return nilListValue;
     const list<value> l = car(a);
-    return cons(l, postArgs(cdr(a)));
+    return cons<value>(l, postArgs(cdr(a)));
 }
 
 /**
@@ -397,7 +397,7 @@
 }
 
 /**
- * Read the content of a POST or PUT.
+ * Read the content of an HTTP request.
  */
 const list<string> read(request_rec* const r) {
     char b[1024];
diff --git a/modules/http/mod-openauth.cpp b/modules/http/mod-openauth.cpp
index 797e8c1..1b70f27 100644
--- a/modules/http/mod-openauth.cpp
+++ b/modules/http/mod-openauth.cpp
@@ -178,7 +178,7 @@
  * Return the user info from a form auth session cookie.
  */
 const failable<value> userInfoFromCookie(const value& sid, const string& realm, request_rec* const r) {
-    const list<list<value>> info = httpd::queryArgs(sid);
+    const list<value> info = httpd::queryArgs(sid);
     debug(info, "modopenauth::userInfoFromCookie::info");
     const list<value> user = assoc<value>(realm + "-user", info);
     if(isNil(user))
@@ -212,7 +212,7 @@
 /**
  * Handle an authenticated request.
  */
-const failable<int> authenticated(const list<list<value> >& info, request_rec* const r) {
+const failable<int> authenticated(const list<value>& info, request_rec* const r) {
     debug(info, "modopenauth::authenticated::info");
 
     // Store user info in the request
@@ -248,7 +248,7 @@
     debug(atype, "modopenauth::checkAuthn::auth_type");
 
     // Get the request args
-    const list<list<value> > args = httpd::queryArgs(r);
+    const list<value> args = httpd::queryArgs(r);
 
     // Get session id from the request
     const maybe<string> sid = sessionID(r, "TuscanyOpenAuth");
diff --git a/modules/http/openauth.hpp b/modules/http/openauth.hpp
index dcf405d..1c49c42 100644
--- a/modules/http/openauth.hpp
+++ b/modules/http/openauth.hpp
@@ -92,9 +92,9 @@
  * Redirect to the configured login page.
  */
 const failable<int> login(const string& page, const value& ref, const value& attempt, request_rec* const r) {
-    const list<list<value> > rarg = ref == string("/")? list<list<value> >() : mklist<list<value> >(mklist<value>("openauth_referrer", httpd::escape(httpd::url(isNil(ref)? r->uri : ref, r))));
-    const list<list<value> > aarg = isNil(attempt)? list<list<value> >() : mklist<list<value> >(mklist<value>("openauth_attempt", attempt));
-    const list<list<value> > largs = append<list<value> >(rarg, aarg);
+    const list<value> rarg = ref == string("/")? nilListValue : mklist<value>(mklist<value>("openauth_referrer", httpd::escape(httpd::url(isNil(ref)? r->uri : ref, r))));
+    const list<value> aarg = isNil(attempt)? nilListValue : mklist<value>(mklist<value>("openauth_attempt", attempt));
+    const list<value> largs = append(rarg, aarg);
     const string loc = isNil(largs)? httpd::url(page, r) : httpd::url(page, r) + string("?") + http::queryString(largs);
     debug(loc, "openauth::login::uri");
     return httpd::externalRedirect(loc, r);
diff --git a/modules/json/json.hpp b/modules/json/json.hpp
index b354547..4976240 100644
--- a/modules/json/json.hpp
+++ b/modules/json/json.hpp
@@ -389,13 +389,13 @@
  * Returns a list of param values other than the id and method args from a list
  * of key value pairs.
  */
-inline const list<value> queryParams(const list<list<value> >& a) {
+inline const list<value> queryParams(const list<value>& a) {
     if (isNil(a))
         return nilListValue;
     const list<value> p = car(a);
     if (car(p) == value("id") || car(p) == value("method"))
         return queryParams(cdr(a));
-    return cons(cadr(p), queryParams(cdr(a)));
+    return cons<value>(cadr(p), queryParams(cdr(a)));
 }
 
 }
diff --git a/modules/oauth/mod-oauth1.cpp b/modules/oauth/mod-oauth1.cpp
index c9d8607..a723880 100644
--- a/modules/oauth/mod-oauth1.cpp
+++ b/modules/oauth/mod-oauth1.cpp
@@ -64,7 +64,7 @@
     gc_mutable_ref<string> ca;
     gc_mutable_ref<string> cert;
     gc_mutable_ref<string> key;
-    gc_mutable_ref<list<list<value> > > appkeys;
+    gc_mutable_ref<list<value> > appkeys;
     gc_mutable_ref<list<string> > mcaddrs;
     gc_mutable_ref<memcache::MemCached> mc;
     gc_mutable_ref<perthread_ptr<http::CURLSession> > cs;
@@ -96,7 +96,7 @@
     const char* const dir;
     bool enabled;
     gc_mutable_ref<string> login;
-    gc_mutable_ref<list<list<value> > > scopeattrs;
+    gc_mutable_ref<list<value> > scopeattrs;
     gc_mutable_ref<list<AuthnProviderConf> > apcs;
 };
 
@@ -139,7 +139,7 @@
 /**
  * Handle an authenticated request.
  */
-const failable<int> authenticated(const list<list<value> >& userinfo, const bool check, request_rec* const r, const list<list<value> >& scopeattrs, const list<AuthnProviderConf>& apcs) {
+const failable<int> authenticated(const list<value>& userinfo, const bool check, request_rec* const r, const list<value>& scopeattrs, const list<AuthnProviderConf>& apcs) {
     debug(userinfo, "modoauth2::authenticated::userinfo");
 
     if (isNil(scopeattrs)) {
@@ -179,7 +179,7 @@
  * Convert a query string containing oauth args to an authorization header.
  */
 const string header(const string& qs, const string& redir, const string& verif) {
-    const list<list<value> > args = httpd::queryArgs(qs);
+    const list<value> args = httpd::queryArgs(qs);
     ostringstream hdr;
     hdr << "Authorization: OAuth "
         << "oauth_nonce=\"" << string(cadr(assoc<value>("oauth_nonce", args))) << "\", ";
@@ -220,7 +220,7 @@
 /**
  * Handle an authorize request.
  */
-const failable<int> authorize(const list<list<value> >& args, request_rec* const r, const list<list<value> >& appkeys, const memcache::MemCached& mc) {
+const failable<int> authorize(const list<value>& args, request_rec* const r, const list<value>& appkeys, const memcache::MemCached& mc) {
     // Extract authorize, access_token, client ID and info URIs
     const list<value> ref = assoc<value>("openauth_referrer", args);
     if (isNil(ref) || isNil(cdr(ref)))
@@ -242,7 +242,7 @@
         return mkfailure<int>("Missing oauth1_info parameter");
 
     // Build the redirect URI
-    const list<list<value> > redirargs = mklist<list<value> >(tok, cid, info, ref);
+    const list<value> redirargs = mklist<value>(tok, cid, info, ref);
     const string redir = httpd::url("/oauth1/access_token/", r) + string("?") + http::queryString(redirargs);
     debug(redir, "modoauth1::authorize::redir");
 
@@ -253,7 +253,7 @@
     list<value> appkey = cadr(app);
 
     // Build and sign the request token URI
-    const string requri = httpd::unescape(cadr(req)) + string("&") + http::queryString(mklist<list<value> >(mklist<value>("oauth_callback", httpd::escape(redir))));
+    const string requri = httpd::unescape(cadr(req)) + string("&") + http::queryString(mklist<value>(mklist<value>("oauth_callback", httpd::escape(redir))));
     const list<string> srequri = sign("POST", requri, appkey, emptyString, emptyString);
     debug(srequri, "modoauth1::authorize::srequri");
 
@@ -267,7 +267,7 @@
     const string res(pres);
     free(pres);
     debug(res, "modoauth1::authorize::res");
-    const list<list<value> > resargs = httpd::queryArgs(res);
+    const list<value> resargs = httpd::queryArgs(res);
 
     // Retrieve the request token
     const list<value> conf = assoc<value>("oauth_callback_confirmed", resargs);
@@ -286,7 +286,7 @@
         return mkfailure<int>(prc);
 
     // Redirect to the authorize URI
-    const string authuri = httpd::unescape(cadr(auth)) + string("?") + http::queryString(mklist<list<value> >(tv));
+    const string authuri = httpd::unescape(cadr(auth)) + string("?") + http::queryString(mklist<value>(tv));
     debug(authuri, "modoauth1::authorize::authuri");
     return httpd::externalRedirect(authuri, r);
 }
@@ -343,7 +343,7 @@
 /**
  * Handle an access_token request.
  */
-const failable<int> accessToken(const list<list<value> >& args, request_rec* r, const list<list<value> >& appkeys, const list<list<value> >& scopeattrs, const list<AuthnProviderConf>& apcs, const memcache::MemCached& mc) {
+const failable<int> accessToken(const list<value>& args, request_rec* r, const list<value>& appkeys, const list<value>& scopeattrs, const list<AuthnProviderConf>& apcs, const memcache::MemCached& mc) {
 
     // Extract access_token URI, client ID and verification code
     const list<value> ref = assoc<value>("openauth_referrer", args);
@@ -377,7 +377,7 @@
         return mkfailure<int>(sv);
 
     // Build and sign access token request URI
-    const string tokuri = httpd::unescape(cadr(tok)) + string("?") + http::queryString(mklist<list<value> >(vv));
+    const string tokuri = httpd::unescape(cadr(tok)) + string("?") + http::queryString(mklist<value>(vv));
     const list<string> stokuri = sign("POST", tokuri, appkey, cadr(tv), content(sv));
     debug(stokuri, "modoauth1::access_token::stokuri");
 
@@ -391,7 +391,7 @@
     const string tokres(ptokres);
     free(ptokres);
     debug(tokres, "modoauth1::access_token::res");
-    const list<list<value> > tokresargs = httpd::queryArgs(tokres);
+    const list<value> tokresargs = httpd::queryArgs(tokres);
 
     // Retrieve the access token
     const list<value> atv = assoc<value>("oauth_token", tokresargs);
@@ -475,7 +475,7 @@
     }
 
     // Get the request args
-    const list<list<value> > args = httpd::queryArgs(r);
+    const list<value> args = httpd::queryArgs(r);
 
     // Handle OAuth authorize request step
     if (string(r->uri) == "/oauth1/authorize/") {
@@ -515,7 +515,7 @@
     debug(httpd::serverName(s), "modoauth1::postConfigMerge::serverName");
 
     // Merge configuration from main server
-    if (isNil((list<list<value> >)sc.appkeys))
+    if (isNil((list<value>)sc.appkeys))
         sc.appkeys = mainsc.appkeys;
     if (isNil((list<string>)sc.mcaddrs))
         sc.mcaddrs = mainsc.mcaddrs;
@@ -575,7 +575,7 @@
 char* const confAppKey(cmd_parms* cmd, unused void *c, char *arg1, char* arg2, char* arg3) {
     const gc_scoped_pool sp(cmd->pool);
     ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_oauth1);
-    sc.appkeys = cons<list<value> >(mklist<value>(arg1, mklist<value>(arg2, arg3)), (list<list<value> >)sc.appkeys);
+    sc.appkeys = cons<value>(mklist<value>(arg1, mklist<value>(arg2, arg3)), (list<value>)sc.appkeys);
     return NULL;
 }
 char* confMemcached(cmd_parms *cmd, unused void *c, char *arg) {
@@ -617,7 +617,7 @@
 char* confScopeAttr(cmd_parms *cmd, void* c, char* arg1, char* arg2) {
     const gc_scoped_pool sp(cmd->pool);
     DirConf& dc = httpd::dirConf<DirConf>(c);
-    dc.scopeattrs = cons<list<value> >(mklist<value>(arg1, arg2), (list<list<value> >)dc.scopeattrs);
+    dc.scopeattrs = cons<value>(mklist<value>(arg1, arg2), (list<value>)dc.scopeattrs);
     return NULL;
 }
 char* confAuthnProvider(cmd_parms *cmd, void *c, char* arg) {
diff --git a/modules/oauth/mod-oauth2.cpp b/modules/oauth/mod-oauth2.cpp
index bedf833..5bc212a 100644
--- a/modules/oauth/mod-oauth2.cpp
+++ b/modules/oauth/mod-oauth2.cpp
@@ -58,7 +58,7 @@
     gc_mutable_ref<string> ca;
     gc_mutable_ref<string> cert;
     gc_mutable_ref<string> key;
-    gc_mutable_ref<list<list<value> > > appkeys;
+    gc_mutable_ref<list<value> > appkeys;
     gc_mutable_ref<list<string> > mcaddrs;
     gc_mutable_ref<memcache::MemCached> mc;
     gc_mutable_ref<perthread_ptr<http::CURLSession> > cs;
@@ -90,7 +90,7 @@
     const char* const dir;
     bool enabled;
     gc_mutable_ref<string> login;
-    gc_mutable_ref<list<list<value> > > scopeattrs;
+    gc_mutable_ref<list<value> > scopeattrs;
     gc_mutable_ref<list<AuthnProviderConf> > apcs;
 };
 
@@ -133,7 +133,7 @@
 /**
  * Handle an authenticated request.
  */
-const failable<int> authenticated(const list<list<value> >& userinfo, const bool check, request_rec* const r, const list<list<value> >& scopeattrs, const list<AuthnProviderConf>& apcs) {
+const failable<int> authenticated(const list<value>& userinfo, const bool check, request_rec* const r, const list<value>& scopeattrs, const list<AuthnProviderConf>& apcs) {
     debug(userinfo, "modoauth2::authenticated::userinfo");
 
     if (isNil(scopeattrs)) {
@@ -172,7 +172,7 @@
 /**
  * Handle an authorize request.
  */
-const failable<int> authorize(const list<list<value> >& args, request_rec* const r, const list<list<value> >& appkeys) {
+const failable<int> authorize(const list<value>& args, request_rec* const r, const list<value>& appkeys) {
     // Extract authorize, access_token, client ID and info URIs
     const list<value> ref = assoc<value>("openauth_referrer", args);
     if (isNil(ref) || isNil(cdr(ref)))
@@ -199,7 +199,7 @@
     debug(redir, "modoauth2::authorize::redir");
 
     // Build the state URI
-    const list<list<value> > stargs = mklist<list<value> >(tok, cid, info, ref);
+    const list<value> stargs = mklist<value>(tok, cid, info, ref);
     const string state = http::queryString(stargs);
     debug(state, "modoauth2::authorize::state");
 
@@ -211,7 +211,7 @@
 
     // Redirect to the authorize URI
     const list<value> adisplay = (isNil(display) || isNil(cdr(display)))? nilListValue : mklist<value>("display", cadr(display));
-    const list<list<value> > aargs = mklist<list<value> >(mklist<value>("response_type", "code"), mklist<value>("client_id", car(appkey)), mklist<value>("scope", cadr(scope)), adisplay, mklist<value>("redirect_uri", httpd::escape(redir)), mklist<value>("state", httpd::escape(state)));
+    const list<value> aargs = mklist<value>(mklist<value>("response_type", "code"), mklist<value>("client_id", car(appkey)), mklist<value>("scope", cadr(scope)), adisplay, mklist<value>("redirect_uri", httpd::escape(redir)), mklist<value>("state", httpd::escape(state)));
     const string uri = httpd::unescape(cadr(auth)) + string("?") + http::queryString(aargs);
     debug(uri, "modoauth2::authorize::uri");
     return httpd::externalRedirect(uri, r);
@@ -229,13 +229,13 @@
 /**
  * Handle an access_token request.
  */
-const failable<int> accessToken(const list<list<value> >& args, request_rec* r, const list<list<value> >& appkeys, const http::CURLSession& cs, const list<list<value> >& scopeattrs, const list<AuthnProviderConf>& apcs, const memcache::MemCached& mc) {
+const failable<int> accessToken(const list<value>& args, request_rec* r, const list<value>& appkeys, const http::CURLSession& cs, const list<value>& scopeattrs, const list<AuthnProviderConf>& apcs, const memcache::MemCached& mc) {
 
     // Extract access_token URI, client ID and authorization code parameters
     const list<value> state = assoc<value>("state", args);
     if (isNil(state) || isNil(cdr(state)))
         return mkfailure<int>("Missing state parameter");
-    const list<list<value> >& stargs = httpd::queryArgs(httpd::unescape(cadr(state)));
+    const list<value>& stargs = httpd::queryArgs(httpd::unescape(cadr(state)));
     const list<value> ref = assoc<value>("openauth_referrer", stargs);
     if (isNil(ref) || isNil(cdr(ref)))
         return mkfailure<int>("Missing openauth_referrer parameter");
@@ -263,7 +263,7 @@
     debug(redir, "modoauth2::access_token::redir");
 
     // Request access token
-    const list<list<value> > targs = mklist<list<value> >(mklist<value>("client_id", car(appkey)), mklist<value>("redirect_uri", httpd::escape(redir)), mklist<value>("client_secret", cadr(appkey)), code, mklist<value>("grant_type", "authorization_code"));
+    const list<value> targs = mklist<value>(mklist<value>("client_id", car(appkey)), mklist<value>("redirect_uri", httpd::escape(redir)), mklist<value>("client_secret", cadr(appkey)), code, mklist<value>("grant_type", "authorization_code"));
     const string tqs = http::queryString(targs);
     debug(tqs, "modoauth2::access_token::tokenqs");
     const string turi = httpd::unescape(cadr(tok));
@@ -285,7 +285,7 @@
 
     // Request user info
     // TODO Make this step configurable
-    const list<list<value> > iargs = mklist<list<value> >(tv);
+    const list<value> iargs = mklist<value>(tv);
     const string iuri = httpd::unescape(cadr(info)) + string("?") + http::queryString(iargs);
     debug(iuri, "modoauth2::access_token::infouri");
     const failable<value> profres = http::get(iuri, cs);
@@ -350,7 +350,7 @@
     }
 
     // Get the request args
-    const list<list<value> > args = httpd::queryArgs(r);
+    const list<value> args = httpd::queryArgs(r);
 
     // Handle OAuth authorize request step
     if (string(r->uri) == "/oauth2/authorize/") {
@@ -390,7 +390,7 @@
     debug(httpd::serverName(s), "modoauth2::postConfigMerge::serverName");
 
     // Merge configuration from main server
-    if (isNil((list<list<value> >)sc.appkeys))
+    if (isNil((list<value>)sc.appkeys))
         sc.appkeys = mainsc.appkeys;
     if (isNil((list<string>)sc.mcaddrs))
         sc.mcaddrs = mainsc.mcaddrs;
@@ -450,7 +450,7 @@
 char* confAppKey(cmd_parms *cmd, unused void *c, char *arg1, char* arg2, char* arg3) {
     const gc_scoped_pool sp(cmd->pool);
     ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_oauth2);
-    sc.appkeys = cons<list<value> >(mklist<value>(arg1, mklist<value>(arg2, arg3)), (list<list<value> >)sc.appkeys);
+    sc.appkeys = cons<value>(mklist<value>(arg1, mklist<value>(arg2, arg3)), (list<value>)sc.appkeys);
     return NULL;
 }
 char* confMemcached(cmd_parms *cmd, unused void *c, char *arg) {
@@ -492,7 +492,7 @@
 char* confScopeAttr(cmd_parms *cmd, void* c, char* arg1, char* arg2) {
     const gc_scoped_pool sp(cmd->pool);
     DirConf& dc = httpd::dirConf<DirConf>(c);
-    dc.scopeattrs = cons<list<value> >(mklist<value>(arg1, arg2), (list<list<value> >)dc.scopeattrs);
+    dc.scopeattrs = cons<value>(mklist<value>(arg1, arg2), (list<value>)dc.scopeattrs);
     return NULL;
 }
 char* confAuthnProvider(cmd_parms *cmd, void *c, char* arg) {
diff --git a/modules/rss/rss.hpp b/modules/rss/rss.hpp
index 7fba736..348d50e 100644
--- a/modules/rss/rss.hpp
+++ b/modules/rss/rss.hpp
@@ -45,15 +45,16 @@
  * Convert a list of elements to a list of element values representing an RSS entry.
  */
 const list<value> entryElementValues(const list<value>& e) {
-    const list<value> lt = filter<value>(selector(mklist<value>(element, "title")), e);
+    const list<value> lt = elementChildren("title", e);
     const value t = isNil(lt)? value(emptyString) : elementValue(car(lt));
-    const list<value> li = filter<value>(selector(mklist<value>(element, "link")), e);
+    const list<value> li = elementChildren("link", e);
     const value i = isNil(li)? value(emptyString) : elementValue(car(li));
-    const list<value> ld = filter<value>(selector(mklist<value>(element, "description")), e);
+    const list<value> ld = elementChildren("description", e);
     return append<value>(nilListValue + element + entry 
                 + value(nilListValue + element + value("title") + t)
                 + value(nilListValue + element + value("id") + i),
-                isNil(ld)? nilListValue : mklist<value>(value(nilListValue + element + value("content") + elementValue(car(ld)))));
+                isNil(ld)? nilListValue : isAttribute(elementValue(car(ld)))? nilListValue :
+                    mklist<value>(value(nilListValue + element + value("content") + elementValue(car(ld)))));
 }
 
 /**
@@ -91,10 +92,10 @@
     const list<value> f = content(xml::readElements(ilist));
     if (isNil(f))
         return mkfailure<list<value> >("Empty feed");
-    const list<value> c = filter<value>(selector(mklist<value>(element, "channel")), car(f));
-    const list<value> t = filter<value>(selector(mklist<value>(element, "title")), car(c));
-    const list<value> i = filter<value>(selector(mklist<value>(element, "link")), car(c));
-    const list<value> e = filter<value>(selector(mklist<value>(element, "item")), car(c));
+    const list<value> c = elementChildren("channel", car(f));
+    const list<value> t = elementChildren("title", car(c));
+    const list<value> i = elementChildren("link", car(c));
+    const list<value> e = elementChildren("item", car(c));
     return mklist<value>(append<value>(nilListValue + element + feed 
                 + value(nilListValue + element + value("title") + elementValue(car(t)))
                 + value(nilListValue + element + value("id") + elementValue(car(i))),
@@ -150,9 +151,9 @@
  */
 template<typename R> const failable<R> writeRSSFeed(const lambda<const R(const string&, const R)>& reduce, const R& initial, const list<value>& ll) {
     const list<value> l = isNil(ll)? ll : (list<value>)car(ll);
-    const list<value> lt = filter<value>(selector(mklist<value>(element, "title")), l);
+    const list<value> lt = elementChildren("title", l);
     const value t = isNil(lt)? value(emptyString) : elementValue(car(lt));
-    const list<value> li = filter<value>(selector(mklist<value>(element, "id")), l);
+    const list<value> li = elementChildren("id", l);
     const value i = isNil(li)? value(emptyString) : elementValue(car(li));
     const list<value> c = nilListValue
         + (nilListValue + element + "title" + t)
@@ -160,7 +161,7 @@
         + (nilListValue + element + "description" + t);
 
     // Write RSS entries
-    const list<value> le = filter<value>(selector(mklist<value>(element, entry)), l);
+    const list<value> le = elementChildren(entry, l);
     if (isNil(le)) {
         const list<value> fe = nilListValue
             + element + "rss" + (nilListValue + attribute + "version" + "2.0")
diff --git a/modules/scdl/scdl-test.cpp b/modules/scdl/scdl-test.cpp
index 9daacb5..2c098d3 100644
--- a/modules/scdl/scdl-test.cpp
+++ b/modules/scdl/scdl-test.cpp
@@ -53,8 +53,8 @@
     const value catalog = named(string("Catalog"), c);
     assert(name(catalog) == string("Catalog"));
 
-    const list<value> t = mkbtree(sort(nameToElementAssoc(c)));
-    assert(assoctree<value>("Catalog", t) == mklist<value>("Catalog" , cadr(c)));
+    const list<value> t = mkrbtree(sort(nameToElementAssoc(c)));
+    assert(rbtreeAssoc<value>("Catalog", t) == mklist<value>("Catalog" , cadr(c)));
     return true;
 }
 
@@ -89,8 +89,8 @@
     assert(uri(binding) == nilValue);
     assert(bindingType(binding) == "binding.jsonrpc");
 
-    const list<value> t = mkbtree(sort(referenceToTargetAssoc(references(store))));
-    assert(assoctree<value>("shoppingCart", t) == mklist<value>(string("shoppingCart"), string("ShoppingCart/Cart")));
+    const list<value> t = mkrbtree(sort(referenceToTargetAssoc(references(store))));
+    assert(rbtreeAssoc<value>("shoppingCart", t) == mklist<value>(string("shoppingCart"), string("ShoppingCart/Cart")));
     return true;
 }
 
diff --git a/modules/scheme/primitive.hpp b/modules/scheme/primitive.hpp
index 2e0c4f6..4815e9a 100644
--- a/modules/scheme/primitive.hpp
+++ b/modules/scheme/primitive.hpp
@@ -26,9 +26,12 @@
  * Script evaluator primitive functions.
  */
 
+#include <math.h>
+
 #include "stream.hpp"
 #include "function.hpp"
 #include "list.hpp"
+#include "tree.hpp"
 #include "value.hpp"
 #include "parallel.hpp"
 
@@ -90,10 +93,30 @@
 }
 
 inline const value assocProc(const list<value>& args) {
-    return assoc(car(args), (list<list<value> >)cadr(args));
+    return assoc(car(args), (list<value>)cadr(args));
 }
 
-inline const value nulProc(const list<value>& args) {
+inline const value delAssocProc(const list<value>& args) {
+    return delAssoc(car(args), (list<value>)cadr(args));
+}
+
+inline const value substAssocProc(const list<value>& args) {
+    return substAssoc(car(args), (list<value>)cadr(args), (list<value>)caddr(args));
+}
+
+inline const value treeDelAssocProc(const list<value>& args) {
+    return treeDelAssoc((list<value>)car(args), (list<value>)cadr(args));
+}
+
+inline const value treeSubstAssocProc(const list<value>& args) {
+    return treeSubstAssoc((list<value>)car(args), (list<value>)cadr(args), (list<value>)caddr(args));
+}
+
+inline const value treeSelectAssocProc(const list<value>& args) {
+    return treeSelectAssoc((list<value>)car(args), (list<value>)cadr(args));
+}
+
+inline const value nullProc(const list<value>& args) {
     const value v(car(args));
     if (isNil(v))
         return true;
@@ -106,6 +129,14 @@
     return (bool)(car(args) == cadr(args));
 }
 
+inline const value greaterProc(const list<value>& args) {
+    return (bool)(car(args) > cadr(args));
+}
+
+inline const value lesserProc(const list<value>& args) {
+    return (bool)(car(args) < cadr(args));
+}
+
 inline const value addProc(const list<value>& args) {
     if (isNil(cdr(args)))
         return (double)car(args);
@@ -126,6 +157,10 @@
     return (double)car(args) / (double)cadr(args);
 }
 
+inline const value sqrtProc(const list<value>& args) {
+    return (double)sqrt((double)car(args));
+}
+
 inline const value displayProc(const list<value>& args) {
     if (isNil(args)) {
         displayStream() << endl;
@@ -216,14 +251,22 @@
     + "cdr"
     + "cons"
     + "list"
-    + "nul"
+    + "null?"
     + "="
     + "equal?"
+    + "<"
+    + ">"
     + "+"
     + "-"
     + "*"
     + "/"
+    + "sqrt"
     + "assoc"
+    + "del-assoc"
+    + "subst-assoc"
+    + "tree-select-assoc"
+    + "tree-del-assoc"
+    + "tree-subst-assoc"
     + "cadr"
     + "caddr"
     + "cadddr"
@@ -242,14 +285,22 @@
     + primitiveProcedure(cdrProc)
     + primitiveProcedure(consProc)
     + primitiveProcedure(listProc)
-    + primitiveProcedure(nulProc)
+    + primitiveProcedure(nullProc)
     + primitiveProcedure(equalProc)
     + primitiveProcedure(equalProc)
+    + primitiveProcedure(lesserProc)
+    + primitiveProcedure(greaterProc)
     + primitiveProcedure(addProc)
     + primitiveProcedure(subProc)
     + primitiveProcedure(mulProc)
     + primitiveProcedure(divProc)
+    + primitiveProcedure(sqrtProc)
     + primitiveProcedure(assocProc)
+    + primitiveProcedure(delAssocProc)
+    + primitiveProcedure(substAssocProc)
+    + primitiveProcedure(treeSelectAssocProc)
+    + primitiveProcedure(treeDelAssocProc)
+    + primitiveProcedure(treeSubstAssocProc)
     + primitiveProcedure(cadrProc)
     + primitiveProcedure(caddrProc)
     + primitiveProcedure(cadddrProc)
diff --git a/modules/scheme/test.scm b/modules/scheme/test.scm
index 4bbff6e..41d6296 100644
--- a/modules/scheme/test.scm
+++ b/modules/scheme/test.scm
@@ -22,7 +22,7 @@
 ; ATOMPub test case
 
 (define (get id)
-  (if (nul id)
+  (if (null? id)
     '((feed (title "Sample Feed") (id "123456789") (entry
        (((title "Item") (id "111") (content (item (name "Apple") (currencyCode "USD") (currencySymbol "$") (price 2.99))))
         ((title "Item") (id "222") (content (item (name "Orange") (currencyCode "USD") (currencySymbol "$") (price 3.55))))
diff --git a/patches/jansson-2.4.patch b/patches/jansson-2.4.patch
index 006d69d..69a195d 100644
--- a/patches/jansson-2.4.patch
+++ b/patches/jansson-2.4.patch
@@ -5,7 +5,7 @@
      size_t length;
  
 -    ret = snprintf(buffer, size, "%.17g", value);
-+    ret = snprintf(buffer, size, "%g", value);
++    ret = snprintf(buffer, size, "%.16g", value);
      if(ret < 0)
          return -1;
  
diff --git a/samples/store-constdb/shopping-cart.scm b/samples/store-constdb/shopping-cart.scm
index e653f1e..3dff67e 100644
--- a/samples/store-constdb/shopping-cart.scm
+++ b/samples/store-constdb/shopping-cart.scm
@@ -23,7 +23,7 @@
 ; Return an empty cart if not found
 (define (getcart id cache)
   (define cart (cache "get" (list id)))
-  (if (nul cart)
+  (if (null? cart)
     (list)
     cart)
 )
@@ -39,7 +39,7 @@
 
 ; Find an item in the cart
 (define (find id cart)
-  (if (nul cart)
+  (if (null? cart)
     (list (list 'entry (list 'title "Item") (list 'id "0")))
     (if (= id (cadr (caddr (car cart))))
       (list (car cart))
@@ -48,7 +48,7 @@
 
 ; Get items from the cart
 (define (get id cache)
-  (if (nul id)
+  (if (null? id)
     (list (append (list 'feed (list 'title "Your Cart") (list 'id cartId)) (getcart cartId cache)))
     (find (car id) (getcart cartId cache))
   )
@@ -56,7 +56,7 @@
 
 ; Delete items from the  cart
 (define (delete id cache)
-  (if (nul id)
+  (if (null? id)
     (cache "delete" (list cartId))
     true
   )
@@ -69,7 +69,7 @@
 
 ; Sum the prices of a list of items
 (define (sum items)
-  (if (nul items)
+  (if (null? items)
     0
     (+ (price (car items)) (sum (cdr items))))
 )
diff --git a/samples/store-cpp/htdocs/test/items-result.txt b/samples/store-cpp/htdocs/test/items-result.txt
index 0b456ea..56f87d2 100644
--- a/samples/store-cpp/htdocs/test/items-result.txt
+++ b/samples/store-cpp/htdocs/test/items-result.txt
@@ -1,23 +1 @@
-{
- "id": 1,
- "result": [
-  {
-   "name": "Apple",
-   "currencyCode": "USD",
-   "currencySymbol": "$",
-   "price": 2.99
-  },
-  {
-   "name": "Orange",
-   "currencyCode": "USD",
-   "currencySymbol": "$",
-   "price": 3.55
-  },
-  {
-   "name": "Pear",
-   "currencyCode": "USD",
-   "currencySymbol": "$",
-   "price": 1.55
-  }
- ]
-}
\ No newline at end of file
+{"id":1,"result":[{"name":"Apple","currencyCode":"USD","currencySymbol":"$","price":2.99},{"name":"Orange","currencyCode":"USD","currencySymbol":"$","price":3.55},{"name":"Pear","currencyCode":"USD","currencySymbol":"$","price":1.55}]}
\ No newline at end of file
diff --git a/samples/store-python/htdocs/test/items-result.txt b/samples/store-python/htdocs/test/items-result.txt
index d6aaf4d..788b7cd 100644
--- a/samples/store-python/htdocs/test/items-result.txt
+++ b/samples/store-python/htdocs/test/items-result.txt
@@ -1,23 +1 @@
-{
- "id": 1,
- "result": [
-  {
-   "name": "Mango",
-   "currencyCode": "USD",
-   "currencySymbol": "$",
-   "price": 2.99
-  },
-  {
-   "name": "Passion",
-   "currencyCode": "USD",
-   "currencySymbol": "$",
-   "price": 3.55
-  },
-  {
-   "name": "Kiwi",
-   "currencyCode": "USD",
-   "currencySymbol": "$",
-   "price": 1.55
-  }
- ]
-}
\ No newline at end of file
+{"id":1,"result":[{"name":"Mango","currencyCode":"USD","currencySymbol":"$","price":2.99},{"name":"Passion","currencyCode":"USD","currencySymbol":"$","price":3.55},{"name":"Kiwi","currencyCode":"USD","currencySymbol":"$","price":1.55}]}
\ No newline at end of file
diff --git a/samples/store-scheme/shopping-cart.scm b/samples/store-scheme/shopping-cart.scm
index e653f1e..3dff67e 100644
--- a/samples/store-scheme/shopping-cart.scm
+++ b/samples/store-scheme/shopping-cart.scm
@@ -23,7 +23,7 @@
 ; Return an empty cart if not found
 (define (getcart id cache)
   (define cart (cache "get" (list id)))
-  (if (nul cart)
+  (if (null? cart)
     (list)
     cart)
 )
@@ -39,7 +39,7 @@
 
 ; Find an item in the cart
 (define (find id cart)
-  (if (nul cart)
+  (if (null? cart)
     (list (list 'entry (list 'title "Item") (list 'id "0")))
     (if (= id (cadr (caddr (car cart))))
       (list (car cart))
@@ -48,7 +48,7 @@
 
 ; Get items from the cart
 (define (get id cache)
-  (if (nul id)
+  (if (null? id)
     (list (append (list 'feed (list 'title "Your Cart") (list 'id cartId)) (getcart cartId cache)))
     (find (car id) (getcart cartId cache))
   )
@@ -56,7 +56,7 @@
 
 ; Delete items from the  cart
 (define (delete id cache)
-  (if (nul id)
+  (if (null? id)
     (cache "delete" (list cartId))
     true
   )
@@ -69,7 +69,7 @@
 
 ; Sum the prices of a list of items
 (define (sum items)
-  (if (nul items)
+  (if (null? items)
     0
     (+ (price (car items)) (sum (cdr items))))
 )
diff --git a/samples/store-sql/shopping-cart.scm b/samples/store-sql/shopping-cart.scm
index e653f1e..3dff67e 100644
--- a/samples/store-sql/shopping-cart.scm
+++ b/samples/store-sql/shopping-cart.scm
@@ -23,7 +23,7 @@
 ; Return an empty cart if not found
 (define (getcart id cache)
   (define cart (cache "get" (list id)))
-  (if (nul cart)
+  (if (null? cart)
     (list)
     cart)
 )
@@ -39,7 +39,7 @@
 
 ; Find an item in the cart
 (define (find id cart)
-  (if (nul cart)
+  (if (null? cart)
     (list (list 'entry (list 'title "Item") (list 'id "0")))
     (if (= id (cadr (caddr (car cart))))
       (list (car cart))
@@ -48,7 +48,7 @@
 
 ; Get items from the cart
 (define (get id cache)
-  (if (nul id)
+  (if (null? id)
     (list (append (list 'feed (list 'title "Your Cart") (list 'id cartId)) (getcart cartId cache)))
     (find (car id) (getcart cartId cache))
   )
@@ -56,7 +56,7 @@
 
 ; Delete items from the  cart
 (define (delete id cache)
-  (if (nul id)
+  (if (null? id)
     (cache "delete" (list cartId))
     true
   )
@@ -69,7 +69,7 @@
 
 ; Sum the prices of a list of items
 (define (sum items)
-  (if (nul items)
+  (if (null? items)
     0
     (+ (price (car items)) (sum (cdr items))))
 )