_zimfw_run_tool() {
  local zaction=${1}
  local -r _zname=${2}
  if [[ -z ${_zurls[${_zname}]} ]]; then
    _zimfw_print_okay 'Skipping external module' 1
    return 0
  fi
  if (( _zfrozens[${_zname}] )); then
    _zimfw_print_okay 'Skipping frozen module' 1
    return 0
  fi
  local -r ztool=${_ztools[${_zname}]}
  if [[ ${ztool} != (degit|git|mkdir) ]]; then
    _zimfw_print_error "Unknown tool ${ztool}"
    return 1
  fi
  set "${_zpaths[${_zname}]}" "${_zurls[${_zname}]}" "${_ztypes[${_zname}]}" "${_zrevs[${_zname}]}" "${_zsubmodules[${_zname}]}" "${_zonpulls[${_zname}]}"
  if [[ ${zaction} == reinstall ]]; then
    _zimfw_tool_${ztool} prereinstall "${@}" && return 0
    if (( _zprintlevel > 0 )); then
      if read -q "?Reinstall ${_zname} [y/N]? "; then
        print
      else
        print
        return 0
      fi
    fi
    local -r zpath_new=.${_zpaths[${_zname}]}_${sysparams[pid]}_${RANDOM}
    {
      _zimfw_tool_${ztool} install ${zpath_new} "${@:2}" || return 1
      if ! ERR=$({ command rm -rf ${_zpaths[${_zname}]} && command mv -f ${zpath_new} ${_zpaths[${_zname}]} } 2>&1); then
        _zimfw_print_error "Error reinstalling ${_zpaths[${_zname}]}" ${ERR}
        return 1
      fi
    } always {
      command rm -rf ${zpath_new} 2>/dev/null
    }
    return 0
  else
    _zimfw_tool_${ztool} pre "${@}" || return 1
  fi
  case ${zaction} in
    install)
      if [[ -e ${_zpaths[${_zname}]} ]]; then
        _zimfw_print_okay 'Skipping already installed module' 1
        return 0
      fi
      ;;
    check|update)
      if [[ ! -d ${_zpaths[${_zname}]} ]]; then
        _zimfw_print_error "Not installed. Run ${_zbold}zimfw install${_znormalred} to install."
        return 1
      fi
      ;;
    *)
      _zimfw_print_error "Unknown action ${zaction}"
      return 1
      ;;
  esac
  _zimfw_tool_${ztool} ${zaction} "${@}"
}
