[Refactor] add `nvm_install_binary_extract`
diff --git a/nvm.sh b/nvm.sh
index a50879f..f6c4ec4 100644
--- a/nvm.sh
+++ b/nvm.sh
@@ -1858,6 +1858,53 @@
   esac
 }
 
+# args: os, prefixed version, version, tarball, extract directory
+nvm_install_binary_extract() {
+  if [ "$#" -ne 5 ]; then
+    nvm_err 'nvm_install_binary_extract needs 5 parameters'
+    return 1
+  fi
+
+  local NVM_OS
+  local PREFIXED_VERSION
+  local VERSION
+  local TARBALL
+  local TMPDIR
+  NVM_OS="${1}"
+  PREFIXED_VERSION="${2}"
+  VERSION="${3}"
+  TARBALL="${4}"
+  TMPDIR="${5}"
+
+  local VERSION_PATH
+
+  [ -n "${TMPDIR-}" ] && \
+  command mkdir -p "${TMPDIR}" && \
+  VERSION_PATH="$(nvm_version_path "${PREFIXED_VERSION}")" || return 1
+
+  local tar_compression_flag
+  tar_compression_flag='z'
+  if nvm_supports_xz "${VERSION}"; then
+    tar_compression_flag='J'
+  fi
+
+  local tar
+  if [ "${NVM_OS}" = 'aix' ]; then
+    tar='gtar'
+  else
+    tar='tar'
+  fi
+  command "${tar}" -x${tar_compression_flag}f "${TARBALL}" -C "${TMPDIR}" --strip-components 1 || return 1
+
+  command mkdir -p "${VERSION_PATH}" || return 1
+
+  command mv "${TMPDIR}/"* "${VERSION_PATH}" || return 1
+
+  command rm -rf "${TMPDIR}"
+
+  return 0
+}
+
 # args: flavor, type, version, reinstall
 nvm_install_binary() {
   local FLAVOR
@@ -1882,19 +1929,15 @@
   local VERSION
   VERSION="$(nvm_strip_iojs_prefix "${PREFIXED_VERSION}")"
 
-  if [ -z "$(nvm_get_os)" ]; then
-    return 2
-  fi
+  local NVM_OS
+  NVM_OS="$(nvm_get_os)"
 
-  local tar_compression_flag
-  tar_compression_flag='z'
-  if nvm_supports_xz "${VERSION}"; then
-    tar_compression_flag='J'
+  if [ -z "${NVM_OS}" ]; then
+    return 2
   fi
 
   local TARBALL
   local TMPDIR
-  local VERSION_PATH
 
   local PROGRESS_BAR
   local NODE_OR_IOJS
@@ -1914,21 +1957,8 @@
   if [ -f "${TARBALL}" ]; then
     TMPDIR="$(dirname "${TARBALL}")/files"
   fi
-  local tar
-  tar='tar'
-  if [ "${NVM_OS}" = 'aix' ]; then
-    tar='gtar'
-  fi
-  if (
-    [ -n "${TMPDIR-}" ] && \
-    command mkdir -p "${TMPDIR}" && \
-    command "${tar}" -x${tar_compression_flag}f "${TARBALL}" -C "${TMPDIR}" --strip-components 1 && \
-    VERSION_PATH="$(nvm_version_path "${PREFIXED_VERSION}")" && \
-    command mkdir -p "${VERSION_PATH}" && \
-    command mv "${TMPDIR}/"* "${VERSION_PATH}" && \
-    command rm -rf "${TMPDIR}"
-  ); then
 
+  if nvm_install_binary_extract "${NVM_OS}" "${PREFIXED_VERSION}" "${VERSION}" "${TARBALL}" "${TMPDIR}"; then
     if [ -n "${ALIAS-}" ]; then
       nvm alias "${ALIAS}" "${provided_version}"
     fi
@@ -3957,7 +3987,7 @@
         nvm_npmrc_bad_news_bears \
         nvm_get_colors nvm_set_colors nvm_print_color_code nvm_format_help_message_colors \
         nvm_echo_with_colors nvm_err_with_colors \
-        nvm_get_artifact_compression \
+        nvm_get_artifact_compression nvm_install_binary_extract \
         >/dev/null 2>&1
       unset NVM_RC_VERSION NVM_NODEJS_ORG_MIRROR NVM_IOJS_ORG_MIRROR NVM_DIR \
         NVM_CD_FLAGS NVM_BIN NVM_INC NVM_MAKE_JOBS \
diff --git a/test/fast/Unit tests/nvm_install_binary_extract b/test/fast/Unit tests/nvm_install_binary_extract
new file mode 100644
index 0000000..a0fc58a
--- /dev/null
+++ b/test/fast/Unit tests/nvm_install_binary_extract
@@ -0,0 +1,56 @@
+#!/bin/sh
+
+cleanup () {
+  [ -d "$tmp_dir" ] && rm -rf "$tmp_dir"
+  [ -d "$NVM_DIR" ] && rm -rf "$NVM_DIR"
+  unset -f die cleanup test_archi nvm_supports_xz
+  unset NVM_DIR tmp_dir version archi
+}
+
+die () { echo "$@" ; cleanup ; exit 1; }
+
+test_archi(){
+  local os="$1"
+  local version="$2"
+  local archi="$os-$3"
+  local node="$4"
+  local ext="$5"
+  local command="$6"
+  local command_option="$7"
+  local node_path="$tmp_dir/node-$version-$archi/$node"
+
+  # Create tarball
+  mkdir -p "$(dirname "$node_path")"
+  echo "node $version" > "$node_path"
+  (cd "$tmp_dir" && "$command" "$command_option" "$tmp_dir/node-$version-$archi.$ext" "node-$version-$archi" && rm -rf "$tmp_dir/node-$version-$archi")
+  [ -f "$tmp_dir/node-$version-$archi.$ext" ] || die "Unable to create fake $ext file"
+
+  # Extract it
+  nvm_install_binary_extract "$os" "$version" "${version:1}" "$tmp_dir/node-$version-$archi.$ext" "$tmp_dir/files"
+  [ "$(cat "$NVM_DIR/versions/node/$version/bin/node")" = "node $version" ] || die "Unable to extract $ext file"
+}
+
+\. ../../../nvm.sh
+
+set -ex
+
+# nvm_install_binary_extract is available
+type nvm_install_binary_extract > /dev/null 2>&1 || die 'nvm_install_binary_extract is not available'
+
+NVM_DIR=$(mktemp -d)
+tmp_dir=$(mktemp -d)
+if [ -z "$NVM_DIR" ] || [ -z "$tmp_dir" ]; then
+  die 'Unable to create temporary folder'
+fi
+
+# Test linux tar.xz
+test_archi 'linux' 'v14.15.4' 'x64' 'bin/node' 'tar.xz' 'tar' '-cJf'
+
+nvm_supports_xz(){
+  return 1
+}
+
+# Test linux tar.gz
+test_archi 'linux' 'v12.9.0' 'x64' 'bin/node' 'tar.gz' 'tar' '-czf'
+
+cleanup