@Override
  public void writeScores(RecordSet rs, ScoreFunction sf) {

    Variable[] variables = rs.getVariableArray();

    if (variables.length > 31)
      throw new UnsupportedOperationException(
          "Current implementation does not support more than 31 variables.");

    final long[] bitmasks = new long[variables.length];
    final long all = (1L << bitmasks.length) - 1;
    for (int i = 0; i < bitmasks.length; i++) bitmasks[i] = 1L << i;
    final int nscores = (int) (all + 1) / 2;

    LOG.debug("All-parent bitmask: " + Long.toBinaryString(all));

    // Initialize the output stream
    try {
      try (DataOutputStream stream =
          new DataOutputStream(new BufferedOutputStream(new FileOutputStream(outFile)))) {

        LOG.debug("Output file opened.");

        // Write the header
        writeHeader(stream, variables.length - 1, rs.size(), variables.length);

        LOG.debug("Header written.");

        // Iterate over all variables
        for (int i = 0; i < variables.length; i++) {

          LOG.info(
              "Writing scores for variable \""
                  + variables[i].getName()
                  + "\" ("
                  + i
                  + " out of "
                  + variables.length
                  + ").");
          LOG.debug("Variable bitmask: " + Long.toBinaryString(bitmasks[i]));

          // Write header for variable
          writeVariable(stream, variables[i], nscores);

          LOG.debug("Variable header weritten. Writing " + nscores + " scores...");

          // Iterate over all subsets
          for (long bits = all; bits >= 0; bits--)
            // If set doesn't contain current variable (i)
            if ((bits & bitmasks[i]) == 0) {

              // Make set
              Set<Variable> set = new HashSet<>();
              for (int j = 0; j < variables.length; j++)
                // If set contains variable j
                if ((bits & bitmasks[j]) != 0) set.add(variables[j]);

              // Compute score
              LOG.trace("Computing score...");
              double score = sf.score(variables[i], set, rs);

              // Write score
              writeScore(stream, bits, score);
            }

          LOG.debug("Scores written.");
        }
      }
    } catch (FileNotFoundException e) {
      LOG.fatal(e.getMessage());
      LOG.trace(e, e);
    } catch (IOException e) {
      LOG.fatal(e.getMessage());
      LOG.trace(e, e);
    }
  }