function createSnapshotFromFactories (factories) {
  const math = create(factories)

  const allFactoryFunctions = {}
  const allFunctionsConstantsClasses = {}
  const allFunctionsConstants = {}
  const allTransformFunctions = {}
  const allDependencyCollections = {}
  const allClasses = {}
  const allNodeClasses = {}

  Object.keys(factories).forEach(factoryName => {
    const factory = factories[factoryName]
    const name = factory.fn
    const isTransformFunction = factory.meta && factory.meta.isTransformFunction
    const isClass = !isLowerCase(name[0]) && (validateTypeOf(math[name]) === 'function')
    const dependenciesName = factory.fn +
      (isTransformFunction ? 'Transform' : '') +
      'Dependencies'
    const former = factory.meta?.formerly ?? ''

    allFactoryFunctions[factoryName] = 'function'
    allFunctionsConstantsClasses[name] = validateTypeOf(math[name])
    if (former) {
      allFunctionsConstantsClasses[former] = allFunctionsConstantsClasses[name]
    }
    allDependencyCollections[dependenciesName] = 'Object'

    if (isTransformFunction) {
      allTransformFunctions[name] = 'function'
      if (former) allTransformFunctions[former] = 'function'
    }

    if (isClass) {
      if (endsWith(name, 'Node')) {
        allNodeClasses[name] = 'function'
      } else {
        allClasses[name] = 'function'
      }
    } else {
      allFunctionsConstants[name] = validateTypeOf(math[name])
      if (former) allFunctionsConstants[former] = allFunctionsConstants[name]
    }
  })

  let embeddedDocs = {}
  Object.keys(factories).forEach(factoryName => {
    const factory = factories[factoryName]
    const name = factory.fn

    if (isLowerCase(factory.fn[0])) { // ignore class names starting with upper case
      embeddedDocs[name] = 'Object'
    }
  })
  embeddedDocs = exclude(embeddedDocs, [
    'equalScalar',
    'addScalar',
    'subtractScalar',
    'multiplyScalar',
    'print',
    'divideScalar',
    'parse',
    'compile',
    'parser',
    'chain',
    'coulomb',
    'reviver',
    'replacer'
  ])

  const allTypeChecks = {}
  Object.keys(allIsFunctions).forEach(name => {
    if (name.indexOf('is') === 0) {
      allTypeChecks[name] = 'function'
    }
  })

  const allErrorClasses = {
    ArgumentsError: 'function',
    DimensionError: 'function',
    IndexError: 'function'
  }

  const expectedInstanceStructure = {
    ...allFunctionsConstantsClasses,

    on: 'function',
    off: 'function',
    once: 'function',
    emit: 'function',
    import: 'function',
    config: 'function',
    create: 'function',
    factory: 'function',

    ...allTypeChecks,
    ...allErrorClasses,

    expression: {
      transform: {
        ...allTransformFunctions
      },
      mathWithTransform: {
        // note that we don't have classes here,
        // only functions and constants are allowed in the editor
        ...exclude(allFunctionsConstants, [
          'chain'
        ]),
        config: 'function'
      }
    }
  }

  const expectedES6Structure = {
    // functions
    ...exclude(allFunctionsConstantsClasses, [
      'E',
      'false',
      'Infinity',
      'NaN',
      'null',
      'PI',
      'true'
    ]),
    create: 'function',
    config: 'function',
    factory: 'function',
    _true: 'boolean',
    _false: 'boolean',
    _null: 'null',
    _Infinity: 'number',
    _NaN: 'number',

    ...allTypeChecks,
    ...allErrorClasses,
    ...allDependencyCollections,
    ...allFactoryFunctions,

    docs: embeddedDocs
  }

  return {
    expectedInstanceStructure,
    expectedES6Structure
  }
}
Based on an object with factory functions, create the expected
structures for ES6 export and a mathjs instance.
@param {Object} factories
@return {{expectedInstanceStructure: Object, expectedES6Structure: Object}}