diff --git a/lib/ansible/playbook/play.py b/lib/ansible/playbook/play.py
index dc1c72fbb0c..e3258dc5841 100644
--- a/lib/ansible/playbook/play.py
+++ b/lib/ansible/playbook/play.py
@@ -119,9 +119,64 @@ class Play(object):
 
     # *************************************************
 
+    def _get_role_path(self, role):
+        """
+        Returns the path on disk to the directory containing
+        the role directories like tasks, templates, etc. Also 
+        returns any variables that were included with the role
+        """
+        orig_path = template(self.basedir,role,self.vars)
+
+        role_vars = {}
+        if type(orig_path) == dict:
+            # what, not a path?
+            role_name = orig_path.get('role', None)
+            if role_name is None:
+                raise errors.AnsibleError("expected a role name in dictionary: %s" % orig_path)
+            role_vars = orig_path
+            orig_path = role_name
+
+        path = utils.path_dwim(self.basedir, os.path.join('roles', orig_path))
+        if not os.path.isdir(path) and not orig_path.startswith(".") and not orig_path.startswith("/"):
+            path2 = utils.path_dwim(self.basedir, orig_path)
+            if not os.path.isdir(path2):
+                raise errors.AnsibleError("cannot find role in %s or %s" % (path, path2))
+            path = path2
+        elif not os.path.isdir(path):
+            raise errors.AnsibleError("cannot find role in %s" % (path))
+
+        return (path, role_vars)
+
+    def _build_role_dependencies(self, roles, dep_stack, vars={}, level=0):
+        # this number is arbitrary, but it seems sane
+        if level > 20:
+            raise errors.AnsibleError("too many levels of recursion while resolving role dependencies")
+        for role in roles:
+            path,role_vars = self._get_role_path(role)
+            # the meta directory contains the yaml that should
+            # hold the list of dependencies (if any)
+            meta = self._resolve_main(utils.path_dwim(self.basedir, os.path.join(path, 'meta')))
+            if os.path.isfile(meta):
+                data = utils.parse_yaml_from_file(meta)
+                if data:
+                    dependencies = data.get('dependencies',[])
+                    for dep in dependencies:
+                        (dep_path,dep_vars) = self._get_role_path(dep)
+                        dep_vars.update(role_vars)
+                        for k in vars.keys():
+                            if not k in dep_vars:
+                                dep_vars[k] = vars[k]
+                        if 'role' in dep_vars:
+                            del dep_vars['role']
+                        self._build_role_dependencies([dep], dep_stack, vars=dep_vars, level=level+1)
+                        dep_stack.append([dep,dep_vars])
+                    # only add the current role when we're at the top level,
+                    # otherwise we'll end up in a recursive loop 
+                    if level == 0:
+                        dep_stack.append([role,role_vars])
+        return dep_stack
+
     def _load_roles(self, roles, ds):
-
-
         # a role is a name that auto-includes the following if they exist
         #    <rolename>/tasks/main.yml
         #    <rolename>/handlers/main.yml
@@ -147,52 +202,37 @@ class Play(object):
         # flush handlers after pre_tasks
         new_tasks.append(dict(meta='flush_handlers'))
 
-        # variables if the role was parameterized (i.e. given as a hash)
-        has_dict = {}
+        roles = self._build_role_dependencies(roles, [], self.vars)
 
-        for role_path in roles:
-            orig_path = template(self.basedir,role_path,self.vars)
-
-            if type(orig_path) == dict:
-                # what, not a path?
-                role_name = orig_path.get('role', None)
-                if role_name is None:
-                    raise errors.AnsibleError("expected a role name in dictionary: %s" % orig_path)
-                has_dict = orig_path
-                orig_path = role_name
+        for role,role_vars in roles:
+            path,ignore = self._get_role_path(role)
 
             # special vars must be extracted from the dict to the included tasks
             special_keys = [ "sudo", "sudo_user", "when", "with_items" ]
             special_vars = {}
             for k in special_keys:
-                if k in has_dict:
-                    special_vars[k] = has_dict[k]
+                if k in role_vars:
+                    special_vars[k] = role_vars[k]
 
-            path = utils.path_dwim(self.basedir, os.path.join('roles', orig_path))
-            if not os.path.isdir(path) and not orig_path.startswith(".") and not orig_path.startswith("/"):
-                path2 = utils.path_dwim(self.basedir, orig_path)
-                if not os.path.isdir(path2):
-                    raise errors.AnsibleError("cannot find role in %s or %s" % (path, path2))
-                path = path2
-            elif not os.path.isdir(path):
-                raise errors.AnsibleError("cannot find role in %s" % (path))
             task_basepath    = utils.path_dwim(self.basedir, os.path.join(path, 'tasks'))
             handler_basepath = utils.path_dwim(self.basedir, os.path.join(path, 'handlers'))
             vars_basepath    = utils.path_dwim(self.basedir, os.path.join(path, 'vars'))
+
             task      = self._resolve_main(task_basepath)
             handler   = self._resolve_main(handler_basepath)
             vars_file = self._resolve_main(vars_basepath)
             library   = utils.path_dwim(self.basedir, os.path.join(path, 'library'))
+
             if not os.path.isfile(task) and not os.path.isfile(handler) and not os.path.isfile(vars_file) and not os.path.isdir(library):
                 raise errors.AnsibleError("found role at %s, but cannot find %s or %s or %s or %s" % (path, task, handler, vars_file, library))
             if os.path.isfile(task):
-                nt = dict(include=pipes.quote(task), vars=has_dict)
+                nt = dict(include=pipes.quote(task), vars=role_vars)
                 for k in special_keys:
                     if k in special_vars:
                         nt[k] = special_vars[k]
                 new_tasks.append(nt)
             if os.path.isfile(handler):
-                nt = dict(include=pipes.quote(handler), vars=has_dict)
+                nt = dict(include=pipes.quote(handler), vars=role_vars)
                 for k in special_keys:
                     if k in special_vars:
                         nt[k] = special_vars[k]
@@ -202,10 +242,9 @@ class Play(object):
             if os.path.isdir(library):
                 utils.plugins.module_finder.add_directory(library)
 
-        tasks = ds.get('tasks', None)
+        tasks      = ds.get('tasks', None)
         post_tasks = ds.get('post_tasks', None)
-
-        handlers = ds.get('handlers', None)
+        handlers   = ds.get('handlers', None)
         vars_files = ds.get('vars_files', None)
 
         if type(tasks) != list:
@@ -223,8 +262,10 @@ class Play(object):
         new_tasks.extend(post_tasks)
         # flush handlers after post tasks
         new_tasks.append(dict(meta='flush_handlers'))
+
         new_handlers.extend(handlers)
         new_vars_files.extend(vars_files)
+
         ds['tasks'] = new_tasks
         ds['handlers'] = new_handlers
         ds['vars_files'] = new_vars_files