function makemsdoc(genobj, new_type, options, gen_private, type_info) {
  /**
   * Generate string of the current date and time.
   *
   * This method generating a string with the current date and time in Office XML format.
   *
   * @return String of the current date and time in Office XML format.
   */
  function getCurDateTimeForOffice() {
    var date = new Date()

    var year = date.getFullYear()
    var month = date.getMonth() + 1
    var day = date.getDate()
    var hour = date.getHours()
    var min = date.getMinutes()
    var sec = date.getSeconds()

    month = (month < 10 ? '0' : '') + month
    day = (day < 10 ? '0' : '') + day
    hour = (hour < 10 ? '0' : '') + hour
    min = (min < 10 ? '0' : '') + min
    sec = (sec < 10 ? '0' : '') + sec

    return (
      year + '-' + month + '-' + day + 'T' + hour + ':' + min + ':' + sec + 'Z'
    )
  }

  /**
   * Compact the given array.
   *
   * This function compacting the given array.
   *
   * @param {object} arr The array to compact.
   */
  function compactArray(arr) {
    var len = arr.length

    for (var i = 0; i < len; i++) {
      if (arr[i]) {
        arr.push(arr[i])
      } // Endif.
    } // End of for loop.

    arr.splice(0, len) // Cut the array and leave only the non-empty values.
  }

  /**
   * Create the main files list resource.
   *
   * @param {object} data Ignored by this callback function.
   * @return Text string.
   */
  function cbMakeMainFilesList(data) {
    var outString = gen_private.plugs.type.msoffice.cbMakeMsOfficeBasicXml(data)
    outString +=
      '<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">'

    for (
      var i = 0, total_size = gen_private.type.msoffice.files_list.length;
      i < total_size;
      i++
    ) {
      if (typeof gen_private.type.msoffice.files_list[i] !== 'undefined') {
        if (gen_private.type.msoffice.files_list[i].ext) {
          // Fixed by @author:vtloc @date:2014Jan09
          // Reason: if we write out duplicate extension, office will raise error
          //
          if (
            outString.indexOf(
              '<Default Extension="' +
                gen_private.type.msoffice.files_list[i].ext
            ) === -1
          ) {
            // check to make sure we don't write duplicate extension tag
            outString +=
              '<Default Extension="' +
              gen_private.type.msoffice.files_list[i].ext +
              '" ContentType="' +
              gen_private.type.msoffice.files_list[i].type +
              '"/>'

            if (gen_private.type.msoffice.files_list[i].ext === 'jpeg') {
              outString += '<Default Extension="jpg" ContentType="image/jpg"/>'
            } // Endif.
          }
        } else {
          outString +=
            '<Override PartName="' +
            gen_private.type.msoffice.files_list[i].name +
            '" ContentType="' +
            gen_private.type.msoffice.files_list[i].type +
            '"/>'
        } // Endif.
      } // Endif.
    } // End of for loop.

    outString += '</Types>\n'
    return outString
  }

  /**
   * Create the theme to use with this document.
   *
   * @param {object} data Ignored by this callback function.
   * @return Text string.
   */
  function cbMakeTheme(data) {
    if (genobj.theme) {
      // console.log ( genobj.theme )
      return genobj.theme
    } // Endif.

    return (
      gen_private.plugs.type.msoffice.cbMakeMsOfficeBasicXml(data) +
      '<a:theme xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" name="Office Theme"><a:themeElements><a:clrScheme name="Office"><a:dk1><a:sysClr val="windowText" lastClr="000000"/></a:dk1><a:lt1><a:sysClr val="window" lastClr="FFFFFF"/></a:lt1><a:dk2><a:srgbClr val="1F497D"/></a:dk2><a:lt2><a:srgbClr val="EEECE1"/></a:lt2><a:accent1><a:srgbClr val="4F81BD"/></a:accent1><a:accent2><a:srgbClr val="C0504D"/></a:accent2><a:accent3><a:srgbClr val="9BBB59"/></a:accent3><a:accent4><a:srgbClr val="8064A2"/></a:accent4><a:accent5><a:srgbClr val="4BACC6"/></a:accent5><a:accent6><a:srgbClr val="F79646"/></a:accent6><a:hlink><a:srgbClr val="0000FF"/></a:hlink><a:folHlink><a:srgbClr val="800080"/></a:folHlink></a:clrScheme><a:fontScheme name="Office"><a:majorFont><a:latin typeface="Calibri"/><a:ea typeface=""/><a:cs typeface=""/><a:font script="Jpan" typeface="MS P????"/><a:font script="Hang" typeface="?? ??"/><a:font script="Hans" typeface="??"/><a:font script="Hant" typeface="????"/><a:font script="Arab" typeface="Times New Roman"/><a:font script="Hebr" typeface="Times New Roman"/><a:font script="Thai" typeface="Angsana New"/><a:font script="Ethi" typeface="Nyala"/><a:font script="Beng" typeface="Vrinda"/><a:font script="Gujr" typeface="Shruti"/><a:font script="Khmr" typeface="MoolBoran"/><a:font script="Knda" typeface="Tunga"/><a:font script="Guru" typeface="Raavi"/><a:font script="Cans" typeface="Euphemia"/><a:font script="Cher" typeface="Plantagenet Cherokee"/><a:font script="Yiii" typeface="Microsoft Yi Baiti"/><a:font script="Tibt" typeface="Microsoft Himalaya"/><a:font script="Thaa" typeface="MV Boli"/><a:font script="Deva" typeface="Mangal"/><a:font script="Telu" typeface="Gautami"/><a:font script="Taml" typeface="Latha"/><a:font script="Syrc" typeface="Estrangelo Edessa"/><a:font script="Orya" typeface="Kalinga"/><a:font script="Mlym" typeface="Kartika"/><a:font script="Laoo" typeface="DokChampa"/><a:font script="Sinh" typeface="Iskoola Pota"/><a:font script="Mong" typeface="Mongolian Baiti"/><a:font script="Viet" typeface="Times New Roman"/><a:font script="Uigh" typeface="Microsoft Uighur"/></a:majorFont><a:minorFont><a:latin typeface="Calibri"/><a:ea typeface=""/><a:cs typeface=""/><a:font script="Jpan" typeface="MS P????"/><a:font script="Hang" typeface="?? ??"/><a:font script="Hans" typeface="??"/><a:font script="Hant" typeface="????"/><a:font script="Arab" typeface="Arial"/><a:font script="Hebr" typeface="Arial"/><a:font script="Thai" typeface="Cordia New"/><a:font script="Ethi" typeface="Nyala"/><a:font script="Beng" typeface="Vrinda"/><a:font script="Gujr" typeface="Shruti"/><a:font script="Khmr" typeface="DaunPenh"/><a:font script="Knda" typeface="Tunga"/><a:font script="Guru" typeface="Raavi"/><a:font script="Cans" typeface="Euphemia"/><a:font script="Cher" typeface="Plantagenet Cherokee"/><a:font script="Yiii" typeface="Microsoft Yi Baiti"/><a:font script="Tibt" typeface="Microsoft Himalaya"/><a:font script="Thaa" typeface="MV Boli"/><a:font script="Deva" typeface="Mangal"/><a:font script="Telu" typeface="Gautami"/><a:font script="Taml" typeface="Latha"/><a:font script="Syrc" typeface="Estrangelo Edessa"/><a:font script="Orya" typeface="Kalinga"/><a:font script="Mlym" typeface="Kartika"/><a:font script="Laoo" typeface="DokChampa"/><a:font script="Sinh" typeface="Iskoola Pota"/><a:font script="Mong" typeface="Mongolian Baiti"/><a:font script="Viet" typeface="Arial"/><a:font script="Uigh" typeface="Microsoft Uighur"/></a:minorFont></a:fontScheme><a:fmtScheme name="Office"><a:fillStyleLst><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:gradFill rotWithShape="1"><a:gsLst><a:gs pos="0"><a:schemeClr val="phClr"><a:tint val="50000"/><a:satMod val="300000"/></a:schemeClr></a:gs><a:gs pos="35000"><a:schemeClr val="phClr"><a:tint val="37000"/><a:satMod val="300000"/></a:schemeClr></a:gs><a:gs pos="100000"><a:schemeClr val="phClr"><a:tint val="15000"/><a:satMod val="350000"/></a:schemeClr></a:gs></a:gsLst><a:lin ang="16200000" scaled="1"/></a:gradFill><a:gradFill rotWithShape="1"><a:gsLst><a:gs pos="0"><a:schemeClr val="phClr"><a:shade val="51000"/><a:satMod val="130000"/></a:schemeClr></a:gs><a:gs pos="80000"><a:schemeClr val="phClr"><a:shade val="93000"/><a:satMod val="130000"/></a:schemeClr></a:gs><a:gs pos="100000"><a:schemeClr val="phClr"><a:shade val="94000"/><a:satMod val="135000"/></a:schemeClr></a:gs></a:gsLst><a:lin ang="16200000" scaled="0"/></a:gradFill></a:fillStyleLst><a:lnStyleLst><a:ln w="9525" cap="flat" cmpd="sng" algn="ctr"><a:solidFill><a:schemeClr val="phClr"><a:shade val="95000"/><a:satMod val="105000"/></a:schemeClr></a:solidFill><a:prstDash val="solid"/></a:ln><a:ln w="25400" cap="flat" cmpd="sng" algn="ctr"><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:prstDash val="solid"/></a:ln><a:ln w="38100" cap="flat" cmpd="sng" algn="ctr"><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:prstDash val="solid"/></a:ln></a:lnStyleLst><a:effectStyleLst><a:effectStyle><a:effectLst><a:outerShdw blurRad="40000" dist="20000" dir="5400000" rotWithShape="0"><a:srgbClr val="000000"><a:alpha val="38000"/></a:srgbClr></a:outerShdw></a:effectLst></a:effectStyle><a:effectStyle><a:effectLst><a:outerShdw blurRad="40000" dist="23000" dir="5400000" rotWithShape="0"><a:srgbClr val="000000"><a:alpha val="35000"/></a:srgbClr></a:outerShdw></a:effectLst></a:effectStyle><a:effectStyle><a:effectLst><a:outerShdw blurRad="40000" dist="23000" dir="5400000" rotWithShape="0"><a:srgbClr val="000000"><a:alpha val="35000"/></a:srgbClr></a:outerShdw></a:effectLst><a:scene3d><a:camera prst="orthographicFront"><a:rot lat="0" lon="0" rev="0"/></a:camera><a:lightRig rig="threePt" dir="t"><a:rot lat="0" lon="0" rev="1200000"/></a:lightRig></a:scene3d><a:sp3d><a:bevelT w="63500" h="25400"/></a:sp3d></a:effectStyle></a:effectStyleLst><a:bgFillStyleLst><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:gradFill rotWithShape="1"><a:gsLst><a:gs pos="0"><a:schemeClr val="phClr"><a:tint val="40000"/><a:satMod val="350000"/></a:schemeClr></a:gs><a:gs pos="40000"><a:schemeClr val="phClr"><a:tint val="45000"/><a:shade val="99000"/><a:satMod val="350000"/></a:schemeClr></a:gs><a:gs pos="100000"><a:schemeClr val="phClr"><a:shade val="20000"/><a:satMod val="255000"/></a:schemeClr></a:gs></a:gsLst><a:path path="circle"><a:fillToRect l="50000" t="-80000" r="50000" b="180000"/></a:path></a:gradFill><a:gradFill rotWithShape="1"><a:gsLst><a:gs pos="0"><a:schemeClr val="phClr"><a:tint val="80000"/><a:satMod val="300000"/></a:schemeClr></a:gs><a:gs pos="100000"><a:schemeClr val="phClr"><a:shade val="30000"/><a:satMod val="200000"/></a:schemeClr></a:gs></a:gsLst><a:path path="circle"><a:fillToRect l="50000" t="50000" r="50000" b="50000"/></a:path></a:gradFill></a:bgFillStyleLst></a:fmtScheme></a:themeElements><a:objectDefaults/><a:extraClrSchemeLst/></a:theme>'
    )
  }

  /**
   * Generate the coreProperties for the document.
   *
   * This method creating the docProps/core.xml resource inside any MS based document. Each type of document generator is adding the
   * supported document properties using calls to gen_private.plugs.type.msoffice.addInfoType().
   *
   * @param {object} data Ignored by this callback function.
   * @return Text string.
   */
  function cbMakeCore(data) {
    var curDateTime = getCurDateTimeForOffice()
    var userName =
      genobj.options.author || genobj.options.creator || 'officegen'
    var extraFields = ''

    // Work on all the properties:
    for (var infoRec in genobj.info) {
      if (
        genobj.info[infoRec] &&
        genobj.info[infoRec].element &&
        genobj.info[infoRec].data
      ) {
        extraFields +=
          '<' +
          genobj.info[infoRec].element +
          '>' +
          gen_private.plugs.type.msoffice.escapeText(
            genobj.info[infoRec].data
          ) +
          '</' +
          genobj.info[infoRec].element +
          '>'
      } // Endif.
    } // End of for loop.

    return (
      gen_private.plugs.type.msoffice.cbMakeMsOfficeBasicXml(data) +
      '<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:dcmitype="http://purl.org/dc/dcmitype/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' +
      extraFields +
      '<dc:creator>' +
      userName +
      '</dc:creator><cp:lastModifiedBy>' +
      userName +
      '</cp:lastModifiedBy><cp:revision>1</cp:revision><dcterms:created xsi:type="dcterms:W3CDTF">' +
      curDateTime +
      '</dcterms:created><dcterms:modified xsi:type="dcterms:W3CDTF">' +
      curDateTime +
      '</dcterms:modified></cp:coreProperties>'
    )
  }

  /**
   * Remove selected records from the given array.
   *
   * This method destroys records inside the given array of the given type.
   *
   * @param {object} arr The array to work on it.
   * @param {object} type_to_clear The type of records to clear.
   */
  function clearSmartArrayFromType(arr, type_to_clear) {
    var is_need_compact = false

    for (var i = 0, total_size = arr.length; i < total_size; i++) {
      if (typeof arr[i] !== 'undefined') {
        if (arr[i].clear && arr[i].clear === type_to_clear) {
          delete arr[i]
          is_need_compact = true
        } // Endif.
      } // Endif.
    } // End of for loop.

    if (is_need_compact) {
      compactArray(arr)
    } // Endif.
  }

  /**
   * Clean after finishing to generate the document.
   *
   * This method destroying any additional resources added by the 'beforeGen' effect to the generator.
   *
   * @param {object} err Generation error message (if there were any).
   * @param {object} written Number of bytes been created.
   */
  function cbOfficeClearAfterGenerate(err, written) {
    if (err) {
      // BMK_TODO:
    } // Endif.

    clearSmartArrayFromType(gen_private.type.msoffice.rels_main, 'generate')
    clearSmartArrayFromType(gen_private.type.msoffice.rels_app, 'generate')
    clearSmartArrayFromType(gen_private.type.msoffice.files_list, 'generate')

    if (genobj.generate_data) {
      genobj.generate_data = null
      delete genobj.generate_data
    } // Endif.
  }

  /**
   * Clear all the information of the current document.
   */
  function cbOfficeClearDocData() {
    clearSmartArrayFromType(gen_private.type.msoffice.rels_main, 'data')
    clearSmartArrayFromType(gen_private.type.msoffice.rels_app, 'data')
    clearSmartArrayFromType(gen_private.type.msoffice.files_list, 'data')

    for (var infoItem in genobj.info) {
      genobj.info[infoItem].data = genobj.info[infoItem].def_data
    } // Endif.

    gen_private.type.msoffice.src_files_list = []

    // Ask the document implementation to clear it's data:
    genobj.emit('clearDocType', gen_private)
  }

  // Basic API for plugins:

  gen_private.plugs.type.msoffice = {}

  /**
   * Configure a new Office property type.
   *
   * This method register a new type of property that the user can configure. This property must be
   * a valid MS-Office property as you can configure on the "files/properties" menu option on MS-Office.
   *
   * @param {object} element_name The name of the XML element of this type.
   * @param {object} def_data Default value of this type.
   * @param {object} prop_name The name of the options property to configure this type.
   * @param {object} user_access_func_name The name of the function to create to configure this type.
   */
  gen_private.plugs.type.msoffice.addInfoType = function (
    element_name,
    def_data,
    prop_name,
    user_access_func_name
  ) {
    genobj.info[element_name] = {}
    genobj.info[element_name].element = element_name
    genobj.info[element_name].data = def_data
    genobj.info[element_name].def_data = def_data

    // The user of officegen can configure this property using the options object:
    if (genobj.options[prop_name]) {
      genobj.info[element_name].data = genobj.options[prop_name]
    } // Endif.

    genobj[user_access_func_name] = function (new_data) {
      genobj.info[element_name].data = new_data
    }
  }

  /**
   * Get the string that opening every Office XML type.
   *
   * Every Microsoft Office XML resource will have this header at the begining of the file.
   *
   * @param {object} data Ignored by this callback function.
   * @return Text string.
   */
  gen_private.plugs.type.msoffice.cbMakeMsOfficeBasicXml = function (data) {
    return '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n'
  }

  /* eslint-disable-next-line no-control-regex */
  var reInvalidChars = /((?:[\0-\x08\x0B\f\x0E-\x1F\uFFFD\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]))/g

  /**
   * Escape HTML entities and removes invalid XML characters
   *
   * Based on https://www.ryadel.com/en/javascript-remove-xml-invalid-chars-characters-string-utf8-unicode-regex/
   *
   * @param {string} text The text to escape
   * @return The escaped string
   */
  gen_private.plugs.type.msoffice.escapeText = function (text) {
    return text
      .replace(/&/g, '&amp;')
      .replace(/</g, '&lt;')
      .replace(/>/g, '&gt;')
      .replace(/"/g, '&quot;')
      .replace(reInvalidChars, '')
  }

  /**
   * Generate rel based XML file.
   *
   * @param {object} data Array filled with all the rels links.
   * @return Text string.
   */
  gen_private.plugs.type.msoffice.cbMakeRels = function (data) {
    var outString = gen_private.plugs.type.msoffice.cbMakeMsOfficeBasicXml(data)
    outString +=
      '<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">'

    // Add all the rels records inside the data array:
    var realRel = 1
    for (var i = 0, total_size = data.length; i < total_size; i++) {
      if (typeof data[i] !== 'undefined') {
        outString +=
          '<Relationship Id="rId' +
          realRel +
          '" Type="' +
          data[i].type +
          '" Target="' +
          data[i].target +
          '"'

        if (data[i].targetMode) {
          outString += ' TargetMode="' + data[i].targetMode + '"'
        } // Endif.

        outString += '/>'
        realRel++
      } // Endif.
    } // End of for loop.

    outString += '</Relationships>\n'
    return outString
  }

  /**
   * Prepare the officegen object to MS-Office documents.
   *
   * Every plugin that implementing gemenrating MS-Office document must call this method to initialize
   * the common stuff.
   *
   * @param {object} main_path The name of the main folder holding the common resources of this type.
   * @param {object} main_file The main resource file name of this type.
   * @param {object} ext_opt Optional settings (unused right now).
   */
  gen_private.plugs.type.msoffice.makeOfficeGenerator = function (
    main_path,
    main_file,
    ext_opt
  ) {
    gen_private.features.type.msoffice = {}
    gen_private.features.type.msoffice.main_path = main_path
    gen_private.features.type.msoffice.main_path_file = main_file
    gen_private.type.msoffice = {}
    gen_private.type.msoffice.rels_main = []
    gen_private.type.msoffice.rels_app = []
    gen_private.type.msoffice.files_list = []
    gen_private.type.msoffice.src_files_list = []

    // Holding all the Office properties:
    genobj.info = {}

    genobj.on('afterGen', cbOfficeClearAfterGenerate)
    genobj.on('clearDoc', cbOfficeClearDocData)

    gen_private.type.msoffice.rels_main.push(
      {
        target: 'docProps/app.xml',
        type:
          'http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties',
        clear: 'type'
      },
      {
        target: 'docProps/core.xml',
        type:
          'http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties',
        clear: 'type'
      },
      {
        target:
          gen_private.features.type.msoffice.main_path +
          '/' +
          gen_private.features.type.msoffice.main_path_file +
          '.xml',
        type:
          'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument',
        clear: 'type'
      }
    )

    gen_private.type.msoffice.files_list.push(
      {
        ext: 'rels',
        type: 'application/vnd.openxmlformats-package.relationships+xml',
        clear: 'type'
      },
      {
        ext: 'xml',
        type: 'application/xml',
        clear: 'type'
      },
      {
        ext: 'jpeg',
        type: 'image/jpeg',
        clear: 'type'
      },
      {
        ext: 'png',
        type: 'image/png',
        clear: 'type'
      },
      {
        ext: 'gif',
        type: 'image/gif',
        clear: 'type'
      },
      {
        name: '/docProps/app.xml',
        type:
          'application/vnd.openxmlformats-officedocument.extended-properties+xml',
        clear: 'type'
      },
      {
        name:
          '/' +
          gen_private.features.type.msoffice.main_path +
          '/theme/theme1.xml',
        type: 'application/vnd.openxmlformats-officedocument.theme+xml',
        clear: 'type'
      },
      {
        name: '/docProps/core.xml',
        type: 'application/vnd.openxmlformats-package.core-properties+xml',
        clear: 'type'
      }
    )

    genobj.theme = genobj.options.themeXml || null

    genobj.setTheme = function (xmlData) {
      genobj.theme = xmlData
      // BMK_TODO: BMK_TODO: In the future I'll add a parser to the .thmx files.
    }

    gen_private.plugs.intAddAnyResourceToParse(
      '_rels\\.rels',
      'buffer',
      gen_private.type.msoffice.rels_main,
      gen_private.plugs.type.msoffice.cbMakeRels,
      true
    )
    gen_private.plugs.intAddAnyResourceToParse(
      '[Content_Types].xml',
      'buffer',
      null,
      cbMakeMainFilesList,
      true
    )
    gen_private.plugs.intAddAnyResourceToParse(
      'docProps\\core.xml',
      'buffer',
      null,
      cbMakeCore,
      true
    )

    gen_private.plugs.intAddAnyResourceToParse(
      gen_private.features.type.msoffice.main_path + '\\theme\\theme1.xml',
      'buffer',
      null,
      cbMakeTheme,
      true
    )
  }

  /**
   * Generate random unique ID.
   *
   * This method generates a random unique ID.
   *
   * @param {object} baseGroup Optional first part of the ID.
   * @return Unique ID string.
   */
  gen_private.plugs.type.msoffice.makeUniqueID = function (baseGroup) {
    var charTable = [
      '0',
      '1',
      '2',
      '3',
      '4',
      '5',
      '6',
      '7',
      '8',
      '9',
      'A',
      'B',
      'C',
      'D',
      'E',
      'F',
      'G',
      'H',
      'I',
      'J',
      'K',
      'L',
      'M',
      'N',
      'O',
      'P',
      'Q',
      'R',
      'S',
      'T',
      'U',
      'V',
      'W',
      'X',
      'Y',
      'Z'
    ]

    function makeRandomChar() {
      return charTable[Math.floor(Math.random() * charTable.length)]
    }

    var outStr =
      baseGroup ||
      makeRandomChar() +
        makeRandomChar() +
        makeRandomChar() +
        makeRandomChar() +
        makeRandomChar() +
        makeRandomChar() +
        makeRandomChar() +
        makeRandomChar()

    outStr +=
      '-' +
      makeRandomChar() +
      makeRandomChar() +
      makeRandomChar() +
      makeRandomChar()
    outStr +=
      '-' +
      makeRandomChar() +
      makeRandomChar() +
      makeRandomChar() +
      makeRandomChar()
    outStr +=
      '-' +
      makeRandomChar() +
      makeRandomChar() +
      makeRandomChar() +
      makeRandomChar()
    outStr +=
      '-' +
      makeRandomChar() +
      makeRandomChar() +
      makeRandomChar() +
      makeRandomChar()
    outStr +=
      makeRandomChar() + makeRandomChar() + makeRandomChar() + makeRandomChar()
    outStr +=
      makeRandomChar() + makeRandomChar() + makeRandomChar() + makeRandomChar()
    return outStr
  }

  return this
}
This method extending the given officegen object with the common code needed by any MS-Office based document.
Use this module for every type of MS-Office document.

@example <caption>Using this module for implementing a new MS-Office based document type:</caption>
var baseobj = require ( "officegen" )
var msdoc = require ( "./lib/msofficegen.js" )

function makeMyDoc ( officegenObj, typeCodeName, options, officegenObjPlugins, typeInfo ) {
  msdoc.makemsdoc ( officegenObj, typeCodeName, options, officegenObjPlugins, typeInfo )
  officegenObjPlugins.plugs.type.msoffice.makeOfficeGenerator ( 'word', 'document', {} )

  officegenObj.on ( 'clearData', function () {
  })
}
@param {object} genobj The object to extend.
@param {object} new_type The type of object to create.
@param {object} options The object's options.
@param {object} gen_private Access to the internals of this object.
@param {object} type_info Additional information about this type.
@summary Extend officegen object with MS-Office support.
@constructor
@name makemsdoc