diff --git a/NodeApp/src/helpers/AutoCompletionHelper.ts b/NodeApp/src/helpers/AutoCompletionHelper.ts
index bb46c1e6eecbdad4538303f5e5bf01c01a60fed1..34c5d7e3d7196fcbd382291a3f16c11237400ed5 100644
--- a/NodeApp/src/helpers/AutoCompletionHelper.ts
+++ b/NodeApp/src/helpers/AutoCompletionHelper.ts
@@ -79,88 +79,62 @@ import { writeFileSync } from 'fs';
 //     return 0
 // }
 
-interface CmdNode {
-    readonly name: string;
-    readonly children: Array<CmdNode>;
-    readonly parent?: string;
+function isLeaf(cmd: Command): boolean {
+    return cmd.commands.length == 0
 }
 
-function createCmdNode(name: string, children: Array<CmdNode>, parent?: string): CmdNode {
-    return {
-        name,
-        children,
-        parent
-    };
-}
-
-function isLeaf(tree: CmdNode): boolean {
-    return tree.children === undefined || tree.children.length == 0
-}
-
-function isRoot(tree: CmdNode): boolean {
-    return tree.parent === undefined
-}
-
-function search(tree: CmdNode, cmdName: string): Array<CmdNode> {
-    if (isLeaf(tree)) {
-        if (tree.name != cmdName) {
+function search(cmd: Command, cmdName: string): Array<Command> {
+    if (isLeaf(cmd)) {
+        if (cmd.name() != cmdName) {
             return []
         } else {
-            return [tree]
+            return [cmd]
         }
-    } else if (tree.name == cmdName) {
-        return tree.children.flatMap(st => search(st, cmdName)).concat(tree)
+    } else if (cmd.name() == cmdName) {
+        return cmd.commands.flatMap(st => search(st, cmdName)).concat(cmd)
     } else {
-        return tree.children.flatMap(st => search(st, cmdName))
+        return cmd.commands.flatMap(st => search(st, cmdName))
     }
 }
 
-function flatten(tree: CmdNode): Array<CmdNode> {
-    if (isLeaf(tree)) {
-        return [tree]
+function flatten(cmd: Command): Array<Command> {
+    if (isLeaf(cmd)) {
+        return [cmd]
     } else {
-        return tree.children
+        return cmd.commands
             .map(child => flatten(child))
-            .reduce((acc, cmd) => acc.concat(cmd), [tree])
+            .reduce((acc, cmd) => acc.concat(cmd), [cmd])
     }
 }
 
-function printWordsGrandParents(node: CmdNode): string {
+function addWordsGrandParents(cmd: Command): string {
     let parentWords = ""
     let ident = 3
-    if (node.parent !== undefined) {
+    if (cmd.parent !== null) {
         parentWords += openCase(ident, 'grand_parent')
         ident += 1
-        parentWords += addLine(ident, `${node.parent})`)
+        parentWords += addLine(ident, `${cmd.parent.name()})`)
         ident += 1
     }
-    parentWords += addLine(ident, `words="${node.children.map(c => c.name).join(" ")} --help -h"`)
+    parentWords += addLine(ident, `words="${commandsAndOptionsToString(cmd)}"`)
     ident -= 1
     parentWords += addLine(ident, ';;')
-    if (node.parent !== undefined) {
+    if (cmd.parent !== null) {
         ident -= 1
         parentWords += `${closeCase(ident)}`
     }
     return parentWords
 }
 
-function getOptions(cmd: Command): Array<CmdNode> {
+function getOptions(cmd: Command): string {
     // we remove <args>, [command], and , from option lines
     return cmd.options.filter(opt => !opt.hidden).map(opt =>
-        createCmdNode(opt.flags.replace(/<.*?>/, '').replace(/\[.*?\]/, '').replace(',', '').trimEnd(), [], cmd.name())
-    )
+        opt.flags.replace(/<.*?>/, '').replace(/\[.*?\]/, '').replace(',', '').trimEnd()
+    ).join(" ")
 }
 
-function getSubCmdNode(cmd: Command, parent: Command): CmdNode {
-    if (cmd.commands.length > 0) {
-        return createCmdNode(cmd.name(), cmd.commands.map(subCmd => getSubCmdNode(subCmd, cmd)).concat(getOptions(cmd)), parent.name())
-    } else {
-        return createCmdNode(cmd.name(), getOptions(cmd), parent.name())
-    }
-}
-
-function buildCmdNode(root: Command): CmdNode {
-    return createCmdNode(root.name(), root.commands.map(subCmd => getSubCmdNode(subCmd, root)).concat(getOptions(root)))
+function commandsAndOptionsToString(cmd: Command): string {
+    return cmd.commands.map(c => c.name()).join(" ").concat(' ' + getOptions(cmd)).trim().concat(' --help -h').trim()
 }
 
 function openCase(identLevel: number, pattern: string): string {
@@ -210,12 +184,11 @@ end
 `
 
 export function getFishCompletion(root: Command, filename: string) {
-    const tree = buildCmdNode(root)
-    const commands = Array.from(new Set(flatten(tree).filter(cmd => !isLeaf(cmd)).map(cmd => cmd.name))).map(name => search(tree, name))
+    const commands = Array.from(new Set(flatten(root).filter(cmd => !isLeaf(cmd)).map(cmd => cmd.name()))).map(name => search(root, name))
     let data = fishFunctions
     for (const node of commands) {
         const cmd = node[0]
-        data += addLine(0, `complete -f -c dojo -n __fish_dojo_needs_command ${cmd.name} -a "${cmd.children.map(c => c.name).join(" ")} --help -h"`)
+        data += addLine(0, `complete -f -c dojo -n __fish_dojo_needs_command ${cmd.name()} -a "${commandsAndOptionsToString(cmd)}"`)
     }
 
 
@@ -224,22 +197,21 @@ export function getFishCompletion(root: Command, filename: string) {
 
 
 export function getBashCompletion(root: Command, filename: string) {
-    const tree = buildCmdNode(root)
-
     let data =
         `${addLine(0, '#/usr/bin/env bash\nfunction _dojo_completions()')}`
         + `${addLine(0, '{')}${addLine(1, 'latest="${COMP_WORDS[$COMP_CWORD]}"')}`
         + `${addLine(1, 'parent="${COMP_WORDS[$COMP_CWORD - 1]}"')}`
         + `${addLine(1, 'grand_parent="${COMP_WORDS[$COMP_CWORD - 2]}"')}`
-        + `${addLine(1, 'words=""')}${openCase(1, "parent")}`
-    const commands = Array.from(new Set(flatten(tree).filter(cmd => !isLeaf(cmd)).map(cmd => cmd.name))).map(name => search(tree, name))
-    for (const node of commands) {
-        const cmd = node[0]
-        data += addLine(2, `${cmd.name})`)
-        if (cmd !== undefined && node.length == 1) {
-            data += addLine(3, `words="${cmd.children.map(c => c.name).join(" ")} --help -h"`)
-        } else if (cmd !== undefined && node.length > 1) {
-            node.forEach(n => data += printWordsGrandParents(n))
+        + `${addLine(1, 'words=""')}`
+        + `${openCase(1, "parent")}`
+    const commands = Array.from(new Set(flatten(root).map(cmd => cmd.name()))).map(name => search(root, name))
+    for (const cmdNode of commands) {
+        const cmd = cmdNode[0]
+        data += addLine(2, `${cmd.name()})`)
+        if (cmd !== undefined && cmdNode.length == 1) {
+            data += addLine(3, `words="${commandsAndOptionsToString(cmd)}"`)
+        } else if (cmd !== undefined && cmdNode.length > 1) {
+            cmdNode.forEach(n => data += addWordsGrandParents(n))
         }
         data += addLine(2, ';;')
     }