def get_all_dangerous_connections(self):
        """
        Get all connections between IO and dangerous
        functions. It is a necessary (but not sufficient)
        condition for a problem like memory corruption
        All code pieces were there already :)
        """
        conn_graphs = []
        dang_conns = []
        dang_funcs = self.get_dangerous_functions()

        if not dang_funcs:
            return []

        for df in dang_funcs:
            for io_caller in self.input_to_function(df):
                # [(u, v), ...]
                dang_conns.append((io_caller, df))

        # Calculate the connect graphs
        for tu in dang_conns:
            u, v = tu   # tuple unpacking
            cg = self.get_connect_graph(u, v)
            sh_path = graphing.cg_shortest_path(cg, u, v)

            if not sh_path:
                # Error. Skipping this one
                continue

            sh_path_len = len(sh_path) - 1  # by definition
            conn_graphs.append((u, v, sh_path_len))

        return conn_graphs