/**
   * Collect and return the code coverage reports for all the raw functions.
   *
   * @param resume The continuation to pass the return value to.
   */
  public static void codeCoverageReportsThen(final Continuation1<List<CodeCoverageReport>> resume) {
    AvailRuntime.current()
        .whenLevelOneSafeDo(
            new AvailTask(FiberDescriptor.commandPriority) {
              @Override
              public void value() {
                final List<CodeCoverageReport> reports = new ArrayList<>(activeRawFunctions.size());

                // Loop over each instance, creating its report object.
                for (final A_RawFunction function : activeRawFunctions) {
                  final A_Module module = function.module();
                  if (!module.equalsNil()) {
                    final CodeCoverageReport report =
                        new CodeCoverageReport(
                            getInvocationStatistic((AvailObject) function).hasRun,
                            function.startingChunk() != L2Chunk.unoptimizedChunk(),
                            function.startingLineNumber(),
                            module.moduleName().asNativeString(),
                            function.methodName().asNativeString());
                    if (!reports.contains(report)) {
                      reports.add(report);
                    }
                  }
                }
                AvailRuntime.current()
                    .whenLevelOneUnsafeDo(
                        new AvailTask(FiberDescriptor.commandPriority) {
                          @Override
                          public void value() {
                            resume.value(reports);
                          }
                        });
              }
            });
  }
 /**
  * Reset the code coverage details of all {@link CompiledCodeDescriptor raw functions} by
  * discarding their L2 optimized chunks and clearing their flags. When complete, resume the
  * supplied {@link Continuation0 continuation}.
  *
  * @param resume The {@link Continuation0 continuation to be executed upon completion}.
  */
 @AvailMethod
 public static void ResetCodeCoverageDetailsThen(final Continuation0 resume) {
   AvailRuntime.current()
       .whenLevelOneSafeDo(
           new AvailTask(FiberDescriptor.commandPriority) {
             @Override
             public void value() {
               L2Chunk.invalidationLock.lock();
               try {
                 // Loop over each instance, setting the touched flag to
                 // false and discarding optimizations.
                 for (final A_RawFunction function : activeRawFunctions) {
                   final AvailObject object = (AvailObject) function;
                   getInvocationStatistic(object).hasRun = false;
                   if (!function.module().equalsNil()) {
                     object.startingChunk().invalidate();
                   }
                 }
                 AvailRuntime.current()
                     .whenLevelOneUnsafeDo(
                         new AvailTask(FiberDescriptor.commandPriority) {
                           @Override
                           public void value() {
                             resume.value();
                           }
                         });
               } finally {
                 L2Chunk.invalidationLock.unlock();
               }
             }
           });
 }
 /**
  * (Re)generate the target {@linkplain Properties properties} file.
  *
  * @throws IOException If an exceptional situation arises while reading properties.
  */
 public void generate() throws IOException {
   // Force correct initialization order... sigh.
   AvailRuntime.nextHash();
   final File fileName =
       new File(
           String.format(
               "src/%s_%s.properties", baseName.replace('.', '/'), locale.getLanguage()));
   System.out.println(fileName.getAbsolutePath());
   final String[] components = baseName.split("\\.");
   final File tempFileName =
       new File(
           String.format(
               "%s/%s_%s.propertiesTEMP",
               System.getProperty("java.io.tmpdir"),
               components[components.length - 1],
               locale.getLanguage()));
   assert fileName.getPath().endsWith(".properties");
   final Properties properties = new Properties();
   try (final FileInputStream inputStream = new FileInputStream(fileName)) {
     try (final InputStreamReader reader =
         new InputStreamReader(inputStream, StandardCharsets.UTF_8)) {
       properties.load(reader);
     }
   } catch (final FileNotFoundException e) {
     // Ignore. It's okay if the file doesn't already exist.
   }
   final PrintWriter writer = new PrintWriter(tempFileName, "UTF-8");
   generatePreamble(writer);
   generateProperties(properties, writer);
   writer.close();
   // Now switch the new file in.  In the rare event of failure between
   // these steps, the complete content will still be available in the
   // corresponding *.propertiesTEMP file.
   boolean worked = fileName.delete();
   if (!worked) {
     System.err.println(
         String.format("deleting the original properties file failed: %s", fileName));
   }
   worked = tempFileName.renameTo(fileName);
   if (!worked) {
     throw new RuntimeException(
         String.format(
             "moving the temporary properties file failed: %s -> %s", tempFileName, fileName));
   }
 }