+
+ def _check_circular_dep(node):
+ g_id = node.get('group')
+ g_pkg_list = groups[g_id]
+ g_dict = {}
+
+ # Set dict for group
+ for pkgname in g_pkg_list:
+ g_dict[pkgname] = None
+
+ for pkgname in g_pkg_list:
+ pkg = pkg_dict[pkgname]
+ # the node is selfchecked (the root node ignores selfchecked)
+ if stack[0]['id'] != pkg['id'] and pkg['selfChecked']:
+ return False
+ # check backward ref.
+ for bname in pkg.get('backward'):
+ # If node is Referenced by another node (Not a node in the group),
+ # unable to uncheck group nodes
+ if not bname in g_dict:
+ return False
+
+ # init visited dict
+ group_visited[g_id] = {}
+ # delete backward reference of group node
+ for pkgname in g_pkg_list:
+ pkg = pkg_dict[pkgname]
+ pkg['backward'] = None;
+ group_visited[g_id][pkg['name']] = -1
+ return True
+
+ def _delete_conflictdata(node):
+ if node.get('conflicts'):
+ for con in node.get('conflicts'):
+ if con['name'] in conflicts:
+ con_list = conflicts[con['name']]
+ for i in range(len(con_list)):
+ if con_list[i]['name'] == node['name']:
+ del con_list[i]
+ break;
+
+ def _remove_reference(parent, node):
+ if parent is not None:
+ # remove backward reference (parent)
+ if node.get('backward'):
+ for i in range(len(node['backward'])):
+ if node['backward'][i] == parent['name']:
+ del node['backward'][i]
+ break
+ # selfCheck node do not remove
+ if pkg_info.get('selfChecked'):
+ return
+
+ if node.get('backward'):
+ if node.get('group') is None or _check_circular_dep(node):
+ return
+
+ # the selected node is uncheckable
+ if node.get('group') and group_visited[node['group']]:
+ group_visited[node['group']][node['name']] = 1
+
+ # if selected node has forward references
+ if node.get('forward'):
+ for fname in node.get('forward'):
+ fnode = pkg_dict[fname]
+
+ # If pkg has a circular dependency and is unchekcable,
+ # circular dep. pkgs can only be visited once
+ if fnode.get('group') and group_visited[fnode['group']][fnode['name']] == 1:
+ continue
+
+ _remove_reference(node, fnode)
+ node['forward'] = None
+ node['group'] = None
+ # delete conflict data from conflicts dict
+ _delete_conflictdata(node)