public function write()
 {
     global $createNewRec, $result;
     $occ = new OmOccurrences();
     $det = new OmOccurDeterminations();
     $collid = $occ->lookupCollId(null, $this->collectioncode);
     // Record exists if there is a matching DarwinCore triplet.
     $exists = $occ->loadByDWCTriplet($occ->lookupInstitutionCode($collid), $this->collectioncode, $this->unitid);
     if (!$exists) {
         // Image upload process in TcnImageTools creates omoccurrences records where
         // collectioncode is not populated, but collid is. Need to handle both cases.
         $exists = $occ->loadByCollidCatalog($collid, $this->unitid);
         // TODO: Question for Ed: Find out if institutioncode and collectioncode should be populated if we
         // end up here.
     }
     if (!$exists) {
         // create new record
         $occ = new OmOccurrences();
         $occ->setcollid($collid);
         $occ->setcollectionCode($this->collectioncode);
         $occ->setinstitutionCode($occ->lookupInstitutionCode($collid));
         $occ->setcatalogNumber($this->unitid);
         $occ->setbasisOfRecord("PreservedSpecimen");
         $occ->setprocessingStatus("unprocessed");
         if (strpos($this->getTypeStatusList(), "Photograph") !== false || strpos($this->getTypeStatusList(), "Drawing") !== false) {
             // Handle case of Iconotypes.
             // Note: GPI/LAPI schema doesn't have a standard means of identifying non-type drawings.
             $occ->setbasisOfRecord("StillImage");
         }
     }
     // Schema documentation suggests, but does not enforce, semicolon as separator for list of collectors.
     if (strpos(";", $this->collectors) > 0) {
         // split on first semicolon.
         $occ->setrecordedBy(substr($this->collectors, 0, strpos(";", $this->collectors)));
         $occ->setassociatedCollectors(substr($this->collectors, strpos(";", $this->collectors), strlen($this->collectors)));
     } else {
         $occ->setrecordedBy($this->collectors);
         $occ->setassociatedCollectors("");
     }
     if ($this->collectornumber != null) {
         $occ->setrecordNumber($this->collectornumber);
     }
     $occ->settypeStatus($this->getTypeStatusList());
     if ($this->countryname != null) {
         $occ->setcountry($this->countryname);
     }
     if (substr($this->locality, 0, 1) == "{") {
         // Depreciated, but there may be FH documents in the wild that put this into
         // Locality rather than Notes.
         $locbits = json_decode($this->locality);
         $occ->setstateProvince($locbits->{'stateProvince'});
         $occ->setcounty($locbits->{'county'});
         $occ->setlocality($locbits->{'locality'});
     } else {
         if ($this->locality != null) {
             $occ->setlocality($this->locality);
         }
     }
     if ($this->collectiondate != NULL) {
         $occ->seteventDate($this->collectiondate->writeStart());
         $occ->setyear($this->collectiondate->startyear);
         $occ->setmonth($this->collectiondate->startday);
         $occ->setday($this->collectiondate->startday);
         $occ->setverbatimEventDate($this->collectiondate->writeAll());
     } else {
         $occ->setverbatimEventDate("[No Data]");
     }
     $filedUnder = $this->getFiledUnderID();
     if ($filedUnder != null) {
         $occ->setsciname($filedUnder->getSciName());
         // Set locality security based on TID of accepted name of filed under name
         $sectid = $det->lookupAcceptedTID($filedUnder->getSciName());
         if ($sectid == null) {
             $sectid = $det->lookupTID($filedUnder->getSciName());
         }
         if ($sectid == null) {
             $occ->setlocalitySecurity(0);
         } else {
             $occ->setlocalitySecurity($det->checkSecurityStatus($sectid));
         }
         if ($det->lookupAcceptedTID($filedUnder->getSciName()) > 0) {
             $occ->settidinterpreted($det->lookupAcceptedTID($filedUnder->getSciName()));
         }
         if ($filedUnder->family != "NoData") {
             $occ->setfamily($filedUnder->family);
         }
         if (strlen($occ->getfamily()) == 0) {
             $occ->setfamily($det->lookupFamilyForTID($det->lookupTID($filedUnder->getSciName())));
         }
         $occ->setgenus($filedUnder->genus);
         $occ->setspecificEpithet($filedUnder->species);
         $occ->setinfraSpecificEpithet($filedUnder->infraspecificepithet);
         $occ->setscientificNameAuthorship($filedUnder->author);
         // work out value for taxon rank.
         $occ->settaxonRank($filedUnder->infraspecificrank);
         if (strlen($filedUnder->infraspecificepithet) > 0 && strlen($filedUnder->infraspecificrank) == 0) {
             $occ->settaxonRank("subspecies");
         }
         if (strlen($filedUnder->infraspecificepithet) == 0 && strlen($filedUnder->species) > 0) {
             $occ->settaxonRank("species");
         }
         if (strlen($filedUnder->infraspecificepithet) == 0 && strlen($filedUnder->species) == 0 && strlen($filedUnder->genus) > 0) {
             $occ->settaxonRank("genus");
         }
         if ($filedUnder->identificationdate != NULL) {
             $occ->setdateIdentified($filedUnder->identificationdate->writeAll());
         }
     }
     if (preg_match("/^[0-9.]+\$/", $this->altitude)) {
         $occ->setminimumElevationInMeters($this->altitude);
     } else {
         if ($this->altitude != null) {
             $occ->setverbatimElevation($this->altitude);
         }
     }
     if (substr($this->notes, 0, 1) == "{") {
         $bits = json_decode($this->notes);
         // Extended higher geography information
         if (array_key_exists('stateProvince', $bits)) {
             $occ->setstateProvince($bits->{'stateProvince'});
         }
         if (array_key_exists('county', $bits)) {
             $occ->setcounty($bits->{'county'});
         }
         if (array_key_exists('municipality', $bits)) {
             $occ->setmunicipality($bits->{'municipality'});
         }
         // Exsicatti
         $extitle = "";
         $exvolume = "";
         $exfasicle = "";
         $exnumber = "";
         $exauthor = "";
         if (array_key_exists('extitle', $bits)) {
             $extitle = $bits->{'extitle'};
         }
         if (array_key_exists('exvolume', $bits)) {
             $exvolume = $bits->{'exvolume'};
         }
         if (array_key_exists('fasicle', $bits)) {
             $exfasicle = $bits->{'fasicle'};
         }
         if (array_key_exists('exnumber', $bits)) {
             $exnumber = $bits->{'exnumber'};
         }
         if (array_key_exists('exauthor', $bits)) {
             $exauthor = $bits->{'exauthor'};
         }
         // TODO: Take Exsiccati data and link(/create?) records in Symbiota
     } else {
         $occ->setoccurrenceRemarks($this->notes);
     }
     if (!$exists || $createNewRec == 1) {
         // if record exists, then TcnImageConf variable createNewRec specifies policy for update.
         if ($occ->save()) {
             if ($exists) {
                 //echo "Updated occid: [".$occ->getoccid()."]\n";
                 $result->successcount++;
                 $result->updatecount++;
             } else {
                 //echo "Added occid: [".$occ->getoccid()."]\n";
                 $result->successcount++;
                 $result->insertcount++;
             }
             foreach ($this->identifications as $id) {
                 $id->occid = $occ->getoccid();
                 $id->write();
             }
         } else {
             $result->errors .= "Error: [" . $occ->errorMessage() . "]\n";
             $result->failurecount++;
         }
     } else {
         echo "Skipping, record exists and specified policy is to not update. [" . $occ->getoccid() . "]\n";
     }
 }