<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:

def upgrade(refresh=True, pkgs=None, **kwargs):
    '''
    Run pkg upgrade, if pkgin used. Otherwise do nothing

    refresh
        Whether or not to refresh the package database before installing.

    Multiple Package Upgrade Options:

    pkgs
        A list of packages to upgrade from a software repository. Must be
        passed as a python list.

        CLI Example:

        .. code-block:: bash

            salt '*' pkg.upgrade pkgs='["foo","bar"]'

    Returns a dictionary containing the changes:

    .. code-block:: python

        {'<package>':  {'old': '<old-version>',
                        'new': '<new-version>'}}


    CLI Example:

    .. code-block:: bash

        salt '*' pkg.upgrade
    '''
    pkgin = _check_pkgin()
    if not pkgin:
        # There is not easy way to upgrade packages with old package system
        return {}

    if salt.utils.data.is_true(refresh):
        refresh_db()

    old = list_pkgs()

    cmds = []
    if not pkgs:
        cmds.append([pkgin, '-y', 'full-upgrade'])
    elif salt.utils.data.is_list(pkgs):
        for pkg in pkgs:
            cmds.append([pkgin, '-y', 'install', pkg])
    else:
        result = {'retcode': 1, 'reason': 'Ignoring the parameter `pkgs` because it is not a list!'}
        log.error(result['reason'])

    for cmd in cmds:
        result = __salt__['cmd.run_all'](cmd,
                                         output_loglevel='trace',
                                         python_shell=False)
        if result['retcode'] != 0:
            break

    __context__.pop('pkg.list_pkgs', None)
    new = list_pkgs()
    ret = salt.utils.data.compare_dicts(old, new)

    if result['retcode'] != 0:
        raise CommandExecutionError(
            'Problem encountered upgrading packages',
            info={'changes': ret, 'result': result}
        )

    return ret