def apply_changes(self):
    assert all(((hasattr(x, 'lineno') and hasattr(x, 'colno') and hasattr(x, 'filename')) for x in self.modified_nodes))
    assert all(((hasattr(x, 'lineno') and hasattr(x, 'colno') and hasattr(x, 'filename')) for x in self.to_remove_nodes))
    assert all((isinstance(x, (ArrayNode, FunctionNode)) for x in self.modified_nodes))
    assert all((isinstance(x, (ArrayNode, AssignmentNode, FunctionNode)) for x in self.to_remove_nodes))
    work_nodes = [{'node': x, 'action': 'modify'} for x in self.modified_nodes]
    work_nodes += [{'node': x, 'action': 'rm'} for x in self.to_remove_nodes]
    work_nodes = list(sorted(work_nodes, key=(lambda x: (x['node'].lineno, x['node'].colno)), reverse=True))
    work_nodes += [{'node': x, 'action': 'add'} for x in self.to_add_nodes]
    str_list = []
    for i in work_nodes:
        new_data = ''
        if ((i['action'] == 'modify') or (i['action'] == 'add')):
            printer = AstPrinter()
            i['node'].accept(printer)
            printer.post_process()
            new_data = printer.result.strip()
        data = {'file': i['node'].filename, 'str': new_data, 'node': i['node'], 'action': i['action']}
        str_list += [data]
    files = {}
    for i in str_list:
        if (i['file'] in files):
            continue
        fpath = os.path.realpath(os.path.join(self.sourcedir, i['file']))
        fdata = ''
        if (not os.path.exists(fpath)):
            with open(fpath, 'w', encoding='utf-8'):
                pass
        with open(fpath, encoding='utf-8') as fp:
            fdata = fp.read()
        m_lines = fdata.splitlines(True)
        offset = 0
        line_offsets = []
        for j in m_lines:
            line_offsets += [offset]
            offset += len(j)
        files[i['file']] = {'path': fpath, 'raw': fdata, 'offsets': line_offsets}

    def remove_node(i):
        offsets = files[i['file']]['offsets']
        raw = files[i['file']]['raw']
        node = i['node']
        line = (node.lineno - 1)
        col = node.colno
        start = (offsets[line] + col)
        end = start
        if isinstance(node, (ArrayNode, FunctionNode)):
            end = (offsets[(node.end_lineno - 1)] + node.end_colno)
        elif (isinstance(node, AssignmentNode) and (i['action'] == 'rm')):
            if isinstance(node.value, (ArrayNode, FunctionNode)):
                remove_node({'file': i['file'], 'str': '', 'node': node.value, 'action': 'rm'})
                raw = files[i['file']]['raw']
            while (raw[end] != '='):
                end += 1
            end += 1
            while (raw[end] in [' ', '\n', '\t']):
                end += 1
        files[i['file']]['raw'] = ((raw[:start] + i['str']) + raw[end:])
    for i in str_list:
        if (i['action'] in ['modify', 'rm']):
            remove_node(i)
        elif (i['action'] in ['add']):
            files[i['file']]['raw'] += (i['str'] + '\n')
    for (key, val) in files.items():
        mlog.log('Rewriting', mlog.yellow(key))
        with open(val['path'], 'w', encoding='utf-8') as fp:
            fp.write(val['raw'])
def apply_changes(self):
    assert all(((hasattr(x, 'lineno') and hasattr(x, 'colno') and hasattr(x, 'filename')) for x in self.modified_nodes))
    assert all(((hasattr(x, 'lineno') and hasattr(x, 'colno') and hasattr(x, 'filename')) for x in self.to_remove_nodes))
    assert all((isinstance(x, (ArrayNode, FunctionNode)) for x in self.modified_nodes))
    assert all((isinstance(x, (ArrayNode, AssignmentNode, FunctionNode)) for x in self.to_remove_nodes))
    work_nodes = [{'node': x, 'action': 'modify'} for x in self.modified_nodes]
    work_nodes += [{'node': x, 'action': 'rm'} for x in self.to_remove_nodes]
    work_nodes = list(sorted(work_nodes, key=(lambda x: (x['node'].lineno, x['node'].colno)), reverse=True))
    work_nodes += [{'node': x, 'action': 'add'} for x in self.to_add_nodes]
    str_list = []
    for i in work_nodes:
        new_data = 
        if ((i['action'] == 'modify') or (i['action'] == 'add')):
            printer = AstPrinter()
            i['node'].accept(printer)
            printer.post_process()
            new_data = printer.result.strip()
        data = {'file': i['node'].filename, 'str': new_data, 'node': i['node'], 'action': i['action']}
        str_list += [data]
    files = {}
    for i in str_list:
        if (i['file'] in files):
            continue
        fpath = os.path.realpath(os.path.join(self.sourcedir, i['file']))
        fdata = 
        if (not os.path.exists(fpath)):
            with open(fpath, 'w', encoding='utf-8'):
                pass
        with open(fpath, encoding='utf-8') as fp:
            fdata = fp.read()
        m_lines = fdata.splitlines(True)
        offset = 0
        line_offsets = []
        for j in m_lines:
            line_offsets += [offset]
            offset += len(j)
        files[i['file']] = {'path': fpath, 'raw': fdata, 'offsets': line_offsets}

    def remove_node(i):
        offsets = files[i['file']]['offsets']
        raw = files[i['file']]['raw']
        node = i['node']
        line = (node.lineno - 1)
        col = node.colno
        start = (offsets[line] + col)
        end = start
        if isinstance(node, (ArrayNode, FunctionNode)):
            end = (offsets[(node.end_lineno - 1)] + node.end_colno)
        elif (isinstance(node, AssignmentNode) and (i['action'] == 'rm')):
            if isinstance(node.value, (ArrayNode, FunctionNode)):
                remove_node({'file': i['file'], 'str': , 'node': node.value, 'action': 'rm'})
                raw = files[i['file']]['raw']
            while (raw[end] != '='):
                end += 1
            end += 1
            while (raw[end] in [' ', '\n', '\t']):
                end += 1
        files[i['file']]['raw'] = ((raw[:start] + i['str']) + raw[end:])
    for i in str_list:
        if (i['action'] in ['modify', 'rm']):
            remove_node(i)
        elif (i['action'] in ['add']):
            files[i['file']]['raw'] += (i['str'] + '\n')
    for (key, val) in files.items():
        mlog.log('Rewriting', mlog.yellow(key))
        with open(val['path'], 'w', encoding='utf-8') as fp:
            fp.write(val['raw'])