function RepoListCtrl($scope, $sanitize, Restangular, UserService, ApiService) {
  $scope.namespace = null;
  $scope.page = 1;
  $scope.publicPageCount = null;

  // When loading the UserService, if the user is logged in, create a list of
  // relevant namespaces for later collecting relevant repositories.
  UserService.load(function() {
    var user = UserService.currentUser();
    if (!user.anonymous) {
      $scope.namespaces = [user];
      for (var i = 0; i < user.organizations.length; i++) {
        $scope.namespaces.push(user.organizations[i]);
      }
      //loadStarredRepos();
      //loadRepos();
    }
  });

  // If someone signs in on this page, we have to watch the user and re-load
  // their repositories after they've signed in to actually have any content
  // on the page.
  $scope.$watch(function(scope) { return scope.user },
                function(user) {
                  if (!user.anonymous) {
                    $scope.namespaces = [user];
                    for (var i = 0; i < user.organizations.length; i++) {
                      $scope.namespaces.push(user.organizations[i]);
                    }
                    loadStarredRepos();
                    loadRepos();
                  }
                });

  $scope.toggleStar = function(repo) {
    if (repo.is_starred) {
      unstarRepo(repo);
    } else {
      starRepo(repo);
    }
  }

  var starRepo = function(repo) {
    var data = {
      'namespace': repo.namespace,
      'repository': repo.name
    };
    ApiService.createStar(data).then(function(result) {
      updateReposAfterStar(repo);
    }, ApiService.errorDisplay('Could not star repository'));
  };

  var unstarRepo = function(repo) {
    var data = {
      'repository': repo.namespace + '/' + repo.name
    };
    ApiService.deleteStar(null, data).then(function(result) {
      updateReposAfterUnstar(repo);
    }, ApiService.errorDisplay('Could not unstar repository'));
  };

  // Finds a repository within the list of namespaces attached to $scope.
  var findRepoInList = function(repoNamespace, repoName) {
    var namespaceIndex = $scope.namespaces.map(function (n) {
      return n.username || n.name;
    }).indexOf(repoNamespace);

    var namespace = $scope.namespaces[namespaceIndex]

    var repoIndex = namespace.repositories.value.map(function (r) {
      return r.namespace + '/' + r.name;
    }).indexOf(repoNamespace + '/' + repoName);

    return repoIndex != -1 ? namespace.repositories.value[repoIndex] : null;
  }

  // Add a starred repository to the list starred repository list and make
  // sure it appears starred elsewhere on the page.
  var updateReposAfterStar = function(repository) {
    $scope.starred_repositories.value.push(repository);

    var repo = findRepoInList(repository.namespace, repository.name);
    if (repo != null) {
      repo.is_starred = true;
    }
  }

  // Remove a repository from the starred repository list and make sure that
  // it doesn't appear starred elsewhere on the page.
  var updateReposAfterUnstar = function(repository) {
    // Remove from the starred listings
    var index = $scope.starred_repositories.value.map(function(r) {
      return r.namespace + '/' + r.name;
    }).indexOf(repository.namespace + '/' + repository.name);
    $scope.starred_repositories.value.splice(index, 1);

    // Set repo from the normal listings to unstarred.
    var repo = findRepoInList(repository.namespace, repository.name);
    if (repo != null) {
      repo.is_starred = false;
    }
  };

  var loadStarredRepos = function() {
    if (!$scope.user || $scope.user.anonymous) {
      return;
    }

    $scope.starred_repositories = ApiService.listStarredReposAsResource().get(function(resp) {
      return resp.repositories.map(function(repo) {
        repo.is_starred = true;
        return repo;
      });
    });
  };

  // Iterate over all of the $scope.namespaces and collect their respective
  // repositories.
  var loadRepos = function() {
    if ($scope.namespaces.length == 0 || $scope.user.anonymous) {
      return;
    }

    for (var i = 0; i < $scope.namespaces.length; i++) {
      var namespace = $scope.namespaces[i];
      var namespaceName = namespace.username || namespace.name;
      var options = {
        'public': false,
        'sort': true,
        'namespace': namespaceName,
      };
      namespace.repositories = ApiService.listReposAsResource().withOptions(options).get(function(resp) {
        return resp.repositories;
      });
    }
  };
}