def method_missing(method, *args, &block)
      if __respond_to_writer?(method)
        __assign!(method.to_s[0..-2].to_sym, args.first)
      elsif __respond_to_method_for_write?(method)
        @data[method]
      elsif __respond_to_method_for_read?(method, *args, &block)
        @data.fetch(method) do
          @not_configured_blocks.evaluate!(@path.add(method), method)
        end
      else
        super
      end
    end
def method_missing(method, *args, &block)
      if __respond_to_writer?(method)
        __assign!(method.to_s[0..-2].to_sym, args.first)
      elsif __respond_to_method_for_write?(method)
        @data[method]
      elsif __respond_to_method_for_read?(method, *args, &block)
        @data.fetch(method) do
          @not_configured_blocks.evaluate!(@path.add(method), method)
        end
      else
        super
      end
    end
Initialize a new configuration
 @param [Hash] options The options to initialize a configuration with
 @option options [Hash] methods a hash of method names pointing to procs
 @option options [Proc] not_configured a proc to evaluate for
   not_configured properties
 @param [Proc] block a block to configure this configuration with
 @yield [HostModule::Configuration] a configuration
 @return [HostModule::Configuration] a configuration
 @note An arbitrary configuration has to control its writeable state,
   therefore configuration is only possible in the initialization block

 Method missing gives access for reading and writing to the underlying
 configuration hash via dot notation