Como exibir uma árvore recolhível no AngularJS + Bootstrap

Eu estou construindo um aplicativo da web onde eu preciso exibir uma árvore usando listas. Minha estrutura básica é assim:

* Node 1
    * Node 1.1
        * Node 1.1.1
            * Node 1.1.1.1
        * Node 1.1.2
    * Node 1.2

http://jsfiddle.net/QffFm/1/

Estou tentando encontrar algo em angular ou bootstrap que eu possa usar de forma que:

Na primeira vista da lista, ela é expandida até a terceira camada. No meu violino, eu gostaria de ver o Nó 1, Nó 1.1, Nó 1.1.1, Nó 1.1.2 e Nó 1.2 (todos exceto a 4ª camada - Nó 1.1.1.1)Ao clicar no ícone de estilo de lista (não no nome da palavra do nó), o nó recolhe ou expandeIdealmente, eu adoraria que o ícone mudasse, dependendo também se o item fosse expandido. Uma seta para a direita se houver mais abaixo, uma seta para baixo se já estiver expandida e talvez um item de lista normal se não houver filhos

Eu sou muito novo no AngularJS e ainda novo no Bootstrap também. Eu vejo que Angular tem uma função de acordeão que não parece lidar com tudo o que eu preciso.

Eu adoraria alguma orientação sobre a melhor abordagem antes de codificar um monte de lógica em meu aplicativo da web que lida com os diferentes casos. Eu acho que isso deve ser um problema comum, então talvez haja algo pronto que eu possa utilizar. Qualquer orientação seria muito apreciada.

Código HTML:

<div ng-app="myApp" ng-controller="controller">
    <my-directive></my-directive>
    <table style="width: 100%"><tbody><td>
        <tree items="tree"></tree>
    </td></tbody></table>
</div>

Código angular:

var app = angular.module('myApp', []);

app.controller('controller', function ($scope){ 

    $scope.tree=[{"name":"Node 1","items":[{"name":"Node 1.1","items":[{"name":"Node 1.1.1","items":[{"name":"Node 1.1.1.1","items":[]}]},{"name":"Node 1.1.2","items":[]}]},{"name":"Node 1.2","items":[]}]}];

});
app.directive('tree', function() {
    return {
        template: '<ul><tree-node ng-repeat="item in items"></tree-node></ul>',
        restrict: 'E',
        replace: true,
        scope: {
            items: '=items',
        }
    };
});

app.directive('treeNode', function($compile) {
    return { 
        restrict: 'E',
        template: '<li >{{item.name}}</li>',
        link: function(scope, elm, attrs) {
        if (scope.item.items.length > 0) {
            var children = $compile('<tree items="item.items"></tree>')(scope);
            elm.append(children);
        }
    }
    };
});

questionAnswers(1)

yourAnswerToTheQuestion