# File lib/couchdb_adapter/attachments.rb, line 12
      def self.included(mod)
        mod.class_eval do

          def add_attachment(file, options = {})
            assert_attachments_property

            filename = File.basename(file.path)

            content_type = options[:content_type] || begin
              mime_types = MIME::Types.of(filename)
              mime_types.empty? ? 'application/octet-stream' : mime_types.first.content_type
            end

            name = options[:name] || filename
            data = file.read

            if new_record? || !model.properties.has_property?(:rev)
              self.attachments ||= {}
              self.attachments[name] = {
                'content_type' => content_type,
                'data'         => Base64.encode64(data).chomp,
              }
            else
              adapter = repository.adapter
              http = Net::HTTP.new(adapter.uri.host, adapter.uri.port)
              uri = Addressable::URI.encode_component("#{attachment_path(name)}?rev=#{self.rev}")
              headers = {
                'Content-Length' => data.size.to_s,
                'Content-Type'   => content_type,
              }
              http.put(uri, data, headers)
              self.reload
            end

          end

          def delete_attachment(name)
            assert_attachments_property

            attachment = self.attachments[name] if self.attachments

            unless attachment
              return false
            end

            response = unless new_record?
              adapter = repository.adapter
              http = Net::HTTP.new(adapter.uri.host, adapter.uri.port)
              uri = Addressable::URI.encode_component("#{attachment_path(name)}?rev=#{self.rev}")
              http.delete(uri, 'Content-Type' => attachment['content_type'])
            end

            if response && !response.kind_of?(Net::HTTPSuccess)
              false
            else
              self.attachments.delete(name)
              self.attachments = nil if self.attachments.empty?
              true
            end
          end

          # TODO: cache data on model? (don't want to make resource dirty though...)
          def get_attachment(name)
            assert_attachments_property

            attachment = self.attachments[name] if self.attachments

            unless self.id && attachment
              nil
            else
              adapter = repository.adapter
              http = Net::HTTP.new(adapter.uri.host, adapter.uri.port)
              uri = Addressable::URI.encode_component(attachment_path(name))
              response, data = http.get(uri, 'Content-Type' => attachment['content_type'])

              unless response.kind_of?(Net::HTTPSuccess)
                nil
              else
                data
              end
            end

          end

          private

          def attachment_path(name)
            if new_record?
              nil
            else
              "/#{repository.adapter.escaped_db_name}/#{self.id}/#{name}"
            end
          end

          def assert_attachments_property
            property = model.properties[:attachments]

            unless property &&
              property.type == DataMapper::Types::JsonObject &&
              property.field == '_attachments'
              raise ArgumentError, "Attachments require   property :attachments, JsonObject, :field => '_attachments'"
            end
          end

        end

      end