docs: private File createThreadDump(File outputDir) {
          // Determine if we're using Java Attach (VirtualMachine.remoteDataDump)
          // or the DiagnosticCommand MBean.  Java Attach is only available on
          // JREs (not JDKs) and sometimes fails to connect, but we prefer it when
          // available because DiagnosticCommand returns the entire thread dump as
          // a single String, which risks OutOfMemoryError.
          VirtualMachine vm = null;
          try {
              vm = getAttachedVirtualMachine();
              if (vm == null && diagnosticCommandName == null) {
                  // Neither Java Attach nor DiagnosticCommand are available, so
                  // it's not possible to create a thread dump.
                  return null;
              }
          } catch (VirtualMachineException e) {
              // Sometimes Java Attach fails spuriously.  If DiagnosticCommand is
              // available, try that.  Otherwise, propagate the failure.
              if (diagnosticCommandName == null) {
                  Throwable cause = e.getCause();
                  throw cause instanceof RuntimeException ? (RuntimeException) cause : new RuntimeException(cause);
              }
          }
  
          File outputFile = null;
          InputStream input = null;
          OutputStream output = null;
          boolean success = false;
  
          try {
              // Use a filename that resembles an IBM javacore.
              outputFile = createNewFile(outputDir, "javadump", "txt");
  
              if (vm != null) {
                  input = vm.remoteDataDump();
                  input = new BufferedInputStream(input);
  
                  output = new FileOutputStream(outputFile);
                  output = new BufferedOutputStream(output);
  
                  byte[] buf = new byte[8192];
                  for (int read; (read = input.read(buf)) != -1;) {
                      output.write(buf, 0, read);
                  }
              } else {
                  String outputString;
                  try {
                      outputString = (String) platformMBeanServer.invoke(diagnosticCommandName,
                                                                         "threadPrint",
                                                                         new Object[] { new String[] { "-l" } },
                                                                         new String[] { String[].class.getName() });
                  } catch (Exception e) {
                      throw new RuntimeException(e);
                  }
  
                  output = new FileOutputStream(outputFile);
                  Writer writer = new OutputStreamWriter(output, "UTF-8");
                  writer.write(outputString);
                  writer.close();
              }
  
              success = true;
          } catch (IOException ex) {
              throw new RuntimeException(ex);
          } finally {
              Utils.tryToClose(input);
              Utils.tryToClose(output);
  
              if (!success && outputFile != null && !outputFile.delete()) {
                  // Avoid FindBugs warning.  We .delete() as a best effort.
                  outputFile = null;
              }
          }
  
          return outputFile;
      }