_volumegroups()
{
    COMPREPLY=( $(compgen -W "$( vgscan 2>/dev/null | \
        sed -n -e 's|.*Found.*"\(.*\)".*$|\1|p' )" -- $cur ) )
}

_physicalvolumes()
{
    COMPREPLY=( $(compgen -W "$( pvscan 2>/dev/null | \
        sed -n -e 's|^.*PV \(.*\) VG.*$|\1|p' )" -- $cur ) )
}

_logicalvolumes()
{
    COMPREPLY=( $(compgen -W "$( lvscan 2>/dev/null | \
        sed -n -e "s|^.*'\(.*\)'.*$|\1|p" )" -- $cur ) )
}

_units()
{
    COMPREPLY=( $( compgen -W 'h s b k m g t H K M G T' -- $cur ) )
}

_sizes()
{
    COMPREPLY=( $( compgen -W 'k K m M g G t T' -- $cur ) )
}

_args()
{
    args=0
    if [[ "${COMP_WORDS[0]}" == lvm ]]; then
        offset=2
    else
        offset=1
    fi
    for (( i=$offset; i < COMP_CWORD; i++ )); do
        if [[ "${COMP_WORDS[i]}" != -* ]]; then
            args=$(($args + 1))
        fi
    done
}

_pvscan()
{
    local cur

    COMPREPLY=()
    cur=`_get_cword`

    if [[ "$cur" == -* ]]; then
        COMPREPLY=( $( compgen -W '-d --debug -e \
            --exported -n --novolumegroup -h -? \
            --help --ignorelockingfailure -P \
            --partial -s --short -u --uuid -v \
            --verbose --version' -- $cur ) )
    fi
}

_pvs()
{
    local cur prev

    COMPREPLY=()
    cur=`_get_cword`
    prev=${COMP_WORDS[COMP_CWORD-1]}

    case "$prev" in
        -@(o|O|-options|-sort))
            COMPREPLY=( $( compgen -W 'pv_fmt pv_uuid \
                pv_size pv_free pv_used pv_name \
                pv_attr pv_pe_count \
                pv_pe_alloc_count' -- $cur ) )
            return 0
            ;;
        --units)
            _units
            return 0
            ;;
    esac

    if [[ "$cur" == -* ]]; then
        COMPREPLY=( $( compgen -W '--aligned -a --all -d --debug \
            -h -? --help --ignorelockingfailure --noheadings \
            --nosuffix -o --options -O --sort \
            --separator --unbuffered --units \
            -v --verbose --version' -- $cur ) )
    else
        _physicalvolumes
    fi
}

_pvdisplay()
{
    local cur prev

    COMPREPLY=()
    cur=`_get_cword`
    prev=${COMP_WORDS[COMP_CWORD-1]}

    case "$prev" in
        --units)
            _units
            return 0
            ;;
    esac

    if [[ "$cur" == -* ]]; then
        COMPREPLY=( $( compgen -W '-c --colon -C --columns --units \
            -v --verbose -d --debug -h --help --version' -- $cur ) )
    else
        _physicalvolumes
    fi
}

_pvchange()
{
    local cur prev

    COMPREPLY=()
    cur=`_get_cword`
    prev=${COMP_WORDS[COMP_CWORD-1]}

    case "$prev" in
        -@(A|x|-autobackup|--allocatable))
            COMPREPLY=( $( compgen -W 'y n' -- $cur ) )
            return 0
            ;;
    esac

    if [[ "$cur" == -* ]]; then
        COMPREPLY=( $( compgen -W '-a --all -A --autobackup \
            -d --debug -h --help -t --test -u --uuid -x \
            --allocatable -v --verbose --addtag --deltag \
            --version' -- $cur ) )
    else
        _physicalvolumes
    fi
}

_pvcreate()
{
    local cur prev

    COMPREPLY=()
    cur=`_get_cword`
    prev=${COMP_WORDS[COMP_CWORD-1]}

    case "$prev" in
        --restorefile)
            _filedir
            return 0
            ;;
        -@(M|-metadatatype))
            COMPREPLY=( $( compgen -W '1 2' -- $cur ) )
            return 0
            ;;
        --metadatacopies)
            COMPREPLY=( $( compgen -W '0 1 2' -- $cur ) )
            return 0
            ;;
        --@(metadatasize|setphysicalvolumesize))
            _sizes
            return 0
            ;;
    esac

    if [[ "$cur" == -* ]]; then
        COMPREPLY=( $( compgen -W '--restorefile -d --debug -f \
            --force -h -? --help --labelsector -M --metadatatype \
            --metadatacopies --metadatasize \
            --setphysicalvolumesize -t --test -u --uuid uuid -v \
            --verbose -y --yes --version' -- $cur ) )
    else
        _physicalvolumes
    fi
}

_pvmove()
{
    local cur prev

    COMPREPLY=()
    cur=`_get_cword`
    prev=${COMP_WORDS[COMP_CWORD-1]}

    case "$prev" in
        -@(A|-autobackup))
            COMPREPLY=( $( compgen -W 'y n' -- $cur ) )
            return 0
            ;;
        -@(n|-name))
            _logicalvolumes
            return 0
    esac

    if [[ "$cur" == -* ]]; then
        COMPREPLY=( $( compgen -W '--abort -A --autobackup \
            -b --background -d --debug -f --force -h -? \
            --help -i --interval -t --test -v --verbose \
            --version -n --name' -- $cur ) )
    else
        _physicalvolumes
    fi
}

_pvremove()
{
    local cur

    COMPREPLY=()
    cur=`_get_cword`

    if [[ "$cur" == -* ]]; then
        COMPREPLY=( $( compgen -W '-d --debug -f --force -h -? \
            --help -y --yes -t --test -v --verbose \
            --version' -- $cur ) )
    else
        _physicalvolumes
    fi
}

_vgscan()
{
    local cur

    COMPREPLY=()
    cur=`_get_cword`

    if [[ "$cur" == -* ]]; then
        COMPREPLY=( $( compgen -W '-d --debug -h --help \
            --ignorelockingfailure --mknodes -P \
            --partial -v --verbose --version' -- $cur ) )
    fi
}

_vgs()
{
    local cur prev

    COMPREPLY=()
    cur=`_get_cword`
    prev=${COMP_WORDS[COMP_CWORD-1]}

    case "$prev" in
        -@(o|O|-options|-sort))
            COMPREPLY=( $( compgen -W 'vg_fmt vg_uuid vg_name \
                vg_attr vg_size vg_free vg_sysid \
                vg_extent_size vg_extent_count vg_free_count \
                max_lv max_pv pv_count lv_count snap_count \
                vg_seqno' -- $cur ) )
            return 0
            ;;
        --units)
            _units
            return 0
            ;;
    esac

    if [[ "$cur" == -* ]]; then
        COMPREPLY=( $( compgen -W '--aligned -d --debug \
            -h --help --ignorelockingfailure --noheadings \
            --nosuffix -o --options -O --sort -P --partial \
            --separator --unbuffered --units \
            -v --verbose --version' -- $cur ) )
    else
        _volumegroups
    fi
}

_vgdisplay()
{
    local cur prev

    COMPREPLY=()
    cur=`_get_cword`
    prev=${COMP_WORDS[COMP_CWORD-1]}

    case "$prev" in
        --units)
            _units
            return 0
            ;;
    esac

    if [[ "$cur" == -* ]]; then
        COMPREPLY=( $( compgen -W '-c --colon -C --columns --units \
            -P --partial -A --activevolumegroups -v --verbose \
            -d --debug -h --help --version' -- $cur ) )
    else
        _volumegroups
    fi
}

_vgchange()
{
    local cur prev

    COMPREPLY=()
    cur=`_get_cword`
    prev=${COMP_WORDS[COMP_CWORD-1]}

    case "$prev" in
        -@(a|A|x|-available|-autobackup|-resizeable))
            COMPREPLY=( $( compgen -W 'y n' -- $cur ) )
            return 0
            ;;
    esac

    if [[ "$cur" == -* ]]; then
        COMPREPLY=( $( compgen -W '-A --autobackup --alloc -P \
            --partial -d --debug -h --help --ignorelockingfailure \
            -t --test -u --uuid -v --verbose --version -a \
            --available -x --resizeable -l --logicalvolume \
            --addtag --deltag' -- $cur ) )
    else
        _volumegroups
    fi
}

_vgcreate()
{
    local cur prev

    COMPREPLY=()
    cur=`_get_cword`
    prev=${COMP_WORDS[COMP_CWORD-1]}

    case "$prev" in
        -@(A|-autobackup))
            COMPREPLY=( $( compgen -W 'y n' -- $cur ) )
            return 0
            ;;
        -@(M|-metadatatype))
            COMPREPLY=( $( compgen -W '1 2' -- $cur ) )
            return 0
            ;;
        -@(s|-physicalextentsize))
            _sizes
            return 0
            ;;
    esac

    if [[ "$cur" == -* ]]; then
        COMPREPLY=( $( compgen -W '-A --autobackup --addtag \
            --alloc -d --debug -h --help -l --maxlogicalvolumes \
            -M --metadatatype -p --maxphysicalvolumes -s \
            --physicalextentsize -t --test -v --verbose \
            --version' -- $cur ) )
    else
        _args
        if [ $args -eq 0 ]; then
            _volumegroups
        else
            _physicalvolumes
        fi
    fi
}

_vgremove()
{
    local cur

    COMPREPLY=()
    cur=`_get_cword`

    if [[ "$cur" == -* ]]; then
        COMPREPLY=( $( compgen -W '-d --debug -h --help -t --test \
        -v --verbose --version' -- $cur ) )
    else
        _volumegroups
    fi
}

_vgrename()
{
    local cur prev

    COMPREPLY=()
    cur=`_get_cword`
    prev=${COMP_WORDS[COMP_CWORD-1]}

    case "$prev" in
        -@(A|-autobackup))
            COMPREPLY=( $( compgen -W 'y n' -- $cur ) )
            return 0
            ;;
    esac

    if [[ "$cur" == -* ]]; then
        COMPREPLY=( $( compgen -W '-A --autobackup -d --debug -h \
            -? --help -t --test -v --verbose --version' -- $cur ) )
    else
        _volumegroups
    fi
}

_vgreduce()
{
    local cur prev

    COMPREPLY=()
    cur=`_get_cword`
    prev=${COMP_WORDS[COMP_CWORD-1]}

    case "$prev" in
        -@(A|-autobackup))
            COMPREPLY=( $( compgen -W 'y n' -- $cur ) )
            return 0
            ;;
    esac

    if [[ "$cur" == -* ]]; then
        COMPREPLY=( $( compgen -W '-a --all -A --autobackup -d \
            --debug -h --help --removemissing -t --test -v \
            --verbose --version' -- $cur ) )

    else
        _args
        if [ $args -eq 0 ]; then
            _volumegroups
        else
            _physicalvolumes
        fi
    fi
}

_vgextend()
{
    local cur prev

    COMPREPLY=()
    cur=`_get_cword`
    prev=${COMP_WORDS[COMP_CWORD-1]}

    case "$prev" in
        -@(A|-autobackup))
            COMPREPLY=( $( compgen -W 'y n' -- $cur ) )
            return 0
            ;;
        -@(L|-size))
            _sizes
            return 0
            ;;
    esac

    if [[ "$cur" == -* ]]; then
        COMPREPLY=( $( compgen -W '-A --autobackup -d --debug -h \
            -? --help -t --test -v --verbose --version' -- $cur ) )
    else
        _args
        if [ $args -eq 0 ]; then
            _volumegroups
        else
            _physicalvolumes
        fi
    fi
}

_vgport()
{
    local cur prev

    COMPREPLY=()
    cur=`_get_cword`

    if [[ "$cur" == -* ]]; then
        COMPREPLY=( $( compgen -W '-a --all -d --debug -h \
            -? --help -v --verbose --version' -- $cur ) )
    else
        _volumegroups
    fi
}

_vgck()
{
    local cur prev

    COMPREPLY=()
    cur=`_get_cword`

    if [[ "$cur" == -* ]]; then
        COMPREPLY=( $( compgen -W '-d --debug -h \
            -? --help -v --verbose --version' -- $cur ) )
    else
        _volumegroups
    fi
}

_vgconvert()
{
    local cur prev

    COMPREPLY=()
    cur=`_get_cword`
    prev=${COMP_WORDS[COMP_CWORD-1]}

    case "$prev" in
        -@(M|-metadatatype))
            COMPREPLY=( $( compgen -W '1 2' -- $cur ) )
            return 0
            ;;
        --metadatacopies)
            COMPREPLY=( $( compgen -W '0 1 2' -- $cur ) )
            return 0
            ;;
        --metadatasize)
            _sizes
            return 0
            ;;
    esac

    if [[ "$cur" == -* ]]; then
        COMPREPLY=( $( compgen -W '-d --debug -h --help --labelsector \ 
            -M --metadatatype --metadatacopies --metadatasize \
            -t --test -v --verbose --version' -- $cur ) )
    else
        _volumegroups
    fi
}

_vgcfgbackup()
{
    local cur prev

    COMPREPLY=()
    cur=`_get_cword`
    prev=${COMP_WORDS[COMP_CWORD-1]}

    case "$prev" in
        -@(f|-file))
            _filedir
            return 0
            ;;
    esac

    if [[ "$cur" == -* ]]; then
        COMPREPLY=( $( compgen -W '-d --debug -f --file -h --help \
            --ignorelockingfailure -P --partial -v --verbose \
            --version' -- $cur ) )
    else
        _volumegroups
    fi
}

_vgcfgrestore()
{
    local cur prev

    COMPREPLY=()
    cur=`_get_cword`
    prev=${COMP_WORDS[COMP_CWORD-1]}

    case "$prev" in
        -@(f|-file))
            _filedir
            return 0
            ;;
        -@(M|-metadatatype))
            COMPREPLY=( $( compgen -W '1 2' -- $cur ) )
            return 0
            ;;
        -@(n|-name))
            _volumegroups
            return 0
            ;;
    esac

    if [[ "$cur" == -* ]]; then
        COMPREPLY=( $( compgen -W '-d --debug -f --file -l --list \
            -h --help -M --Metadatatype -n --name -t --test \
            -v --verbose --version' -- $cur ) )
    else
        _volumegroups
    fi
}

_vgmerge()
{
    local cur prev

    COMPREPLY=()
    cur=`_get_cword`
    prev=${COMP_WORDS[COMP_CWORD-1]}

    case "$prev" in
        -@(A|-autobackup))
            COMPREPLY=( $( compgen -W 'y n' -- $cur ) )
            return 0
            ;;
    esac

    if [[ "$cur" == -* ]]; then
        COMPREPLY=( $( compgen -W '-A --autobackup -d --debug \
            -h --help -l --list -t --test -v --verbose \
            --version' -- $cur ) )
    else
        _volumegroups
    fi
}

_vgsplit()
{
    local cur prev

    COMPREPLY=()
    cur=`_get_cword`
    prev=${COMP_WORDS[COMP_CWORD-1]}

    case "$prev" in
        -@(A|-autobackup))
            COMPREPLY=( $( compgen -W 'y n' -- $cur ) )
            return 0
            ;;
        -@(M|-metadatatype))
            COMPREPLY=( $( compgen -W '1 2' -- $cur ) )
            return 0
            ;;
    esac

    if [[ "$cur" == -* ]]; then
        COMPREPLY=( $( compgen -W '-A --autobackup -d --debug \
            -h --help -l --list -M --metadatatype -t --test \
            -v --verbose --version' -- $cur ) )
    else
        _args
        if [ $args -eq 0 -o $args -eq 1 ]; then
            _volumegroups
        else
            _physicalvolumes
        fi
    fi
}

_vgmknodes()
{
    local cur

    COMPREPLY=()
    cur=`_get_cword`

    if [[ "$cur" == -* ]]; then
        COMPREPLY=( $( compgen -W '-d --debug -h --help -v --verbose \
            --version' -- $cur ) )
    else
        _volumegroups
    fi
}

_lvscan()
{
    local cur

    COMPREPLY=()
    cur=`_get_cword`

    if [[ "$cur" == -* ]]; then
        COMPREPLY=( $( compgen -W '-b --blockdevice -d --debug \
            -h -? --help --ignorelockingfailure -P \
            --partial -v --verbose --version' -- $cur ) )
    fi
}

_lvs()
{
    local cur prev

    COMPREPLY=()
    cur=`_get_cword`
    prev=${COMP_WORDS[COMP_CWORD-1]}

    case "$prev" in
        -@(o|O|-options|-sort))
            COMPREPLY=( $( compgen -W 'lv_uuid lv_name \
                lv_attr lv_minor lv_size seg_count \
                origin snap_percent segtype stripes \
                stripesize chunksize seg_start \
                seg_size' -- $cur ) )
            return 0
            ;;
        --units)
            _units
            return 0
            ;;
    esac

    if [[ "$cur" == -* ]]; then
        COMPREPLY=( $( compgen -W '--aligned -d --debug \
            -h --help --ignorelockingfailure --noheadings \
            --nosuffix -o --options -O --sort -P --partial \
            --segments --separator --unbuffered --units \
            -v --verbose --version' -- $cur ) )
    else
        _logicalvolumes
    fi
}

_lvdisplay()
{
    local cur prev

    COMPREPLY=()
    cur=`_get_cword`
    prev=${COMP_WORDS[COMP_CWORD-1]}

    case "$prev" in
        --units)
            _units
            return 0
            ;;
    esac

    if [[ "$cur" == -* ]]; then
        COMPREPLY=( $( compgen -W '-c --colon -C --columns --units \
            -P --partial -m --maps -v --verbose -d --debug -h \
            --help --version' -- $cur ) )
    else
        _logicalvolumes
    fi
}

_lvchange()
{
    local cur prev

    COMPREPLY=()
    cur=`_get_cword`
    prev=${COMP_WORDS[COMP_CWORD-1]}

    case "$prev" in
        -@(a|A|C|M|-available|-autobackup|-continguous|-persistent))
            COMPREPLY=( $( compgen -W 'y n' -- $cur ) )
            return 0
            ;;
        -@(p|-permission))
            COMPREPLY=( $( compgen -W 'r rw' -- $cur ) )
            return 0
            ;;
    esac

    if [[ "$cur" == -* ]]; then
        COMPREPLY=( $( compgen -W '-A --autobackup -a --available \
            --addtag --alloc -C --contiguous -d --debug --deltag \
            -f --force -h --help --ignorelockingfailure -M \
            --persistent --major major --minor minor -P --partial \
            -p --permission -r --readahead --refresh -t --test \
            -v --verbose --version' -- $cur ) )
    else
        _logicalvolumes
    fi
}

_lvcreate()
{
    local cur prev

    COMPREPLY=()
    cur=`_get_cword`
    prev=${COMP_WORDS[COMP_CWORD-1]}

    case "$prev" in
        -@(A|C|M|Z|-autobackup|-continguous|-persistent|-zero))
            COMPREPLY=( $( compgen -W 'y n' -- $cur ) )
            return 0
            ;;
        -@(L|-size))
            _sizes
            return 0
            ;;
        -@(p|-permission))
            COMPREPLY=( $( compgen -W 'r rw' -- $cur ) )
            return 0
            ;;
        -@(n|-name))
            _logicalvolumes
            return 0
            ;;
    esac

    if [[ "$cur" == -* ]]; then
        COMPREPLY=( $( compgen -W '-A --autobackup --addtag --alloc \
            -C --contiguous -d --debug -h -? --help -i --stripes \
            -I --stripesize -l --extents -L --size -M --persistent \
            --major --minor -n --name -p --permission -r \
            --readahead -t --test --type -v --verbose -Z --zero \
            --version' -- $cur ) )
    else
        _args
        if [ $args -eq 0 ]; then
            _volumegroups
        else
            _physicalvolumes
        fi
    fi
}

_lvremove()
{
    local cur prev

    COMPREPLY=()
    cur=`_get_cword`
    prev=${COMP_WORDS[COMP_CWORD-1]}

    case "$prev" in
        -@(A|-autobackup))
            COMPREPLY=( $( compgen -W 'y n' -- $cur ) )
            return 0
            ;;
    esac

    if [[ "$cur" == -* ]]; then
        COMPREPLY=( $( compgen -W '-A --autobackup -d --debug -f \
            --force -h -?  --help -t --test -v --verbose \
            --version' -- $cur ) )
    else
        _logicalvolumes
    fi
}

_lvrename()
{
    local cur prev

    COMPREPLY=()
    cur=`_get_cword`
    prev=${COMP_WORDS[COMP_CWORD-1]}

    case "$prev" in
        -@(A|-autobackup))
            COMPREPLY=( $( compgen -W 'y n' -- $cur ) )
            return 0
            ;;
    esac

    if [[ "$cur" == -* ]]; then
        COMPREPLY=( $( compgen -W '-A --autobackup -d --debug -h \
            -? --help -t --test -v --verbose --version' -- $cur ) )
    else
        _logicalvolumes
    fi
}

_lvreduce()
{
    local cur prev

    COMPREPLY=()
    cur=`_get_cword`
    prev=${COMP_WORDS[COMP_CWORD-1]}

    case "$prev" in
        -@(A|-autobackup))
            COMPREPLY=( $( compgen -W 'y n' -- $cur ) )
            return 0
            ;;
        -@(L|-size))
            _sizes
            return 0
            ;;
    esac

    if [[ "$cur" == -* ]]; then
        COMPREPLY=( $( compgen -W '-A --autobackup -d \
            --debug -f --force -h --help -l --extents \
            -L --size -n --nofsck -r --resizefs -t --test \
            -v --verbose --version' -- $cur ) )
    else
        _logicalvolumes
    fi
}

_lvresize()
{
    local cur prev

    COMPREPLY=()
    cur=`_get_cword`
    prev=${COMP_WORDS[COMP_CWORD-1]}

    case "$prev" in
        -@(A|-autobackup))
            COMPREPLY=( $( compgen -W 'y n' -- $cur ) )
            return 0
            ;;
        -@(L|-size))
            _sizes
            return 0
            ;;
    esac

    if [[ "$cur" == -* ]]; then
        COMPREPLY=( $( compgen -W '-A --autobackup --alloc -d \
            --debug -h --help -i --stripes -I --stripesize \
            -l --extents -L --size -n --nofsck -r --resizefs \
            -t --test --type -v --verbose --version' -- $cur ) )
    else
        _args
        if [ $args -eq 0 ]; then
            _logicalvolumes
        else
            _physicalvolumes
        fi
    fi
}

_lvextend()
{
    local cur prev

    COMPREPLY=()
    cur=`_get_cword`
    prev=${COMP_WORDS[COMP_CWORD-1]}

    case "$prev" in
        -@(A|-autobackup))
            COMPREPLY=( $( compgen -W 'y n' -- $cur ) )
            return 0
            ;;
        -@(L|-size))
            _sizes
            return 0
            ;;
    esac

    if [[ "$cur" == -* ]]; then
        COMPREPLY=( $( compgen -W '-A --autobackup --alloc -d \
            --debug -h --help -i --stripes -I --stripesize \
            -l --extents -L --size -n --nofsck -r --resizefs \
            -t --test --type -v --verbose --version' -- $cur ) )
    else
        _args
        if [ $args -eq 0 ]; then
            _logicalvolumes
        else
            _physicalvolumes
        fi
    fi
}
