diff --git a/cdist/conf/type/__cron/explorer/entry b/cdist/conf/type/__cron/explorer/entry
old mode 100755
new mode 100644
diff --git a/cdist/conf/type/__cron/gencode-remote b/cdist/conf/type/__cron/gencode-remote
index c04a7245..712eb1a1 100755
--- a/cdist/conf/type/__cron/gencode-remote
+++ b/cdist/conf/type/__cron/gencode-remote
@@ -2,6 +2,7 @@
 #
 # 2011 Steven Armstrong (steven-cdist at armstrong.cc)
 # 2013      Nico Schottelius (nico-cdist at schottelius.org)
+# 2013      Thomas Oettli (otho at sfs.biz)
 #
 # This file is part of cdist.
 #
@@ -26,6 +27,8 @@ command="$(cat "$__object/parameter/command")"
 if [ -f "$__object/parameter/raw" ]; then
    raw="$(cat "$__object/parameter/raw")"
    entry="$raw $command"
+elif [ -f "$__object/parameter/raw_command" ]; then
+   entry="$command"
 else
    minute="$(cat "$__object/parameter/minute" 2>/dev/null || echo "*")"
    hour="$(cat "$__object/parameter/hour" 2>/dev/null || echo "*")"
@@ -55,8 +58,9 @@ state_should="$(cat "$__object/parameter/state" 2>/dev/null || echo "present")"
 # These are the old markers
 prefix="#cdist:__cron/$__object_id"
 suffix="#/cdist:__cron/$__object_id"
+filter="^# DO NOT EDIT THIS FILE|^# \(.* installed on |^# \(Cron version V"
 cat << DONE
-crontab -u $user -l | awk -v prefix="$prefix" -v suffix="$suffix" '
+crontab -u $user -l 2>/dev/null | grep -v -E "$filter" | awk -v prefix="$prefix" -v suffix="$suffix" '
 {
    if (index(\$0,prefix)) {
       triggered=1
@@ -75,12 +79,12 @@ DONE
 case "$state_should" in
     present)
         echo "("
-        echo "crontab -u $user -l 2>/dev/null || true"
+        echo "crontab -u $user -l 2>/dev/null | grep -v -E \"$filter\" 2>/dev/null || true"
         echo "echo '$entry'"
         echo ") | crontab -u $user -"
     ;;
     absent)
-        echo "( crontab -u $user -l 2>/dev/null || true ) | \\"
+        echo "( crontab -u $user -l 2>/dev/null | grep -v -E \"$filter\" 2>/dev/null || true ) | \\"
         echo "grep -v \"# $name\\$\" | crontab -u $user -"
     ;;
 esac
diff --git a/cdist/conf/type/__cron/man.text b/cdist/conf/type/__cron/man.text
index 22627234..f4e80a08 100644
--- a/cdist/conf/type/__cron/man.text
+++ b/cdist/conf/type/__cron/man.text
@@ -41,6 +41,10 @@ raw::
    Can for example be used to specify cron EXTENSIONS like reboot, yearly etc.
    See crontab(5) for the extensions if any that your cron implementation
    implements.
+raw_command::
+   Take whatever the user has given in the commmand and ignore everything else.
+   If given, the command will be added to crontab.
+   Can for example be used to define variables like SHELL or MAILTO.
 
 
 EXAMPLES
@@ -57,6 +61,10 @@ __cron some-id --user root --command "/path/to/script" \
 
 # remove cronjob
 __cron some-id --user root --command "/path/to/script" --state absent
+
+# define default shell
+__cron some-id --user root --raw_command --command "SHELL=/bin/bash" \
+   --state present
 --------------------------------------------------------------------------------
 
 
diff --git a/cdist/conf/type/__cron/manifest b/cdist/conf/type/__cron/manifest
new file mode 100644
index 00000000..9992df25
--- /dev/null
+++ b/cdist/conf/type/__cron/manifest
@@ -0,0 +1,24 @@
+#!/bin/sh
+#
+# 2013 Thomas Oettli (otho at sfs.biz)
+#
+# 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/>.
+#
+
+if [ -f "$__object/parameter/raw" ] && [ -f "$__object/parameter/raw_command" ]; then
+    echo "ERROR: both raw and raw_command specified" >&2
+    exit 1
+fi
diff --git a/cdist/conf/type/__cron/parameter/boolean b/cdist/conf/type/__cron/parameter/boolean
new file mode 100644
index 00000000..54cfb0b3
--- /dev/null
+++ b/cdist/conf/type/__cron/parameter/boolean
@@ -0,0 +1 @@
+raw_command
diff --git a/cdist/conf/type/__directory/gencode-remote b/cdist/conf/type/__directory/gencode-remote
index 800fc6e4..05c301b3 100755
--- a/cdist/conf/type/__directory/gencode-remote
+++ b/cdist/conf/type/__directory/gencode-remote
@@ -56,15 +56,18 @@ get_current_value() {
 }
 
 set_group() {
-   echo chgrp $recursive \"$1\" \"$destination\"
+    echo chgrp $recursive \"$1\" \"$destination\"
+    echo chgrp $recursive $1 >> "$__messages_out"
 }
 
 set_owner() {
-   echo chown $recursive \"$1\" \"$destination\"
+    echo chown $recursive \"$1\" \"$destination\"
+    echo chown $recursive $1 >> "$__messages_out"
 }
 
 set_mode() {
-   echo chmod $recursive \"$1\" \"$destination\"
+    echo chmod $recursive \"$1\" \"$destination\"
+    echo chmod $recursive $1 >> "$__messages_out"
 }
 
 case "$state_should" in
@@ -77,6 +80,7 @@ case "$state_should" in
 rm -f "$destination"
 mkdir $mkdiropt "$destination"
 DONE
+        echo "remove non directory" >> "$__messages_out"
       fi
 
       # Note: Mode - needs to happen last as a chown/chgrp can alter mode by
@@ -85,16 +89,23 @@ DONE
          if [ -f "$__object/parameter/$attribute" ]; then
             value_should="$(cat "$__object/parameter/$attribute")"
             value_is="$(get_current_value "$attribute" "$value_should")"
-            if [ "$set_attributes" -o "$value_should" != "$value_is" ]; then
+
+            # change 0xxx format to xxx format => same as stat returns
+            if [ "$attribute" = mode ]; then
+                value_should="$(echo $value_should | sed 's/^0\(...\)/\1/')"
+            fi
+
+            if [ "$set_attributes" = 1 ] || [ "$value_should" != "$value_is" ]; then
                "set_$attribute" "$value_should"
             fi
          fi
       done
    ;;
    absent)
-      if [ "$type" = "directory" ]; then
-         echo rm -rf \"$destination\"
-      fi
+        if [ "$type" = "directory" ]; then
+            echo rm -rf \"$destination\"
+            echo remove >> "$__messages_out"
+        fi
    ;;
    *)
       echo "Unknown state: $state_should" >&2
diff --git a/cdist/conf/type/__group/gencode-remote b/cdist/conf/type/__group/gencode-remote
index bb6797c2..1cffa8d4 100755
--- a/cdist/conf/type/__group/gencode-remote
+++ b/cdist/conf/type/__group/gencode-remote
@@ -58,10 +58,12 @@ if grep -q "^${name}:" "$__object/explorer/group"; then
 
       if [ "$new_value" != "$current_value" ]; then
          set -- "$@" "$proparg" \"$new_value\"
+         echo change $property $new_value $current_value >> "$__messages_out"
       fi
    done
 
    if [ $# -gt 0 ]; then
+      echo mod >> "$__messages_out"
       case $os in
          freebsd)
             echo pw group mod "$@" "$name"
@@ -72,6 +74,7 @@ if grep -q "^${name}:" "$__object/explorer/group"; then
       esac
    fi
 else
+   echo add >> "$__messages_out"
    for property in $(ls .); do
       new_value="$(cat "$property")"
       if [ "$os" = "freebsd" ]; then
@@ -95,6 +98,7 @@ else
       fi
 
       set -- "$@" "$proparg" \"$new_value\"
+      echo set $property $new_value >> "$__messages_out"
    done
 
    case $os in
diff --git a/cdist/conf/type/__key_value/gencode-remote b/cdist/conf/type/__key_value/gencode-remote
index c1a6bca8..ec91894f 100755
--- a/cdist/conf/type/__key_value/gencode-remote
+++ b/cdist/conf/type/__key_value/gencode-remote
@@ -26,8 +26,8 @@ state_should=present
 
 file="$(cat "$__object/parameter/file")"
 delimiter="$(cat "$__object/parameter/delimiter")"
-value="$(cat "$__object/parameter/value")"
-
+# escape double quotes, as that is what we use ourself below
+value_escaped="$(cat "$__object/parameter/value" | sed -e "s/\([\"]\)/\\\\\1/g")"
 state_is="$(cat "$__object/explorer/state")"
 
 [ "$state_is" = "$state_should" ] && exit 0
@@ -35,20 +35,29 @@ state_is="$(cat "$__object/explorer/state")"
 case "$state_should" in
     absent)
         # remove lines starting with key
-        echo "sed '/^$key\($delimiter\+\)/d' \"$file\" > \"$file.cdist-tmp\""
-        echo "mv \"$file.cdist-tmp\" \"$file\""
+        cat << DONE
+tmpfile=\$(mktemp ${file}.cdist.XXXXXXXXXX)
+# preserve ownership and permissions by copying existing file over tmpfile
+cp -p "$file" "\$tmpfile"
+sed '/^$key\($delimiter\+\)/d' "$file" > "\$tmpfile"
+mv -f "\$tmpfile" "$file"
+DONE
     ;;
     present)
         case "$state_is" in
             absent)
                 # add new key and value
-                echo "echo \"${key}${delimiter}${value}\" >> \"$file\""
+                printf 'echo "%s%s%s" >> "%s"' "$key" "$delimiter" "$value_escaped" "$file"
             ;;
             wrongvalue)
                 # change exisiting value
-                printf 'sed "s|^%s\(%s\+\).*|%s\\1%s|" "%s" > "%s.cdist-tmp"\n' \
-                    "$key" "$delimiter" "$key" "$value" "$file" "$file"
-                echo "mv \"$file.cdist-tmp\" \"$file\""
+                cat << DONE
+tmpfile=\$(mktemp ${file}.cdist.XXXXXXXXXX)
+# preserve ownership and permissions by copying existing file over tmpfile
+cp -p "$file" "\$tmpfile"
+sed "s|^$key\($delimiter\+\).*|$key\\1$value_escaped|" "$file" > "\$tmpfile"
+mv -f "\$tmpfile" "$file"
+DONE
             ;;
             *)
                 echo "Unknown explorer state: $state_is" >&2
@@ -58,4 +67,4 @@ case "$state_should" in
     *)
        echo "Unknown state: $state_should" >&2
        exit 1
-esac 
+esac
diff --git a/cdist/conf/type/__line/gencode-remote b/cdist/conf/type/__line/gencode-remote
index 1c46c16c..d4796965 100755
--- a/cdist/conf/type/__line/gencode-remote
+++ b/cdist/conf/type/__line/gencode-remote
@@ -49,7 +49,15 @@ case "$state_should" in
         # Replace all \ so \t and other combinations are not interpreted
         #
 
-        line_sanitised=$(cat "$__object/parameter/line" | sed -e "s/'/'\"'\"'/g" -e 's/\\/\\\\/g')
+
+        # line_sanitised=$(cat "$__object/parameter/line" | sed -e "s/'/'\"'\"'/g" -e 's/\\/\\\\/g')
+        # The one above does not work:
+        #     --line "PS1='[\t] \[\033[1m\]\h\[\033[0m\]:\w\\$ '"
+        # becomes
+        # PS1='[\\t] \\[\\033[1m\\]\\h\\[\\033[0m\\]:\\w\\$ '
+
+        # Only replace ' with '"'"' and keep \ as they are
+        line_sanitised=$(cat "$__object/parameter/line" | sed -e "s/'/'\"'\"'/g")
         echo "printf '%s\n' '$line_sanitised' >> $file"
 
     ;;
diff --git a/cdist/conf/type/__package/manifest b/cdist/conf/type/__package/manifest
index 6a84cb7f..0ebf0099 100755
--- a/cdist/conf/type/__package/manifest
+++ b/cdist/conf/type/__package/manifest
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# 2011 Steven Armstrong (steven-cdist at armstrong.cc)
+# 2011-2013 Steven Armstrong (steven-cdist at armstrong.cc)
 #
 # This file is part of cdist.
 #
@@ -44,10 +44,12 @@ else
    esac
 fi
 
-set -- "$@" "$__object_id"
+state="$(cat "$__object/parameter/state")"
+
+set -- "$@" "$__object_id" "--state" "$state"
 cd "$__object/parameter"
 for property in $(ls .); do
-   if [ "$property" != "type" ]; then
+   if [ "$property" != "type" -a "$property" != "state" ]; then
       set -- "$@" "--$property" "$(cat "$property")"
    fi
 done
diff --git a/cdist/conf/type/__package/parameter/default/state b/cdist/conf/type/__package/parameter/default/state
new file mode 100644
index 00000000..e7f6134f
--- /dev/null
+++ b/cdist/conf/type/__package/parameter/default/state
@@ -0,0 +1 @@
+present
diff --git a/cdist/conf/type/__package/parameter/optional b/cdist/conf/type/__package/parameter/optional
index 9982507e..d674f32e 100644
--- a/cdist/conf/type/__package/parameter/optional
+++ b/cdist/conf/type/__package/parameter/optional
@@ -3,3 +3,4 @@ version
 type
 pkgsite
 state
+ptype
diff --git a/cdist/conf/type/__package_apt/gencode-remote b/cdist/conf/type/__package_apt/gencode-remote
index 7aba76d5..57339db3 100755
--- a/cdist/conf/type/__package_apt/gencode-remote
+++ b/cdist/conf/type/__package_apt/gencode-remote
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# 2011-2012 Nico Schottelius (nico-cdist at schottelius.org)
+# 2011-2013 Nico Schottelius (nico-cdist at schottelius.org)
 #
 # This file is part of cdist.
 #
@@ -42,6 +42,8 @@ case "$state_is" in
     ;;
 esac
 
+# Hint if we need to avoid questions at some point:
+# DEBIAN_PRIORITY=critical can reduce the number of questions
 aptget="DEBIAN_FRONTEND=noninteractive apt-get --quiet --yes --no-install-recommends -o DPkg::Options::=\"--force-confold\""
 
 [ "$state_is" = "$state_should" ] && exit 0
diff --git a/cdist/conf/type/__package_emerge/explorer/pkg_version b/cdist/conf/type/__package_emerge/explorer/pkg_version
new file mode 100644
index 00000000..7053eaff
--- /dev/null
+++ b/cdist/conf/type/__package_emerge/explorer/pkg_version
@@ -0,0 +1,35 @@
+#!/bin/sh
+#
+# 2013 Thomas Oettli (otho at sfs.biz)
+#
+# 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/>.
+#
+#
+# Retrieve the status of a package
+#
+
+if [ ! -x /usr/bin/equery ]; then
+    echo "gentoolkit not installed!" 1>&2
+    exit 1
+fi
+
+if [ -f "$__object/parameter/name" ]; then
+   name="$(cat "$__object/parameter/name")"
+else
+   name="$__object_id"
+fi
+
+equery -q l -F '$cp $fullversion' "$name" || true
diff --git a/cdist/conf/type/__package_emerge/gencode-remote b/cdist/conf/type/__package_emerge/gencode-remote
new file mode 100644
index 00000000..d4cee37e
--- /dev/null
+++ b/cdist/conf/type/__package_emerge/gencode-remote
@@ -0,0 +1,72 @@
+#!/bin/sh
+#
+# 2013 Thomas Oettli (otho at sfs.biz)
+#
+# 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/>.
+#
+#
+# Manage packages with Portage (mostly gentoo)
+#
+
+if [ -f "$__object/parameter/name" ]; then
+   name="$__object/parameter/name"
+else
+   name="$__object_id"
+fi
+
+if [ -f "$__object/parameter/state" ]; then
+   state_should="$(cat "$__object/parameter/state")"
+else
+   state_should="present"
+fi
+
+pkg_version="$(cat "$__object/explorer/pkg_version")"
+if [ -z "$pkg_version" ]; then
+    state_is="absent"
+elif [ $(echo "$pkg_version" | wc -l) -gt 1 ]; then
+    echo "Package name is not unique! The following packages are installed:"
+    echo "$pkg_version"
+    exit 1
+else
+    state_is="present"
+    installed_version="$(echo "$pkg_version" | cut -d " " -f 2)"
+fi
+
+if [ -f "$__object/parameter/version" ]; then
+    version="$(cat "$__object/parameter/version")"
+    if [ ! -z "$version" ]; then
+        name="=$name-$version"
+    fi
+else
+    version=""
+fi
+
+# Exit if nothing is needed to be done
+[ "$state_is" = "$state_should" ] && ( [ -z "$version" ] || [ "$installed_version" = "$version" ] ) && exit 0
+[ "$state_should" = "absent" ] && [ ! -z "$version" ] && [ "$installed_version" != "$version" ] && exit 0
+
+case "$state_should" in
+   present)
+        echo "emerge \"$name\" &>/dev/null || exit 1"
+        ;;
+   absent)
+        echo "emerge -C \"$name\" &>/dev/null || exit 1"
+        ;;
+   *)
+        echo "Unknown state: $state_should" >&2
+        exit 1
+        ;;
+esac
diff --git a/cdist/conf/type/__package_emerge/man.text b/cdist/conf/type/__package_emerge/man.text
new file mode 100644
index 00000000..983b49a8
--- /dev/null
+++ b/cdist/conf/type/__package_emerge/man.text
@@ -0,0 +1,60 @@
+cdist-type__package_emerge(7)
+=============================
+Thomas Oettli <otho--@--sfs.biz>
+
+
+NAME
+----
+cdist-type__package_emerge - Manage packages with portage
+
+
+DESCRIPTION
+-----------
+Portage is usually used on the gentoo distribution to manage packages.
+This type requires app-portage/gentoolkit installed on the target host.
+cdist-type__package_emerge_dependencies is supposed to install the needed
+packages on the target host.
+
+
+REQUIRED PARAMETERS
+-------------------
+None
+
+
+OPTIONAL PARAMETERS
+-------------------
+name::
+    If supplied, use the name and not the object id as the package name.
+
+state::
+    Either "present" or "absent", defaults to "present".
+
+version::
+    If supplied, use to install or uninstall a specific version of the package named.
+
+EXAMPLES
+--------
+
+--------------------------------------------------------------------------------
+# Ensure sys-devel/gcc is installed
+__package_emerge sys-devel/gcc --state present
+
+# If you want a specific version of a package
+__package_emerge app-portage/gentoolkit --state present --version 0.3.0.8-r2
+
+# Remove package
+__package_emerge sys-devel/gcc --state absent
+--------------------------------------------------------------------------------
+
+
+SEE ALSO
+--------
+- cdist-type(7)
+- cdist-type__package(7)
+- cdist-type__package_emerge_dependencies(7)
+
+
+COPYING
+-------
+Copyright \(C) 2013 Thomas Oettli. Free use of this software is
+granted under the terms of the GNU General Public License version 3 (GPLv3).
diff --git a/cdist/conf/type/__package_emerge/parameter/optional b/cdist/conf/type/__package_emerge/parameter/optional
new file mode 100644
index 00000000..f5c897df
--- /dev/null
+++ b/cdist/conf/type/__package_emerge/parameter/optional
@@ -0,0 +1,3 @@
+name
+state
+version
diff --git a/cdist/conf/type/__package_emerge_dependencies/explorer/flaggie_installed b/cdist/conf/type/__package_emerge_dependencies/explorer/flaggie_installed
new file mode 100644
index 00000000..1652ffc3
--- /dev/null
+++ b/cdist/conf/type/__package_emerge_dependencies/explorer/flaggie_installed
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+if [ -x /usr/bin/flaggie ]; then
+    echo "true"
+else
+    echo "false"
+fi
diff --git a/cdist/conf/type/__package_emerge_dependencies/explorer/gentoolkit_installed b/cdist/conf/type/__package_emerge_dependencies/explorer/gentoolkit_installed
new file mode 100644
index 00000000..74c2378d
--- /dev/null
+++ b/cdist/conf/type/__package_emerge_dependencies/explorer/gentoolkit_installed
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+if [ -x /usr/bin/q ]; then
+    echo "true"
+else
+    echo "false"
+fi
diff --git a/cdist/conf/type/__package_emerge_dependencies/gencode-remote b/cdist/conf/type/__package_emerge_dependencies/gencode-remote
new file mode 100644
index 00000000..0c84e53d
--- /dev/null
+++ b/cdist/conf/type/__package_emerge_dependencies/gencode-remote
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+gentoolkit_installed="$(cat "$__object/explorer/gentoolkit_installed")"
+flaggie_installed="$(cat "$__object/explorer/flaggie_installed")"
+
+if [ "${gentoolkit_installed}" != "true" ]; then
+    # emerge app-portage/gentoolkit
+    echo "emerge app-portage/gentoolkit &> /dev/null || exit 1"
+fi
+
+if [ "${flaggie_installed}" != "true" ]; then
+    # emerge app-portage/flaggie
+    echo "emerge app-portage/flaggie &> /dev/null || exit 1"
+fi
+
diff --git a/cdist/conf/type/__package_emerge_dependencies/man.text b/cdist/conf/type/__package_emerge_dependencies/man.text
new file mode 100644
index 00000000..0862256b
--- /dev/null
+++ b/cdist/conf/type/__package_emerge_dependencies/man.text
@@ -0,0 +1,48 @@
+cdist-type__package_emerge_dependencies(7)
+==========================================
+Thomas Oettli <otho--@--sfs.biz>
+
+
+NAME
+----
+cdist-type__package_emerge_dependencies - Install dependencies for __package_emerge
+
+
+DESCRIPTION
+-----------
+Portage is usually used on the gentoo distribution to manage packages.
+This type installs the following tools which are required by __package_emerge to work:
+app-portage/flaggie
+app-portage/gentoolkit
+
+
+REQUIRED PARAMETERS
+-------------------
+None
+
+
+OPTIONAL PARAMETERS
+-------------------
+None
+
+
+EXAMPLES
+--------
+
+--------------------------------------------------------------------------------
+# Ensure app-portage/flaggie and app-portage/gentoolkit are installed
+__package_emerge_dependencies
+--------------------------------------------------------------------------------
+
+
+SEE ALSO
+--------
+- cdist-type(7)
+- cdist-type__package(7)
+- cdist-type__package_emerge(7)
+
+
+COPYING
+-------
+Copyright \(C) 2013 Thomas Oettli. Free use of this software is
+granted under the terms of the GNU General Public License version 3 (GPLv3).
diff --git a/cdist/conf/type/__package_emerge_dependencies/singleton b/cdist/conf/type/__package_emerge_dependencies/singleton
new file mode 100644
index 00000000..e69de29b
diff --git a/cdist/conf/type/__package_zypper/explorer/pkg_version b/cdist/conf/type/__package_zypper/explorer/pkg_version
index 655b464d..7f203067 100644
--- a/cdist/conf/type/__package_zypper/explorer/pkg_version
+++ b/cdist/conf/type/__package_zypper/explorer/pkg_version
@@ -1,6 +1,7 @@
 #!/bin/sh
 #
 # 2011-2012 Nico Schottelius (nico-cdist at schottelius.org)
+# 2013 Daniel Heule (hda at sfs.biz)
 #
 # This file is part of cdist.
 #
@@ -18,7 +19,7 @@
 # along with cdist. If not, see <http://www.gnu.org/licenses/>.
 #
 #
-# Retrieve the status of a package
+# Retrieve the status of a package of different types
 #
 
 if [ -f "$__object/parameter/name" ]; then
@@ -27,4 +28,21 @@ else
    name="$__object_id"
 fi
 
-rpm -q --whatprovides "$name"  | grep -v 'no package provides' || true
+if [ -f "$__object/parameter/ptype" ]; then
+   ptype="$(cat "$__object/parameter/ptype")"
+else
+   ptype="package"
+fi
+
+case "$ptype" in
+    package)
+        zypper search --details --match-exact --installed-only --type "$ptype" "$name" | grep -E '^i' | cut -d " " -f 3,7 || true
+    ;;
+    patch|pattern|product|srcpackage)
+        zypper search --match-exact --installed-only --type "$ptype" "$name" | grep -E '^i' | cut -d " " -f 3 || true
+    ;;
+    *)
+        echo "unknown ptype in __package_zypper explorer" &>2
+        exit 1
+    ;;
+esac
diff --git a/cdist/conf/type/__package_zypper/gencode-remote b/cdist/conf/type/__package_zypper/gencode-remote
index d1766126..51713590 100644
--- a/cdist/conf/type/__package_zypper/gencode-remote
+++ b/cdist/conf/type/__package_zypper/gencode-remote
@@ -1,6 +1,7 @@
 #!/bin/sh
 #
 # 2012 Nico Schottelius (nico-cdist at schottelius.org)
+# 2013 Daniel Heule (hda at sfs.biz)
 #
 # This file is part of cdist.
 #
@@ -28,36 +29,59 @@
 globalopts="--quiet --non-interactive"
 
 if [ -f "$__object/parameter/name" ]; then
-   name="$__object/parameter/name"
+    name="$__object/parameter/name"
 else
-   name="$__object_id"
+    name="$__object_id"
 fi
 
 if [ -f "$__object/parameter/state" ]; then
-   state_should="$(cat "$__object/parameter/state")"
+    state_should="$(cat "$__object/parameter/state")"
 else
-   state_should="present"
+    state_should="present"
+fi
+
+if [ -f "$__object/parameter/ptype" ]; then
+    ptype="$(cat "$__object/parameter/ptype")"
+else
+    ptype="package"
+fi
+
+if [ -f "$__object/parameter/version" ]; then
+    version_should="$(cat "$__object/parameter/version")"
+    if [ "$ptype" != "package" ]; then
+        echo "version support only for type package implemented" >&2
+        exit 2
+    fi
+else
+    version_should=""
 fi
 
 pkg_version="$(cat "$__object/explorer/pkg_version")"
 if [ -z "$pkg_version" ]; then
     state_is="absent"
+    version_is=""
 else
     state_is="present"
+    version_is=${pkg_version##* }
 fi
 
-# Exit if nothing is needed to be done
-[ "$state_is" = "$state_should" ] && exit 0
 
 case "$state_should" in
-   present)
-         echo zypper $globalopts install --auto-agree-with-licenses \"$name\" ">/dev/null"
-   ;;
-   absent)
-         echo zypper $globalopts remove \"$name\" ">/dev/null"
-   ;;
-   *)
-      echo "Unknown state: $state_should" >&2
-      exit 1
-   ;;
+    present)
+        if [ -z "$version_should" ]; then
+            [ "$state_is" = "present" ] && exit 0 # if state is present, we dont need to do anything
+            echo zypper $globalopts install --type \"$ptype\" --auto-agree-with-licenses \"$name\" ">/dev/null"
+        else
+            [ "$state_is" = "present" ] && [ "$version_should" = "$version_is" ] && exit 0 # if state is present and version is correct, we dont need to do anything
+            echo zypper $globalopts install --oldpackage --type \"$ptype\" --auto-agree-with-licenses \"$name\" = \"$version_should\" ">/dev/null"
+        fi
+    ;;
+    absent)
+        [ "$state_is" = "absent" ] && exit 0 # if state is absent, we dont need to do anything
+        echo zypper $globalopts remove --type \"$ptype\" \"$name\" ">/dev/null"
+    ;;
+    *)
+        echo "Unknown state: $state_should" >&2
+        exit 1
+    ;;
 esac
diff --git a/cdist/conf/type/__package_zypper/man.text b/cdist/conf/type/__package_zypper/man.text
index e2261d33..104d3a7a 100644
--- a/cdist/conf/type/__package_zypper/man.text
+++ b/cdist/conf/type/__package_zypper/man.text
@@ -1,6 +1,6 @@
 cdist-type__package_zypper(7)
 =============================
-Nico Schottelius <nico-cdist--@--schottelius.org>
+Daniel Heule <hda--@--sfs.biz>
 
 
 NAME
@@ -26,19 +26,33 @@ name::
 state::
     Either "present" or "absent", defaults to "present"
 
+version::
+    The version of the package to install. Default is to install the version
+    choosen by the local package manager. For a list of available versions,
+    have a look at the output of "zypper se -s packagename"
+
+ptype::
+    Either "package", "patch", "pattern", "product" or "srcpackage", defaults to "package". For a description see man zypper.
+
 
 EXAMPLES
 --------
 
 --------------------------------------------------------------------------------
-# Ensure zsh in installed
+# Ensure zsh is installed
 __package_zypper zsh --state present
 
 # If you don't want to follow pythonX packages, but always use python
 __package_zypper python --state present --name python2
 
+# Ensure binutils is installed and the version is forced to be 2.23.1-0.19.2
+__package_zypper binutils --state present --version 2.23.1-0.19.2
+
 # Remove package
 __package_zypper cfengine --state absent
+
+# install all packages which belongs to pattern x11
+__package_zypper x11 --ptype pattern --state present
 --------------------------------------------------------------------------------
 
 
@@ -50,5 +64,6 @@ SEE ALSO
 
 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).
+Copyright \(C) 2012 Nico Schottelius.
+Copyright \(C) 2013 Daniel Heule.
+Free use of this software is granted under the terms of the GNU General Public License version 3 (GPLv3).
diff --git a/cdist/conf/type/__package_zypper/parameter/default/ptype b/cdist/conf/type/__package_zypper/parameter/default/ptype
new file mode 100644
index 00000000..ba3bd787
--- /dev/null
+++ b/cdist/conf/type/__package_zypper/parameter/default/ptype
@@ -0,0 +1 @@
+package
diff --git a/cdist/conf/type/__package_zypper/parameter/optional b/cdist/conf/type/__package_zypper/parameter/optional
index 1b423dc4..bc8565fc 100644
--- a/cdist/conf/type/__package_zypper/parameter/optional
+++ b/cdist/conf/type/__package_zypper/parameter/optional
@@ -1,2 +1,4 @@
 name
 state
+ptype
+version
diff --git a/cdist/conf/type/__postfix/manifest b/cdist/conf/type/__postfix/manifest
index 2dc70ce2..52a13919 100755
--- a/cdist/conf/type/__postfix/manifest
+++ b/cdist/conf/type/__postfix/manifest
@@ -22,7 +22,7 @@
 os=$(cat "$__global/explorer/os")
 
 case "$os" in
-   ubuntu|debian|archlinux)
+   ubuntu|debian|archlinux|suse)
       __package postfix --state present
    ;;
    *)
diff --git a/cdist/conf/type/__postfix_master/manifest b/cdist/conf/type/__postfix_master/manifest
index 1642e91b..87e2329b 100755
--- a/cdist/conf/type/__postfix_master/manifest
+++ b/cdist/conf/type/__postfix_master/manifest
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# 2012 Steven Armstrong (steven-cdist at armstrong.cc)
+# 2012 - 2013 Steven Armstrong (steven-cdist at armstrong.cc)
 #
 # This file is part of cdist.
 #
@@ -32,6 +32,7 @@ case "$os" in
    ;;
 esac
 
+__postfix
 
 # Default to object_id
 service="$(cat "$__object/parameter/service" 2>/dev/null || echo "$__object_id")"
diff --git a/cdist/conf/type/__postfix_postconf/explorer/value b/cdist/conf/type/__postfix_postconf/explorer/value
index edf48b48..e08c6da6 100755
--- a/cdist/conf/type/__postfix_postconf/explorer/value
+++ b/cdist/conf/type/__postfix_postconf/explorer/value
@@ -22,7 +22,7 @@
 os=$("$__explorer/os")
 
 case "$os" in
-   ubuntu|debian|archlinux)
+   ubuntu|debian|archlinux|suse)
       :
    ;;
    *)
diff --git a/cdist/conf/type/__postfix_postconf/gencode-remote b/cdist/conf/type/__postfix_postconf/gencode-remote
index 60143590..43c0482e 100755
--- a/cdist/conf/type/__postfix_postconf/gencode-remote
+++ b/cdist/conf/type/__postfix_postconf/gencode-remote
@@ -21,7 +21,7 @@
 os=$(cat "$__global/explorer/os")
 
 case "$os" in
-   ubuntu|debian|archlinux)
+   ubuntu|debian|archlinux|suse)
       :
    ;;
    *)
diff --git a/cdist/conf/type/__postfix_postconf/manifest b/cdist/conf/type/__postfix_postconf/manifest
new file mode 100755
index 00000000..0dde64e9
--- /dev/null
+++ b/cdist/conf/type/__postfix_postconf/manifest
@@ -0,0 +1,21 @@
+#!/bin/sh
+#
+# 2012 - 2013 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/>.
+#
+
+__postfix
diff --git a/cdist/conf/type/__postfix_postmap/manifest b/cdist/conf/type/__postfix_postmap/manifest
new file mode 100755
index 00000000..0dde64e9
--- /dev/null
+++ b/cdist/conf/type/__postfix_postmap/manifest
@@ -0,0 +1,21 @@
+#!/bin/sh
+#
+# 2012 - 2013 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/>.
+#
+
+__postfix
diff --git a/cdist/conf/type/__postfix_reload/manifest b/cdist/conf/type/__postfix_reload/manifest
new file mode 100755
index 00000000..0dde64e9
--- /dev/null
+++ b/cdist/conf/type/__postfix_reload/manifest
@@ -0,0 +1,21 @@
+#!/bin/sh
+#
+# 2012 - 2013 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/>.
+#
+
+__postfix
diff --git a/cdist/conf/type/__start_on_boot/explorer/state b/cdist/conf/type/__start_on_boot/explorer/state
index 4e0c82c2..e9e4318e 100755
--- a/cdist/conf/type/__start_on_boot/explorer/state
+++ b/cdist/conf/type/__start_on_boot/explorer/state
@@ -1,6 +1,7 @@
 #!/bin/sh
 #
 # 2012-2013 Nico Schottelius (nico-cdist at schottelius.org)
+# 2013 Daniel Heule (hda at sfs.biz)
 #
 # This file is part of cdist.
 #
@@ -23,9 +24,9 @@
 
 os=$("$__explorer/os")
 runlevel=$("$__explorer/runlevel")
+target_runlevel="$(cat "$__object/parameter/target_runlevel")"
 name="$__object_id"
 
-
 case "$os" in
     archlinux)
         state=$(systemctl is-enabled "$name" >/dev/null 2>&1 \
@@ -38,11 +39,23 @@ case "$os" in
         [ -f "/etc/rc$runlevel.d/S"??"$name" ] || state="absent"
     ;;
 
-    amazon|centos|fedora|owl|redhat|suse)
+    amazon|centos|fedora|owl|redhat)
         state=$(chkconfig --level "$runlevel" "$name" || echo absent)
         [ "$state" ] || state="present"
     ;;
-
+    suse)
+        # check for target if set, usable for boot. services in runlevel B
+        if [ "$target_runlevel" != 'default' ]; then
+            runlevel="$target_runlevel"
+        fi
+        # suses chkconfig has the same name, but works different ...
+        state=$(chkconfig --check "$name" "$runlevel" || echo absent)
+        [ "$state" ] || state="present"
+    ;;
+    gentoo)
+        state="present"
+        [ -f "/etc/runlevels/${target_runlevel}/${name}" ] || state="absent"
+    ;;
     *)
        echo "Unsupported os: $os" >&2
        exit 1
diff --git a/cdist/conf/type/__start_on_boot/gencode-remote b/cdist/conf/type/__start_on_boot/gencode-remote
index 58ff6a4a..61b2b9fe 100755
--- a/cdist/conf/type/__start_on_boot/gencode-remote
+++ b/cdist/conf/type/__start_on_boot/gencode-remote
@@ -1,6 +1,7 @@
 #!/bin/sh
 #
 # 2012-2013 Nico Schottelius (nico-cdist at schottelius.org)
+# 2013 Daniel Heule (hda at sfs.biz)
 #
 # This file is part of cdist.
 #
@@ -19,8 +20,9 @@
 #
 #
 
-state_should="$(cat "$__object/parameter/state" 2>/dev/null || echo present)"
+state_should="$(cat "$__object/parameter/state")"
 state_is=$(cat "$__object/explorer/state")
+target_runlevel="$(cat "$__object/parameter/target_runlevel")"
 
 # Short circuit if nothing is to be done
 [ "$state_should" = "$state_is" ] && exit 0
@@ -38,10 +40,9 @@ case "$state_should" in
                 echo "update-rc.d \"$name\" defaults >/dev/null"
             ;;
 
-#           FIXME: Disabled until the explorer is checked
-#            gentoo)
-#                echo rc-update add \"$name\" default
-#            ;;
+            gentoo)
+                echo rc-update add \"$name\" \"$target_runlevel\"
+            ;;
 
             amazon|centos|fedora|owl|redhat|suse)
                 echo chkconfig \"$name\" on
@@ -70,10 +71,9 @@ case "$state_should" in
                 echo update-rc.d -f \"$name\" remove
             ;;
 
-# FIXME: Disabled until the explorer is checked
-#            gentoo)
-#                echo rc-update del \"$name\"
-#            ;;
+            gentoo)
+                echo rc-update del \"$name\"  \"$target_runlevel\"
+            ;;
 
             centos|fedora|owl|redhat|suse)
                 echo chkconfig \"$name\" off
diff --git a/cdist/conf/type/__start_on_boot/man.text b/cdist/conf/type/__start_on_boot/man.text
index 6d804884..dfada6d8 100644
--- a/cdist/conf/type/__start_on_boot/man.text
+++ b/cdist/conf/type/__start_on_boot/man.text
@@ -14,7 +14,7 @@ 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).
+supported (i.e. *bsd are not implemented).
 
 
 REQUIRED PARAMETERS
@@ -25,6 +25,8 @@ OPTIONAL PARAMETERS
 -------------------
 state::
     Either "present" or "absent", defaults to "present"
+target_runlevel::
+    Runlevel which should be modified, defaults to "default" (only used on gentoo systems).
 
 
 EXAMPLES
diff --git a/cdist/conf/type/__start_on_boot/parameter/default/state b/cdist/conf/type/__start_on_boot/parameter/default/state
new file mode 100644
index 00000000..e7f6134f
--- /dev/null
+++ b/cdist/conf/type/__start_on_boot/parameter/default/state
@@ -0,0 +1 @@
+present
diff --git a/cdist/conf/type/__start_on_boot/parameter/default/target_runlevel b/cdist/conf/type/__start_on_boot/parameter/default/target_runlevel
new file mode 100644
index 00000000..4ad96d51
--- /dev/null
+++ b/cdist/conf/type/__start_on_boot/parameter/default/target_runlevel
@@ -0,0 +1 @@
+default
diff --git a/cdist/conf/type/__start_on_boot/parameter/optional b/cdist/conf/type/__start_on_boot/parameter/optional
index ff72b5c7..91685caf 100644
--- a/cdist/conf/type/__start_on_boot/parameter/optional
+++ b/cdist/conf/type/__start_on_boot/parameter/optional
@@ -1 +1,2 @@
 state
+target_runlevel
diff --git a/cdist/conf/type/__user/TODO b/cdist/conf/type/__user/TODO
deleted file mode 100644
index fa6aeee7..00000000
--- a/cdist/conf/type/__user/TODO
+++ /dev/null
@@ -1,2 +0,0 @@
-- delete users
-
diff --git a/cdist/conf/type/__user/gencode-remote b/cdist/conf/type/__user/gencode-remote
index a2cdfd22..463fbe49 100755
--- a/cdist/conf/type/__user/gencode-remote
+++ b/cdist/conf/type/__user/gencode-remote
@@ -2,6 +2,7 @@
 #
 # 2011 Steven Armstrong (steven-cdist at armstrong.cc)
 # 2011 Nico Schottelius (nico-cdist at schottelius.org)
+# 2013 Daniel Heule (hda at sfs.biz)
 #
 # This file is part of cdist.
 #
@@ -21,11 +22,14 @@
 #
 # Manage users.
 #
+#set -x
 
 name="$__object_id"
 
 os="$(cat "$__global/explorer/os")"
 
+state=$(cat "$__object/parameter/state")
+
 # We need to shorten options for both usermod and useradd since on some
 # systems (such as *BSD, Darwin) those commands do not handle GNU style long
 # options.
@@ -40,80 +44,99 @@ shorten_property() {
 	shell) ret="-s";;
 	uid) ret="-u";;
     create-home) ret="-m";;
+    system) ret="-r";;
     esac
     echo "$ret"
 }
 
-cd "$__object/parameter"
-if grep -q "^${name}:" "$__object/explorer/passwd"; then
-   for property in $(ls .); do
-      new_value="$(cat "$property")"
-      unset current_value
+if [ "$state" = "present" ]; then
+    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"
+          file="$__object/explorer/passwd"
 
-      case "$property" in
-         gid)
-            if $(echo "$new_value" | grep -q '^[0-9][0-9]*$'); then
-               field=4
+          case "$property" in
+             gid)
+                if $(echo "$new_value" | grep -q '^[0-9][0-9]*$'); then
+                   field=4
+                else
+                   # 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)
+                field=2
+                file="$__object/explorer/shadow"
+             ;;
+             comment) field=5 ;;
+             home)    field=6 ;;
+             shell)   field=7 ;;
+             uid)     field=3 ;;
+             create-home) continue;; # Does not apply to user modification
+             system) continue;; # Does not apply to user modification
+             state) continue;; # Does not apply to user modification
+             remove-home) continue;; # Does not apply to user modification
+          esac
+
+          # 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 -- "$@" "$(shorten_property $property)" \'$new_value\'
+          fi
+       done
+
+       if [ $# -gt 0 ]; then
+          echo mod >> "$__messages_out"
+          if [ "$os" = "freebsd" ]; then
+             echo pw usermod "$@" "$name"
+          else
+             echo usermod "$@" "$name"
+          fi
+       else
+          true
+       fi
+    else
+        echo add >> "$__messages_out"
+        for property in $(ls .); do
+            [ "$property" = "state" ] && continue
+            [ "$property" = "remove-home" ] && continue
+            new_value="$(cat "$property")"
+            if [ -z "$new_value" ];then       # Boolean values have no value
+              set -- "$@" "$(shorten_property $property)"
             else
-               # 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
+              set -- "$@" "$(shorten_property $property)" \'$new_value\'
             fi
-         ;;
-         password)
-            field=2
-            file="$__object/explorer/shadow"
-         ;;
-         comment) field=5 ;;
-         home)    field=6 ;;
-         shell)   field=7 ;;
-         uid)     field=3 ;;
-         create-home) continue;; # Does not apply to user modification
-      esac
+        done
 
-      # 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 -- "$@" "$(shorten_property $property)" \'$new_value\'
-      fi
-   done
-
-   if [ $# -gt 0 ]; then
-      if [ "$os" = "freebsd" ]; then
-         echo pw usermod "$@" "$name"
-      else
-         echo usermod "$@" "$name"
-      fi
-   else
-      true
-   fi
+       if [ "$os" = "freebsd" ]; then
+          echo pw useradd "$@" "$name"
+       else
+          echo useradd "$@" "$name"
+       fi
+    fi
 else
-   for property in $(ls .); do
-      new_value="$(cat "$property")"
-      if [ -z "$new_value" ];then       # Boolean values have no value
-          set -- "$@" "$(shorten_property $property)"
-      else
-          set -- "$@" "$(shorten_property $property)" \'$new_value\'
-      fi
-   done
-
-   if [ "$os" = "freebsd" ]; then
-      echo pw useradd "$@" "$name"
-   else
-      echo useradd "$@" "$name"
-   fi
+    if grep -q "^${name}:" "$__object/explorer/passwd"; then
+        #user exists, but state != present, so delete it
+        if [ -f "$__object/parameter/remove-home" ]; then
+            echo userdel -r "${name}"
+        else
+            echo userdel "${name}"
+        fi
+    fi
 fi
diff --git a/cdist/conf/type/__user/man.text b/cdist/conf/type/__user/man.text
index 9db4a9f0..47e63d3d 100644
--- a/cdist/conf/type/__user/man.text
+++ b/cdist/conf/type/__user/man.text
@@ -20,19 +20,29 @@ None.
 
 OPTIONAL PARAMETERS
 -------------------
+state::
+    absent or present, defaults to present
 comment::
-   see usermod(8)
+    see usermod(8)
 home::
-   see above
+    see above
 gid::
-   see above
+    see above
 password::
-   see above
+    see above
 shell::
-   see above
+    see above
 uid::
-   see above
+    see above
 
+BOOLEAN PARAMETERS
+------------------
+system::
+    see useradd(8), apply only on user create
+create-home::
+    see useradd(8), apply only on user create
+remove-home::
+    see userdel(8), apply only on user delete
 
 EXAMPLES
 --------
@@ -44,8 +54,14 @@ __user foobar
 # Same but with a different shell
 __user foobar --shell /bin/zsh
 
+# Same but for a system account
+__user foobar --system
+
 # Set explicit uid and home
 __user foobar --uid 1001 --shell /bin/zsh --home /home/foobar
+
+# Drop user if exists
+__user foobar --state absent
 --------------------------------------------------------------------------------
 
 
diff --git a/cdist/conf/type/__user/parameter/boolean b/cdist/conf/type/__user/parameter/boolean
index e0517c6a..83afdebe 100644
--- a/cdist/conf/type/__user/parameter/boolean
+++ b/cdist/conf/type/__user/parameter/boolean
@@ -1 +1,3 @@
 create-home
+remove-home
+system
diff --git a/cdist/conf/type/__user/parameter/default/state b/cdist/conf/type/__user/parameter/default/state
new file mode 100644
index 00000000..e7f6134f
--- /dev/null
+++ b/cdist/conf/type/__user/parameter/default/state
@@ -0,0 +1 @@
+present
diff --git a/cdist/conf/type/__user/parameter/optional b/cdist/conf/type/__user/parameter/optional
index e3cf52d5..de6c3838 100644
--- a/cdist/conf/type/__user/parameter/optional
+++ b/cdist/conf/type/__user/parameter/optional
@@ -1,3 +1,4 @@
+state
 comment
 home
 gid
diff --git a/cdist/conf/type/__zypper_repo/explorer/all_repo_ids b/cdist/conf/type/__zypper_repo/explorer/all_repo_ids
new file mode 100644
index 00000000..b37d8ac5
--- /dev/null
+++ b/cdist/conf/type/__zypper_repo/explorer/all_repo_ids
@@ -0,0 +1,24 @@
+#!/bin/sh
+#
+# 2013 Daniel Heule (hda at sfs.biz)
+#
+# 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/>.
+#
+#
+# Retrieve all repo id nummbers - parsed zypper output
+#
+#
+echo $(zypper lr | cut -d'|' -f 1 | grep -E '^[0-9]')
diff --git a/cdist/conf/type/__zypper_repo/explorer/enabled_repo_ids b/cdist/conf/type/__zypper_repo/explorer/enabled_repo_ids
new file mode 100644
index 00000000..2dfb946f
--- /dev/null
+++ b/cdist/conf/type/__zypper_repo/explorer/enabled_repo_ids
@@ -0,0 +1,26 @@
+#!/bin/sh
+#
+# 2013 Daniel Heule (hda at sfs.biz)
+#
+# 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/>.
+#
+#
+# Retrieve all repo id nummbers from enabled repos - parsed zypper output
+#
+#
+# simpler command which works only on SLES11 SP3 or newer:
+# echo $(zypper lr -E | cut -d'|' -f 1 | grep -E '^[0-9]')
+echo $(zypper lr |  grep -E '^[0-9]([^|]+\|){3,3} Yes' | cut -d'|' -f 1)
diff --git a/cdist/conf/type/__zypper_repo/explorer/repo_id b/cdist/conf/type/__zypper_repo/explorer/repo_id
new file mode 100644
index 00000000..83a698b7
--- /dev/null
+++ b/cdist/conf/type/__zypper_repo/explorer/repo_id
@@ -0,0 +1,29 @@
+#!/bin/sh
+#
+# 2013 Daniel Heule (hda at sfs.biz)
+#
+# 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/>.
+#
+#
+# Retrieve the id from the repo with the uri from parameter repo_uri  - parsed zypper output
+#
+#
+if [ -f "$__object/parameter/repo_uri" ]; then
+   uri="$(cat "$__object/parameter/repo_uri")"
+else
+   uri="$__object_id"
+fi
+echo $(zypper lr -u | grep -E "\<$uri\>" | cut -d'|' -f 1 | grep -E '^[0-9]' )
diff --git a/cdist/conf/type/__zypper_repo/gencode-remote b/cdist/conf/type/__zypper_repo/gencode-remote
new file mode 100644
index 00000000..4d834c47
--- /dev/null
+++ b/cdist/conf/type/__zypper_repo/gencode-remote
@@ -0,0 +1,102 @@
+#!/bin/sh
+#
+# 2013 Daniel Heule (hda at sfs.biz)
+#
+# 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/>.
+#
+#
+# Manage repo services with Zypper (mostly suse)
+#
+
+# Debug
+#exec >&2
+#set -x
+
+zypper_def_opts=" -q "
+
+if [ -f "$__object/parameter/repo_desc" ]; then
+   desc="$(cat "$__object/parameter/repo_desc")"
+else
+   desc="$__object_id"
+fi
+
+if [ -f "$__object/parameter/repo_uri" ]; then
+   uri="$(cat "$__object/parameter/repo_uri")"
+else
+   uri="$__object_id"
+fi
+
+if [ -f "$__object/parameter/repo_id" ]; then
+   id="$(cat "$__object/parameter/repo_id")"
+else
+   id="$__object_id"
+fi
+
+if [ -f "$__object/parameter/state" ]; then
+   state="$(cat "$__object/parameter/state")"
+else
+   state="present"
+fi
+
+repo_id="$(cat "$__object/explorer/repo_id")"
+
+act_id=""
+if grep -q "$id" "$__object/explorer/all_repo_ids"; then
+    act_id="$id"
+elif grep -q "$repo_id" "$__object/explorer/all_repo_ids"; then
+    act_id="$repo_id" 
+fi
+
+repostate="disabled"
+if grep -q "$act_id" "$__object/explorer/enabled_repo_ids"; then
+    repostate="enabled"
+fi
+
+
+case "$state" in
+   present)
+         if [ -z "$desc" ] || [ -z "$uri" ]; then
+             echo "parameter repo_desc and repo_uri for $state needed" >&2
+             exit 4
+         fi
+         if [ -z "$repo_id" ]; then
+             # Repo not present, so we need to create it 
+             echo zypper $zypper_def_opts addrepo "'$uri'" "'$desc'"
+         fi
+   ;;
+   absent)
+         if [ ! -z "$act_id" ]; then
+             # Repo present (act_id not ""), so we ned to delete it
+             echo zypper $zypper_def_opts removerepo "$act_id"
+         fi
+   ;;
+   enabled)
+         if [ ! -z "$act_id" ] && [ "$repostate" = "disabled" ]; then
+             # Repo present (act_id not "") and repostate not enabled, so a enable call is needed
+             echo zypper $zypper_def_opts modifyrepo -e "$act_id"
+         fi
+   ;;
+   disabled)
+         if [ ! -z "$act_id" ] && [ "$repostate" = "enabled" ]; then
+             # Repo present (act_id not "") and repostate enabled, so a disable call is needed
+             echo zypper $zypper_def_opts modifyrepo -d "$act_id"
+         fi
+   ;;
+   *)
+      echo "Unknown state: $state" >&2
+      exit 1
+   ;;
+esac
diff --git a/cdist/conf/type/__zypper_repo/man.text b/cdist/conf/type/__zypper_repo/man.text
new file mode 100644
index 00000000..6ea88f16
--- /dev/null
+++ b/cdist/conf/type/__zypper_repo/man.text
@@ -0,0 +1,73 @@
+cdist-type__zypper_repo(7)
+==========================
+Daniel Heule <hda--@--sfs.biz>
+
+
+NAME
+----
+cdist-type__zypper_repo - repository management with zypper
+
+
+DESCRIPTION
+-----------
+zypper is usually used on the SuSE distribution to manage repositories.
+
+
+REQUIRED PARAMETERS
+-------------------
+None
+
+
+OPTIONAL PARAMETERS
+-------------------
+state::
+    Either "present" or "absent" or "enabled" or "disabled", defaults to "present" + 
+    #present#  - make sure that the repo is aviable, needs repo_uri and repo_desc + 
+         for all following states, the repo can be searched via repo_id or repo_uri + 
+    #absent#   - drop the repo if found + 
+    #enabled#  - a repo can have state disabled if installed via zypper service (ris), in this case, you can enable the repo + 
+    #disabled# - instead of absent (drop), a repo can also set to disabled, wich makes it inaccessible + 
+
+repo_uri::
+    If supplied, use the uri and not the object id as repo uri.
+
+repo_desc::
+    If supplied, use the description and not the object id as repo description, only used if the state is present and the repo has to be created
+
+repo_id::
+    If supplied, use the id and not the object id as repo id, can be used with state absent, enabled and disabled
+
+
+EXAMPLES
+--------
+
+--------------------------------------------------------------------------------
+# Ensure testrepo in installed
+__zypper_repo testrepo --state present --repo_uri http://url.to.your.repo/with/path
+
+# Drop repo by repo uri
+__zypper_repo testrepo --state absent --repo_uri http://url.to.your.repo/with/path
+
+# Drop repo by id number (attention: repos are always numbered from 1 to max)
+__zypper_repo testrepo --state absent --repo_id 1
+
+# enable repo by id
+__zypper_repo testrepo2 --state enabled --repo_id 2
+
+# enable repo by uri
+__zypper_repo testrepo3 --state enabled --repo_uri http://url.to.your.repo/with/path
+
+# disable a repo works like enabling it
+__zypper_repo testrepo4 --state disabled --repo_id 4
+--------------------------------------------------------------------------------
+
+
+SEE ALSO
+--------
+- cdist-type(7)
+
+
+COPYING
+-------
+Copyright \(C) 2013 Daniel Heule. Free use of this software is
+granted under the terms of the GNU General Public License version 3 (GPLv3).
diff --git a/cdist/conf/type/__zypper_repo/parameter/default/state b/cdist/conf/type/__zypper_repo/parameter/default/state
new file mode 100644
index 00000000..e7f6134f
--- /dev/null
+++ b/cdist/conf/type/__zypper_repo/parameter/default/state
@@ -0,0 +1 @@
+present
diff --git a/cdist/conf/type/__zypper_repo/parameter/optional b/cdist/conf/type/__zypper_repo/parameter/optional
new file mode 100644
index 00000000..6f5a8325
--- /dev/null
+++ b/cdist/conf/type/__zypper_repo/parameter/optional
@@ -0,0 +1,4 @@
+state
+repo_uri
+repo_desc
+repo_id
diff --git a/cdist/conf/type/__zypper_service/explorer/repo_ids b/cdist/conf/type/__zypper_service/explorer/repo_ids
new file mode 100644
index 00000000..e831b76c
--- /dev/null
+++ b/cdist/conf/type/__zypper_service/explorer/repo_ids
@@ -0,0 +1,27 @@
+#!/bin/sh
+#
+# 2013 Daniel Heule (hda at sfs.biz)
+#
+# 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/>.
+#
+#
+# Manage services with Zypper (mostly suse)
+#
+#
+# simpler command which works only on SLES11 SP3 or newer:
+# echo $(zypper lr -u -E | cut -d'|' -f 1 | grep -E '^[0-9]')
+# on older systems, zypper doesn't know the parameter -E 
+echo $(zypper lr -u | grep -E '^([^|]+\|){3,3} Yes' | cut -d'|' -f 1 | grep -E '^[0-9]')
diff --git a/cdist/conf/type/__zypper_service/explorer/service_id b/cdist/conf/type/__zypper_service/explorer/service_id
new file mode 100644
index 00000000..9c3d3a2d
--- /dev/null
+++ b/cdist/conf/type/__zypper_service/explorer/service_id
@@ -0,0 +1,30 @@
+#!/bin/sh
+#
+# 2013 Daniel Heule (hda at sfs.biz)
+#
+# 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/>.
+#
+#
+# Manage services with Zypper (mostly suse)
+#
+if [ -f "$__object/parameter/service_uri" ]; then
+   uri="$(cat "$__object/parameter/service_uri")"
+else
+   uri="/$__object_id"
+fi
+# simpler command which works only on SLES11 SP3 or newer:
+# echo $(zypper ls -u -E | grep -E "\<$uri\>" | cut -d'|' -f 1 )
+echo $(zypper ls -u | grep -E '^([^|]+\|){3,3} Yes' | grep -E "\<$uri\>" | cut -d'|' -f 1 )
diff --git a/cdist/conf/type/__zypper_service/explorer/service_ids b/cdist/conf/type/__zypper_service/explorer/service_ids
new file mode 100644
index 00000000..0f1f4186
--- /dev/null
+++ b/cdist/conf/type/__zypper_service/explorer/service_ids
@@ -0,0 +1,25 @@
+#!/bin/sh
+#
+# 2013 Daniel Heule (hda at sfs.biz)
+#
+# 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/>.
+#
+#
+# Manage services with Zypper (mostly suse)
+#
+# simpler command which works only on SLES11 SP3 or newer:
+# echo $(zypper ls -u -E | cut -d'|' -f 1 | grep -E '^[0-9]')
+echo $(zypper ls -u | grep -E '^([^|]+\|){3,3} Yes' | cut -d'|' -f 1 | grep -E '^[0-9]')
diff --git a/cdist/conf/type/__zypper_service/explorer/service_uri b/cdist/conf/type/__zypper_service/explorer/service_uri
new file mode 100644
index 00000000..2f4f8960
--- /dev/null
+++ b/cdist/conf/type/__zypper_service/explorer/service_uri
@@ -0,0 +1,30 @@
+#!/bin/sh
+#
+# 2013 Daniel Heule (hda at sfs.biz)
+#
+# 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/>.
+#
+#
+# Manage services with Zypper (mostly suse)
+#
+if [ -f "$__object/parameter/service_uri" ]; then
+   uri="$(cat "$__object/parameter/service_uri")"
+else
+   uri="/$__object_id"
+fi
+# simpler command which works only on SLES11 SP3 or newer:
+# echo $(zypper ls -u -E | grep -E "\<$uri\>" | cut -d'|' -f 7)
+echo $(zypper ls -u | grep -E '^([^|]+\|){3,3} Yes' | grep -E "\<$uri\>" | cut -d'|' -f 7 )
diff --git a/cdist/conf/type/__zypper_service/gencode-remote b/cdist/conf/type/__zypper_service/gencode-remote
new file mode 100644
index 00000000..d11749ae
--- /dev/null
+++ b/cdist/conf/type/__zypper_service/gencode-remote
@@ -0,0 +1,94 @@
+#!/bin/sh
+#
+# 2013 Daniel Heule (hda at sfs.biz)
+#
+# 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/>.
+#
+#
+# Manage services with Zypper (mostly suse)
+#
+
+# Debug
+#exec >&2
+#set -x
+
+zypper_def_opts=" -q "
+
+if [ -f "$__object/parameter/service_desc" ]; then
+   desc="$(cat "$__object/parameter/service_desc")"
+else
+   desc="$__object_id"
+fi
+
+if [ -f "$__object/parameter/service_uri" ]; then
+   uri="$(cat "$__object/parameter/service_uri")"
+else
+   uri="$__object_id"
+fi
+
+if [ -f "$__object/parameter/state" ]; then
+   state_should="$(cat "$__object/parameter/state")"
+else
+   state_should="present"
+fi
+
+if [ -f "$__object/parameter/type" ]; then
+   stype="$(cat "$__object/parameter/type")"
+else
+   stype="ris"
+fi
+
+exp_uri="$(cat "$__object/explorer/service_uri")"
+exp_id="$(cat "$__object/explorer/service_id")"
+
+# we need this list to remove ids, but we must do this in reverse order
+exp_ids="$(cat "$__object/explorer/service_ids" | rev)"
+
+if [ "$uri" = "$exp_uri" ] ; then
+    state_is="present"
+else
+    state_is="absent"
+fi
+
+# remove all other services if needed ...
+if [ -f "$__object/parameter/remove-all-other-services" ]; then
+   # file exists -> True
+   for i in $exp_ids; do
+     if [ "$i" != "$exp_id" ] ; then
+       echo zypper $zypper_def_opts  removeservice "$i" "&>/dev/null"
+     fi
+   done 
+   echo zypper $zypper_def_opts refs "&>/dev/null"
+fi
+
+
+# Exit if nothing is needed to be done
+[ "$state_is" = "$state_should" ] && exit 0
+
+case "$state_should" in
+   present)
+         echo zypper $zypper_def_opts addservice -t "$stype" "$uri" \"$desc\"
+         echo zypper $zypper_def_opts refs
+   ;;
+   absent)
+         echo zypper $zypper_def_opts removeservice "$service_id"
+         echo zypper $zypper_def_opts refs
+   ;;
+   *)
+      echo "Unknown state: $state_should" >&2
+      exit 1
+   ;;
+esac
diff --git a/cdist/conf/type/__zypper_service/man.text b/cdist/conf/type/__zypper_service/man.text
new file mode 100644
index 00000000..31543d93
--- /dev/null
+++ b/cdist/conf/type/__zypper_service/man.text
@@ -0,0 +1,67 @@
+cdist-type__zypper_service(7)
+=============================
+Daniel Heule <hda--@--sfs.biz>
+
+
+NAME
+----
+cdist-type__zypper_service - service management with zypper
+
+
+DESCRIPTION
+-----------
+zypper is usually used on SuSE systems to manage services.
+
+
+REQUIRED PARAMETERS
+-------------------
+service_uri::
+    Uri of the service
+
+
+OPTIONAL PARAMETERS
+-------------------
+service_desc::
+    If supplied, use the service_desc and not the object id as descritpion for the service.
+
+state::
+    Either "present" or "absent", defaults to "present"  
+
+type::
+    Defaults to "ris", the standard type of services at SLES11. For other values, see manpage of zypper.
+
+
+BOOLEAN PARAMETERS
+------------------
+remove-all-other-services::
+   Drop all other services found on the target host before adding the new one.
+
+remove-all-repos::
+   If supplied, remove all existing repos prior to setup the new service.
+
+
+EXAMPLES
+--------
+
+--------------------------------------------------------------------------------
+# Ensure that internal SLES11 SP3 RIS is in installed and all other services and repos are discarded
+__zypper_service INTERNAL_SLES11_SP3 --service_desc "Internal SLES11 SP3 RIS" --service_uri "http://path/to/your/ris/dir" --remove-all-other-services --remove-all-repos
+
+# Ensure that internal SLES11 SP3 RIS is in installed, no changes to ohter services or repos
+__zypper_service INTERNAL_SLES11_SP3 --service_desc "Internal SLES11 SP3 RIS" --service_uri "http://path/to/your/ris/dir"
+
+# Drop service by uri, no changes to ohter services or repos
+__zypper_service INTERNAL_SLES11_SP3 --state absent --service_uri "http://path/to/your/ris/dir"
+
+--------------------------------------------------------------------------------
+
+
+SEE ALSO
+--------
+- cdist-type(7)
+
+
+COPYING
+-------
+Copyright \(C) 2013 Daniel Heule. Free use of this software is
+granted under the terms of the GNU General Public License version 3 (GPLv3).
diff --git a/cdist/conf/type/__zypper_service/manifest b/cdist/conf/type/__zypper_service/manifest
new file mode 100644
index 00000000..d8773605
--- /dev/null
+++ b/cdist/conf/type/__zypper_service/manifest
@@ -0,0 +1,63 @@
+#!/bin/sh
+#
+# 2013 Daniel Heule (hda at sfs.biz)
+#
+# 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/>.
+#
+#
+# Manage services with Zypper (mostly suse)
+#
+
+# Debug
+#exec >&2
+#set -x
+
+zypper_def_opts=" -q "
+
+if [ -f "$__object/parameter/service_uri" ]; then
+   uri="$(cat "$__object/parameter/service_uri")"
+else
+   uri="$__object_id"
+fi
+
+if [ -f "$__object/parameter/state" ]; then
+   state_should="$(cat "$__object/parameter/state")"
+else
+   state_should="present"
+fi
+
+exp_uri="$(cat "$__object/explorer/service_uri")"
+
+if [ "$uri" = "$exp_uri" ] ; then
+    state_is="present"
+else
+    state_is="absent"
+fi
+
+
+# Exit if nothing is needed to be done
+[ "$state_is" = "$state_should" ] && exit 0
+
+# we need this list to remove ids, but we must do this in reverse order
+exp_repos="$(cat "$__object/explorer/repo_ids" | rev)"
+
+# boolean parameter
+if [ -f "$__object/parameter/remove-all-repos" ]; then
+   # file exists -> True
+   for i in $exp_repos; do
+     __zypper_repo "droprepo${i}" --state absent --repo_id "${i}"
+   done 
+fi
diff --git a/cdist/conf/type/__zypper_service/parameter/boolean b/cdist/conf/type/__zypper_service/parameter/boolean
new file mode 100644
index 00000000..ca711ded
--- /dev/null
+++ b/cdist/conf/type/__zypper_service/parameter/boolean
@@ -0,0 +1,2 @@
+remove-all-other-services
+remove-all-repos
diff --git a/cdist/conf/type/__zypper_service/parameter/default/state b/cdist/conf/type/__zypper_service/parameter/default/state
new file mode 100644
index 00000000..e7f6134f
--- /dev/null
+++ b/cdist/conf/type/__zypper_service/parameter/default/state
@@ -0,0 +1 @@
+present
diff --git a/cdist/conf/type/__zypper_service/parameter/default/type b/cdist/conf/type/__zypper_service/parameter/default/type
new file mode 100644
index 00000000..b928830f
--- /dev/null
+++ b/cdist/conf/type/__zypper_service/parameter/default/type
@@ -0,0 +1 @@
+ris
diff --git a/cdist/conf/type/__zypper_service/parameter/optional b/cdist/conf/type/__zypper_service/parameter/optional
new file mode 100644
index 00000000..b26c78d8
--- /dev/null
+++ b/cdist/conf/type/__zypper_service/parameter/optional
@@ -0,0 +1,3 @@
+service_desc
+state
+type
diff --git a/cdist/conf/type/__zypper_service/parameter/required b/cdist/conf/type/__zypper_service/parameter/required
new file mode 100644
index 00000000..2b4645ee
--- /dev/null
+++ b/cdist/conf/type/__zypper_service/parameter/required
@@ -0,0 +1 @@
+service_uri
diff --git a/cdist/core/cdist_object.py b/cdist/core/cdist_object.py
index e3c1c532..45b5e3ff 100644
--- a/cdist/core/cdist_object.py
+++ b/cdist/core/cdist_object.py
@@ -201,7 +201,6 @@ class CdistObject(object):
     autorequire = fsproperty.FileListProperty(lambda obj: os.path.join(obj.absolute_path, 'autorequire'))
     parameters = fsproperty.DirectoryDictProperty(lambda obj: os.path.join(obj.base_path, obj.parameter_path))
     explorers = fsproperty.DirectoryDictProperty(lambda obj: os.path.join(obj.base_path, obj.explorer_path))
-    changed = fsproperty.FileBooleanProperty(lambda obj: os.path.join(obj.absolute_path, "changed"))
     state = fsproperty.FileStringProperty(lambda obj: os.path.join(obj.absolute_path, "state"))
     source = fsproperty.FileListProperty(lambda obj: os.path.join(obj.absolute_path, "source"))
     code_local = fsproperty.FileStringProperty(lambda obj: os.path.join(obj.base_path, obj.code_local_path))
diff --git a/cdist/emulator.py b/cdist/emulator.py
index b1cd8f2d..b70ef956 100644
--- a/cdist/emulator.py
+++ b/cdist/emulator.py
@@ -37,6 +37,20 @@ class MissingRequiredEnvironmentVariableError(cdist.Error):
         return self.message
 
 
+class DefaultList(list):
+    """Helper class to allow default values for optional_multiple parameters.
+
+    @see https://groups.google.com/forum/#!msg/comp.lang.python/sAUvkJEDpRc/RnRymrzJVDYJ
+    """
+    def __copy__(self):
+        return []
+
+    @classmethod
+    def create(cls, initial=None):
+        if initial:
+            return cls(initial.split('\n'))
+
+
 class Emulator(object):
     def __init__(self, argv, stdin=sys.stdin.buffer, env=os.environ):
         self.argv           = argv
@@ -101,7 +115,7 @@ class Emulator(object):
         for parameter in self.cdist_type.optional_multiple_parameters:
             argument = "--" + parameter
             parser.add_argument(argument, dest=parameter, action='append', required=False,
-                default=self.cdist_type.parameter_defaults.get(parameter, None))
+                default=DefaultList.create(self.cdist_type.parameter_defaults.get(parameter, None)))
         for parameter in self.cdist_type.boolean_parameters:
             argument = "--" + parameter
             parser.add_argument(argument, dest=parameter, action='store_const', const='')
@@ -128,8 +142,6 @@ class Emulator(object):
         self.parameters = {}
         for key,value in vars(self.args).items():
             if value is not None:
-                if isinstance(value, list):
-                    value = '\n'.join(value)
                 self.parameters[key] = value
 
         if self.cdist_object.exists:
diff --git a/cdist/test/cdist_object/__init__.py b/cdist/test/cdist_object/__init__.py
index ffb2ba79..54ecf637 100644
--- a/cdist/test/cdist_object/__init__.py
+++ b/cdist/test/cdist_object/__init__.py
@@ -102,7 +102,6 @@ class ObjectTestCase(test.CdistTestCase):
         self.cdist_object = core.CdistObject(self.cdist_type, object_base_path, 'moon') 
 
     def tearDown(self):
-        self.cdist_object.changed = False
         self.cdist_object.prepared = False
         self.cdist_object.ran = False
         self.cdist_object.source = []
@@ -172,13 +171,6 @@ class ObjectTestCase(test.CdistTestCase):
         expected = []
         self.assertEqual(list(self.cdist_object.requirements), expected)
 
-    def test_changed(self):
-        self.assertFalse(self.cdist_object.changed)
-
-    def test_changed_after_changing(self):
-        self.cdist_object.changed = True
-        self.assertTrue(self.cdist_object.changed)
-
     def test_state(self):
         self.assertEqual(self.cdist_object.state, '')
 
diff --git a/cdist/util/fsproperty.py b/cdist/util/fsproperty.py
index 5814b2b4..49d4a32d 100644
--- a/cdist/util/fsproperty.py
+++ b/cdist/util/fsproperty.py
@@ -134,7 +134,11 @@ class DirectoryDict(collections.MutableMapping):
     def __setitem__(self, key, value):
         try:
             with open(os.path.join(self.path, key), "w") as fd:
-                if type(value) == type([]):
+                if (not hasattr(value, 'strip') and
+                    (hasattr(value, '__getitem__') or
+                    hasattr(value, '__iter__'))):
+                    # if it looks like a sequence and quacks like a sequence,
+                    # it is a sequence
                     for v in value:
                         fd.write(str(v) + '\n')
                 else:
diff --git a/docs/changelog b/docs/changelog
index 577194bf..d83552f5 100644
--- a/docs/changelog
+++ b/docs/changelog
@@ -4,11 +4,41 @@ Changelog
 	* Changes are always commented with their author in (braces)
 	* Exception: No braces means author == Nico Schottelius
 
+3.0.1:
+	* Type __line: Remove unecessary backslash escape
+	* Type __directory: Add messaging support (Daniel Heule)
+	* Type __directory: Do not generate code if mode is 0xxx ((Daniel Heule)
+	* Type __directory: Add messaging support (Daniel Heule)
+	* Type __package: Fix typo in optional parameter ptype (Daniel Heule)
+	* Type __start_on_boot: Fix for SuSE's chkconfig (Daniel Heule)
 
-3.0.0:
-	* Core: Messaging support added
-	* Type: __iptables_rule: Use default parameter
+3.0.0: 2013-12-24
+	* Core: Added messaging support
+	* Core: Removed unused "changed" attribute of objects 
+	* Core: Support default values for multiple parameters (Steven Armstrong)
+	* Core: Ensure Object Parameter file contains \n (Steven Armstrong)
+	* New Type: __zypper_repo (Daniel Heule)
+	* New Type: __zypper_service (Daniel Heule)
+	* New Type: __package_emerge (Daniel Heule)
+	* New Type: __package_emerge_dependencies (Daniel Heule)
+	* Type __cron: Add support for raw lines (Daniel Heule)
+	* Type __cron: Suppress stderr output from crontab (Daniel Heule)
+	* Type __cron: Fix quoting issue (Daniel Heule)
 	* Type __file: Do not generate code if mode is 0xxx
+	* Type __iptables_rule: Use default parameter
+	* Type __key_value: Fix quoting issue (Steven Armstrong)
+	* Type __package: Use state --present by default (Steven Armstrong)
+	* Type __package_zypper: Support non packages as well (Daniel Heule)
+	* Type __package_zypper: Support package versions (Daniel Heule)
+	* Type __postfix_*: Depend on __postfix Type (Steven Armstrong)
+	* Type __postfix_postconf: Enable support for SuSE (Daniel Heule)
+	* Type __postfix: Enable support for SuSE (Daniel Heule)
+	* Type __start_on_boot: Use default parameter state
+	* Type __start_on_boot: Add support for gentoo (Daniel Heule)
+	* Type __user: Add support for state parameter (Daniel Heule)
+	* Type __user: Add support for system users (Daniel Heule)
+	* Type __user: Add messaging support (Steven Armstrong)
+	* Type __zypper_service: Support older SuSE releases (Daniel Heule)
 
 2.3.7: 2013-12-02
 	* Type __file: Secure the file transfer by using mktemp (Steven Armstrong)
diff --git a/docs/changelog.future b/docs/changelog.future
deleted file mode 100644
index 12adf8c3..00000000
--- a/docs/changelog.future
+++ /dev/null
@@ -1,10 +0,0 @@
-Changelog
----------
-
-	* Changes are always commented with their author in (braces)
-	* Exception: No braces means author == Nico Schottelius
-
-future (maybe 3.x?):
-	* Type __cron: Dropped support for old internal format
-	  Using this version prior to running cdist 2.1.2 will
-	  break add the cron entries twice.
diff --git a/docs/dev/factsheet.odt b/docs/dev/factsheet.odt
new file mode 100644
index 00000000..2bb2a84b
Binary files /dev/null and b/docs/dev/factsheet.odt differ
diff --git a/docs/dev/factsheet.pdf b/docs/dev/factsheet.pdf
new file mode 100644
index 00000000..c59a1a6f
Binary files /dev/null and b/docs/dev/factsheet.pdf differ
diff --git a/docs/dev/logs/2011-11-16.workflow-example.dia b/docs/dev/logs/2011-11-16.workflow-example.dia
new file mode 100644
index 00000000..8dab4a2c
Binary files /dev/null and b/docs/dev/logs/2011-11-16.workflow-example.dia differ
diff --git a/docs/dev/logs/2011-11-16.workflow-example.png b/docs/dev/logs/2011-11-16.workflow-example.png
new file mode 100644
index 00000000..07a0f126
Binary files /dev/null and b/docs/dev/logs/2011-11-16.workflow-example.png differ
diff --git a/docs/dev/logs/2011-11-17.workflow-example.dia b/docs/dev/logs/2011-11-17.workflow-example.dia
new file mode 100644
index 00000000..7a9cd0f7
Binary files /dev/null and b/docs/dev/logs/2011-11-17.workflow-example.dia differ
diff --git a/docs/dev/logs/2013-08-27-notifications.xoj b/docs/dev/logs/2013-08-27-notifications.xoj
new file mode 100644
index 00000000..c34c4676
Binary files /dev/null and b/docs/dev/logs/2013-08-27-notifications.xoj differ
diff --git a/docs/dev/logs/2013-12-12.discussion b/docs/dev/logs/2013-12-12.discussion
new file mode 100644
index 00000000..58d25517
--- /dev/null
+++ b/docs/dev/logs/2013-12-12.discussion
@@ -0,0 +1,6 @@
+With Steven
+
+- Implement environments
+    - for configuring "anything" including switches
+    - can disable / use other global explorers
+- 98% of our framework is generic and can be used for any applikation
diff --git a/docs/man/man7/cdist-hacker.text b/docs/man/man7/cdist-hacker.text
index 9dd52d35..2cbf5a8b 100644
--- a/docs/man/man7/cdist-hacker.text
+++ b/docs/man/man7/cdist-hacker.text
@@ -33,7 +33,6 @@ nearby, so grepping for FIXME gives all positions that need to be fixed.
 
 Indention is 4 spaces (welcome to the python world).
 
-
 HOW TO SUBMIT STUFF FOR INCLUSION INTO UPSTREAM CDIST
 -----------------------------------------------------
 If you did some cool changes to cdist, which you value as a benefit for
@@ -75,14 +74,91 @@ code and thus such a type introduces redundant functionality that is given by
 core cdist already.
 
 
+EXAMPLE GIT WORKFLOW
+---------------------
+The following workflow works fine for most developers:
+
+--------------------------------------------------------------------------------
+# get latest upstream master branch
+git clone https://github.com/telmich/cdist.git
+
+# update if already existing
+cd cdist; git fetch -v; git merge origin/master
+
+# create a new branch for your feature/bugfix
+cd cdist # if you haven't done before
+git checkout -b documentation_cleanup
+
+# *hack*
+*hack*
+
+# clone the cdist repository on github if you haven't done so
+
+# configure your repo to know about your clone (only once)
+git remote add github git@github.com:YOURUSERNAME/cdist.git
+
+# push the new branch to github 
+git push github documentation_cleanup
+
+# (or everything)
+git push --mirror github
+
+# create a pull request at github (use a browser)
+# *fixthingsbecausequalityassurancefoundissuesinourpatch*
+*hack*
+
+# push code to github again
+git push ... # like above
+
+# add comment that everything should be green now (use a browser)
+
+# go back to master branch
+git checkout master
+
+# update master branch that includes your changes now
+git fetch -v origin
+git diff master..origin/master
+git merge origin/master
+--------------------------------------------------------------------------------
+
+If at any point you want to go back to the original master branch, you can
+use **git stash** to stash your changes away:
+
+--------------------------------------------------------------------------------
+# assume you are on documentation_cleanup
+git stash
+
+# change to master and update to most recent upstream version
+git checkout master
+git fetch -v origin
+git merge origin/master
+--------------------------------------------------------------------------------
+
+Similar when you want to develop another new feature, you go back
+to the master branch and create another branch based on it:
+
+--------------------------------------------------------------------------------
+# change to master and update to most recent upstream version
+git checkout master
+git fetch -v origin
+git merge origin/master
+
+git checkout -b another_feature
+--------------------------------------------------------------------------------
+
+(you can repeat the code above for as many features as you want to develop
+in parallel)
 
 
 SEE ALSO
 --------
 - cdist(7)
+- git(1)
+- git-checkout(1)
+- git-stash(1)
 
 
 COPYING
 -------
-Copyright \(C) 2011-2012 Nico Schottelius. Free use of this software is
+Copyright \(C) 2011-2013 Nico Schottelius. Free use of this software is
 granted under the terms of the GNU General Public License version 3 (GPLv3).
diff --git a/docs/web/cdist/update.mdwn b/docs/web/cdist/update.mdwn
index 9e47fccc..2e3e9b92 100644
--- a/docs/web/cdist/update.mdwn
+++ b/docs/web/cdist/update.mdwn
@@ -55,6 +55,11 @@ To upgrade to the lastet version do
 
 ## General Update Instructions
 
+### Updating from 2.3 to 3.0
+
+The **changed** attribute of objects has been removed.
+Use [messaging](/software/cdist/man/3.0.0/man7/cdist-messaging.html) instead.
+
 ### Updating from 2.2 to 2.3
 
 No incompatiblities.