docs: public int doCommand(Script recScript, Map<String,Object> properties)
      {
          int iErrorCode = DBConstants.NORMAL_RETURN;
          if (recScript.getEditMode() != DBConstants.EDIT_CURRENT)
              return DBConstants.ERROR_RETURN;
          if (properties == null)
          {   // First time, climb the tree and set up the properties.
              properties = new Hashtable<String,Object>();
              Script recTempScript = new Script(this);
              try {
                  int iParentScriptID = (int)recScript.getField(Script.PARENT_FOLDER_ID).getValue();
                  recTempScript.getField(Script.ID).setValue(iParentScriptID);
                  while ((iParentScriptID > 0) && (recTempScript.seek(null) == true))
                  {
                      if (!recTempScript.getField(Script.PROPERTIES).isNull())
                      {   // Execute this script
                          Map<String,Object> propRecord = ((PropertiesField)recTempScript.getField(Script.PROPERTIES)).getProperties();
                          propRecord.putAll(properties);  // These properties override parent properties
                          properties = propRecord;
                      }
                      iParentScriptID = (int)recTempScript.getField(Script.PARENT_FOLDER_ID).getValue();
                      recTempScript.addNew();
                      recTempScript.getField(Script.ID).setValue(iParentScriptID);
                  }
              } catch (DBException ex) {
                  ex.printStackTrace();
              } finally {
                  recTempScript.free();
                  recTempScript = null;
              }
          }
          if (!recScript.getField(Script.PROPERTIES).isNull())
          {   // Execute this script
              Map<String,Object> propRecord = ((PropertiesField)recScript.getField(Script.PROPERTIES)).getProperties();
              properties = new Hashtable<String,Object>(properties);    // Create a copy, so you don't mess up the original
              properties.putAll(propRecord);
          }
          
          String strCommand = recScript.getField(Script.COMMAND).toString();
          if (Script.RUN.equalsIgnoreCase(strCommand))
              iErrorCode = this.doRunCommand(recScript, properties);
          else if (Script.RUN_REMOTE.equalsIgnoreCase(strCommand))
          {
              BaseMessage message = new MapMessage(new TrxMessageHeader(MessageConstants.TRX_SEND_QUEUE, MessageConstants.INTRANET_QUEUE, properties), properties);
              ((Application)this.getTask().getApplication()).getMessageManager().sendMessage(message);
          }
          else if (Script.SEEK.equalsIgnoreCase(strCommand))
              iErrorCode = this.doSeekCommand(recScript, properties);
          else if (Script.COPY_RECORDS.equalsIgnoreCase(strCommand))
              iErrorCode = this.doCopyRecordsCommand(recScript, properties);
          else if (Script.COPY_FIELDS.equalsIgnoreCase(strCommand))
              iErrorCode = this.doCopyFieldsCommand(recScript, properties);
          else if (Script.COPY_DATA.equalsIgnoreCase(strCommand))
              iErrorCode = this.doCopyDataCommand(recScript, properties);
          if (iErrorCode != DONT_READ_SUB_SCRIPT)
              if (iErrorCode != DBConstants.NORMAL_RETURN)
                  return iErrorCode;
          
          if (iErrorCode != DONT_READ_SUB_SCRIPT)
              iErrorCode = this.doSubScriptCommands(recScript, properties);
          else
              iErrorCode = DBConstants.NORMAL_RETURN;
          
          return iErrorCode;
      }