have dcache &&
_dcache()
{
  local dccmd cur prev

  dccmd=${COMP_WORDS[1]}
  cur=${COMP_WORDS[COMP_CWORD]}
  prev=${COMP_WORDS[COMP_CWORD-1]}

  case ${COMP_CWORD} in
    1)
        COMPREPLY=( $( compgen -W 'alarm billing check-config condrestart database dump kpwd ports pool property restart services start status stop version' -- "$cur" ) )
        return 0
        ;;
    2)
        case $prev in
          alarm)
              COMPREPLY=( $( compgen -W 'list send add modify remove' -- "$cur" ) )
              return 0
              ;;
          database)
            COMPREPLY=( $( compgen -W 'ls update showUpdateSQL tag rollback rollbackToDate listLocks releaseLocks doc' -- "$cur" ) )
              return 0
              ;;
          dump)
            COMPREPLY=( $( compgen -W 'heap threads' -- "$cur" ) )
              return 0
              ;;
          pool)
            COMPREPLY=( $( compgen -W 'convert create reconstruct ls yaml' -- "$cur" ) )
              return 0
              ;;
          property)
            defaultsdir="$(dcache property dcache.paths.share)/defaults"
            COMPREPLY=( $( compgen -W "$(grep -P '^(\(((one-of\?)|(immutable)|(not-for-services))[^)]+\))? {0,2}[a-zA-Z][a-zA-Z\._-]*(?= *=)' -o -h ${defaultsdir}/*|grep -e '[a-zA-Z][a-zA-Z\._-]*$' -o)" -- "$cur" ) )
            return 0
            ;;
          billing)
              COMPREPLY=( $( compgen -o nospace -W '--format= --since= --until= -f=' -- "$cur" ) )
              return 0
              ;;
          start|stop|restart|condrestart)
              domains=$(dcache property dcache.domains)
              COMPREPLY=( $( compgen -W "${domains}" -- "$cur" ) )
              return 0
              ;;
        esac
        ;;
    *)
        case $dccmd in
          billing)
              COMPREPLY=( $( compgen -o nospace -W '--format= --since= --until= -f=' -- "$cur" ) )
              return 0
              ;;
          property)
              configdir=$(dcache property dcache.paths.config)
              [ -f "${configdir}/cache" ] && . "${configdir}/cache"
              case ${COMP_CWORD} in
                3)
                  domains=$(dcache property dcache.domains)
                  COMPREPLY=( $( compgen -W "${domains}" -- "$cur" ) )
                  return 0
                  ;;
                4)
                  cells=$(dcache property dcache.domain.cells "$3")
                  COMPREPLY=( $( compgen -W "${cells}" -- "$cur") )
                  return 0
                  ;;
              esac
              ;;
          start|stop|restart|condrestart)
              domains=$(dcache property dcache.domains)
              COMPREPLY=( $( compgen -W "${domains}" -- "$cur" ) )
              return 0
              ;;
        esac
        ;;
  esac
} &&
complete -F _dcache dcache
