docs: def invokeSMCLI(rh, api, parms, hideInLog=[]):
      """
      Invoke SMCLI and parse the results.
  
      Input:
         Request Handle
         API name,
         SMCLI parms as an array
         (Optional) List of parms (by index) to hide in
            sysLog by replacing the parm with "<hidden>".
  
      Output:
         Dictionary containing the following:
            overallRC - overall return code, 0: success, non-zero: failure
            rc        - RC returned from SMCLI if overallRC = 0.
            rs        - RS returned from SMCLI if overallRC = 0.
            errno     - Errno returned from SMCLI if overallRC = 0.
            response  - String output of the SMCLI command.
  
      Note:
         - If the first three words of the header returned from smcli
           do not do not contain words that represent valid integer
           values or contain too few words then one or more error
           messages are generated. THIS SHOULD NEVER OCCUR !!!!
      """
      if len(hideInLog) == 0:
          rh.printSysLog("Enter vmUtils.invokeSMCLI, userid: " +
                         rh.userid + ", function: " + api +
                         ", parms: " + str(parms))
      else:
          logParms = parms
          for i in hideInLog:
              logParms[i] = '<hidden>'
          rh.printSysLog("Enter vmUtils.invokeSMCLI, userid: " +
                 rh.userid + ", function: " + api +
                 ", parms: " + str(logParms))
      goodHeader = False
  
      results = {
                'overallRC': 0,
                'rc': 0,
                'rs': 0,
                'errno': 0,
                'response': [],
                'strError': '',
               }
  
      cmd = []
      cmd.append('sudo')
      cmd.append('/opt/zthin/bin/smcli')
      cmd.append(api)
      cmd.append('--addRCheader')
  
      try:
          smcliResp = subprocess.check_output(cmd + parms,
              close_fds=True)
          if isinstance(smcliResp, bytes):
              smcliResp = bytes.decode(smcliResp, errors='replace')
  
          smcliResp = smcliResp.split('\n', 1)
          results['response'] = smcliResp[1]
          results['overallRC'] = 0
          results['rc'] = 0
  
      except CalledProcessError as e:
          strCmd = " ".join(cmd + parms)
  
          # Break up the RC header into its component parts.
          if e.output == '':
              smcliResp = ['']
          else:
              smcliResp = bytes.decode(e.output).split('\n', 1)
  
          # Split the header into its component pieces.
          rcHeader = smcliResp[0].split('(details)', 1)
          if len(rcHeader) == 0:
              rcHeader = ['', '']
          elif len(rcHeader) == 1:
              # No data after the details tag.  Add empty [1] value.
              rcHeader.append('')
          codes = rcHeader[0].split(' ')
  
          # Validate the rc, rs, and errno.
          if len(codes) < 3:
              # Unexpected number of codes.  Need at least 3.
              results = msgs.msg['0301'][0]
              results['response'] = msgs.msg['0301'][1] % (modId, api,
                  strCmd, rcHeader[0], rcHeader[1])
          else:
              goodHeader = True
              # Convert the first word (overall rc from SMAPI) to an int
              # and set the SMT overall rc based on this value.
              orcError = False
              try:
                  results['overallRC'] = int(codes[0])
                  if results['overallRC'] not in [8, 24, 25]:
                      orcError = True
              except ValueError:
                  goodHeader = False
                  orcError = True
              if orcError:
                  results['overallRC'] = 25    # SMCLI Internal Error
                  results = msgs.msg['0302'][0]
                  results['response'] = msgs.msg['0302'][1] % (modId,
                      api, codes[0], strCmd, rcHeader[0], rcHeader[1])
  
              # Convert the second word to an int and save as rc.
              try:
                  results['rc'] = int(codes[1])
              except ValueError:
                  goodHeader = False
                  results = msgs.msg['0303'][0]
                  results['response'] = msgs.msg['0303'][1] % (modId,
                      api, codes[1], strCmd, rcHeader[0], rcHeader[1])
  
              # Convert the second word to an int and save it as either
              # the rs or errno.
              try:
                  word3 = int(codes[2])
                  if results['overallRC'] == 8:
                      results['rs'] = word3    # Must be an rs
                  elif results['overallRC'] == 25:
                      results['errno'] = word3    # Must be the errno
                  # We ignore word 3 for everyone else and default to 0.
              except ValueError:
                  goodHeader = False
                  results = msgs.msg['0304'][0]
                  results['response'] = msgs.msg['0304'][1] % (modId,
                      api, codes[1], strCmd, rcHeader[0], rcHeader[1])
  
          results['strError'] = rcHeader[1].lstrip()
  
          if goodHeader:
              # Produce a message that provides the error info.
              results['response'] = msgs.msg['0300'][1] % (modId,
                      api, results['overallRC'], results['rc'],
                      results['rs'], results['errno'],
                      strCmd, smcliResp[1])
  
      except Exception as e:
          # All other exceptions.
          strCmd = " ".join(cmd + parms)
          results = msgs.msg['0305'][0]
          results['response'] = msgs.msg['0305'][1] % (modId, strCmd,
              type(e).__name__, str(e))
  
      rh.printSysLog("Exit vmUtils.invokeSMCLI, rc: " +
          str(results['overallRC']))
      return results