def convert_graph(context, graph, outputs=None):
    """
    Construct Core ML ops corresponding to `graph`.

    Inputs:

    - context (TranscriptContext)

    - graph (dict of str -> ParsedTFNode): op name --> ParsedTFNode

    - outputs (list[str]): List of output names. If outputs is None, the last
      node graph (after topsort) must have op type return.

    Returns:

    list[Var]: the output Vars of the constructed Block.
    """
    connect_global_initializer(graph)
    nodes = topsort(graph)

    if outputs is None:
        # infer outputs from return
        last_node = graph[nodes[-1]]
        if last_node.op != "return":
            msg = "Expect the last node in graph to be 'return'; Got {}"
            raise ValueError(msg.format(last_node.op))
        second_last_node = graph[last_node.inputs[0]]
        if second_last_node.op == "make_tuple":
            outputs = second_last_node.inputs
        else:
            # single output function
            outputs = second_last_node.name

    # Translate the non-placeholder ops.
    num_nodes = len(nodes)
    for i, node_name in enumerate(
        _tqdm(nodes, desc="Converting TF Frontend ==> MIL Ops", unit=" ops")
    ):
        node = graph[node_name]
        if node.op == "return":
            continue
        logger.info(
            "[{}/{}] Converting {} op '{}'".format(i + 1, num_nodes, node.op, node.name)
        )

        if node.op in ("NoOp", "Assert"):
            continue

        add_op = _TF_OPS_REGISTRY.get(node.op, None)
        if add_op is None:
            msg = "Conversion for TF op '{0}' not implemented.\n \n{1}".format(
                node.op, node.original_node
            )
            raise NotImplementedError(msg)
        add_op(context, node)

        if len(node.outputs) > 0:
            # set_global / get_global / NoOp has no direct consumer / outputs
            x = context[node.name]
            check_output_shapes(x, node)

    output_is_list = isinstance(outputs, (tuple, list))
    if not output_is_list:
        outputs = [outputs]

    output_vars = []
    for output in outputs:
        x = context[output.split(":")[0]]
        if isinstance(x, (tuple, list)):
            idx = int(output.split(":")[1])
            output_vars.append(x[idx])
        else:
            output_vars.append(x)

    return output_vars if output_is_list else output_vars[0]

    Construct Core ML ops corresponding to `graph`.

    Inputs:

    - context (TranscriptContext)

    - graph (dict of str -> ParsedTFNode): op name --> ParsedTFNode

    - outputs (list[str]): List of output names. If outputs is None, the last
      node graph (after topsort) must have op type return.

    Returns:

    list[Var]: the output Vars of the constructed Block.
    
coremltools/converters/mil/frontend/tensorflow/convert_utils.py