docs: function ui5Download(sDownloadURL, sDownloadPath, sUI5Version, oOptions = {}) {
    // check params
    if (!sDownloadURL) {
      return Promise.reject('No download URL provided')
    }
    if (!sDownloadPath) {
      return Promise.reject('No download path provided')
    }
    if (!sUI5Version) {
      return Promise.reject('No UI5 version provided')
    }
  
    const oSteps = {
      download: {
        number: 1,
        details: { name: 'download' }
      },
      unzip: {
        number: 2,
        details: { name: 'unzip' }
      }
    }
    const iTotalSteps = Object.keys(oSteps).length
    const sTargetPath = `${sDownloadPath}/${sUI5Version}`
    const sSuccessMessage = `UI5 download (${sUI5Version}) already exist at ${sDownloadPath}/${sUI5Version}`
    const fnProgressCallback =
      typeof oOptions.onProgress === 'function' ? oOptions.onProgress : () => {}
  
    // check if ui5 library was already downloaded and ectracted
    return fs.existsSync(sTargetPath)
      ? // download is already available
        Promise.resolve(sSuccessMessage)
      : // download and unzip sources
        new Promise((resolve, reject) => {
          progress(
            request.get(
              sDownloadURL,
              { encoding: null },
              (oError, oResponse, oData) => {
                if (oError) {
                  // reject promise
                  return reject(oError)
                }
  
                // update progress information (start step 2)
                const oStep = oSteps['unzip']
                fnProgressCallback(oStep.number, iTotalSteps, oStep.details)
  
                // Do something after request finishes
                const oBuffer = new Buffer(oData, 'binary')
                const zip = new Zip(oBuffer)
                const overwrite = true
  
                // extracts everything
                zip.extractAllTo(sTargetPath, overwrite)
  
                // if sap-ui-core.js is not located in extracted root,
                // we will rename the download directory to 'resources'
                if (!fs.existsSync(`${sTargetPath}/sap-ui-core.js`)) {
                  // read all extracted files in current directory
                  const aFiles = fs.readdirSync(sTargetPath)
                  aFiles.forEach(sFileName => {
                    if (
                      fs.statSync(`${sTargetPath}/${sFileName}`).isDirectory()
                    ) {
                      // rename download folder in root
                      try {
                        fs.renameSync(
                          `${sTargetPath}/${sFileName}`,
                          `${sTargetPath}/resources`
                        )
                      } catch (e) {
                        // skip renaming
                      }
                    }
                  })
                }
  
                // resolve promise
                return resolve(`UI5 download successful: ${sTargetPath}`)
              }
            )
          ).on('progress', oProgressDetails => {
            // update progress information
            const oStep = oSteps['download']
            fnProgressCallback(
              oStep.number,
              iTotalSteps,
              Object.assign({}, oStep.details, {
                progress: oProgressDetails.percent * 100
              })
            )
          })
        })
  }