code: function cloneStructure(keys, getter, setter, traversedValues) {
    for (let key of keys) {
      let value = getter(key)
      let keyClone
      
      if (key instanceof Object) {
        if (traversedValues.has(key)) {
          keyClone = traversedValues.get(key)
        } else {
          keyClone = cloneValue(key, traversedValues)
          traversedValues.set(key, keyClone)
        }
      } else {
        keyClone = key
      }
      
      if (value instanceof Object) {
        if (traversedValues.has(value)) {
          setter(keyClone, traversedValues.get(value))
        } else {
          let clonedValue = cloneValue(value, traversedValues)
          traversedValues.set(value, clonedValue)
          setter(keyClone, clonedValue)
        }
      } else {
        setter(keyClone, value)
      }
    }
  }
docs: Clones the structure having the specified property keys, using the provided
  getters and setters. The function clones the keys and values before setting
  them using the setters.
  
  The cloned structure may contain circular references, the function keeps
  track of those using the {@code traversedValues} map.
  
  @param {(*[]|{[Symbol.iterator]: function(): {next: function(): *}})} keys
  The keys or iterator or iterable object generating the keys to
  properties to clone.
  @param {function(*): *} getter A callback that returns the value of the
  source structure for the provided key.
  @param {function(*, *)} setter A callback that sets the provided value (2nd
  argument) to the property identified by the specified key (1st
  argument) in the structure clone.
  @param {Map<Object, Object>} traversedValues A map of traversed
  non-primitive keys and values. The keys are the keys and values
  traversed in the source structure or structures referencing this
  structure, the values are the clones of the keys and values.