'Specialized Routine creation for Octave.'

def routine(self, name, expr, argument_sequence, global_vars):

    if (is_sequence(expr) and (not isinstance(expr, (MatrixBase, MatrixExpr)))):
        if (not expr):
            raise ValueError('No    expression    given')
        expressions = Tuple(*expr)
    else:
        expressions = Tuple(expr)
    local_vars = {i.label for i in expressions.atoms(Idx)}
    global_vars = (set() if (global_vars is None) else set(global_vars))
    old_symbols = ((expressions.free_symbols - local_vars) - global_vars)
    symbols = set([])
    for s in old_symbols:
        if isinstance(s, Idx):
            symbols.update(s.args[1].free_symbols)
        else:
            symbols.add(s)
    return_vals = []
    for (i, expr) in enumerate(expressions):
        if isinstance(expr, Equality):
            out_arg = expr.lhs
            expr = expr.rhs
            symbol = out_arg
            if isinstance(out_arg, Indexed):
                symbol = out_arg.base.label
            if (not isinstance(out_arg, (Indexed, Symbol, MatrixSymbol))):
                raise CodeGenError('Only    Indexed,    Symbol,    or    MatrixSymbol    can    define    output    arguments.')
            return_vals.append(Result(expr, name=symbol, result_var=out_arg))
            if (not expr.has(symbol)):
                symbols.remove(symbol)
        else:
            return_vals.append(Result(expr, name=('out%d' % (i + 1))))
    arg_list = []
    array_symbols = {}
    for array in expressions.atoms(Indexed):
        array_symbols[array.base.label] = array
    for array in expressions.atoms(MatrixSymbol):
        array_symbols[array] = array
    for symbol in sorted(symbols, key=str):
        arg_list.append(InputArgument(symbol))
    if (argument_sequence is not None):
        new_sequence = []
        for arg in argument_sequence:
            if isinstance(arg, IndexedBase):
                new_sequence.append(arg.label)
            else:
                new_sequence.append(arg)
        argument_sequence = new_sequence
        missing = [x for x in arg_list if (x.name not in argument_sequence)]
        if missing:
            msg = "Argument    list    didn't    specify:    {0}    "
            msg = msg.format(',    '.join([str(m.name) for m in missing]))
            raise CodeGenArgumentListError(msg, missing)
        name_arg_dict = {x.name: x for x in arg_list}
        new_args = []
        for symbol in argument_sequence:
            try:
                new_args.append(name_arg_dict[symbol])
            except KeyError:
                new_args.append(InputArgument(symbol))
        arg_list = new_args
    return Routine(name, arg_list, return_vals, local_vars, global_vars)
