Refactored the subcommand invocation logic to form a more hierarchical structure and a cleaner design.
diff --git a/git-flow b/git-flow
index f44f261..09a1b13 100755
--- a/git-flow
+++ b/git-flow
@@ -36,12 +36,16 @@
 	. "$GITFLOW_DIR/git-flow-version"
 	echo "git-flow, version $GITFLOW_VERSION"
 	echo
-	echo "usage: git flow <cmd> <type> <args>"
-	echo "       git flow init [<url>]"
+	echo "usage: git flow <subcommand>"
 	echo
-	echo "<type> can be any of: feature, release, hotfix, support"
+	echo "Available subcommands are:"
+	echo "   init      Initialize a new git repo with support for the branching model."
+	echo "   feature   Manage your feature branches."
+	echo "   release   Manage your release branches."
+	echo "   hotfix    Manage your hotfix branches."
+	echo "   support   Manage your support branches."
 	echo
-	echo "Try 'git flow help <type>' for details."
+	echo "Try 'git flow <subcommand> help' for details."
 }
 
 main() {
@@ -51,16 +55,9 @@
 	fi
 
 	# sanity checks
-	ACTION="$1"; shift
+	SUBCOMMAND="$1"; shift
 
-	if [ "$ACTION" = "init" ]; then
-		gitflow_init "$@"
-		exit 0
-	fi
-
-	BTYPE="$1"; shift
-
-	if [ ! -e "$GITFLOW_DIR/git-flow-$BTYPE" ]; then
+	if [ ! -e "$GITFLOW_DIR/git-flow-$SUBCOMMAND" ]; then
 		usage
 		exit 1
 	fi
@@ -75,69 +72,27 @@
 	ALL_BRANCHES="$LOCAL_BRANCHES $REMOTE_BRANCHES"
 
 	# run command
-	. "$GITFLOW_DIR/git-flow-$BTYPE"
+	. "$GITFLOW_DIR/git-flow-$SUBCOMMAND"
 
-	if ! typeset -f cmd_$ACTION >/dev/null; then
+	if ! typeset -f sub_main >/dev/null; then
 		usage
 		exit 1
 	fi
 
 	# run command
-	cmd_$ACTION "$@"
+	sub_main "$@"
 }
 
-gitflow_init() {
-	echo
-	echo "Summary of actions:"
-
-	if ! git rev-parse --git-dir 2>&1 >/dev/null; then
-		git init --quiet
-		echo "- A new git repository at $PWD was created"
+sub_main() {
+	SUBACTION="${1:-default}"; shift
+	if ! typeset -f cmd_$SUBACTION 2>&1 >/dev/null; then
+		warn "Unknown subcommand: '$1'"
+		usage
+		exit 1
 	fi
 
-	if ! git rev-parse --quiet --verify HEAD 2>&1 >/dev/null; then
-		touch $README
-		git add $README
-		git commit --quiet -m "initial commit"
-		if [ "$MASTER_BRANCH" != "master" ]; then
-			git branch -m master $MASTER_BRANCH
-		fi
-		echo "- An initial commit was created at branch '$MASTER_BRANCH'"
-	fi
-
-	if ! git rev-parse --verify $MASTER_BRANCH 2>&1 >/dev/null; then
-		die "Cannot find your master branch. Try: git branch -m <mymaster> $MASTER_BRANCH"
-	fi
-
-	gitflow_check_clean_working_tree
-
-	if git remote | grep -q $ORIGIN; then
-		git fetch -q $ORIGIN
-		gitflow_require_branches_equal $MASTER_BRANCH $ORIGIN/$MASTER_BRANCH
-	fi
-
-	if git rev-parse --verify $DEVELOP_BRANCH 2>&1 >/dev/null; then
-		gitflow_require_branches_equal $DEVELOP_BRANCH $ORIGIN/$DEVELOP_BRANCH
-	else
-		git checkout -q -b $DEVELOP_BRANCH $MASTER_BRANCH
-		echo "- A new branch '$DEVELOP_BRANCH' was created"
-		echo "- You are now on branch '$DEVELOP_BRANCH'"
-	fi
-
-	if ! git remote | grep -q $ORIGIN; then
-		if [ "$1" = "" ]; then
-			echo "- No remote location was added. Try: git remote add $ORIGIN <url>"
-		else
-			git remote add $ORIGIN $1
-			echo "- A new remote location '$1' was added"
-		fi
-	fi
-
-	echo
-
-	if git remote | grep -q $ORIGIN; then
-		git push $ORIGIN $MASTER_BRANCH $DEVELOP_BRANCH
-	fi
+	# run the specified action
+	cmd_$SUBACTION "$@"
 }
 
 gitflow_check_clean_working_tree() {
diff --git a/git-flow-feature b/git-flow-feature
index 663e788..43132d7 100644
--- a/git-flow-feature
+++ b/git-flow-feature
@@ -13,12 +13,12 @@
 #
 
 usage() {
-	echo "usage: git flow list feature"
-	echo "       git flow start feature <name> [<base>]"
-	echo "       git flow finish feature <name> [<base>]"
-	echo "       git flow publish feature <name>"
-	echo "       git flow track feature <name>"
-	echo "       git flow diff feature <name>"
+	echo "usage: git flow feature"
+	echo "       git flow feature start <name> [<base>]"
+	echo "       git flow feature finish <name> [<base>]"
+	echo "       git flow feature publish <name>"
+	echo "       git flow feature track <name>"
+	echo "       git flow feature diff <name>"
 	# TODO
 	#echo ""
 	#echo "options:"
@@ -46,6 +46,17 @@
 	BRANCH=$PREFIX$NAME
 }
 
+cmd_default() {
+	# TODO: refactor this, because passing in this dummy "foo" is really ugly!
+	parse_args "$@" foo
+	FEATURE_BRANCHES="$(echo "$LOCAL_BRANCHES" | grep "^$PREFIX")"
+	if [ -z "$FEATURE_BRANCHES" ]; then
+		warn "No feature branches exist."
+		exit 0
+	fi
+	echo "$FEATURE_BRANCHES" | sed "s?^$PREFIX??g"
+}
+
 cmd_help() {
 	usage
 	exit 0
@@ -157,17 +168,6 @@
 	echo
 }
 
-cmd_list() {
-	# TODO: refactor this, because passing in this dummy "foo" is really ugly!
-	parse_args "$@" foo
-	FEATURE_BRANCHES="$(echo "$LOCAL_BRANCHES" | grep "^$PREFIX")"
-	if [ -z "$FEATURE_BRANCHES" ]; then
-		warn "No feature branches exist."
-		exit 0
-	fi
-	echo "$FEATURE_BRANCHES" | sed "s?^$PREFIX??g"
-}
-
 cmd_diff() {
 	parse_args "$@"
 	# TODO: if this feature has been based on a non-develop branch, we really
diff --git a/git-flow-hotfix b/git-flow-hotfix
index 47b2bd7..d921762 100644
--- a/git-flow-hotfix
+++ b/git-flow-hotfix
@@ -13,8 +13,9 @@
 #
 
 usage() {
-	echo "usage: git flow start hotfix <version> [<base>]"
-	echo "       git flow finish hotfix <version> [<base>]"
+	echo "usage: git flow hotfix"
+	echo "       git flow hotfix start <version> [<base>]"
+	echo "       git flow hotfix finish <version> [<base>]"
 	# TODO
 	#echo ""
 	#echo "options:"
@@ -39,6 +40,17 @@
 	BRANCH=$PREFIX$VERSION
 }
 
+cmd_default() {
+	# TODO: Refactor getting this prefix into a general function
+	PREFIX=$(git config --get gitflow.prefix.hotfix || echo hotfix/)
+	HOTFIX_BRANCHES="$(echo "$LOCAL_BRANCHES" | grep "^$PREFIX")"
+	if [ -z "$HOTFIX_BRANCHES" ]; then
+		warn "No hotfix branches exist."
+		exit 0
+	fi
+	echo "$HOTFIX_BRANCHES" | sed "s?^$PREFIX??g"
+}
+
 cmd_help() {
 	usage
 	exit 0
diff --git a/git-flow-init b/git-flow-init
new file mode 100644
index 0000000..84ba142
--- /dev/null
+++ b/git-flow-init
@@ -0,0 +1,78 @@
+#
+# git-flow -- A collection of Git extensions to provide high-level
+# repository operations for Vincent Driessen's branching model.
+#
+# Original blog post presenting this model is found at:
+#    http://nvie.com/archives/323
+#
+# Feel free to contribute to this project at:
+#    http://github.com/nvie/gitflow
+#
+# Copyright (c) 2010 by Vincent Driessen
+# Copyright (c) 2010 by Benedikt Böhm
+#
+
+usage() {
+	echo "usage: git flow init"
+}
+
+cmd_help() {
+	usage
+	exit 0
+}
+
+# Default entry when no SUBACTION is given
+cmd_default() {
+	echo
+	echo "Summary of actions:"
+
+	if ! git rev-parse --git-dir 2>&1 >/dev/null; then
+		git init --quiet
+		echo "- A new git repository at $PWD was created"
+	fi
+
+	if ! git rev-parse --quiet --verify HEAD 2>&1 >/dev/null; then
+		touch $README
+		git add $README
+		git commit --quiet -m "initial commit"
+		if [ "$MASTER_BRANCH" != "master" ]; then
+			git branch -m master $MASTER_BRANCH
+		fi
+		echo "- An initial commit was created at branch '$MASTER_BRANCH'"
+	fi
+
+	if ! git rev-parse --verify $MASTER_BRANCH 2>&1 >/dev/null; then
+		die "Cannot find your master branch. Try: git branch -m <mymaster> $MASTER_BRANCH"
+	fi
+
+	gitflow_check_clean_working_tree
+
+	if git remote | grep -q $ORIGIN; then
+		git fetch -q $ORIGIN
+		gitflow_require_branches_equal $MASTER_BRANCH $ORIGIN/$MASTER_BRANCH
+	fi
+
+	if git rev-parse --verify $DEVELOP_BRANCH 2>&1 >/dev/null; then
+		gitflow_require_branches_equal $DEVELOP_BRANCH $ORIGIN/$DEVELOP_BRANCH
+	else
+		git checkout -q -b $DEVELOP_BRANCH $MASTER_BRANCH
+		echo "- A new branch '$DEVELOP_BRANCH' was created"
+		echo "- You are now on branch '$DEVELOP_BRANCH'"
+	fi
+
+	if ! git remote | grep -q $ORIGIN; then
+		if [ "$1" = "" ]; then
+			echo "- No remote location was added. Try: git remote add $ORIGIN <url>"
+		else
+			git remote add $ORIGIN $1
+			echo "- A new remote location '$1' was added"
+		fi
+	fi
+
+	echo
+
+	if git remote | grep -q $ORIGIN; then
+		git push $ORIGIN $MASTER_BRANCH $DEVELOP_BRANCH
+	fi
+}
+