def slice_string(currentline, source, name, invert=False,
                 formatter=programslice.formatter.LineFormatter):
    """
    Slices the given source code from the given currentline.

    :param currentline: A line from which to start the slicing.
    :type currentline: int
    :param source: The source code to parse.
    :type source: string
    :param name: filename of the given source code.
    :type name: string
    :param invert: Invert the result and return lines which don't depend
                    on the ``currentline``. Defaults to **False**.
    :type invert: bool
    :param formatter: Formatter class to format the slice result.
                        Defaults to LineFormatter which only outputs the
                        line numbers.
    :type formatter: class
    """
    lines = []
    # catch encoding declarations and shebangs
    head = re.compile(r'#!\/.*\n|#.*coding[:=]\s*(?P<enc>[-\w.]+).*')
    source = head.sub('', source)

    node = ast.parse(source, name)
    visitor = programslice.visitor.LineDependencyVisitor()
    visitor.visit(node)
    graph = visitor.get_graph_for(currentline)
    if graph:
        lines = graph.slice_forward(currentline)
        inverted = set(range(graph.first, graph.last + 1)) - set(lines)
    result = list(inverted) if invert else lines
    return formatter(result, source)()
    def test_get_graph_for(self):
        visitor = programslice.visitor.LineDependencyVisitor()
        graph1 = programslice.graph.Graph('function1')
        graph1.add(3)
        graph1.add(5)
        graph1.add(11)

        graph2 = programslice.graph.Graph('function2')
        graph2.add(12)
        graph2.add(13)
        graph2.add(15)
        visitor.graphs = [graph1, graph2]

        self.assertEqual('function1', visitor.get_graph_for(4).name)
        self.assertEqual('function2', visitor.get_graph_for(12).name)
        self.assertEqual(None, visitor.get_graph_for(2))