docs: public static ScanResult fromJSON(final String json) {
          final Matcher matcher = Pattern.compile("\\{[\\n\\r ]*\"format\"[ ]?:[ ]?\"([^\"]+)\"").matcher(json);
          if (!matcher.find()) {
              throw new IllegalArgumentException("JSON is not in correct format");
          }
          if (!CURRENT_SERIALIZATION_FORMAT.equals(matcher.group(1))) {
              throw new IllegalArgumentException(
                      "JSON was serialized in a different format from the format used by the current version of "
                              + "ClassGraph -- please serialize and deserialize your ScanResult using "
                              + "the same version of ClassGraph");
          }
  
          // Deserialize the JSON
          final SerializationFormat deserialized = JSONDeserializer.deserializeObject(SerializationFormat.class,
                  json);
          if (!deserialized.format.equals(CURRENT_SERIALIZATION_FORMAT)) {
              // Probably the deserialization failed before now anyway, if fields have changed, etc.
              throw new IllegalArgumentException("JSON was serialized by newer version of ClassGraph");
          }
  
          // Perform a new "scan" with performScan set to false, which resolves all the ClasspathElement objects
          // and scans classpath element paths (needed for classloading), but does not scan the actual classfiles
          final ClassGraph classGraph = new ClassGraph();
          classGraph.scanSpec = deserialized.scanSpec;
          classGraph.scanSpec.performScan = false;
          if (classGraph.scanSpec.overrideClasspath == null) {
              // Use the same classpath as before, if classpath was not overridden
              classGraph.overrideClasspath(deserialized.classpath);
          }
          final ScanResult scanResult = classGraph.scan();
          scanResult.rawClasspathEltOrderStrs = deserialized.classpath;
          scanResult.scanSpec.performScan = true;
  
          // Set the fields related to ClassInfo in the new ScanResult, based on the deserialized JSON 
          scanResult.scanSpec = deserialized.scanSpec;
          scanResult.classNameToClassInfo = new HashMap<>();
          if (deserialized.classInfo != null) {
              for (final ClassInfo ci : deserialized.classInfo) {
                  scanResult.classNameToClassInfo.put(ci.getName(), ci);
                  ci.setScanResult(scanResult);
              }
          }
          scanResult.moduleNameToModuleInfo = new HashMap<>();
          if (deserialized.moduleInfo != null) {
              for (final ModuleInfo mi : deserialized.moduleInfo) {
                  scanResult.moduleNameToModuleInfo.put(mi.getName(), mi);
              }
          }
          scanResult.packageNameToPackageInfo = new HashMap<>();
          if (deserialized.packageInfo != null) {
              for (final PackageInfo pi : deserialized.packageInfo) {
                  scanResult.packageNameToPackageInfo.put(pi.getName(), pi);
              }
          }
  
          // Index Resource and ClassInfo objects 
          scanResult.indexResourcesAndClassInfo();
  
          scanResult.isObtainedFromDeserialization = true;
          return scanResult;
      }