docs: public int handleRecordChange(FieldInfo field, int iChangeType, boolean bDisplayOption)     // init this field override for other value
      {
          if (iChangeType == DBConstants.FIELD_CHANGED_TYPE)
          { // If a field changed, only pass the first time through
              if (this.getEditMode() == Constants.EDIT_NONE)
                  return DBConstants.NORMAL_RETURN; // No status = no action
              if (this.getEditMode() == Constants.EDIT_IN_PROGRESS) // No status = no action
                  return DBConstants.NORMAL_RETURN; // Already locked
              if (this.getEditMode() == Constants.EDIT_ADD) // No status = no action
                  if ((this.getOpenMode() & DBConstants.OPEN_REFRESH_AND_LOCK_ON_CHANGE_STRATEGY) != DBConstants.OPEN_REFRESH_AND_LOCK_ON_CHANGE_STRATEGY)
                      return DBConstants.NORMAL_RETURN; // Don't do this listener on an Add unless OPEN_REFRESH_AND_LOCK_ON_CHANGE.
              // NOTE: fall through if ((this.GetEditMode() == Constants.EDIT_CURRENT)    // No status = no action
          }
          // Do file listeners
          int iErrorCode = DBConstants.NORMAL_RETURN;
          if (m_table != null)
              iErrorCode = this.getTable().doRecordChange(field, iChangeType, bDisplayOption);    // Give the table a shot at it
          if (iErrorCode != DBConstants.NORMAL_RETURN)
              return iErrorCode;
          BaseListener nextListener = this.getNextEnabledListener();
          while (nextListener != null)
          {
              int iOldEditMode = this.getEditMode();
              boolean bOldState = nextListener.setEnabledListener(false);  // Don't allow it to be called again
              iErrorCode = ((FileListener)nextListener).doRecordChange(field, iChangeType, bDisplayOption);
              nextListener.setEnabledListener(bOldState);
              if (iErrorCode != DBConstants.NORMAL_RETURN)
                  break;
              if (iOldEditMode != this.getEditMode())
                  if (this.getEditMode() == DBConstants.EDIT_IN_PROGRESS)
                      if (iOldEditMode != DBConstants.EDIT_IN_PROGRESS)
                          this.handleRecordChange(DBConstants.LOCK_TYPE); // If the record was auto-locked, make sure the listeners know.
              nextListener = nextListener.getNextEnabledListener();
          }
          if (iErrorCode == DBConstants.NORMAL_RETURN)
              iErrorCode = this.doRecordChange(field, iChangeType, bDisplayOption);
          // Messaging
          if ((iChangeType == DBConstants.AFTER_UPDATE_TYPE)
              || (iChangeType == DBConstants.AFTER_ADD_TYPE)
              || (iChangeType == DBConstants.AFTER_DELETE_TYPE))
          { // If the record was updated, notify any other copies of this same record
              try   {
                  Object dsBookmark = this.getHandle(DBConstants.BOOKMARK_HANDLE);
                  if (iChangeType == DBConstants.AFTER_ADD_TYPE)
                      dsBookmark = this.getLastModified(DBConstants.BOOKMARK_HANDLE);
                  if (dsBookmark != null)
                      if (this.getTable() != null)
                          if ((this.getDatabaseType() & DBConstants.UNSHAREABLE_MEMORY) != DBConstants.UNSHAREABLE_MEMORY)    // Don't send any messages for unshared tables
                  {
                      Map<String,Object> mapHints = null;
                      if (iChangeType == DBConstants.AFTER_ADD_TYPE)
                      {   // For new record, need some hints to tell the filter if it needs to add this record.
                          for (int iKeyArea = 1; iKeyArea < this.getKeyAreaCount(); iKeyArea++)
                          {   // Add any keys that have reference fields.
                              KeyArea keyArea = this.getKeyArea(iKeyArea);
                              BaseField fieldOne = keyArea.getField(0);
                              if (fieldOne instanceof ReferenceField)
                              {
                                  String strKey = keyArea.getKeyName();
                                  Object dsData = fieldOne.getData();
                                  if (dsData != null)
                                  {
                                      if (mapHints == null)
                                          mapHints = new Hashtable<String,Object>();
                                      mapHints.put(strKey, dsData);
                                  }
                              }
                          }
                      }
                      BaseMessage message = new RecordMessage(new RecordMessageHeader(this, dsBookmark, this, iChangeType, mapHints));
                      if (this.getRecordOwner() != null)
                          if (this.getRecordOwner().getTask() instanceof LocalTask)
                      {
                          RemoteTask messageTask = ((LocalTask)this.getRecordOwner().getTask()).getRemoteMessageTask();
                          if (this.getSupressRemoteMessages())
                              message.setProcessedByClientSession(messageTask);   // Don't echo back up to my server.
                      }
                      else
                      {
                          if (DBConstants.TRUE.equals(this.getTable().getCurrentTable().getProperty(DBParams.SUPRESSREMOTEDBMESSAGES)))
                              message.setProcessedByServer(true); // Don't send this message down to the server.
                      }
                      if ((DBConstants.REMOTE != (this.getDatabaseType() & DBConstants.TABLE_TYPE_MASK))   // Track remotely for remote files only
                          && (DBConstants.REMOTE_MEMORY != (this.getDatabaseType() & DBConstants.TABLE_TYPE_MASK)))
                              message.setProcessedByServer(true); // Don't send this message down to the server.
                      BaseDatabase database = this.getTable().getCurrentTable().getDatabase();
                      if (DBConstants.FALSE.equals(database.getProperty(DBParams.MESSAGES_TO_REMOTE)))
                          message.setProcessedByServer(true); // Don't send this message down to the server.
                      if (this.getTask() != null)
                          if (this.getTask().getApplication() instanceof Application)	// Always
                          if (((Application)this.getTask().getApplication()).getMessageManager() != null)
                          	((Application)this.getTask().getApplication()).getMessageManager().sendMessage(message);  // Have database notify everyone else
                  }
              } catch (DBException ex)    {
                  ex.printStackTrace();
              }
          }
          return iErrorCode;
      }