# File lib/dm-core/property.rb, line 736
    def initialize(model, name, options = {})
      options = options.to_hash.dup

      if INVALID_NAMES.include?(name.to_s) || (kind_of?(Boolean) && INVALID_NAMES.include?("#{name}?"))
        raise ArgumentError,
          "+name+ was #{name.inspect}, which cannot be used as a property name since it collides with an existing method or a query option"
      end

      assert_valid_options(options)

      predefined_options = self.class.options

      @repository_name        = model.repository_name
      @model                  = model
      @name                   = name.to_s.chomp('?').to_sym
      @options                = predefined_options.merge(options).freeze
      @instance_variable_name = "@#{@name}".freeze

      @primitive = self.class.primitive
      @field     = @options[:field].freeze unless @options[:field].nil?
      @default   = @options[:default]

      @serial       = @options.fetch(:serial,       false)
      @key          = @options.fetch(:key,          @serial)
      @unique       = @options.fetch(:unique,       @key ? :key : false)
      @required     = @options.fetch(:required,     @key)
      @allow_nil    = @options.fetch(:allow_nil,    !@required)
      @allow_blank  = @options.fetch(:allow_blank,  !@required)
      @index        = @options.fetch(:index,        false)
      @unique_index = @options.fetch(:unique_index, @unique)
      @lazy         = @options.fetch(:lazy,         false) && !@key

      determine_visibility

      bind
    end