convertToGroup = elem => {
  const selectedElements = svgCanvas.getSelectedElements()
  if (!elem) {
    elem = selectedElements[0]
  }
  const $elem = elem
  const batchCmd = new BatchCommand()
  let ts
  const dataStorage = svgCanvas.getDataStorage()
  if (dataStorage.has($elem, 'gsvg')) {
    // Use the gsvg as the new group
    const svg = elem.firstChild
    const pt = {
      x: Number(svg.getAttribute('x')),
      y: Number(svg.getAttribute('y'))
    }

    // $(elem.firstChild.firstChild).unwrap();
    const firstChild = elem.firstChild.firstChild
    if (firstChild) {
      firstChild.outerHTML = firstChild.innerHTML
    }
    dataStorage.remove(elem, 'gsvg')

    const tlist = getTransformList(elem)
    const xform = svgCanvas.getSvgRoot().createSVGTransform()
    xform.setTranslate(pt.x, pt.y)
    tlist.appendItem(xform)
    recalculateDimensions(elem)
    svgCanvas.call('selected', [elem])
  } else if (dataStorage.has($elem, 'symbol')) {
    elem = dataStorage.get($elem, 'symbol')

    ts = $elem.getAttribute('transform') || ''
    const pos = {
      x: Number($elem.getAttribute('x')),
      y: Number($elem.getAttribute('y'))
    }

    const vb = elem.getAttribute('viewBox')

    if (vb) {
      const nums = vb.split(/[ ,]+/)
      pos.x -= Number(nums[0])
      pos.y -= Number(nums[1])
    }

    // Not ideal, but works
    ts += ' translate(' + (pos.x || 0) + ',' + (pos.y || 0) + ')'

    const prev = $elem.previousElementSibling

    // Remove <use> element
    batchCmd.addSubCommand(
      new RemoveElementCommand(
        $elem,
        $elem.nextElementSibling,
        $elem.parentNode
      )
    )
    $elem.remove()

    // See if other elements reference this symbol
    const svgContent = svgCanvas.getSvgContent()
    // const hasMore = svgContent.querySelectorAll('use:data(symbol)').length;
    // @todo review this logic
    const hasMore = svgContent.querySelectorAll('use').length

    const g = svgCanvas.getDOMDocument().createElementNS(NS.SVG, 'g')
    const childs = elem.childNodes

    let i
    for (i = 0; i < childs.length; i++) {
      g.append(childs[i].cloneNode(true))
    }

    // Duplicate the gradients for Gecko, since they weren't included in the <symbol>
    if (isGecko()) {
      const svgElement = findDefs()
      const gradients = svgElement.querySelectorAll(
        'linearGradient,radialGradient,pattern'
      )
      for (let i = 0, im = gradients.length; im > i; i++) {
        g.appendChild(gradients[i].cloneNode(true))
      }
    }

    if (ts) {
      g.setAttribute('transform', ts)
    }

    const parent = elem.parentNode

    svgCanvas.uniquifyElems(g)

    // Put the dupe gradients back into <defs> (after uniquifying them)
    if (isGecko()) {
      const svgElement = findDefs()
      const elements = g.querySelectorAll(
        'linearGradient,radialGradient,pattern'
      )
      for (let i = 0, im = elements.length; im > i; i++) {
        svgElement.appendChild(elements[i])
      }
    }

    // now give the g itself a new id
    g.id = svgCanvas.getNextId()

    prev.after(g)

    if (parent) {
      if (!hasMore) {
        // remove symbol/svg element
        const { nextSibling } = elem
        elem.remove()
        batchCmd.addSubCommand(
          new RemoveElementCommand(elem, nextSibling, parent)
        )
      }
      batchCmd.addSubCommand(new InsertElementCommand(g))
    }

    svgCanvas.setUseData(g)

    if (isGecko()) {
      svgCanvas.convertGradients(findDefs())
    } else {
      svgCanvas.convertGradients(g)
    }

    // recalculate dimensions on the top-level children so that unnecessary transforms
    // are removed
    walkTreePost(g, n => {
      try {
        recalculateDimensions(n)
      } catch (e) {
        console.error(e)
      }
    })

    // Give ID for any visible element missing one
    const visElems = g.querySelectorAll(svgCanvas.getVisElems())
    Array.prototype.forEach.call(visElems, el => {
      if (!el.id) {
        el.id = svgCanvas.getNextId()
      }
    })

    svgCanvas.selectOnly([g])

    const cm = pushGroupProperty(g, true)
    if (cm) {
      batchCmd.addSubCommand(cm)
    }

    svgCanvas.addCommandToHistory(batchCmd)
  } else {
    console.warn('Unexpected element to ungroup:', elem)
  }
}
Converts selected/given `<use>` or child SVG element to a group.
@function module:selected-elem.SvgCanvas#convertToGroup
@param {Element} elem
@fires module:selected-elem.SvgCanvas#event:selected
@returns {void}