diff --git a/README b/README
index 51fb323c..965138c4 100644
--- a/README
+++ b/README
@@ -89,7 +89,7 @@ cdist was tested or is know to run on at least
 
 ## Installation
 
-### Preperation
+### Preparation
 
 Ensure you have Python 3.2 installed on the machine you use to **deploy to the targets**
 (the ***source host***).
diff --git a/build b/build
index ea4ca83c..2d98e862 100755
--- a/build
+++ b/build
@@ -85,7 +85,7 @@ case "$1" in
    ;;
 
    release)
-      "$0" clean && "$0" man && "$0" web
+        ./doc/dev/releasechecklist
    ;;
 
    speeches)
@@ -113,8 +113,8 @@ case "$1" in
       # cp ${SPEECHESDIR}/*.pdf ${WEBDIR}/${WEBBASE}/speeches
       # git describe > ${WEBDIR}/${WEBBASE}/man/VERSION
 
-      cp ${MAN1DSTDIR}/*.html ${WEBMAN}/man1 
-      cp ${MAN7DSTDIR}/*.html ${WEBMAN}/man7
+      cp ${MAN1DSTDIR}/*.html ${MAN1DSTDIR}/*.css ${WEBMAN}/man1 
+      cp ${MAN7DSTDIR}/*.html ${MAN7DSTDIR}/*.css ${WEBMAN}/man7
       
       cd ${WEBDIR} && git add ${WEBBASE}
       cd ${WEBDIR} && git commit -m "cdist update" ${WEBBASE} ${WEBPAGE}
@@ -123,7 +123,7 @@ case "$1" in
       # Fix ikiwiki, which does not like symlinks for pseudo security
       ssh tee.schottelius.org \
         "cd /home/services/www/nico/www.nico.schottelius.org/www/software/cdist/man &&
-            ln -sf "$version" latest"
+            rm -f latest && ln -sf "$version" latest"
    ;;
 
    p|pu|pub)
diff --git a/conf/explorer/runlevel b/conf/explorer/runlevel
new file mode 100755
index 00000000..7cdd81ef
--- /dev/null
+++ b/conf/explorer/runlevel
@@ -0,0 +1,26 @@
+#!/bin/sh
+#
+# 2012 Nico Schottelius (nico-cdist at schottelius.org)
+#
+# This file is part of cdist.
+#
+# cdist is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# cdist is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with cdist. If not, see <http://www.gnu.org/licenses/>.
+#
+#
+
+set +e
+executable=$(which runlevel 2>/dev/null)
+if [ -x "$executable" ]; then
+   "$executable" | awk '{ print $2 }'
+fi
diff --git a/conf/type/__key_value/explorer/state b/conf/type/__key_value/explorer/state
new file mode 100755
index 00000000..94a5ea7f
--- /dev/null
+++ b/conf/type/__key_value/explorer/state
@@ -0,0 +1,53 @@
+#!/bin/sh
+#
+# 2011 Steven Armstrong (steven-cdist at armstrong.cc)
+#
+# This file is part of cdist.
+#
+# cdist is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# cdist is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with cdist. If not, see <http://www.gnu.org/licenses/>.
+#
+
+key="$(cat "$__object/parameter/key" 2>/dev/null \
+   || echo "$__object_id")"
+state="$(cat "$__object/parameter/state" 2>/dev/null \
+   || echo "present")"
+file="$(cat "$__object/parameter/file")"
+delimiter="$(cat "$__object/parameter/delimiter")"
+value="$(cat "$__object/parameter/value" 2>/dev/null \
+   || echo "__CDIST_NOTSET__")"
+
+case "$state" in
+   absent)
+      if grep -q -E "^$key$delimiter+" "$file"; then
+         # if the key exists, with whatever value, we will have to remove it
+         # so report it as present
+         echo present
+      else
+         # key does not exist
+         echo absent
+      fi
+   ;;
+   present)
+      if grep -q -E "^$key$delimiter+$value$" "$file"; then
+         # key exists and value is same
+         echo present
+      elif grep -q -E "^$key$delimiter+" "$file"; then
+         # key exists, but value is empty or different
+         echo wrongvalue
+      else
+         # key does not exist
+         echo absent
+      fi
+   ;;
+esac
diff --git a/conf/type/__key_value/gencode-remote b/conf/type/__key_value/gencode-remote
index eff0925c..0846dca1 100755
--- a/conf/type/__key_value/gencode-remote
+++ b/conf/type/__key_value/gencode-remote
@@ -18,35 +18,40 @@
 # along with cdist. If not, see <http://www.gnu.org/licenses/>.
 #
 
-value_is="$(cat "$__object/explorer/value")"
-value_should="$(cat "$__object/parameter/value")"
-
 key="$(cat "$__object/parameter/key")"
 file="$(cat "$__object/parameter/file")"
 delimiter="$(cat "$__object/parameter/delimiter")"
+value="$(cat "$__object/parameter/value")"
 
-if [ "$value_is" != "$value_should" ]; then
-   case "$value_is" in
-      __NOTSET__)
-         # add key and value
-         echo "echo \"${key}${delimiter}${value_should}\" >> \"$file\""
-      ;;
-      *)
-         if [ "$value_should" = '__NOTSET__' ]; then
-            # remove key and value
-            cat << DONE
-sed -i '/^${key}/d' "$file"
-DONE
-         else
-            # change value
-            cat << DONE
-awk -F "$delimiter" '
-/${key}${delimiter}*/{gsub("$value_is", "$value_should")};{print}' "$file" > "${file}+" \
-&& mv "${file}+" "$file"
+state_is="$(cat "$__object/explorer/state")"
+state_should="$(cat "$__object/parameter/state")"
 
-DONE
-         fi
-      ;;
-   esac
+if [ "$state_is" = "$state_should" ]; then
+   # nothing to do
+   exit 0
 fi
 
+case "$state_should" in
+   absent)
+      # remove lines starting with key
+      echo "sed -i '/^$key\($delimiter\+\)/d' \"$file\""
+   ;;
+   present)
+      case "$state_is" in
+         absent)
+            # add new key and value
+            echo "echo \"${key}${delimiter}${value}\" >> \"$file\""
+         ;;
+         wrongvalue)
+            # change exisiting value
+            echo "sed -i \"s|^$key\($delimiter\+\).*|$key\1$value|\" \"$file\""
+         ;;
+         *)
+            echo "Unknown explorer state: $state_is" >&2
+            exit 1
+      esac
+   ;;
+   *)
+      echo "Unknown state: $state_should" >&2
+      exit 1
+esac 
diff --git a/conf/type/__key_value/man.text b/conf/type/__key_value/man.text
index 3e4e8013..1423fc7d 100644
--- a/conf/type/__key_value/man.text
+++ b/conf/type/__key_value/man.text
@@ -16,9 +16,6 @@ file.
 
 REQUIRED PARAMETERS
 -------------------
-value::
-   The value for the key. Setting the value to `__NOTSET__` will remove the key
-   from the file.
 file::
    The file to operate on.
 delimiter::
@@ -27,8 +24,13 @@ delimiter::
 
 OPTIONAL PARAMETERS
 -------------------
+state::
+   present or absent, defaults to present. If present, sets the key to value,
+   if absent, removes the key from the file.
 key::
    The key to change. Defaults to object_id.
+value::
+   The value for the key. Optional if state=absent, required otherwise.
 
 
 EXAMPLES
@@ -45,6 +47,9 @@ __key_value my-fancy-id --file /etc/login.defs --key SYS_UID_MAX --value 666 \
 # Enable packet forwarding
 __key_value net.ipv4.ip_forward --file /etc/sysctl.conf --value 1 \
    --delimiter '='
+
+# Remove existing key/value
+__key_value LEGACY_KEY --file /etc/somefile --state absent --delimiter '=' 
 --------------------------------------------------------------------------------
 
 
diff --git a/conf/type/__key_value/manifest b/conf/type/__key_value/manifest
index 706b0b0d..2e75e175 100755
--- a/conf/type/__key_value/manifest
+++ b/conf/type/__key_value/manifest
@@ -18,9 +18,13 @@
 # along with cdist. If not, see <http://www.gnu.org/licenses/>.
 #
 
-if [ -f "$__object/parameter/key" ]; then
-   key="$(cat "$__object/parameter/key")"
-else
-   echo "$__object_id" > "$__object/parameter/key"
-fi
+# set defaults
+key="$(cat "$__object/parameter/key" 2>/dev/null \
+   || echo "$__object_id" | tee "$__object/parameter/key")"
+state="$(cat "$__object/parameter/state" 2>/dev/null \
+   || echo "present" | tee "$__object/parameter/state")"
 
+if [ "$state" = "present" -a ! -f "$__object/parameter/value" ]; then
+   echo "Missing required parameter 'value'" >&2
+   exit 1
+fi 
diff --git a/conf/type/__key_value/parameter/optional b/conf/type/__key_value/parameter/optional
index 06bfde49..483e3192 100644
--- a/conf/type/__key_value/parameter/optional
+++ b/conf/type/__key_value/parameter/optional
@@ -1 +1,3 @@
 key
+value
+state
diff --git a/conf/type/__key_value/parameter/required b/conf/type/__key_value/parameter/required
index 8f4aa53c..3ae10da3 100644
--- a/conf/type/__key_value/parameter/required
+++ b/conf/type/__key_value/parameter/required
@@ -1,3 +1,2 @@
-value
 file
 delimiter
diff --git a/conf/type/__package_pip/explorer/state b/conf/type/__package_pip/explorer/state
index 3a086e58..5be07280 100644
--- a/conf/type/__package_pip/explorer/state
+++ b/conf/type/__package_pip/explorer/state
@@ -35,14 +35,15 @@ else
     pip="pip"
 fi
 
-# which is not posix, but command is :-)
+# If there is no pip, it may get created from somebody else.
+# If it will be created, there is probably no package installed.
 if ! command -v "$pip" >/dev/null 2>&1; then
-    echo "No usable pip found at path \"$pip\"" >&2
-    exit 1
-fi
-
-if "$pip" freeze | grep -i -q "^$name=="; then
-    echo present
-else
     echo absent
+else
+
+    if "$pip" freeze | grep -i -q "^$name=="; then
+        echo present
+    else
+        echo absent
+    fi
 fi
diff --git a/conf/type/__package_pip/man.text b/conf/type/__package_pip/man.text
index bc773763..2a620658 100644
--- a/conf/type/__package_pip/man.text
+++ b/conf/type/__package_pip/man.text
@@ -1,5 +1,5 @@
 cdist-type__package_pip(7)
-=============================
+==========================
 Nico Schottelius <nico-cdist--@--schottelius.org>
 
 
diff --git a/conf/type/__start_on_boot/explorer/state b/conf/type/__start_on_boot/explorer/state
new file mode 100755
index 00000000..ff092a65
--- /dev/null
+++ b/conf/type/__start_on_boot/explorer/state
@@ -0,0 +1,64 @@
+#!/bin/sh
+#
+# 2012 Nico Schottelius (nico-cdist at schottelius.org)
+#
+# This file is part of cdist.
+#
+# cdist is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# cdist is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with cdist. If not, see <http://www.gnu.org/licenses/>.
+#
+#
+# Check whether the given name will be started on boot or not
+#
+
+os=$("$__explorer/os")
+runlevel=$("$__explorer/runlevel")
+name="$__object_id"
+
+
+case "$os" in
+    archlinux)
+        # convert bash array to shell
+        daemons=$(grep ^DAEMONS /etc/rc.conf | sed -e 's/^.*=(//' -e 's/)$//')
+
+        # absent, as long as not found
+        state="absent"
+
+        # iterate, last one wins.
+        for daemon in $daemons; do
+            if [ "$daemon" = "$name" -o "$daemon" = "@${name}" ]; then
+                state="present"
+            elif [ "$daemon" = "!${name}" ]; then
+                state="absent"
+            fi
+        done
+    ;;
+
+    debian|ubuntu)
+        state="present"
+        [ -f "/etc/rc$runlevel.d/S"??"$name" ] || state="absent"
+    ;;
+
+    centos|fedora|owl|redhat)
+        state="present"
+        state=$(chkconfig --level "$runlevel" \"$name\" || echo absent)
+        [ "$state" ] || state="present"
+    ;;
+
+    *)  
+       echo "Unsupported os: $os" >&2
+       exit 1
+    ;;
+esac
+
+echo $state
diff --git a/conf/type/__start_on_boot/gencode-remote b/conf/type/__start_on_boot/gencode-remote
new file mode 100755
index 00000000..be2bd98b
--- /dev/null
+++ b/conf/type/__start_on_boot/gencode-remote
@@ -0,0 +1,89 @@
+#!/bin/sh
+#
+# 2012 Nico Schottelius (nico-cdist at schottelius.org)
+#
+# This file is part of cdist.
+#
+# cdist is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# cdist is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with cdist. If not, see <http://www.gnu.org/licenses/>.
+#
+#
+
+state_should="$(cat "$__object/parameter/state")"
+state_is=$(cat "$__object/explorer/state")
+
+# Nothing todo, go away
+[ "$state_should" = "$state_is" ] && exit 0
+
+os=$(cat "$__global/explorer/os")
+name="$__object_id"
+
+case "$state_should" in
+    present)
+        case "$os" in
+            archlinux)
+                echo "sed -i /etc/rc.conf \'s/^\\(DAEMONS=.*\\))/\\1 $name)/\'"
+            ;;
+            debian|ubuntu)
+                echo "update-rc.d \"$name\" defaults >/dev/null"
+            ;;
+
+#           FIXME: Disabled until the explorer is checked
+#            gentoo)
+#                echo rc-update add \"$name\" default
+#            ;;
+
+            centos|fedora|owl|redhat)
+                echo chkconfig \"$name\" on
+            ;;
+
+            *)
+               echo "Unsupported os: $os" >&2
+               exit 1
+            ;;
+        esac
+    ;;
+
+    absent)
+        case "$os" in
+            archlinux)
+                # Replace a) at the beginning b) in the middle c) end d) only
+                # Support @name as well...makes it more ugly, but well...
+                echo "sed -i /etc/rc.conf -e 's/^\\(DAEMONS=(\\)@\\{0,1\\}$name /\\1/' -e 's/^\\(DAEMONS=(.* \\)@\\{0,1\\}$name \\(.*\\)/\\1\\2/' -e 's/^\\(DAEMONS=(.*\\) @\\{0,1\\}$name)/\\1)/' -e 's/^\\(DAEMONS=(\\)@\\{0,1\\}$name)/\\1)/'"
+            ;;
+            debian|ubuntu)
+                echo update-rc.d -f \"$name\" remove
+            ;;
+
+# FIXME: Disabled until the explorer is checked
+#            gentoo)
+#                echo rc-update del \"$name\"
+#            ;;
+
+            centos|fedora|owl|redhat)
+                echo chkconfig \"$name\" off
+            ;;
+
+            *)
+               echo "Unsupported os: $os" >&2
+               exit 1
+            ;;
+        esac
+ 
+    ;;
+
+    *)
+        echo "Unknown state: $state_should" >&2
+        exit 1
+    ;;
+esac
diff --git a/conf/type/__start_on_boot/man.text b/conf/type/__start_on_boot/man.text
new file mode 100644
index 00000000..0e75c9ab
--- /dev/null
+++ b/conf/type/__start_on_boot/man.text
@@ -0,0 +1,53 @@
+cdist-type__start_on_boot(7)
+============================
+Nico Schottelius <nico-cdist--@--schottelius.org>
+
+
+NAME
+----
+cdist-type__start_on_boot - Manage stuff to be started at boot
+
+
+DESCRIPTION
+-----------
+This cdist type allows you to enable or disable stuff to be started
+at boot of your operating system.
+
+Warning: This type has not been tested intensively and is not fully
+supported (i.e. gentoo and *bsd are not implemented).
+
+
+REQUIRED PARAMETERS
+-------------------
+None.
+
+OPTIONAL PARAMETERS
+-------------------
+state::
+   'present' or 'absent', defaults to 'present'
+
+
+EXAMPLES
+--------
+
+--------------------------------------------------------------------------------
+# Ensure snmpd is started at boot
+__start_on_boot snmpd
+
+# Same, but more explicit
+__start_on_boot snmpd --state present
+
+# Ensure legacy configuration management will not be started
+__start_on_boot puppet --state absent
+--------------------------------------------------------------------------------
+
+
+SEE ALSO
+--------
+- cdist-type(7)
+
+
+COPYING
+-------
+Copyright \(C) 2012 Nico Schottelius. Free use of this software is
+granted under the terms of the GNU General Public License version 3 (GPLv3).
diff --git a/conf/type/__key_value/explorer/value b/conf/type/__start_on_boot/manifest
similarity index 62%
rename from conf/type/__key_value/explorer/value
rename to conf/type/__start_on_boot/manifest
index 3afc7cc5..6b5e1ca7 100755
--- a/conf/type/__key_value/explorer/value
+++ b/conf/type/__start_on_boot/manifest
@@ -1,6 +1,7 @@
 #!/bin/sh
 #
 # 2011 Steven Armstrong (steven-cdist at armstrong.cc)
+# 2012 Nico Schottelius (nico-cdist at schottelius.org)
 #
 # This file is part of cdist.
 #
@@ -17,21 +18,7 @@
 # You should have received a copy of the GNU General Public License
 # along with cdist. If not, see <http://www.gnu.org/licenses/>.
 #
-#
-# Get the current value of key or __NOTSET__ if the key doesn't exist.
-#
-
-if [ -f "$__object/parameter/key" ]; then
-   key="$(cat "$__object/parameter/key")"
-else
-   key="$__object_id"
-fi
-file="$(cat "$__object/parameter/file")"
-delimiter="$(cat "$__object/parameter/delimiter")"
-
-awk -F "$delimiter" '
-BEGIN { found=0 }
-/^'$key'/ { print $2; found=1 }
-END { if (found) exit 0; else exit 1 }' "$file" \
-|| echo "__NOTSET__"
 
+# set default: present, if not setup
+statefile="$__object/parameter/state"
+[ -f "$statefile" ] || echo present > "$statefile"
diff --git a/conf/type/__start_on_boot/parameter/optional b/conf/type/__start_on_boot/parameter/optional
new file mode 100644
index 00000000..ff72b5c7
--- /dev/null
+++ b/conf/type/__start_on_boot/parameter/optional
@@ -0,0 +1 @@
+state
diff --git a/conf/type/__user/gencode-remote b/conf/type/__user/gencode-remote
index 595c7f64..8979c56e 100755
--- a/conf/type/__user/gencode-remote
+++ b/conf/type/__user/gencode-remote
@@ -28,6 +28,7 @@ cd "$__object/parameter"
 if grep -q "^${name}:" "$__object/explorer/passwd"; then
    for property in $(ls .); do
       new_value="$(cat "$property")"
+      unset current_value
 
       file="$__object/explorer/passwd"
 
@@ -36,9 +37,16 @@ if grep -q "^${name}:" "$__object/explorer/passwd"; then
             if $(echo "$new_value" | grep -q '^[0-9][0-9]*$'); then
                field=4
             else
-               # group name
-               file="$__object/explorer/group"
-               field=1
+               # We were passed a group name.  Compare the gid in
+               # the user's /etc/passwd entry with the gid of the
+               # group returned by the group explorer.
+               gid_from_group=$(awk -F: '{ print $3 }' "$__object/explorer/group")
+               gid_from_passwd=$(awk -F: '{ print $4 }' "$file")
+               if [ "$gid_from_group" != "$gid_from_passwd" ]; then
+                  current_value="$gid_from_passwd"
+               else
+                  current_value="$new_value"
+               fi
             fi
          ;;
          password)
@@ -51,8 +59,12 @@ if grep -q "^${name}:" "$__object/explorer/passwd"; then
          uid)     field=3 ;;
       esac
 
-      export field
-      current_value="$(awk -F: '{ print $ENVIRON["field"] }' < "$file")"
+      # If we haven't already set $current_value above, pull it from the
+      # appropriate file/field.
+      if [ -z "$current_value" ]; then
+         export field
+         current_value="$(awk -F: '{ print $ENVIRON["field"] }' < "$file")"
+      fi
 
       if [ "$new_value" != "$current_value" ]; then
          set -- "$@" "--$property" \'$new_value\'
diff --git a/doc/changelog b/doc/changelog
index 7e070cc5..ab006435 100644
--- a/doc/changelog
+++ b/doc/changelog
@@ -4,11 +4,22 @@ Changelog
 	* Changes are always commented with their author in (braces)
 	* Exception: No braces means author == Nico Schottelius
 
-2.0.7:
+2.0.8:
+	* Cleanup: Better hint to source of error
+	* Cleanup: Do not output failing script, but path to script only
+	* Cleanup: Remove support for __debug variable in manifests (Type != Core
+		debugging)
+	* Feature Core: Support boolean parameters (Steven Armstrong)
+
+2.0.7: 2012-02-13
 	* Bugfix __file: Use chmod after chown/chgrp (Matt Coddington)
 	* Bugfix __user: Correct shadow field in explorer (Matt Coddington)
 	* Bugfix __link: Properly handle existing links (Steven Armstrong)
+	* Bugfix __key_value: More robust implementation (Steven Armstrong)
+	* Bugfix __user: Fix for changing a user's group by name (Matt Coddington)
 	* New Type: __package_pip
+	* Bugfix/Cleanup: Correctly allow Object ID to start and end with /, but
+		not contain //.
 
 2.0.6: 2012-01-28
 	* Bugfix __apt_ppa:
diff --git a/doc/dev/logs/2012-02-10.object_id-and-slashes b/doc/dev/logs/2012-02-10.object_id-and-slashes
new file mode 100644
index 00000000..de46a1f8
--- /dev/null
+++ b/doc/dev/logs/2012-02-10.object_id-and-slashes
@@ -0,0 +1,18 @@
+__typename /foo/bar # possible, usual use case
+require="__a//b" __typename /foo/bar # possible and happens often for __a/$id in loops
+
+__typename /foo/bar/ # trailing slash will be stripped, can be documented
+
+__typename /foo//bar//baz # // will be converted to / implicitly through fs; error prone; disallow
+
+require="__a//b//c" __typename # // will be converted to / implicitly through fs; error prone; disallow
+
+
+Solution:
+
+    1) allow require __a//b: type __a, object id /b
+        => strip first slash of object id, as we do in non-dep-mode
+    2) allow _one_ trailing /: __type /foo/bar/ and require="__foo/abc/"
+        => strip one leading slash of object id
+    3) disallow // within object id
+    4) disallow starting or ending / after 1) and 2)
diff --git a/doc/dev/logs/2012-02-13.dependencies b/doc/dev/logs/2012-02-13.dependencies
new file mode 100644
index 00000000..3b0f3f21
--- /dev/null
+++ b/doc/dev/logs/2012-02-13.dependencies
@@ -0,0 +1,23 @@
+possible dependencies:
+
+    - unix pattern __foo/*
+    - object: __foo//bar, __foo/bar
+    - singleton with object_id: __foo/singleton
+    - singleton without object_id: __foo/
+
+solving dependencies:
+
+    solve_dep(object, run_list):
+        - list = [me]
+        - if status == IN_DEPENDENCY:
+            fail: circular dependency
+        - status = IN_DEPENDENCY
+        - create_list_of_deps(object)
+            - try pattern expansion
+        - for each dependency:
+            if object does not exist:
+                fail
+            else:
+                list.append(solve_dep(object, run_list)):
+        - status == IN_LIST
+        - return [me, dependencies [, dependencies of dependencies]]
diff --git a/doc/dev/logs/2012-02-15.steven b/doc/dev/logs/2012-02-15.steven
new file mode 100644
index 00000000..2d513728
--- /dev/null
+++ b/doc/dev/logs/2012-02-15.steven
@@ -0,0 +1,132 @@
+- parameter/setting default from manifest
+    ==> BRANCH[feature_default_parameters],
+    ==> PERSON[Steven or Nico]
+    ==> PROPOSAL(1)
+    - current bug
+    - proposal 1: parameter/default/$name (for optional ones)
+        - new way
+        - catches --state absent|present
+        - needs changes of types
+        - also possible for explorer
+        - support for it in core?
+            - handling of ${o} $o "$o" ?
+            - handling which variables?
+            - introduction of "templating language"
+                - aka macros
+                - possible problems:
+                    - inconsistency
+                    - redoing shell functionality
+                    - raising expectations for more templating from users
+                - possible benefit
+                    - no need for eval
+                    - once in core, not everytime in type
+                        - OTOH: one extra word. 
+                        - a=$(cat $__object/parameter/name) vs. $(eval $(cat $__object/parameter/name))
+        - only possible for static defaults
+            - --name overrides name not possible vs. object_id
+                - Is this the only case????
+                    - if yes: don't care.
+                - possible solution:
+                    - echo '/$__object_id' > typename/parameter/default/name
+                    - eval $(cat $__object/parameter/name)
+                        - probably allows code injection
+                            - is possible anyway???
+                            - $(cat /etc/shadow)
+                        - other eval side effects???
+                            - none: go for it
+                            - some: have headache
+                            - many: don't do
+    - proposal 2: 2 dbs (user input vs. stuff changable by type)
+        - explicit 2nd db [parameter_user and parameter/]
+        - not very clean (both agreed)
+    - proposal 3: parameter are read-only
+        - breaks current types (in core probably elsewhere)
+        - can't enforce, but user is on his own => breaks, her problem
+        + clean seperation between core and type (nico)
+            - parameter belongs to type not core (steven)
+    - proposal 4: core ignores changes in parameter/* of object
+        - implicit 2nd db [see automagic below]
+        - steven+++
+        - does not work with divergent emulator not being in core
+            - because emulators primary db __is__ fs.
+
+1 manifest:
+
+__foo bar == emulator
+echo present > $__global/object/__foo/bar/parameter/state
+
+# fails
+__foo bar == emulator
+
+! automagic / filesystem
+    ! fsproperty:
+        - kill, write explicitly to disk
+    ==> BRANCH[cleanup_fsproperty]
+    ==> PERSON[Steven]
+    ==> PROPOSAL(just cleanup)
+
+    - implicit/automatic writes/read to fs
+        - explicit interfaces are better then implicit
+        - same problems as in cdist 1.x to 2.x move! (environment!)
+    - format on disk should not change/dictate code flow
+        - degrade python to shell (nico++! steven--)
+            - user should not care about python, ruby, .net or ASM implementation (steven++ nico++)
+
+    ? proposal 1: diverge emulator / core
+        - emulator verifies input
+        - emulator writes to fs
+        - core reads/syncs from/to fs before passing control to user
+
+    ? proposal 2: emulator is dumb and passes data to core
+        - core creates objects
+        - no fs involved
+        - core reads/syncs from/to fs before passing control to user
+        - passing:
+            - full objects via pickle
+            - parameters only
+            - how???
+                - unix socket?
+                    - not everywhere possible?
+                - tcp / ip
+                    - not everywhere possible
+                        - chroot / local only
+                - rfc 1149
+                    - not everywhere possible
+                        - missing avian carriers
+                - 0mq
+                    - not everywhere possible
+                        - not installed
+                - shm (ipcs and friends)
+                    - not everywhere possible
+                        - no /dev/shm, different libraries? cleanups needed...
+                - what speaks against FS?
+                    - emulator_input/.../
+
+                - nico: to fancy probably
+
+! boolean implementation
+    ==> BRANCH[feature_boolean_parameter]
+    ==> PERSON[Steven]
+    - nico: 
+        - parameters/boolean: document
+        - argparse changes (consider parameters/boolean)
+            - create 
+    - can be implemented with changes in emulator
+        - use store_true, del if false => never seen by core
+    - INDEPENDENT INDEPENDT OF FS.PROPERTIES!!111111!
+
+- emulator:
+    - how much integrated into core
+        - also: using CdistObject????
+    - dependency on filesystem: good (nico) | bad (steven)
+
+- singleton / support without object_id
+    - not discussed
+
+- __apt_ppa:
+    ==> BRANCH[bugfix_do_not_change_state_in_manifest]
+    ==> PERSON[Nico]
+
+- logging divergent between emulator / core
+    - no problem (nico)
+    - may be helpful (steven)
diff --git a/doc/dev/releasechecklist b/doc/dev/releasechecklist
index 19ab7b18..eba81dc0 100755
--- a/doc/dev/releasechecklist
+++ b/doc/dev/releasechecklist
@@ -15,11 +15,21 @@ changelog_version=$(grep '^[[:digit:]]' doc/changelog | head -n1 | sed 's/:.*//'
 #git_version=$(git describe)
 lib_version=$(grep ^VERSION lib/cdist/__init__.py | sed -e 's/.*= //' -e 's/"//g')
 
+# get date
+date_today="$(date +%Y-%m-%d)"
+date_changelog=$(grep '^[[:digit:]]' doc/changelog | head -n1 | sed 's/.*: //')
+
 echo "Ensure you fixed/prepared version files: $files"
 echo "changelog: $changelog_version"
 #echo "git: $git_version"
 echo "lib: $lib_version"
 
+if [ "$date_today" != "$date_changelog" ]; then
+    echo "Messed up date, not releasing:"
+    echo "Changelog: $date_changelog"
+    exit 1
+fi
+
 if [ "$lib_version" != "$changelog_version" ]; then
     echo "Messed up versions, not releasing"
     exit 1
diff --git a/doc/dev/todo/TAKEME b/doc/dev/todo/TAKEME
index 95bda7fb..b40936f6 100644
--- a/doc/dev/todo/TAKEME
+++ b/doc/dev/todo/TAKEME
@@ -35,3 +35,5 @@ USER INTERFACE
 TYPES
 ------
 - Add testing framework (proposed by Evax Software)
+- __user
+   add option to include --create-home
diff --git a/doc/dev/todo/niconext b/doc/dev/todo/niconext
index 4db98d58..bead6d72 100644
--- a/doc/dev/todo/niconext
+++ b/doc/dev/todo/niconext
@@ -1,11 +1,13 @@
-- __file/foo/bar//bar
-    - fails later
+- introduce default parameters
+
+- cleanup object_id handling
+    - have a look at singletons
 
-- __user
-   add option to include --create-home
 - ensure that all types, which support --state support
     present and absent (consistent look and feel)
 
+--------------------------------------------------------------------------------
+
 - update/create docs
     - cdist-cache::
         How to get use information about the hosts we have been working on [advanced]
diff --git a/doc/man/cdist-reference.text.sh b/doc/man/cdist-reference.text.sh
index 898771c7..a76e7941 100755
--- a/doc/man/cdist-reference.text.sh
+++ b/doc/man/cdist-reference.text.sh
@@ -49,10 +49,10 @@ The following global explorers are available:
 
 eof
 (
-   cd ../../conf/explorer
-   for explorer in *; do
-      echo "- $explorer"
-   done
+    cd ../../conf/explorer
+    for explorer in *; do
+       echo "- $explorer"
+    done
 )
 
 cat << eof 
@@ -62,77 +62,80 @@ PATHS
 If not specified otherwise, all paths are relative to the checkout directory.
 
 conf/::
-   Contains the (static) configuration like manifests, types and explorers.  
+    Contains the (static) configuration like manifests, types and explorers.  
 
 conf/manifest/init::
-   This is the central entry point used by cdist-manifest-init(1).
-   It is an executable (+x bit set) shell script that can use
-   values from the explorers to decide which configuration to create
-   for the specified target host.
-   It should be primary used to define mapping from configurations to hosts.
+    This is the central entry point used by cdist-manifest-init(1).
+    It is an executable (+x bit set) shell script that can use
+    values from the explorers to decide which configuration to create
+    for the specified target host.
+    It should be primary used to define mapping from configurations to hosts.
 
 conf/manifest/*::
-   All other files in this directory are not directly used by cdist, but you
-   can seperate configuration mappings, if you have a lot of code in the
-   manifest/init file. This may also be helpful to have different admins
-   maintain different groups of hosts.
+    All other files in this directory are not directly used by cdist, but you
+    can seperate configuration mappings, if you have a lot of code in the
+    manifest/init file. This may also be helpful to have different admins
+    maintain different groups of hosts.
 
 conf/explorer/<name>::
-   Contains explorers to be run on the target hosts, see cdist-explorer(7).
+    Contains explorers to be run on the target hosts, see cdist-explorer(7).
 
 conf/type/::
-   Contains all available types, which are used to provide
-   some kind of functionality. See cdist-type(7).
+    Contains all available types, which are used to provide
+    some kind of functionality. See cdist-type(7).
 
 conf/type/<name>/::
-   Home of the type <name>.
+    Home of the type <name>.
 
-   This directory is referenced by the variable __type (see below).
+    This directory is referenced by the variable __type (see below).
 
 conf/type/<name>/man.text::
-   Manpage in Asciidoc format (required for inclusion into upstream)
+    Manpage in Asciidoc format (required for inclusion into upstream)
 
 conf/type/<name>/manifest::
-   Used to generate additional objects from a type.
+    Used to generate additional objects from a type.
 
 conf/type/<name>/gencode-local::
-   Used to generate code to be executed on the server.
+    Used to generate code to be executed on the server.
 
 conf/type/<name>/gencode-remote::
-   Used to generate code to be executed on the client.
+    Used to generate code to be executed on the client.
 
-conf/type/<name>/parameters/required::
-   Parameters required by type, \n seperated list.
+conf/type/<name>/parameter/required::
+    Parameters required by type, \n seperated list.
 
-conf/type/<name>/parameters/optional::
-   Parameters optionally accepted by type, \n seperated list.
+conf/type/<name>/parameter/optional::
+    Parameters optionally accepted by type, \n seperated list.
+
+conf/type/<name>/parameter/boolean::
+   Boolean parameters accepted by type, \n seperated list.
 
 conf/type/<name>/explorer::
-   Location of the type specific explorers.
-   This directory is referenced by the variable __type_explorer (see below).
-   See cdist-explorer(7).
+    Location of the type specific explorers.
+    This directory is referenced by the variable __type_explorer (see below).
+    See cdist-explorer(7).
 
 out/::
-   This directory contains output of cdist and is usually located
-   in a temporary directory and thus will be removed after the run.
-   This directory is referenced by the variable __global (see below).
+    This directory contains output of cdist and is usually located
+    in a temporary directory and thus will be removed after the run.
+    This directory is referenced by the variable __global (see below).
 
 out/explorer::
-   Output of general explorers.
+    Output of general explorers.
 
 out/object::
-   Objects created for the host.
+    Objects created for the host.
 
 out/object/<object>::
-   Contains all object specific information.
-   This directory is referenced by the variable __object (see below).
+    Contains all object specific information.
+    This directory is referenced by the variable __object (see below).
 
 out/object/<object>/explorers::
-   Output of type specific explorers, per object.
+    Output of type specific explorers, per object.
 
 tmp_dir::
-   A tempdir and a tempfile is used by cdist internally,
-   which will be removed when the scripts end automatically.
+    A tempdir and a tempfile is used by cdist internally,
+    which will be removed when the scripts end automatically.
 
 TYPES
 -----
@@ -141,13 +144,13 @@ The following types are available:
 eof
 
 for type in man7/cdist-type__*.text; do
-   no_dir="${type#man7/}";
-   no_type="${no_dir#cdist-type}";
-   name="${no_type%.text}";
-   name_no_underline="$(echo $name | sed 's/^__/\\__/g')"
-   man="${no_dir%.text}(7)"
+    no_dir="${type#man7/}";
+    no_type="${no_dir#cdist-type}";
+    name="${no_type%.text}";
+    name_no_underline="$(echo $name | sed 's/^__/\\__/g')"
+    man="${no_dir%.text}(7)"
 
-   echo "- $name_no_underline" "($man)"
+    echo "- $name_no_underline" "($man)"
 done
 
 cat << eof
@@ -159,43 +162,47 @@ For object to object communication and tests, the following paths are
 usable within a object directory:
 
 changed::
-   This empty file exists in an object directory, if the object has
-   code to be excuted (either remote or local)
+    This empty file exists in an object directory, if the object has
+    code to be excuted (either remote or local)
 
 
 ENVIRONMENT VARIABLES
 ---------------------
 __explorer::
-   Directory that contains all global explorers.
-   Available for: explorer
+    Directory that contains all global explorers.
+    Available for: explorer, type explorer
 __manifest::
-   Directory that contains the initial manifest.
-   Available for: initial manifest
+    Directory that contains the initial manifest.
+    Available for: initial manifest
 __global::
-   Directory that contains generic output like explorer.
-   Available for: initial manifest, type manifest, type gencode
+    Directory that contains generic output like explorer.
+    Available for: initial manifest, type manifest, type gencode
 __object::
-   Directory that contains the current object.
-   Available for: type manifest, type explorer, type gencode
+    Directory that contains the current object.
+    Available for: type manifest, type explorer, type gencode
 __object_id::
-   The type unique object id.
-   Available for: type manifest, type explorer, type gencode
-   Note: The leading "/" will always be stripped.
+    The type unique object id.
+    Available for: type manifest, type explorer, type gencode
+
+    Note: The leading and the trailing "/" will always be stripped (caused by
+    the filesystem database and ensured by the core).
+
+    Note: Double slashes ("//") will not be fixed and result in an error.
 __self::
-   DEPRECATED: Same as __object_name, do not use anymore, use __object_name instead.
-   Will be removed in cdist 3.x.
+    DEPRECATED: Same as __object_name, do not use anymore, use __object_name instead.
+    Will be removed in cdist 3.x.
 __object_name::
-   The full qualified name of the current object.
-   Available for: type manifest, type explorer, type gencode
+    The full qualified name of the current object.
+    Available for: type manifest, type explorer, type gencode
 __target_host::
-   The host we are deploying to.
-   Available for: initial manifest, type manifest, type gencode
+    The host we are deploying to.
+    Available for: explorer, initial manifest, type explorer, type manifest, type gencode
 __type::
-   Path to the current type.
-   Available for: type manifest, type gencode
+    Path to the current type.
+    Available for: type manifest, type gencode
 __type_explorer::
-   Directory that contains the type explorers.
-   Available for: type explorer
+    Directory that contains the type explorers.
+    Available for: type explorer
 
 
 SEE ALSO
diff --git a/doc/man/man7/cdist-hacker.text b/doc/man/man7/cdist-hacker.text
index 9bdf63d4..646439a3 100644
--- a/doc/man/man7/cdist-hacker.text
+++ b/doc/man/man7/cdist-hacker.text
@@ -61,12 +61,19 @@ including it.
 
 HOW TO SUBMIT A NEW TYPE
 ------------------------
+For detailled information about types, see cdist-type(7).
+
 Submitting a type works as described above, with the additional requirement
 that a corresponding manpage named man.text in asciidoc format with
 the manpage-name "cdist-type__NAME" is included in the type directory
 AND asciidoc is able to compile it (i.e. do NOT have to many "=" in the second
 line).
 
+Warning: Submitting "exec" or "run" types that simply echo their parameter in
+gencode* will not be accepted, because they are of no use. Every type can output
+code and thus such a type introduces redundant functionality that is given by
+core cdist already.
+
 
 SEE ALSO
 --------
diff --git a/doc/man/man7/cdist-type.text b/doc/man/man7/cdist-type.text
index 48d412f1..1147511e 100644
--- a/doc/man/man7/cdist-type.text
+++ b/doc/man/man7/cdist-type.text
@@ -40,7 +40,7 @@ A list of supported types can be found in the cdist-reference(7) manpage.
 
 SINGLETON TYPES
 ---------------
-If a type is flagged as a singleton, it may be used only 
+If a type is flagged as a singleton, it may be used only
 once per host. This is useful for types which can be used only once on a
 system. Singleton types do not take an object name as argument.
 
@@ -72,15 +72,42 @@ To begin a new type, just create the directory **conf/type/__NAME**.
 
 DEFINING PARAMETERS
 -------------------
-Every type consists of optional and required parameters, which must
-be created in a newline seperated file in ***parameters/required*** and
-***parameters/optional***. If either or both missing, the type will have
-no required, no optional or no parameters at all.
+Every type consists of required, optional and boolean parameters, which must
+be created in a newline seperated file in ***parameter/required***,
+***parameter/optional*** and ***parameter/boolean***. If either is missing,
+the type will have no required, no optional, no boolean or no parameters at
+all.
 
 Example:
 --------------------------------------------------------------------------------
 echo servername >> conf/type/__nginx_vhost/parameter/required
 echo logdirectory >> conf/type/__nginx_vhost/parameter/optional
+echo use_ssl >> conf/type/__nginx_vhost/parameter/boolean
+--------------------------------------------------------------------------------
+
+
+USING PARAMETERS
+----------------
+The parameters given to a type can be accessed and used in all type scripts
+(e.g manifest, gencode-*, explorer/*). Note that boolean parameters are
+represented by file existence. File exists -> True,
+file does not exist -> False
+
+Example: (e.g. in conf/type/__nginx_vhost/manifest)
+--------------------------------------------------------------------------------
+# required parameter
+servername="$(cat "$__object/parameter/servername")"
+
+# optional parameter
+if [ -f "$__object/parameter/logdirectory" ]; then
+   logdirectory="$(cat "$__object/parameter/logdirectory")"
+fi
+
+# boolean parameter
+if [ -f "$__object/parameter/use_ssl" ]; then
+   # file exists -> True
+   # do some fancy ssl stuff
+fi
 --------------------------------------------------------------------------------
 
 
@@ -116,7 +143,7 @@ SINGLETON - ONLY INSTANCE ONLY
 ------------------------------
 If you want to ensure that a type can only be used once per target, you can
 mark it as a singleton: Just create the (empty) file "singleton" in your type
-directory: 
+directory:
 
 --------------------------------------------------------------------------------
 touch conf/type/__NAME/singleton
@@ -128,7 +155,7 @@ This will also change the way your type must be called:
 __YOURTYPE --parameter value
 --------------------------------------------------------------------------------
 
-As you can see, the object ID is omitted, because it does not make any sense, 
+As you can see, the object ID is omitted, because it does not make any sense,
 if your type can be used only once.
 
 
diff --git a/lib/cdist/__init__.py b/lib/cdist/__init__.py
index 664b6456..4742a937 100644
--- a/lib/cdist/__init__.py
+++ b/lib/cdist/__init__.py
@@ -19,7 +19,7 @@
 #
 #
 
-VERSION     = "2.0.6"
+VERSION     = "2.0.7"
 
 BANNER = """
              ..          .       .x+=:.        s
@@ -44,15 +44,17 @@ class Error(Exception):
     """Base exception class for this project"""
     pass
 
+class CdistObjectError(Error):
+    """Something went wrong with an object"""
+    
+    def __init__(self, cdist_object, message):
+        self.name = cdist_object.name
+        self.source = " ".join(cdist_object.source)
+        self.message = message
 
-class MissingEnvironmentVariableError(Error):
-    """Raised when a required environment variable is not set."""
-
-    def __init__(self, name):
-        self.name = name
 
     def __str__(self):
-        return 'Missing required environment variable: ' + str(self.name)
+        return '%s: %s (defined at %s)' % (self.name, self.message, self.source)
 
 def file_to_list(filename):
     """Return list from \n seperated file"""
diff --git a/lib/cdist/config_install.py b/lib/cdist/config_install.py
index 542f2024..7cce240e 100644
--- a/lib/cdist/config_install.py
+++ b/lib/cdist/config_install.py
@@ -89,9 +89,9 @@ class ConfigInstall(object):
         new_objects_created = True
         while new_objects_created:
             new_objects_created = False
-            for cdist_object in core.Object.list_objects(self.local.object_path,
+            for cdist_object in core.CdistObject.list_objects(self.local.object_path,
                                                          self.local.type_path):
-                if cdist_object.state == core.Object.STATE_PREPARED:
+                if cdist_object.state == core.CdistObject.STATE_PREPARED:
                     self.log.debug("Skipping re-prepare of object %s", cdist_object)
                     continue
                 else:
@@ -103,16 +103,16 @@ class ConfigInstall(object):
         self.log.info("Running manifest and explorers for " + cdist_object.name)
         self.explorer.run_type_explorers(cdist_object)
         self.manifest.run_type_manifest(cdist_object)
-        cdist_object.state = core.Object.STATE_PREPARED
+        cdist_object.state = core.CdistObject.STATE_PREPARED
 
     def object_run(self, cdist_object):
         """Run gencode and code for an object"""
         self.log.debug("Trying to run object " + cdist_object.name)
-        if cdist_object.state == core.Object.STATE_DONE:
+        if cdist_object.state == core.CdistObject.STATE_DONE:
             # TODO: remove once we are sure that this really never happens.
             raise cdist.Error("Attempting to run an already finished object: %s", cdist_object)
 
-        cdist_type = cdist_object.type
+        cdist_type = cdist_object.cdist_type
 
         # Generate
         self.log.info("Generating and executing code for " + cdist_object.name)
@@ -130,13 +130,13 @@ class ConfigInstall(object):
 
         # Mark this object as done
         self.log.debug("Finishing run of " + cdist_object.name)
-        cdist_object.state = core.Object.STATE_DONE
+        cdist_object.state = core.CdistObject.STATE_DONE
 
     def stage_run(self):
         """The final (and real) step of deployment"""
         self.log.info("Generating and executing code")
 
-        objects = core.Object.list_objects(
+        objects = core.CdistObject.list_objects(
             self.local.object_path,
             self.local.type_path)
 
diff --git a/lib/cdist/core/__init__.py b/lib/cdist/core/__init__.py
index c61c659b..66ee00a5 100644
--- a/lib/cdist/core/__init__.py
+++ b/lib/cdist/core/__init__.py
@@ -19,11 +19,11 @@
 #
 #
 
-from cdist.core.type import Type
-from cdist.core.type import NoSuchTypeError
-from cdist.core.object import Object
-from cdist.core.object import IllegalObjectIdError
-from cdist.core.object import OBJECT_MARKER
-from cdist.core.explorer import Explorer
-from cdist.core.manifest import Manifest
-from cdist.core.code import Code
+from cdist.core.cdist_type      import CdistType
+from cdist.core.cdist_type      import NoSuchTypeError
+from cdist.core.cdist_object    import CdistObject
+from cdist.core.cdist_object    import IllegalObjectIdError
+from cdist.core.cdist_object    import OBJECT_MARKER
+from cdist.core.explorer        import Explorer
+from cdist.core.manifest        import Manifest
+from cdist.core.code            import Code
diff --git a/lib/cdist/core/object.py b/lib/cdist/core/cdist_object.py
similarity index 74%
rename from lib/cdist/core/object.py
rename to lib/cdist/core/cdist_object.py
index da2f21a6..e12bcfbd 100644
--- a/lib/cdist/core/object.py
+++ b/lib/cdist/core/cdist_object.py
@@ -1,7 +1,7 @@
 # -*- coding: utf-8 -*-
 #
 # 2011 Steven Armstrong (steven-cdist at armstrong.cc)
-# 2011 Nico Schottelius (nico-cdist at schottelius.org)
+# 2011-2012 Nico Schottelius (nico-cdist at schottelius.org)
 #
 # This file is part of cdist.
 #
@@ -42,7 +42,7 @@ class IllegalObjectIdError(cdist.Error):
         return '%s: %s' % (self.message, self.object_id)
 
 
-class Object(object):
+class CdistObject(object):
     """Represents a cdist object.
 
     All interaction with objects in cdist should be done through this class.
@@ -61,7 +61,7 @@ class Object(object):
         """Return a list of object instances"""
         for object_name in cls.list_object_names(object_base_path):
             type_name, object_id = cls.split_name(object_name)
-            yield cls(cdist.core.Type(type_base_path, type_name), object_base_path, object_id=object_id)
+            yield cls(cdist.core.CdistType(type_base_path, type_name), object_base_path, object_id=object_id)
 
     @classmethod
     def list_type_names(cls, object_base_path):
@@ -96,30 +96,58 @@ class Object(object):
         """
         return os.path.join(type_name, object_id)
 
-    @staticmethod
-    def validate_object_id(object_id):
+    def validate_object_id(self):
+        # FIXME: also check that there is no object ID when type is singleton?
+
         """Validate the given object_id and raise IllegalObjectIdError if it's not valid.
         """
-        if object_id:
-            if object_id.startswith('/'):
-                raise IllegalObjectIdError(object_id, 'object_id may not start with /')
-            if OBJECT_MARKER in object_id.split(os.sep):
-                raise IllegalObjectIdError(object_id, 'object_id may not contain \'%s\'' % OBJECT_MARKER)
+        if self.object_id:
+            if OBJECT_MARKER in self.object_id.split(os.sep):
+                raise IllegalObjectIdError(self.object_id, 'object_id may not contain \'%s\'' % OBJECT_MARKER)
+            if '//' in self.object_id:
+                raise IllegalObjectIdError(self.object_id, 'object_id may not contain //')
+
+        # If no object_id and type is not singleton => error out
+        if not self.object_id and not self.cdist_type.is_singleton:
+            raise IllegalObjectIdError(self.object_id,
+                "Missing object_id and type is not a singleton.")
 
     def __init__(self, cdist_type, base_path, object_id=None):
-        self.validate_object_id(object_id)
-        self.type = cdist_type # instance of Type
+        self.cdist_type = cdist_type # instance of Type
         self.base_path = base_path
         self.object_id = object_id
-        self.name = self.join_name(self.type.name, self.object_id)
-        self.path = os.path.join(self.type.path, self.object_id, OBJECT_MARKER)
+
+        self.validate_object_id()
+        self.sanitise_object_id()
+
+        self.name = self.join_name(self.cdist_type.name, self.object_id)
+        self.path = os.path.join(self.cdist_type.path, self.object_id, OBJECT_MARKER)
         self.absolute_path = os.path.join(self.base_path, self.path)
         self.code_local_path = os.path.join(self.path, "code-local")
         self.code_remote_path = os.path.join(self.path, "code-remote")
         self.parameter_path = os.path.join(self.path, "parameter")
 
+    def object_from_name(self, object_name):
+        """Convenience method for creating an object instance from an object name.
+
+        Mainly intended to create objects when resolving requirements.
+
+        e.g:
+            <CdistObject __foo/bar>.object_from_name('__other/object') -> <CdistObject __other/object>
+
+        """
+
+        base_path = self.base_path
+        type_path = self.cdist_type.base_path
+
+        type_name, object_id = self.split_name(object_name)
+
+        cdist_type = self.cdist_type.__class__(type_path, type_name)
+
+        return self.__class__(cdist_type, base_path, object_id=object_id)
+
     def __repr__(self):
-        return '<Object %s>' % self.name
+        return '<CdistObject %s>' % self.name
 
     def __eq__(self, other):
         """define equality as 'name is the same'"""
@@ -128,23 +156,23 @@ class Object(object):
     def __hash__(self):
         return hash(self.name)
 
-
     def __lt__(self, other):
         return isinstance(other, self.__class__) and self.name < other.name
 
-    def object_from_name(self, object_name):
-        """Convenience method for creating an object instance from an object name.
-
-        Mainly intended to create objects when resolving requirements.
-
-        e.g:
-            <Object __foo/bar>.object_from_name('__other/object') -> <Object __other/object>
-
+    def sanitise_object_id(self):
         """
-        type_path = self.type.base_path
-        base_path = self.base_path
-        type_name, object_id = self.split_name(object_name)
-        return self.__class__(self.type.__class__(type_path, type_name), base_path, object_id=object_id)
+        Remove leading and trailing slash (one only)
+        """
+
+        # Allow empty object id for singletons
+        if self.object_id:
+            # Remove leading slash
+            if self.object_id[0] == '/':
+                self.object_id = self.object_id[1:]
+
+            # Remove trailing slash
+            if self.object_id[-1] == '/':
+                self.object_id = self.object_id[:-1]
 
     # FIXME: still needed?
     @property
diff --git a/lib/cdist/core/type.py b/lib/cdist/core/cdist_type.py
similarity index 86%
rename from lib/cdist/core/type.py
rename to lib/cdist/core/cdist_type.py
index 20365b8d..1d2472c4 100644
--- a/lib/cdist/core/type.py
+++ b/lib/cdist/core/cdist_type.py
@@ -34,7 +34,7 @@ class NoSuchTypeError(cdist.Error):
         return "Type '%s' does not exist at %s" % (self.type_path, self.type_absolute_path)
 
 
-class Type(object):
+class CdistType(object):
     """Represents a cdist type.
 
     All interaction with types in cdist should be done through this class.
@@ -61,7 +61,7 @@ class Type(object):
         # name is second argument
         name = args[1]
         if not name in cls._instances:
-            instance = super(Type, cls).__new__(cls)
+            instance = super(CdistType, cls).__new__(cls)
             cls._instances[name] = instance
             # return instance so __init__ is called
         return cls._instances[name]
@@ -82,9 +82,10 @@ class Type(object):
         self.__explorers = None
         self.__required_parameters = None
         self.__optional_parameters = None
+        self.__boolean_parameters = None
 
     def __repr__(self):
-        return '<Type %s>' % self.name
+        return '<CdistType %s>' % self.name
 
     def __eq__(self, other):
         return isinstance(other, self.__class__) and self.name == other.name
@@ -144,3 +145,19 @@ class Type(object):
             finally:
                 self.__optional_parameters = parameters
         return self.__optional_parameters
+
+    @property
+    def boolean_parameters(self):
+        """Return a list of boolean parameters"""
+        if not self.__boolean_parameters:
+            parameters = []
+            try:
+                with open(os.path.join(self.absolute_path, "parameter", "boolean")) as fd:
+                    for line in fd:
+                        parameters.append(line.strip())
+            except EnvironmentError:
+                # error ignored
+                pass
+            finally:
+                self.__boolean_parameters = parameters
+        return self.__boolean_parameters
diff --git a/lib/cdist/core/code.py b/lib/cdist/core/code.py
index 51912559..2ffef9cf 100644
--- a/lib/cdist/core/code.py
+++ b/lib/cdist/core/code.py
@@ -92,17 +92,14 @@ class Code(object):
             '__global': self.local.out_path,
         }
 
-        if log.getEffectiveLevel() == logging.DEBUG:
-            self.env.update({'__debug': "yes" })
-
     def _run_gencode(self, cdist_object, which):
-        cdist_type = cdist_object.type
+        cdist_type = cdist_object.cdist_type
         script = os.path.join(self.local.type_path, getattr(cdist_type, 'gencode_%s_path' % which))
         if os.path.isfile(script):
             env = os.environ.copy()
             env.update(self.env)
             env.update({
-                '__type': cdist_object.type.absolute_path,
+                '__type': cdist_object.cdist_type.absolute_path,
                 '__object': cdist_object.absolute_path,
                 '__object_id': cdist_object.object_id,
                 '__object_name': cdist_object.name,
diff --git a/lib/cdist/core/explorer.py b/lib/cdist/core/explorer.py
index 01c4c81d..d49b7ac4 100644
--- a/lib/cdist/core/explorer.py
+++ b/lib/cdist/core/explorer.py
@@ -73,8 +73,6 @@ class Explorer(object):
             '__target_host': self.target_host,
             '__explorer': self.remote.global_explorer_path,
         }
-        if self.log.getEffectiveLevel() == logging.DEBUG:
-            self.env.update({'__debug': "yes" })
         self._type_explorers_transferred = []
 
     ### global
@@ -121,15 +119,28 @@ class Explorer(object):
         in the object.
 
         """
-        self.log.debug("Transfering type explorers for type: %s", cdist_object.type)
-        self.transfer_type_explorers(cdist_object.type)
+        self.log.debug("Transfering type explorers for type: %s", cdist_object.cdist_type)
+        self.transfer_type_explorers(cdist_object.cdist_type)
         self.log.debug("Transfering object parameters for object: %s", cdist_object.name)
         self.transfer_object_parameters(cdist_object)
-        for explorer in self.list_type_explorer_names(cdist_object.type):
+        for explorer in self.list_type_explorer_names(cdist_object.cdist_type):
             output = self.run_type_explorer(explorer, cdist_object)
             self.log.debug("Running type explorer '%s' for object '%s'", explorer, cdist_object.name)
             cdist_object.explorers[explorer] = output
 
+    def run_type_explorer(self, explorer, cdist_object):
+        """Run the given type explorer for the given object and return it's output."""
+        cdist_type = cdist_object.cdist_type
+        env = self.env.copy()
+        env.update({
+            '__object': os.path.join(self.remote.object_path, cdist_object.path),
+            '__object_id': cdist_object.object_id,
+            '__object_fq': cdist_object.path,
+            '__type_explorer': os.path.join(self.remote.type_path, cdist_type.explorer_path)
+        })
+        script = os.path.join(self.remote.type_path, cdist_type.explorer_path, explorer)
+        return self.remote.run_script(script, env=env, return_output=True)
+
     def transfer_type_explorers(self, cdist_type):
         """Transfer the type explorers for the given type to the remote side."""
         if cdist_type.explorers:
@@ -149,16 +160,3 @@ class Explorer(object):
             destination = os.path.join(self.remote.object_path, cdist_object.parameter_path)
             self.remote.mkdir(destination)
             self.remote.transfer(source, destination)
-
-    def run_type_explorer(self, explorer, cdist_object):
-        """Run the given type explorer for the given object and return it's output."""
-        cdist_type = cdist_object.type
-        env = self.env.copy()
-        env.update({
-            '__object': os.path.join(self.remote.object_path, cdist_object.path),
-            '__object_id': cdist_object.object_id,
-            '__object_fq': cdist_object.path,
-            '__type_explorer': os.path.join(self.remote.type_path, cdist_type.explorer_path)
-        })
-        script = os.path.join(self.remote.type_path, cdist_type.explorer_path, explorer)
-        return self.remote.run_script(script, env=env, return_output=True)
diff --git a/lib/cdist/core/manifest.py b/lib/cdist/core/manifest.py
index 704a3978..8b784229 100644
--- a/lib/cdist/core/manifest.py
+++ b/lib/cdist/core/manifest.py
@@ -87,7 +87,7 @@ class Manifest(object):
         self.local.run_script(script, env=env)
 
     def run_type_manifest(self, cdist_object):
-        script = os.path.join(self.local.type_path, cdist_object.type.manifest_path)
+        script = os.path.join(self.local.type_path, cdist_object.cdist_type.manifest_path)
         if os.path.isfile(script):
             env = os.environ.copy()
             env.update(self.env)
@@ -96,7 +96,7 @@ class Manifest(object):
                 '__object_id': cdist_object.object_id,
                 '__object_name': cdist_object.name,
                 '__self': cdist_object.name,
-                '__type': cdist_object.type.absolute_path,
+                '__type': cdist_object.cdist_type.absolute_path,
                 '__cdist_manifest': script,
             })
             self.local.run_script(script, env=env)
diff --git a/lib/cdist/emulator.py b/lib/cdist/emulator.py
index 05202a39..c4b84feb 100644
--- a/lib/cdist/emulator.py
+++ b/lib/cdist/emulator.py
@@ -1,6 +1,6 @@
 # -*- coding: utf-8 -*-
 #
-# 2011 Nico Schottelius (nico-cdist at schottelius.org)
+# 2011-2012 Nico Schottelius (nico-cdist at schottelius.org)
 #
 # This file is part of cdist.
 #
@@ -26,29 +26,22 @@ import os
 import cdist
 from cdist import core
 
-
-class IllegalRequirementError(cdist.Error):
-    def __init__(self, requirement, message=None):
-        self.requirement = requirement
-        self.message = message or 'Illegal requirement'
-
-    def __str__(self):
-        return '%s: %s' % (self.message, self.requirement)
-
 class Emulator(object):
     def __init__(self, argv):
         self.argv           = argv
         self.object_id      = False
 
         self.global_path    = os.environ['__global']
-        self.object_source  = os.environ['__cdist_manifest']
         self.target_host    = os.environ['__target_host']
+
+        # Internally only
+        self.object_source  = os.environ['__cdist_manifest']
         self.type_base_path = os.environ['__cdist_type_base_path']
 
         self.object_base_path = os.path.join(self.global_path, "object")
 
         self.type_name      = os.path.basename(argv[0])
-        self.cdist_type     = core.Type(self.type_base_path, self.type_name)
+        self.cdist_type     = core.CdistType(self.type_base_path, self.type_name)
 
         self.__init_log()
 
@@ -94,7 +87,7 @@ class Emulator(object):
     def commandline(self):
         """Parse command line"""
 
-        parser = argparse.ArgumentParser(add_help=False)
+        parser = argparse.ArgumentParser(add_help=False, argument_default=argparse.SUPPRESS)
 
         for parameter in self.cdist_type.optional_parameters:
             argument = "--" + parameter
@@ -102,6 +95,9 @@ class Emulator(object):
         for parameter in self.cdist_type.required_parameters:
             argument = "--" + parameter
             parser.add_argument(argument, dest=parameter, action='store', required=True)
+        for parameter in self.cdist_type.boolean_parameters:
+            argument = "--" + parameter
+            parser.add_argument(argument, dest=parameter, action='store_const', const='')
 
         # If not singleton support one positional parameter
         if not self.cdist_type.is_singleton:
@@ -113,20 +109,15 @@ class Emulator(object):
 
 
     def setup_object(self):
-        # FIXME: verify object id
-
-        # Setup object_id
+        # Setup object_id - FIXME: unset / do not setup anymore!
         if self.cdist_type.is_singleton:
             self.object_id = "singleton"
         else:
             self.object_id = self.args.object_id[0]
             del self.args.object_id
 
-            # strip leading slash from object_id
-            self.object_id = self.object_id.lstrip('/')
-
         # Instantiate the cdist object we are defining
-        self.cdist_object = core.Object(self.cdist_type, self.object_base_path, self.object_id)
+        self.cdist_object = core.CdistObject(self.cdist_type, self.object_base_path, self.object_id)
 
         # Create object with given parameters
         self.parameters = {}
@@ -137,12 +128,15 @@ class Emulator(object):
         if self.cdist_object.exists:
             if self.cdist_object.parameters != self.parameters:
                 raise cdist.Error("Object %s already exists with conflicting parameters:\n%s: %s\n%s: %s"
-                    % (self.cdist_object, " ".join(self.cdist_object.source), self.cdist_object.parameters, self.object_source, self.parameters)
+                    % (self.cdist_object.name, " ".join(self.cdist_object.source), self.cdist_object.parameters, self.object_source, self.parameters)
             )
         else:
             self.cdist_object.create()
             self.cdist_object.parameters = self.parameters
 
+        # Record / Append source
+        self.cdist_object.source.append(self.object_source)
+
     def record_requirements(self):
         """record requirements"""
 
@@ -151,25 +145,17 @@ class Emulator(object):
             self.log.debug("reqs = " + requirements)
             for requirement in requirements.split(" "):
                 # Ignore empty fields - probably the only field anyway
-                if len(requirement) == 0:
-                    continue
+                if len(requirement) == 0: continue
 
-                requirement_type_name, requirement_object_id = core.Object.split_name(requirement)
-                # Instantiate type which fails if type does not exist
-                requirement_type = core.Type(self.type_base_path, requirement_type_name)
-
-                if requirement_object_id:
-                    # Validate object_id if any
-                    core.Object.validate_object_id(requirement_object_id)
-                elif not requirement_type.is_singleton:
-                    # Only singeltons have no object_id
-                    raise IllegalRequirementError(requirement, "Missing object_id and type is not a singleton.")
+                # Raises an error, if object cannot be created
+                cdist_object = self.cdist_object.object_from_name(requirement)
 
                 self.log.debug("Recording requirement: " + requirement)
-                self.cdist_object.requirements.append(requirement)
 
-        # Record / Append source
-        self.cdist_object.source.append(self.object_source)
+                # Save the sanitised version, not the user supplied one
+                # (__file//bar => __file/bar)
+                # This ensures pattern matching is done against sanitised list
+                self.cdist_object.requirements.append(cdist_object.name)
 
     def record_auto_requirements(self):
         """An object shall automatically depend on all objects that it defined in it's type manifest.
diff --git a/lib/cdist/exec/local.py b/lib/cdist/exec/local.py
index 613f5cf2..d3c6a0ce 100644
--- a/lib/cdist/exec/local.py
+++ b/lib/cdist/exec/local.py
@@ -32,18 +32,6 @@ import logging
 import cdist
 from cdist import core
 
-
-class LocalScriptError(cdist.Error):
-    def __init__(self, script, command, script_content):
-        self.script = script
-        self.command = command
-        self.script_content = script_content
-
-    def __str__(self):
-        plain_command = " ".join(self.command)
-        return "Local script execution failed: %s" % plain_command
-
-
 class Local(object):
     """Execute commands locally.
 
@@ -119,35 +107,16 @@ class Local(object):
         command = ["/bin/sh", "-e"]
         command.append(script)
 
-        self.log.debug("Local run script: %s", command)
-
-        if env is None:
-            env = os.environ.copy()
-        # Export __target_host for use in __remote_{copy,exec} scripts
-        env['__target_host'] = self.target_host
-
-        self.log.debug("Local run script env: %s", env)
-
-        try:
-            if return_output:
-                return subprocess.check_output(command, env=env).decode()
-            else:
-                subprocess.check_call(command, env=env)
-        except subprocess.CalledProcessError as error:
-            script_content = self.run(["cat", script], return_output=True)
-            self.log.error("Code that raised the error:\n%s", script_content)
-            raise LocalScriptError(script, command, script_content)
-        except EnvironmentError as error:
-            raise cdist.Error(" ".join(command) + ": " + error.args[1])
+        return self.run(command, env, return_output)
 
     def link_emulator(self, exec_path):
         """Link emulator to types"""
         src = os.path.abspath(exec_path)
-        for cdist_type in core.Type.list_types(self.type_path):
+        for cdist_type in core.CdistType.list_types(self.type_path):
             dst = os.path.join(self.bin_path, cdist_type.name)
             self.log.debug("Linking emulator: %s to %s", src, dst)
 
             try:
                 os.symlink(src, dst)
             except OSError as e:
-                raise cdist.Error("Linking emulator from " + src + " to " + dst + " failed: " + e.__str__())
+                raise cdist.Error("Linking emulator from %s to %s failed: %s" % (src, dst, e.__str__()))
diff --git a/lib/cdist/exec/remote.py b/lib/cdist/exec/remote.py
index 87db7273..124c1b4f 100644
--- a/lib/cdist/exec/remote.py
+++ b/lib/cdist/exec/remote.py
@@ -20,8 +20,6 @@
 #
 #
 
-# FIXME: common base class with Local?
-
 import io
 import os
 import sys
@@ -30,17 +28,6 @@ import logging
 
 import cdist
 
-
-class RemoteScriptError(cdist.Error):
-    def __init__(self, script, command, script_content):
-        self.script = script
-        self.command = command
-        self.script_content = script_content
-
-    def __str__(self):
-        plain_command = " ".join(self.command)
-        return "Remote script execution failed: %s" % plain_command
-
 class DecodeError(cdist.Error):
     def __init__(self, command):
         self.command = command
@@ -93,6 +80,17 @@ class Remote(object):
         command.extend(["-r", source, self.target_host + ":" + destination])
         self._run_command(command)
 
+    def run_script(self, script, env=None, return_output=False):
+        """Run the given script with the given environment on the remote side.
+        Return the output as a string.
+
+        """
+
+        command = ["/bin/sh", "-e"]
+        command.append(script)
+
+        return self.run(command, env, return_output)
+
     def run(self, command, env=None, return_output=False):
         """Run the given command with the given environment on the remote side.
         Return the output as a string.
@@ -101,7 +99,15 @@ class Remote(object):
         # prefix given command with remote_exec
         cmd = self._exec.split()
         cmd.append(self.target_host)
+
+        # can't pass environment to remote side, so prepend command with
+        # variable declarations
+        if env:
+            remote_env = ["%s=%s" % item for item in env.items()]
+            cmd.extend(remote_env)
+
         cmd.extend(command)
+
         return self._run_command(cmd, env=env, return_output=return_output)
 
     def _run_command(self, command, env=None, return_output=False):
@@ -115,14 +121,6 @@ class Remote(object):
         os_environ = os.environ.copy()
         os_environ['__target_host'] = self.target_host
 
-        # can't pass environment to remote side, so prepend command with
-        # variable declarations
-        if env:
-            cmd = ["%s=%s" % item for item in env.items()]
-            cmd.extend(command)
-        else:
-            cmd = command
-
         self.log.debug("Remote run: %s", command)
         try:
             if return_output:
@@ -135,39 +133,3 @@ class Remote(object):
             raise cdist.Error(" ".join(*args) + ": " + error.args[1])
         except UnicodeDecodeError:
             raise DecodeError(command)
-
-    def run_script(self, script, env=None, return_output=False):
-        """Run the given script with the given environment on the remote side.
-        Return the output as a string.
-
-        """
-        command = self._exec.split()
-        command.append(self.target_host)
-
-        # export target_host for use in __remote_{exec,copy} scripts
-        os_environ = os.environ.copy()
-        os_environ['__target_host'] = self.target_host
-
-        # can't pass environment to remote side, so prepend command with
-        # variable declarations
-        if env:
-            command.extend(["%s=%s" % item for item in env.items()])
-
-        command.extend(["/bin/sh", "-e"])
-        command.append(script)
-
-        self.log.debug("Remote run script: %s", command)
-        if env:
-            self.log.debug("Remote run script env: %s", env)
-
-        try:
-            if return_output:
-                return subprocess.check_output(command, env=os_environ).decode()
-            else:
-                subprocess.check_call(command, env=os_environ)
-        except subprocess.CalledProcessError as error:
-            script_content = self.run(["cat", script], return_output=True)
-            self.log.error("Code that raised the error:\n%s", script_content)
-            raise RemoteScriptError(script, command, script_content)
-        except EnvironmentError as error:
-            raise cdist.Error(" ".join(command) + ": " + error.args[1])
diff --git a/lib/cdist/resolver.py b/lib/cdist/resolver.py
index 24a5e496..368c9eb8 100644
--- a/lib/cdist/resolver.py
+++ b/lib/cdist/resolver.py
@@ -125,7 +125,7 @@ class DependencyResolver(object):
             resolved.append(cdist_object)
             unresolved.remove(cdist_object)
         except RequirementNotFoundError as e:
-            raise cdist.Error(cdist_object.name + " requires non-existing " + e.requirement)
+            raise cdist.CdistObjectError(cdist_object, "requires non-existing " + e.requirement)
 
     def __iter__(self):
         """Iterate over all unique objects while resolving dependencies.
diff --git a/lib/cdist/test/code/__init__.py b/lib/cdist/test/code/__init__.py
index 2f061086..dc701cce 100644
--- a/lib/cdist/test/code/__init__.py
+++ b/lib/cdist/test/code/__init__.py
@@ -54,8 +54,8 @@ class CodeTestCase(test.CdistTestCase):
 
         self.code = code.Code(self.target_host, self.local, self.remote)
 
-        self.cdist_type = core.Type(self.local.type_path, '__dump_environment')
-        self.cdist_object = core.Object(self.cdist_type, self.local.object_path, 'whatever')
+        self.cdist_type = core.CdistType(self.local.type_path, '__dump_environment')
+        self.cdist_object = core.CdistObject(self.cdist_type, self.local.object_path, 'whatever')
         self.cdist_object.create()
 
         self.log = logging.getLogger("cdist")
diff --git a/lib/cdist/test/emulator/__init__.py b/lib/cdist/test/emulator/__init__.py
index e67bed4a..370d3d82 100644
--- a/lib/cdist/test/emulator/__init__.py
+++ b/lib/cdist/test/emulator/__init__.py
@@ -79,7 +79,7 @@ class EmulatorTestCase(test.CdistTestCase):
         os.environ.update(self.env)
         os.environ['require'] = '__file'
         emu = emulator.Emulator(argv)
-        self.assertRaises(emulator.IllegalRequirementError, emu.run)
+        self.assertRaises(core.IllegalObjectIdError, emu.run)
 
     def test_singleton_object_requirement(self):
         argv = ['__file', '/tmp/foobar']
@@ -119,14 +119,14 @@ class AutoRequireEmulatorTestCase(test.CdistTestCase):
     def test_autorequire(self):
         initial_manifest = os.path.join(self.local.manifest_path, "init")
         self.manifest.run_initial_manifest(initial_manifest)
-        cdist_type = core.Type(self.local.type_path, '__saturn')
-        cdist_object = core.Object(cdist_type, self.local.object_path, 'singleton')
+        cdist_type = core.CdistType(self.local.type_path, '__saturn')
+        cdist_object = core.CdistObject(cdist_type, self.local.object_path, 'singleton')
         self.manifest.run_type_manifest(cdist_object)
         expected = ['__planet/Saturn', '__moon/Prometheus']
         self.assertEqual(sorted(cdist_object.requirements), sorted(expected))
 
 
-class ArgumentsWithDashesTestCase(test.CdistTestCase):
+class ArgumentsTestCase(test.CdistTestCase):
 
     def setUp(self):
         self.temp_dir = self.mkdtemp()
@@ -156,6 +156,62 @@ class ArgumentsWithDashesTestCase(test.CdistTestCase):
         emu = emulator.Emulator(argv)
         emu.run()
 
-        cdist_type = core.Type(self.local.type_path, '__arguments_with_dashes')
-        cdist_object = core.Object(cdist_type, self.local.object_path, 'some-id')
+        cdist_type = core.CdistType(self.local.type_path, '__arguments_with_dashes')
+        cdist_object = core.CdistObject(cdist_type, self.local.object_path, 'some-id')
         self.assertTrue('with-dash' in cdist_object.parameters)
+
+    def test_boolean(self):
+        type_name = '__arguments_boolean'
+        object_id = 'some-id'
+        argv = [type_name, object_id, '--boolean1']
+        os.environ.update(self.env)
+        emu = emulator.Emulator(argv)
+        emu.run()
+
+        cdist_type = core.CdistType(self.local.type_path, type_name)
+        cdist_object = core.CdistObject(cdist_type, self.local.object_path, object_id)
+        self.assertTrue('boolean1' in cdist_object.parameters)
+        self.assertFalse('boolean2' in cdist_object.parameters)
+        # empty file -> True
+        self.assertTrue(cdist_object.parameters['boolean1'] == '')
+
+    def test_required(self):
+        type_name = '__arguments_required'
+        object_id = 'some-id'
+        value = 'some value'
+        argv = [type_name, object_id, '--required1', value, '--required2', value]
+        os.environ.update(self.env)
+        emu = emulator.Emulator(argv)
+        emu.run()
+
+        cdist_type = core.CdistType(self.local.type_path, type_name)
+        cdist_object = core.CdistObject(cdist_type, self.local.object_path, object_id)
+        self.assertTrue('required1' in cdist_object.parameters)
+        self.assertTrue('required2' in cdist_object.parameters)
+        self.assertEqual(cdist_object.parameters['required1'], value)
+        self.assertEqual(cdist_object.parameters['required2'], value)
+
+#    def test_required_missing(self):
+#        type_name = '__arguments_required'
+#        object_id = 'some-id'
+#        value = 'some value'
+#        argv = [type_name, object_id, '--required1', value]
+#        os.environ.update(self.env)
+#        emu = emulator.Emulator(argv)
+#        
+#        self.assertRaises(SystemExit, emu.run)
+
+    def test_optional(self):
+        type_name = '__arguments_optional'
+        object_id = 'some-id'
+        value = 'some value'
+        argv = [type_name, object_id, '--optional1', value]
+        os.environ.update(self.env)
+        emu = emulator.Emulator(argv)
+        emu.run()
+
+        cdist_type = core.CdistType(self.local.type_path, type_name)
+        cdist_object = core.CdistObject(cdist_type, self.local.object_path, object_id)
+        self.assertTrue('optional1' in cdist_object.parameters)
+        self.assertFalse('optional2' in cdist_object.parameters)
+        self.assertEqual(cdist_object.parameters['optional1'], value)
diff --git a/lib/cdist/test/emulator/fixtures/conf/type/__arguments_boolean/parameter/boolean b/lib/cdist/test/emulator/fixtures/conf/type/__arguments_boolean/parameter/boolean
new file mode 100644
index 00000000..3215c409
--- /dev/null
+++ b/lib/cdist/test/emulator/fixtures/conf/type/__arguments_boolean/parameter/boolean
@@ -0,0 +1,2 @@
+boolean1
+boolean2
diff --git a/lib/cdist/test/emulator/fixtures/conf/type/__arguments_optional/parameter/optional b/lib/cdist/test/emulator/fixtures/conf/type/__arguments_optional/parameter/optional
new file mode 100644
index 00000000..31647628
--- /dev/null
+++ b/lib/cdist/test/emulator/fixtures/conf/type/__arguments_optional/parameter/optional
@@ -0,0 +1 @@
+optional1
diff --git a/lib/cdist/test/emulator/fixtures/conf/type/__arguments_required/parameter/required b/lib/cdist/test/emulator/fixtures/conf/type/__arguments_required/parameter/required
new file mode 100644
index 00000000..e0fba2c9
--- /dev/null
+++ b/lib/cdist/test/emulator/fixtures/conf/type/__arguments_required/parameter/required
@@ -0,0 +1,2 @@
+required1
+required2
diff --git a/lib/cdist/test/explorer/__init__.py b/lib/cdist/test/explorer/__init__.py
index cafe34fc..257ad8a9 100644
--- a/lib/cdist/test/explorer/__init__.py
+++ b/lib/cdist/test/explorer/__init__.py
@@ -83,19 +83,19 @@ class ExplorerClassTestCase(test.CdistTestCase):
         shutil.rmtree(out_path)
 
     def test_list_type_explorer_names(self):
-        cdist_type = core.Type(self.local.type_path, '__test_type')
+        cdist_type = core.CdistType(self.local.type_path, '__test_type')
         expected = cdist_type.explorers
         self.assertEqual(self.explorer.list_type_explorer_names(cdist_type), expected)
 
     def test_transfer_type_explorers(self):
-        cdist_type = core.Type(self.local.type_path, '__test_type')
+        cdist_type = core.CdistType(self.local.type_path, '__test_type')
         self.explorer.transfer_type_explorers(cdist_type)
         source = os.path.join(self.local.type_path, cdist_type.explorer_path)
         destination = os.path.join(self.remote.type_path, cdist_type.explorer_path)
         self.assertEqual(os.listdir(source), os.listdir(destination))
 
     def test_transfer_type_explorers_only_once(self):
-        cdist_type = core.Type(self.local.type_path, '__test_type')
+        cdist_type = core.CdistType(self.local.type_path, '__test_type')
         # first transfer
         self.explorer.transfer_type_explorers(cdist_type)
         source = os.path.join(self.local.type_path, cdist_type.explorer_path)
@@ -109,8 +109,8 @@ class ExplorerClassTestCase(test.CdistTestCase):
         self.assertFalse(os.listdir(destination))
 
     def test_transfer_object_parameters(self):
-        cdist_type = core.Type(self.local.type_path, '__test_type')
-        cdist_object = core.Object(cdist_type, self.local.object_path, 'whatever')
+        cdist_type = core.CdistType(self.local.type_path, '__test_type')
+        cdist_object = core.CdistObject(cdist_type, self.local.object_path, 'whatever')
         cdist_object.create()
         cdist_object.parameters = {'first': 'first value', 'second': 'second value'}
         self.explorer.transfer_object_parameters(cdist_object)
@@ -119,15 +119,15 @@ class ExplorerClassTestCase(test.CdistTestCase):
         self.assertEqual(sorted(os.listdir(source)), sorted(os.listdir(destination)))
 
     def test_run_type_explorer(self):
-        cdist_type = core.Type(self.local.type_path, '__test_type')
-        cdist_object = core.Object(cdist_type, self.local.object_path, 'whatever')
+        cdist_type = core.CdistType(self.local.type_path, '__test_type')
+        cdist_object = core.CdistObject(cdist_type, self.local.object_path, 'whatever')
         self.explorer.transfer_type_explorers(cdist_type)
         output = self.explorer.run_type_explorer('world', cdist_object)
         self.assertEqual(output, 'hello\n')
 
     def test_run_type_explorers(self):
-        cdist_type = core.Type(self.local.type_path, '__test_type')
-        cdist_object = core.Object(cdist_type, self.local.object_path, 'whatever')
+        cdist_type = core.CdistType(self.local.type_path, '__test_type')
+        cdist_object = core.CdistObject(cdist_type, self.local.object_path, 'whatever')
         cdist_object.create()
         self.explorer.run_type_explorers(cdist_object)
         self.assertEqual(cdist_object.explorers, {'world': 'hello'})
diff --git a/lib/cdist/test/manifest/__init__.py b/lib/cdist/test/manifest/__init__.py
index 2383adf7..a188c788 100644
--- a/lib/cdist/test/manifest/__init__.py
+++ b/lib/cdist/test/manifest/__init__.py
@@ -79,8 +79,8 @@ class ManifestTestCase(test.CdistTestCase):
         self.assertEqual(output_dict['__manifest'], self.local.manifest_path)
 
     def test_type_manifest_environment(self):
-        cdist_type = core.Type(self.local.type_path, '__dump_environment')
-        cdist_object = core.Object(cdist_type, self.local.object_path, 'whatever')
+        cdist_type = core.CdistType(self.local.type_path, '__dump_environment')
+        cdist_object = core.CdistObject(cdist_type, self.local.object_path, 'whatever')
         handle, output_file = self.mkstemp(dir=self.temp_dir)
         os.close(handle)
         os.environ['__cdist_test_out'] = output_file
diff --git a/lib/cdist/test/object/__init__.py b/lib/cdist/test/object/__init__.py
index f199ffb5..3a91f709 100644
--- a/lib/cdist/test/object/__init__.py
+++ b/lib/cdist/test/object/__init__.py
@@ -25,6 +25,8 @@ import shutil
 from cdist import test
 from cdist import core
 
+import cdist
+
 import os.path as op
 my_dir = op.abspath(op.dirname(__file__))
 fixtures = op.join(my_dir, 'fixtures')
@@ -34,48 +36,48 @@ type_base_path = op.join(fixtures, 'type')
 class ObjectClassTestCase(test.CdistTestCase):
 
     def test_list_object_names(self):
-        object_names = list(core.Object.list_object_names(object_base_path))
+        object_names = list(core.CdistObject.list_object_names(object_base_path))
         self.assertEqual(object_names, ['__first/man', '__second/on-the', '__third/moon'])
 
     def test_list_type_names(self):
-        type_names = list(core.Object.list_type_names(object_base_path))
+        type_names = list(cdist.core.CdistObject.list_type_names(object_base_path))
         self.assertEqual(type_names, ['__first', '__second', '__third'])
 
     def test_list_objects(self):
-        objects = list(core.Object.list_objects(object_base_path, type_base_path))
+        objects = list(core.CdistObject.list_objects(object_base_path, type_base_path))
         objects_expected = [
-            core.Object(core.Type(type_base_path, '__first'), object_base_path, 'man'),
-            core.Object(core.Type(type_base_path, '__second'), object_base_path, 'on-the'),
-            core.Object(core.Type(type_base_path, '__third'), object_base_path, 'moon'),
+            core.CdistObject(core.CdistType(type_base_path, '__first'), object_base_path, 'man'),
+            core.CdistObject(core.CdistType(type_base_path, '__second'), object_base_path, 'on-the'),
+            core.CdistObject(core.CdistType(type_base_path, '__third'), object_base_path, 'moon'),
         ]
         self.assertEqual(objects, objects_expected)
 
 
 class ObjectIdTestCase(test.CdistTestCase):
-    def test_object_id_starts_with_slash(self):
-        cdist_type = core.Type(type_base_path, '__third')
-        illegal_object_id = '/object_id/may/not/start/with/slash'
+    def test_object_id_contains_double_slash(self):
+        cdist_type = core.CdistType(type_base_path, '__third')
+        illegal_object_id = '/object_id//may/not/contain/double/slash'
         with self.assertRaises(core.IllegalObjectIdError):
-            core.Object(cdist_type, object_base_path, illegal_object_id)
+            core.CdistObject(cdist_type, object_base_path, illegal_object_id)
 
     def test_object_id_contains_object_marker(self):
-        cdist_type = core.Type(type_base_path, '__third')
+        cdist_type = core.CdistType(type_base_path, '__third')
         illegal_object_id = 'object_id/may/not/contain/%s/anywhere' % core.OBJECT_MARKER
         with self.assertRaises(core.IllegalObjectIdError):
-            core.Object(cdist_type, object_base_path, illegal_object_id)
+            core.CdistObject(cdist_type, object_base_path, illegal_object_id)
 
     def test_object_id_contains_object_marker_string(self):
-        cdist_type = core.Type(type_base_path, '__third')
+        cdist_type = core.CdistType(type_base_path, '__third')
         illegal_object_id = 'object_id/may/contain_%s_in_filename' % core.OBJECT_MARKER
-        core.Object(cdist_type, object_base_path, illegal_object_id)
+        core.CdistObject(cdist_type, object_base_path, illegal_object_id)
         # if we get here, the test passed
 
 
 class ObjectTestCase(test.CdistTestCase):
 
     def setUp(self):
-        self.cdist_type = core.Type(type_base_path, '__third')
-        self.cdist_object = core.Object(self.cdist_type, object_base_path, 'moon') 
+        self.cdist_type = core.CdistType(type_base_path, '__third')
+        self.cdist_object = core.CdistObject(self.cdist_type, object_base_path, 'moon') 
 
     def tearDown(self):
         self.cdist_object.changed = False
@@ -159,16 +161,16 @@ class ObjectTestCase(test.CdistTestCase):
         self.assertEqual(self.cdist_object.state, '')
 
     def test_state_prepared(self):
-        self.cdist_object.state = core.Object.STATE_PREPARED
-        self.assertEqual(self.cdist_object.state, core.Object.STATE_PREPARED)
+        self.cdist_object.state = core.CdistObject.STATE_PREPARED
+        self.assertEqual(self.cdist_object.state, core.CdistObject.STATE_PREPARED)
 
     def test_state_running(self):
-        self.cdist_object.state = core.Object.STATE_RUNNING
-        self.assertEqual(self.cdist_object.state, core.Object.STATE_RUNNING)
+        self.cdist_object.state = core.CdistObject.STATE_RUNNING
+        self.assertEqual(self.cdist_object.state, core.CdistObject.STATE_RUNNING)
 
     def test_state_done(self):
-        self.cdist_object.state = core.Object.STATE_DONE
-        self.assertEqual(self.cdist_object.state, core.Object.STATE_DONE)
+        self.cdist_object.state = core.CdistObject.STATE_DONE
+        self.assertEqual(self.cdist_object.state, core.CdistObject.STATE_DONE)
 
     def test_source(self):
         self.assertEqual(list(self.cdist_object.source), [])
@@ -195,6 +197,6 @@ class ObjectTestCase(test.CdistTestCase):
         self.cdist_object.code_remote = 'Hello World'
         other_name = '__first/man'
         other_object = self.cdist_object.object_from_name(other_name)
-        self.assertTrue(isinstance(other_object, core.Object))
-        self.assertEqual(other_object.type.name, '__first')
+        self.assertTrue(isinstance(other_object, core.CdistObject))
+        self.assertEqual(other_object.cdist_type.name, '__first')
         self.assertEqual(other_object.object_id, 'man')
diff --git a/lib/cdist/test/resolver/__init__.py b/lib/cdist/test/resolver/__init__.py
index cca058a4..ae8f6915 100644
--- a/lib/cdist/test/resolver/__init__.py
+++ b/lib/cdist/test/resolver/__init__.py
@@ -37,7 +37,7 @@ type_base_path = op.join(fixtures, 'type')
 class ResolverTestCase(test.CdistTestCase):
 
     def setUp(self):
-        self.objects = list(core.Object.list_objects(object_base_path, type_base_path))
+        self.objects = list(core.CdistObject.list_objects(object_base_path, type_base_path))
         self.object_index = dict((o.name, o) for o in self.objects)
         self.dependency_resolver = resolver.DependencyResolver(self.objects)
 
diff --git a/lib/cdist/test/type/__init__.py b/lib/cdist/test/type/__init__.py
index 7bb8654c..5e774aa9 100644
--- a/lib/cdist/test/type/__init__.py
+++ b/lib/cdist/test/type/__init__.py
@@ -33,115 +33,126 @@ class TypeTestCase(test.CdistTestCase):
 
     def test_list_type_names(self):
         base_path = op.join(fixtures, 'list_types')
-        type_names = core.Type.list_type_names(base_path)
+        type_names = core.CdistType.list_type_names(base_path)
         self.assertEqual(type_names, ['__first', '__second', '__third'])
 
     def test_list_types(self):
         base_path = op.join(fixtures, 'list_types')
-        types = list(core.Type.list_types(base_path))
+        types = list(core.CdistType.list_types(base_path))
         types_expected = [
-            core.Type(base_path, '__first'),
-            core.Type(base_path, '__second'),
-            core.Type(base_path, '__third'),
+            core.CdistType(base_path, '__first'),
+            core.CdistType(base_path, '__second'),
+            core.CdistType(base_path, '__third'),
         ]
         self.assertEqual(types, types_expected)
 
     def test_only_one_instance(self):
         base_path = fixtures
-        cdist_type1 = core.Type(base_path, '__name_path')
-        cdist_type2 = core.Type(base_path, '__name_path')
+        cdist_type1 = core.CdistType(base_path, '__name_path')
+        cdist_type2 = core.CdistType(base_path, '__name_path')
         self.assertEqual(id(cdist_type1), id(cdist_type2))
 
     def test_nonexistent_type(self):
         base_path = fixtures
-        self.assertRaises(core.NoSuchTypeError, core.Type, base_path, '__i-dont-exist')
+        self.assertRaises(core.NoSuchTypeError, core.CdistType, base_path, '__i-dont-exist')
 
     def test_name(self):
         base_path = fixtures
-        cdist_type = core.Type(base_path, '__name_path')
+        cdist_type = core.CdistType(base_path, '__name_path')
         self.assertEqual(cdist_type.name, '__name_path')
 
     def test_path(self):
         base_path = fixtures
-        cdist_type = core.Type(base_path, '__name_path')
+        cdist_type = core.CdistType(base_path, '__name_path')
         self.assertEqual(cdist_type.path, '__name_path')
 
     def test_base_path(self):
         base_path = fixtures
-        cdist_type = core.Type(base_path, '__name_path')
+        cdist_type = core.CdistType(base_path, '__name_path')
         self.assertEqual(cdist_type.base_path, base_path)
 
     def test_absolute_path(self):
         base_path = fixtures
-        cdist_type = core.Type(base_path, '__name_path')
+        cdist_type = core.CdistType(base_path, '__name_path')
         self.assertEqual(cdist_type.absolute_path, os.path.join(base_path, '__name_path'))
 
     def test_manifest_path(self):
         base_path = fixtures
-        cdist_type = core.Type(base_path, '__name_path')
+        cdist_type = core.CdistType(base_path, '__name_path')
         self.assertEqual(cdist_type.manifest_path, os.path.join('__name_path', 'manifest'))
 
     def test_explorer_path(self):
         base_path = fixtures
-        cdist_type = core.Type(base_path, '__name_path')
+        cdist_type = core.CdistType(base_path, '__name_path')
         self.assertEqual(cdist_type.explorer_path, os.path.join('__name_path', 'explorer'))
 
     def test_gencode_local_path(self):
         base_path = fixtures
-        cdist_type = core.Type(base_path, '__name_path')
+        cdist_type = core.CdistType(base_path, '__name_path')
         self.assertEqual(cdist_type.gencode_local_path, os.path.join('__name_path', 'gencode-local'))
 
     def test_gencode_remote_path(self):
         base_path = fixtures
-        cdist_type = core.Type(base_path, '__name_path')
+        cdist_type = core.CdistType(base_path, '__name_path')
         self.assertEqual(cdist_type.gencode_remote_path, os.path.join('__name_path', 'gencode-remote'))
 
     def test_singleton_is_singleton(self):
         base_path = fixtures
-        cdist_type = core.Type(base_path, '__singleton')
+        cdist_type = core.CdistType(base_path, '__singleton')
         self.assertTrue(cdist_type.is_singleton)
 
     def test_not_singleton_is_singleton(self):
         base_path = fixtures
-        cdist_type = core.Type(base_path, '__not_singleton')
+        cdist_type = core.CdistType(base_path, '__not_singleton')
         self.assertFalse(cdist_type.is_singleton)
 
     def test_install_is_install(self):
         base_path = fixtures
-        cdist_type = core.Type(base_path, '__install')
+        cdist_type = core.CdistType(base_path, '__install')
         self.assertTrue(cdist_type.is_install)
 
     def test_not_install_is_install(self):
         base_path = fixtures
-        cdist_type = core.Type(base_path, '__not_install')
+        cdist_type = core.CdistType(base_path, '__not_install')
         self.assertFalse(cdist_type.is_install)
 
     def test_with_explorers(self):
         base_path = fixtures
-        cdist_type = core.Type(base_path, '__with_explorers')
+        cdist_type = core.CdistType(base_path, '__with_explorers')
         self.assertEqual(cdist_type.explorers, ['whatever'])
 
     def test_without_explorers(self):
         base_path = fixtures
-        cdist_type = core.Type(base_path, '__without_explorers')
+        cdist_type = core.CdistType(base_path, '__without_explorers')
         self.assertEqual(cdist_type.explorers, [])
 
     def test_with_required_parameters(self):
         base_path = fixtures
-        cdist_type = core.Type(base_path, '__with_required_parameters')
+        cdist_type = core.CdistType(base_path, '__with_required_parameters')
         self.assertEqual(cdist_type.required_parameters, ['required1', 'required2'])
 
     def test_without_required_parameters(self):
         base_path = fixtures
-        cdist_type = core.Type(base_path, '__without_required_parameters')
+        cdist_type = core.CdistType(base_path, '__without_required_parameters')
         self.assertEqual(cdist_type.required_parameters, [])
 
     def test_with_optional_parameters(self):
         base_path = fixtures
-        cdist_type = core.Type(base_path, '__with_optional_parameters')
+        cdist_type = core.CdistType(base_path, '__with_optional_parameters')
         self.assertEqual(cdist_type.optional_parameters, ['optional1', 'optional2'])
 
     def test_without_optional_parameters(self):
         base_path = fixtures
-        cdist_type = core.Type(base_path, '__without_optional_parameters')
+        cdist_type = core.CdistType(base_path, '__without_optional_parameters')
         self.assertEqual(cdist_type.optional_parameters, [])
+
+    def test_with_boolean_parameters(self):
+        base_path = fixtures
+        cdist_type = core.CdistType(base_path, '__with_boolean_parameters')
+        self.assertEqual(cdist_type.boolean_parameters, ['boolean1', 'boolean2'])
+
+    def test_without_boolean_parameters(self):
+        base_path = fixtures
+        cdist_type = core.CdistType(base_path, '__without_boolean_parameters')
+        self.assertEqual(cdist_type.boolean_parameters, [])
+
diff --git a/lib/cdist/test/type/fixtures/__with_boolean_parameters/parameter/boolean b/lib/cdist/test/type/fixtures/__with_boolean_parameters/parameter/boolean
new file mode 100644
index 00000000..3215c409
--- /dev/null
+++ b/lib/cdist/test/type/fixtures/__with_boolean_parameters/parameter/boolean
@@ -0,0 +1,2 @@
+boolean1
+boolean2
diff --git a/lib/cdist/test/type/fixtures/__without_boolean_parameters/.keep b/lib/cdist/test/type/fixtures/__without_boolean_parameters/.keep
new file mode 100644
index 00000000..e69de29b