def create_object(obj)
      if CaTissue::Address === obj then
        return create_address(obj)
      elsif CollectibleEventParameters === obj and obj.specimen_collection_group then
        return save_collectible_scg_event_parameters(obj)
      elsif CaTissue::Specimen === obj then
        obj.add_defaults
        # Work around aliquot bug
        if obj.parent and obj.characteristics == obj.parent.characteristics then
          if obj.label.nil? then
            obj.label = obj.barcode = Jinx::UID.generate.to_s
            logger.debug { "Worked around caTissue 1.2 bug by creating #{obj} aliquot label and barcode." }
          end
          obj.barcode = obj.label if obj.barcode.nil?
        end
        # Special case for an unavailable specimen.
        # The obj.is_available == false test is required as opposed to obj.is_available?,
        # since a nil is_available flag does not imply an unavailable specimen.
        if obj.is_available == false or obj.available_quantity.zero? or obj.disposed? then
          return create_unavailable_specimen(obj)
        end
      end
      
      # standard create
      super

      # replicate caTissue create side-effects in the submitted object
      if CaTissue::DisposalEventParameters === obj then
        obj.specimen.activity_status = 'Closed'
        logger.debug { "Set the created DisposalEventParameters #{obj.qp} owner #{obj.specimen.qp} activity status to Closed." }
        unless obj.specimen.consent_tier_statuses.empty? then
          obj.specimen.consent_tier_statuses.clear
          logger.debug { "Cleared the created DisposalEventParameters #{obj.qp} owner #{obj.specimen.qp} consent tier statuses." }
        end
      end
      
      # An annotation snapshot is not updated, since the annotation is not persisted.
      # If the annotation has been changed, then it might be subsequently updated, which
      # is disallowed. Therefore, refresh the snapshot here.
      obj.take_snapshot if Annotation === obj and obj.changed?
      
      obj
    end
def create_object(obj)
      if CaTissue::Address === obj then
        return create_address(obj)
      elsif CollectibleEventParameters === obj and obj.specimen_collection_group then
        return save_collectible_scg_event_parameters(obj)
      elsif CaTissue::Specimen === obj then
        obj.add_defaults
        # Work around aliquot bug
        if obj.parent and obj.characteristics == obj.parent.characteristics then
          if obj.label.nil? then
            obj.label = obj.barcode = Jinx::UID.generate.to_s
            logger.debug { "Worked around caTissue 1.2 bug by creating #{obj} aliquot label and barcode." }
          end
          obj.barcode = obj.label if obj.barcode.nil?
        end
        # Special case for an unavailable specimen.
        # The obj.is_available == false test is required as opposed to obj.is_available?,
        # since a nil is_available flag does not imply an unavailable specimen.
        if obj.is_available == false or obj.available_quantity.zero? or obj.disposed? then
          return create_unavailable_specimen(obj)
        end
      end
      
      # standard create
      super

      # replicate caTissue create side-effects in the submitted object
      if CaTissue::DisposalEventParameters === obj then
        obj.specimen.activity_status = 'Closed'
        logger.debug { "Set the created DisposalEventParameters #{obj.qp} owner #{obj.specimen.qp} activity status to Closed." }
        unless obj.specimen.consent_tier_statuses.empty? then
          obj.specimen.consent_tier_statuses.clear
          logger.debug { "Cleared the created DisposalEventParameters #{obj.qp} owner #{obj.specimen.qp} consent tier statuses." }
        end
      end
      
      # An annotation snapshot is not updated, since the annotation is not persisted.
      # If the annotation has been changed, then it might be subsequently updated, which
      # is disallowed. Therefore, refresh the snapshot here.
      obj.take_snapshot if Annotation === obj and obj.changed?
      
      obj
    end
Augment +CaRuby::Database::Writer.create_object+ to work around caTissue bugs and pass through
 an {Annotation::Proxy} to the referenced annotations.

 @quirk caTissue Bug #124: SCG SpecimenEventParameters save fails validation.
   Work-around is to create the SEP by updating the SCG.

 @quirk caTissue If the save argument domain object is a CaTissue::Specimen with the +is_available+
 flag set to false, then work around the bug described in {#create_unavailable_specimen}.

 @quirk caTissue Bug #161: Specimen API disposal is not reflected in the saved result activity status.
   DisposalEventParameters create sets the owner Specimen activity_status to +Closed+ as a side-effect.
   Reflect this side-effect in the submitted DisposalEventParameters owner Specimen object.

 @quirk caTissue 1.2 An undocumented caTissue "feature" is that Specimen API disposal clears the
   Specimen consent tier statuses as a side-effect. Reflect this side-effect in the submitted
   DisposalEventParameters owner Specimen object.

 @quirk caTissue 1.2 Creating a specimen aliquot without a label or barcode resuts in a server
   uniqueness constraint failure SQL error. Work-around is to generate the aliquot and barcode
   on the fly.

 @quirk caTissue caTissue API create with an Address argument completes without an exception but
   silently ignores the argument and does not create the record. The create call has a result
   that is a copy of the argument, including the missing identifier.
   Unlike the {Database} {#create} method, this private {#create_object} method must allow an Address
   object in order to support the user address update caTissue bug work-around. However, the address
   update bug work-around encounters the Address create missing id caTissue bug. The
   work-around for this caTissue bug work-around bug is to bypass the caTissue API, hit the database
   directly with SQL, find the matching database record, and set the identifier to the matching record
   identifier. The match is complicated by the possibility that a different client might create an
   address after the SQL transaction but before the max id query. The work-around for this potential
   caTissue bug work-around bug work-around bug is to fetch addresses until one matches, then set the
   created address identifier to that fetched record identifier.

 @param [Resource] obj the dependent domain object to save