def convertSubroutinesToProcedures(parse_tree, entry_points, line_mapper, options):
    logger.info("Convert subroutines to procedures")   
    entry_point_names_to_remove = []
    entry_points_to_add = {}
    for name, entry_point in entry_points.items():
        # TODO: This will only work with simple (i.e. single entry) subroutines
        print "name = %s, entry_point = %s" % (name, entry_point)
        subname = iter(entry_point.entryPoints).next()
        if subname.startswith('SUB'):
            procname = 'PROCSub' + subname[3:]
            assert len(entry_point.inEdges) == 0
            defproc = DefineProcedure(name=procname, formalParameters=None)
            insertStatementBefore(entry_point, defproc)
            deTagSuccessors(entry_point)
            entry_point.clearEntryPoints()
            entry_point_names_to_remove.append(name)
            entry_points_to_add[procname] = defproc
            entry_point.clearComeFromGosubEdges()
            tagSuccessors(defproc, line_mapper)
    for name in entry_point_names_to_remove:
        del entry_points[name]
    entry_points.update(entry_points_to_add)
    
    csv = ConvertSubVisitor()
    parse_tree.accept(csv)
def guardExecutableDefinitions(entry_points):
    logging.debug("Checking for direct execution of function or procedure bodies...")
    
    for entry_point in entry_points.values():
        if isinstance(entry_point, syntax.ast.DefinitionStatement):
            if len(entry_point.inEdges) != 0:
                
                reachable_predecessors = (len(predecessor.entryPoints) > 0 for predecessor in entry_point.inEdges)
                if any(reachable_predecessors):
                    errors.warning("Execution of procedure/function at line %s" % entry_point.lineNum)
                    # TODO: Could use ERROR statement here
                    # TODO: Could also have an option to allow procedures to be directly executable
                    # which may involve inserting a call to the procedure at this point ... probably
                    # more appropriate for GOSUBroutines.
                    raise_stmt = syntax.ast.Raise(type="ExecutedDefinitionException")
                    raise_stmt.lineNum = entry_point.lineNum
                    ast_utils.insertStatementBefore(entry_point, raise_stmt)
                    raise_stmt.clearOutEdges()
                    entry_point.clearInEdges()
    return entry_point, entry_points