docs: function extend(to_extend, new_defaults = {}) {
  
      let new_default_props = Object.getOwnPropertyNames(new_defaults);
      let old_props = to_extend.getImmutablePropertyNames();
      let new_props = new_default_props.filter(e => old_props.indexOf(e) < 0);
      //let overriden_props = new_default_props.filter(e => old_props.indexOf(e) >= 0);
      let props = old_props.concat(new_props);
  
      debug('merged props', props);
      
      /** Immutable class created from new_defaults and the extended class
       *
       */
      let immutableClass = class extends to_extend {
  
          /** Constructor.
           *
           * Can take a single object argument, in which case the properties of the object are copied over into
           * any matching default propertis that were defined in 'create'. Can also take normal arguments, in which
           * case the arguments are matched to the default properties in the base class, and then to additional 
           * properties defined in the new_defaults object .
           */
          constructor() {
  
              // Handle case where we have one argument that's an object: assume it's properties to pass in
              let values = processArguments(props, arguments, new_defaults);
  
              // Handle values for base class
              super(values);
              // assign values to properties in order
              for (let prop of new_props) {
                  let value = values[prop];
                  debug('value', value);
                  Object.defineProperty(this, prop, { value, enumerable: true, writable: false });
              }           
          }
  
          /** Get the immutable property names
           *
           * An immutable object may legitimately have transient proprerties that are not part of the public
           * interface of the object. We therefore create a getImmutablePropertyNames static method that gets
           * the list of immutable properties names that is defined for this class.
           */
          static getImmutablePropertyNames() { return props; }
  
  
          /** Extends an immutable object, making a new immutable object.
           *
           * @param new_defaults additional properties for the extended object, plus default values for them.
           */
          static extend(new_defaults) { return extend(immutableClass, new_defaults)}
      };
  
      for (let prop of new_props) {
          let setterName = 'set' + prop.slice(0,1).toUpperCase() + prop.slice(1);
          immutableClass.prototype[setterName] = function(val) {
              debug(setterName, prop, val);
              return this.merge({ [prop] : val });
          };
      }
  
      return immutableClass;  
  }