static function &getInstance($data, $simple = true)
 {
     global $gedcom_record_cache, $GEDCOM, $pgv_changes;
     if (is_array($data)) {
         $ged_id = $data['ged_id'];
         $pid = $data['xref'];
     } else {
         $ged_id = get_id_from_gedcom($GEDCOM);
         $pid = $data;
     }
     // Check the cache first
     if (isset($gedcom_record_cache[$pid][$ged_id])) {
         return $gedcom_record_cache[$pid][$ged_id];
     }
     // Look for the record in the database
     if (!is_array($data)) {
         $data = fetch_gedcom_record($pid, $ged_id);
         // If we didn't find the record in the database, it may be remote
         if (!$data && strpos($pid, ':')) {
             list($servid, $remoteid) = explode(':', $pid);
             $service = ServiceClient::getInstance($servid);
             if ($service) {
                 // TYPE will be replaced with the type from the remote record
                 $data = $service->mergeGedcomRecord($remoteid, "0 @{$pid}@ TYPE\n1 RFN {$pid}", false);
             }
         }
         // If we didn't find the record in the database, it may be new/pending
         if (!$data && PGV_USER_CAN_EDIT && isset($pgv_changes[$pid . '_' . $GEDCOM])) {
             $data = find_updated_record($pid);
             $fromfile = true;
         }
         // If we still didn't find it, it doesn't exist
         if (!$data) {
             return null;
         }
     }
     // Create the object
     if (is_array($data)) {
         $type = $data['type'];
     } elseif (preg_match('/^0 @' . PGV_REGEX_XREF . '@ (' . PGV_REGEX_TAG . ')/', $data, $match)) {
         $type = $match[1];
     } else {
         $type = '';
     }
     switch ($type) {
         case 'INDI':
             $object = new Person($data, $simple);
             break;
         case 'FAM':
             $object = new Family($data, $simple);
             break;
         case 'SOUR':
             $object = new Source($data, $simple);
             break;
             //BH ==================
         //BH ==================
         case 'NOTE':
             $object = new Note($data, $simple);
             break;
         case 'REPO':
             $object = new Repository($data, $simple);
             break;
         case 'OBJE':
             $object = new Media($data, $simple);
             break;
         default:
             $object = new GedcomRecord($data, $simple);
             break;
     }
     // This is an object from the database, but we created it from raw gedcom
     // rather than a database row.  Set the gedcom to indicate that it is not
     // a dynamically created record.
     $object->ged_id = $ged_id;
     if (!empty($fromfile)) {
         $object->setChanged(true);
     }
     // Store it in the cache
     $gedcom_record_cache[$object->xref][$object->ged_id] =& $object;
     //-- also store it using its reference id (sid:pid and local gedcom for remote links)
     $gedcom_record_cache[$pid][$ged_id] =& $object;
     return $object;
 }