code: func (p *Pool) NewCollectionWithOptions(model Model, options CollectionOptions) (*Collection, error) {
  	typ := reflect.TypeOf(model)
  	// If options.Name is empty use the name of the concrete model type (without
  	// the package prefix).
  	if options.Name == "" {
  		options.Name = getDefaultModelSpecName(typ)
  	} else if strings.Contains(options.Name, ":") {
  		return nil, fmt.Errorf("zoom: CollectionOptions.Name cannot contain a colon. Got: %s", options.Name)
  	}
  
  	// Make sure the name and type have not been previously registered
  	switch {
  	case p.typeIsRegistered(typ):
  		return nil, fmt.Errorf("zoom: Error in NewCollection: The type %T has already been registered", model)
  	case p.nameIsRegistered(options.Name):
  		return nil, fmt.Errorf("zoom: Error in NewCollection: The name %s has already been registered", options.Name)
  	case !typeIsPointerToStruct(typ):
  		return nil, fmt.Errorf("zoom: NewCollection requires a pointer to a struct as an argument. Got type %T", model)
  	}
  
  	// Compile the spec for this model and store it in the maps
  	spec, err := compileModelSpec(typ)
  	if err != nil {
  		return nil, err
  	}
  	spec.name = options.Name
  	spec.fallback = options.FallbackMarshalerUnmarshaler
  	p.modelTypeToSpec[typ] = spec
  	p.modelNameToSpec[options.Name] = spec
  
  	collection := &Collection{
  		spec:  spec,
  		pool:  p,
  		index: options.Index,
  	}
  	addCollection(collection)
  	return collection, nil
  }
docs: // NewCollectionWithOptions registers and returns a new collection of the given
  // model type and with the provided options.