public function createNodeCreatorTraverser($config)
    {
        $traverser = new Traverser($config);

        $traverser->addVisitor(
            array($this, 'createArgNode'),
            function ($path) {
                return (count($path) == 4 && $path[0] == 'tasks' && $path[2] == 'args');
            },
            Traverser::BEFORE
        );
        $traverser->addVisitor(
            array($this, 'createOptNode'),
            function ($path) {
                return (count($path) == 4 && $path[0] == 'tasks' && $path[2] == 'opts');
            },
            Traverser::BEFORE
        );
        $traverser->addVisitor(
            array($this, 'createSetNode'),
            function ($path) {
                return (count($path) == 4 && $path[0] == 'tasks' && $path[2] == 'set');
            },
            Traverser::BEFORE
        );

        $traverser->addVisitor(
            array($this, 'createExpressionNode'),
            function ($path) {
                return
                    count($path) === 3
                    && $path[0] == 'tasks'
                    && in_array($path[2], array('unless', 'assert', 'yield', 'if'))
                    ;
            },
            Traverser::BEFORE
        );
        $traverser->addVisitor(
            array($this, 'createScriptNode'),
            function ($path) {
                return
                    count($path) == 4
                    && $path[0] == 'tasks'
                    && in_array($path[2], array('do', 'pre', 'post'))
                ;
            },
            Traverser::BEFORE
        );
        $traverser->addVisitor(
            array($this, 'createTaskNode'),
            function ($path) {
                return count($path) == 2 && $path[0] == 'tasks';
            },
            Traverser::AFTER
        );
        $traverser->addVisitor(
            array($this, 'createDeclarationNode'),
            array($this, 'isExpressionPath'),
            Traverser::AFTER
        );
        $traverser->addVisitor(
            array($this, 'createDefinitionNode'),
            function ($path, $node) {
                return $path[0] !== 'tasks' && (is_scalar($node) || (is_array($node) && count($node) === 0));
            },
            Traverser::AFTER
        );

        return $traverser;
    }