Printable E.123 (Notation for national and international telephone numbers
    from ITU) numbers.

    :param number: string
    :param areasize: int
    :param groupsize: int
    :param national: bool

    >>> print(e123(155542315678))
    +1 555 4231 5678
    >>> print(e123('+31654231567', areasize=1))
    +31 6 5423 1567
    >>> print(e123('+3114020', areasize=2))
    +31 14 020
    >>> print(e123('+312054231567', areasize=2, national=True))
    (020) 5423 1567

def e123(number, areasize=3, groupsize=4, national=False):
    '''
    Printable E.123 (Notation for national and international telephone numbers
    from ITU) numbers.

    :param number: string
    :param areasize: int
    :param groupsize: int
    :param national: bool

    >>> print(e123(155542315678))
    +1 555 4231 5678
    >>> print(e123('+31654231567', areasize=1))
    +31 6 5423 1567
    >>> print(e123('+3114020', areasize=2))
    +31 14 020
    >>> print(e123('+312054231567', areasize=2, national=True))
    (020) 5423 1567
    '''

    if isinstance(number, six.integer_types):
        return e123('+%s' % number, areasize, groupsize)

    elif isinstance(number, six.string_types):
        number = strip(number, '-. ()')
        if number.startswith('+'):
            number = number[1:]

        if not number.isdigit():
            raise ValueError(_('Invalid telephone number'))

        groups = []
        prefix = ''
        remain = number

        if national:
            for x in six.moves.xrange(3, 0, -1):
                if number[:x] in PHONE_PREFIX:
                    groups.append('(0%s)' % number[x:x + areasize])
                    remain = number[x + areasize:]
                    break

        else:
            prefix = '+'
            for x in six.moves.xrange(3, 0, -1):
                if number[:x] in PHONE_PREFIX:
                    groups.append(number[:x])
                    groups.append(number[x:x + areasize])
                    remain = number[x + areasize:]
                    break

        for x in six.moves.xrange(0, len(remain) + 1, groupsize):
            groups.append(remain[x:x + groupsize])

        return '%s%s' % (prefix, ' '.join(list(filter(None, groups))))