<!DOCTYPE HTML>

<html>
<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8">

<style type="text/css">
  <!--
  table { outline:3px solid black; border-spacing:0px; font-family:arial, sans serif}
  thead { text-align:center}
  tbody { text-align:right}
  tfoot { text-align:center}
  tr:hover { background-color:yellow}
  td { border:1px solid black}
  td:first-child { text-align:left; white-space:nowrap}
  tbody td:first-child { font-family: monospace; }
  #options td:not(:first-child) {  text-align:left; font-size: x-small;
                                   font-family: monospace; }
  .columnTitles td:first-child { font-family: monospace; font-size: x-small; }
  tbody tr:first-child td { border-top:3px solid black}
  tfoot tr:first-child td { border-top:3px solid black}
  .status { text-align: center; }
  .correct.safe, .correct.unsafe { color:green}
  .wrong.safe, .wrong.unsafe { color:red; font-weight: bold; }
  .unknown { color:orange; font-weight: bold; }
  .error { color:magenta; font-weight: bold; }
  .score { text-align:center; font-size:large; font-weight:bold; }
  a { color: inherit; text-decoration: none; display: block; }
  a:hover, .clickable:hover { background: lime; cursor: pointer; }

  #contentPaneBackground { height:5000px; width:5000px;
           position:fixed; top:0px; left:0px;
           background-color:green;
           opacity:0.2; display:none }
  #contentPane {
    height:90%; width:90%;
    position:fixed;
    top:5%; left:5%;
    border:solid 10px black; border-radius:15px;
    background-color:white;
    opacity:1;
    display:none;
    overflow:auto;
  }

@media print {
  /* don't print tfoot on each page */
  tfoot { display: table-row-group; }
}

  -->
</style>


<!-- ################## Base JS ################## -->

<script type="text/javascript" src="http://www.sosy-lab.org/lib/jquery-1.7.1.min.js"></script>

<script type="text/javascript">

// All the data from the table head in nice JS data structures.
var tests = [{"name": "with-output-files", "cpuCores": null, "memlimit": "12000 MB", "benchmarkname": "benchmark-cpachecker-bitvector-ppreds-integrated", "tool": "CPAchecker", "ram": "16385312 kB", "cpu": "Intel(R) Core(TM) i7-3770 CPU @ 3.40GHz", "timelimit": "300 s", "host": "molnar", "version": "1.2-svn e5c9ef1+", "branch": "", "date": "13-08-23 20:34", "cores": "4", "freq": "3401 MHz", "os": "Linux 3.2.0-52-generic x86_64", "options": "-heap 9000M -config /home/mikhail/repos/cpachecker/config/predicateAnalysis-PredAbsRefiner-ABEl-UF.properties -spec /home/mikhail/repos/cpachecker/config/specification/sv-comp.spc -setprop output.path=test/results/${benchmark_name}.${benchmark_date}.output/${sourcefile_name}/ -setprop analysis.machineModel=LINUX32 -setprop cpa.predicate.memoryAllocationsAlwaysSucceed=true -setprop output.disable=true -setprop log.level=OFF -setprop cpa.predicate.refinement.dumpInterpolationProblems=false -disable-java-assertions"}, {"name": "with-output-files", "cpuCores": null, "memlimit": "12000 MB", "benchmarkname": "benchmark-cpachecker-bitvector-predicate", "tool": "CPAchecker", "ram": "16385312 kB", "cpu": "Intel(R) Core(TM) i7-3770 CPU @ 3.40GHz", "timelimit": "300 s", "host": "molnar", "version": "1.2-svn e5c9ef1+", "branch": "", "date": "13-08-23 21:24", "cores": "4", "freq": "3401 MHz", "os": "Linux 3.2.0-52-generic x86_64", "options": "-heap 9000M -config /home/mikhail/repos/cpachecker/config/predicateAnalysis-PredAbsRefiner-ABEl-bv.properties -spec /home/mikhail/repos/cpachecker/config/specification/sv-comp.spc -setprop output.path=test/results/${benchmark_name}.${benchmark_date}.output/${sourcefile_name}/ -setprop analysis.machineModel=LINUX32 -setprop cpa.predicate.memoryAllocationsAlwaysSucceed=true -setprop output.disable=true -setprop log.level=OFF -setprop cpa.predicate.refinement.dumpInterpolationProblems=false -setprop analysis.summaryEdges=true -setprop analysis.functionPointerCalls=true -setprop cpa.callstack.skipRecursion=true -setprop cpa.conditions.global.time.wall=-1 -disable-java-assertions"}];   // list with the attributes of all run sets
var columns = [["status", "cputime", "walltime", "memUsage", "total", "reached"], ["status", "cputime", "walltime", "memUsage", "total", "reached"]]; // nested list with all the columns headings
var columnsToTest = [];         // for each column of the table the test it belongs to (first column is 0)

for (var i = 0; i < columns.length; i++) {
  tests[i].columns = columns[i];
}
for (var i = 0; i < tests.length; i++) {
  for (var j = 0; j < tests[i].columns.length; j++) {
    columnsToTest.push(tests[i]);
  }
}

var currentlySelectedCell = null;

// callback that is fired when user clicks on cellsWithUrls (see down below)
function highlightCell(event) {
  var target = event.target;
  if (target.nodeName === 'A') {
    target = target.parentNode;

    // unhighlight currentlySelectedCell
    if (currentlySelectedCell != null) {
      currentlySelectedCell.style.borderColor = 'black';
    }

    // highlight cell that has been just clicked on
    target.style.borderColor = 'red';
    currentlySelectedCell = target;
  }
}

function debug(logInfo) {
  if (!true) {
    console.log(logInfo);
  }
}

function showContentPane() {
  // add function for cleanup, first unbind any old function
  $('#contentPaneBackground').unbind().click(hideContentPane).show();
  $('#contentPane').show().focus();
}

function hideContentPane(event) {
  // hide the content pane on mouse click outside the content pane
  // or when pressing the "Esc" or "c" key with the content pane focused
  if (event.type == "click" || escKeyPressed(event) || cKeyPressed(event)) {
    $('#contentPaneBackground').hide();
    $('#contentPane').hide().empty();
  }
}

function escKeyPressed(event) {
  return event.keyCode == 27;
}

function cKeyPressed(event) {
  // only "c" is pressed, not in combination with Ctrl-key
  return (event.keyCode == 67 && event.ctrlKey == false);
}

function fKeyPressed(event) {
  // only "f" is pressed, not in combination with Ctrl-key
  return (event.keyCode == 70 && event.ctrlKey == false);
}

// input: the index of the column in the table
function getNameOfTest(column) {
  var test = columnsToTest[column-1];
  return getNameOfTestDirect(test);
}

function getNameOfTestDirect(test) {
  return test.tool + ' '
       + (test.date ? test.date + ' ' : '')
       + test.name
       + (test.benchmarkname ? '.' + test.benchmarkname : '');
}

$(document).ready(function() {
  $('body').keydown(hideContentPane);
});

</script>


<!-- ################## Make links load via AJAX and show content in extra panel ################## -->

<style type="text/css">
  #contentPane > pre#content {
    width: 100%;
    height: 100%;
    margin: 0;
  }
</style>

<script type="text/javascript">

function loadContentWrapper(event) {
  var url = $(event.target).attr("href");
  loadContent(url);
  return false;
}

function loadContent(url) {
  var contentPane = $('<pre id="content"></pre>').appendTo("#contentPane")

  $.ajax({
    async: false, // wait for isError
    url: url,
    cache: false,
    dataType: "text",
    beforeSend: function() {
      showContentPane();
      contentPane.html("loading...");
    },
    success: function(text) {
      newtext = text.replace(/&/g, "&")
                    .replace(/"/g, """)
                    .replace(/</g, "<")
                    .replace(/>/g, ">")
                    .replace(/\\n/g, "<br>");
      contentPane.html(newtext);
    },
    error: function() {
      contentPane.html("error while loading content.<br>" +
        "this could be a problem of the 'same-origin-policy' of your browser.<br><br>" +
        "only firefox seems to be able to access files from local directories<br>" +
        "and this works only if the file is in the same directory as this website.<br><br>" +
        "you can try to download the file: <a href=" + url + ">" + url + "</a>");
    },
  });
}

$(document).ready(function() {
  var cellsWithUrls = $('a');
  cellsWithUrls.each(
    function(index, elem) {
      $(elem).click(highlightCell).click(loadContentWrapper);
    });
});
</script>


<!-- ################## Possibility to select displayed columns by clicking on left-most cell in title row ################## -->

<style type="text/css">
  #toggleTable { margin: auto; }
  #toggleTable td { padding-bottom: 5px; padding-top: 5px; }
  #toggleTable tr:hover { background-color: transparent; }
  #toggleTable tbody td:first-child { font-family: arial, sans serif; }
  #toggleTableWrapper { height: 100%; overflow: auto; width: 100%; }
  .hiddenCell { background: red; }
  .visibleCell { background: green; }
  .clickableCell:hover { opacity: 0.5; cursor: pointer; }
</style>

<script type="text/javascript">

// a two-dimensional array of all the cells in the table header,
// but each cell occurs as often in a row as its colspan attribute says
var headerAndFooterArray = null;

function createHeaderAndFooterArray() {
  headerAndFooterArray = [];
  var rows = $('#dataTable > thead > tr, #dataTable > tfoot > tr');
  for (var i=0; i<rows.length; i++) {
    var rowIndices = expandColSpanToNums(rows[i]);
    headerAndFooterArray.push(rowIndices);
  }
}

function expandColSpanToNums(row) {
  var list = [];
  for (var i=0; i<row.cells.length; i++) {
    for (var j=0; j<parseInt(row.cells[i].colSpan); j++) {
      list.push($(row.cells[i]));
    }
  }
  return list;
}

function incColspan(col) {
  var span = parseInt(col.attr("colspan"));
  if (span == 0) { col.show(); }
  col.attr("colspan", span + 1);
}

function decColspan(col) {
  var span = col.attr("colspan");
  span = (span == undefined) ? 1 : parseInt(span);
  col.attr("colspan", span - 1);
  if (span == 1) { col.hide(); }
}

// this function shows or hides a column and enlarges or shrinks the header-columns
// @param index: index of a column in row "columnTitle"
function toggleColumn (shouldBeVisible, index) {
    if (headerAndFooterArray == null) { createHeaderAndFooterArray(); }
    var columnTitles = $('#columnTitles > td');
    // if column is hidden (or visible), we do not hide (or show) it again
    if ($(columnTitles[index]).is(":visible") != shouldBeVisible) {
        for (var i=0; i<headerAndFooterArray.length; i++) {
            var cell = headerAndFooterArray[i][index];
            shouldBeVisible ? incColspan(cell) : decColspan(cell);
        }
        var childIndex = index+1; // first child is number 1
        var children = $("#dataTable > tbody > tr > td:nth-child(" + childIndex + ")");
        shouldBeVisible ? children.show() : children.hide();
    }
}

// "id->cell", "id" is the columnIndex in the dataTable,
// "cell" is the jQuery-object of the cell of the column-toggle-table
var indexToCell = {};

// this function toggles a list of cells and 
// makes the cells equally toggled to the first cell
function toggleCells(indices) {
    var checked = indexToCell[indices[0]].isChecked; 
    for (var i=0; i<indices.length; i++) {
        var cell = indexToCell[indices[i]];
        toggleColumn (!checked, indices[i]);
        cell.removeClass(!checked ? 'hiddenCell' : 'visibleCell')
            .addClass(checked ? 'hiddenCell' : 'visibleCell');
        cell.isChecked = !checked;
    }
}


function createColumnToggleView() {

    // collect all columns
    var tableColumns = [];
    var titlesToColumns = {};
    var columnIndex = 1; // column 1 is the first data-column
    for (var i = 0; i < tests.length; i++) {
        var test = tests[i];
        test.indexToColumn = {} // from test-column-index to table-index
        test.indices = [] // equal to values from test.indexToColumn

        var cols = columns[i];
        for (var j = 0; j < cols.length; j++, columnIndex++) {
            var title = cols[j];
            var index = tableColumns.indexOf(title);
            if (title in titlesToColumns) {
                titlesToColumns[title].push(columnIndex);
            } else { // new title
                // assert(index == -1);
                titlesToColumns[title] = [columnIndex];
                tableColumns.push(title);
                index = tableColumns.length - 1; // index of last position
            }
            test.indexToColumn[index] = columnIndex;
            test.indices.push(columnIndex);
        }
    }

    // create header for table
    var list = []; for (var i=1; i<columnIndex; i++) { list.push(i); }
    var rowHeader = $('<tr>');
    $('<td>') // create top-left cell
        .click( {indices: list},
                function(event) { toggleCells(event.data.indices); } )
        .addClass('clickable')
        .attr('title', 'Click here to toggle all columns')
        .appendTo(rowHeader);
    for (var j = 0; j < tableColumns.length; j++) {
        $('<td>').append(tableColumns[j]) // create column-title-cell
            .click( {indices: titlesToColumns[tableColumns[j]]}, 
                    function(event) { toggleCells(event.data.indices); } )
            .addClass('clickable')
            .attr('title', 'Click here to toggle all columns with this title')
            .appendTo(rowHeader);
    }

    var tableHTML = $('<table>').attr('id', 'toggleTable')
                    .append($('<thead>').append(rowHeader));

    // create body for table
    var tableBody = $('<tbody>').appendTo(tableHTML);
    for (var i = 0; i < tests.length; i++) {
        rowHTML = $('<tr>').appendTo(tableBody);
        var test = tests[i];
        
        // get indices of row and create rowTitle-cell
        var rowTitle = test.tool + ' ' + (test.date ? test.date + ' ' : '') + test.name;
        $('<td>').append(rowTitle)
            .click( {indices: test.indices}, 
                    function(event) { toggleCells(event.data.indices); } )
            .addClass('clickable')
            .attr('title', 'Click here to toggle all columns of this test')
            .appendTo(rowHTML);
    
        // get cells of row
        var cols = columns[i];
        for (var j = 0; j < tableColumns.length; j++) {
            var cell = $('<td>').appendTo(rowHTML);
            var index = test.indexToColumn[j];
            if (index) {
                indexToCell[index] = cell;
                var childIndex = index + 1;
                var checked = $('#columnTitles > td:nth-child(' + childIndex + ')').is(':visible');
                cell.isChecked = checked;
                cell.addClass(checked ? 'visibleCell' : 'hiddenCell')
                    .click( {index: [index]}, 
                            function(event) { toggleCells(event.data.index); } )
                    .addClass('clickableCell');
                    
            }
        }
    }
    $('<div>').attr('id', 'toggleTableWrapper')
              .append(tableHTML)
              .appendTo($("#contentPane"));
    showContentPane();
}

$(document).ready(function() {
  $('.columnTitles > td:first-child')
    .addClass("clickable")
    .attr("title", "Click here to toggle visibility of columns")
    .click(function (event) {
        return createColumnToggleView(); });
});
</script>


<!-- ################## Possibility to select displayed rows by pressing f ################## -->

<style type="text/css">
  button:hover { cursor: pointer; }
  #rowFilterButtons ul { list-style-type:none }
  #rowFilterSelector   { position:absolute; top:20px; right:140px; width:100px; height:300px; }
  #button-filter-reset { position:absolute; top:20px; right:20px; width:100px; height:30px; }
  #button-filter-all   { position:absolute; top:60px; right:20px; width:100px; height:30px; }
  #button-filter-none  { position:absolute; top:100px; right:20px; width:100px; height:30px; }
  #button-filter-start { position:absolute; top:140px; right:20px; width:100px; height:30px; }
</style>

<script type="text/javascript">

function createRowFilterButtons() {
  $("#contentPane").empty();

  var buttonList = $('<form>', {id:'rowFilterButtons', onsubmit:'return false'})
        .appendTo($("#contentPane"));
  var columnIndex = 1; // columns start with 1
  for (var i = 0; i < tests.length; i++) {
    var test = tests[i];
    var sublist = $('<ul>').text(getNameOfTest(columnIndex)).appendTo(buttonList);

    for (var j = 0; j < test.columns.length; j++, columnIndex++) {
      var target = 'check' + columnIndex;
      var button = $('<input>', {
                    type:'radio', name:'filter', id:target, 
                    onclick:('fillRowFilterField(' + columnIndex + ')')});
      var label = $('<label>', {for:target}).text(test.columns[j]).addClass("clickable");
      $('<li>').append(button).append(label).appendTo(sublist);
    }
  }

  $('<button>').text('reset filter').attr('id', 'button-filter-reset')
        .attr('title', 'Click here to restore the complete table')
        .click(function(){ 
                var dataRows = $('#dataTable > tbody')[0].rows;
                for (var i = 0; i < dataRows.length; i++) {
                    $(dataRows[i]).show();
                }
                // delete outdated elements and selections
                removeFilterButtons();
                $('#rowFilterButtons input').each(function(_, elem) {elem.checked=false;})
            })
        .appendTo($("#contentPane"));

  showContentPane();
}

function fillRowFilterField(columnIndex) {

    // determinate options
    var options = [];
    var columnName = $('#columnTitles')[0].cells[columnIndex].textContent;
    if (columnName == 'status') {
        options = options.concat(['correct', 'wrong', 'unknown']);        
    }
    $('#dataTable > tbody > tr').filter(':visible').each(function(_, row) {
        currentValue = row.cells[columnIndex].textContent;
        if (jQuery.inArray(currentValue, options) === -1) {
            options.push(currentValue);
        }
    });

    // sort options, in most cases we have numbers
    options.sort( function(a, b) {
        if (a == null || isNaN(a)) return 1;
        if (b == null || isNaN(b)) return -1;
        return a - b;
    } );

    // delete old elements
    removeFilterButtons();

    // create new selection field with options
    var rowFilter = $('<select>').attr('id', 'rowFilterSelector')
        .attr('multiple', 'multiple').appendTo($('#contentPane'));
    $.each(options, function(_, option) {
        rowFilter.append(new Option(option, option));
    });

    $('<button>').text('select all').attr('id', 'button-filter-all')
        .attr('title', 'Click here to select all values')
        .click(function(){ $('#rowFilterSelector option').attr('selected',true); })
        .appendTo($('#contentPane'));

    $('<button>').text('select none').attr('id', 'button-filter-none')
        .attr('title', 'Click here to deselect all values')
        .click(function(){ $('#rowFilterSelector option').attr('selected',false); })
        .appendTo($('#contentPane'));

    $('<button>').text('apply filter').attr('id', 'button-filter-start')
        .attr('title', 'Click here to filter all matching rows in the table. ' +
                       'If you select multiple values, a row is shown, if any value matches')
        .click(function(){ 
                        hideRows(rowFilter.val() || [], columnIndex); 
                        // clean and hide contentPane
                        $('#contentPaneBackground').hide();
                        $('#contentPane').hide().empty();
                    })
        .appendTo($('#contentPane'));
}

function removeFilterButtons() {
    $('#rowFilterSelector, #button-filter-all, #button-filter-none, #button-filter-start').remove();
}

/* this function hides all rows, 
in which the column with the columnIndex does not match one of the values. */
function hideRows(values, columnIndex) {
    var columnName = $('#columnTitles')[0].cells[columnIndex].textContent;

    var dataRows = $('#dataTable > tbody')[0].rows;
    for (var i = 0; i < dataRows.length; i++) {
        var row = dataRows[i];
        var isVisible = false;

        // show all matching rows
        if (jQuery.inArray(row.cells[columnIndex].textContent, values) != -1) {
            isVisible = true;
        }

        // special case: show 'correct', 'wrong' and 'unknown' results
        if (!isVisible && columnName == 'status') {
            var classNames = row.cells[columnIndex].className.split(' ');
            for (var j = 0; j < values.length; j++) {
                var value = values[j];
                switch (value) {
                    case 'correct':
                    case 'wrong':
                        if (anyStartsWith(value, classNames)) {
                            isVisible = true;
                        }
                        break;

                    case 'unknown':
                        if (!anyStartsWith('correct', classNames) && !anyStartsWith('wrong', classNames)) {
                            isVisible = true;
                        }
                        break;

                    default: // do nothing, inVisible=false
                }
            }
        }
        if (!isVisible) $(row).hide();
    }
}

function anyStartsWith(key, values) {
    for (var i = 0; i < values.length; i++) {
        if (values[i].indexOf(key) == 0) { return true; }
    }
    return false;
}

$(document).ready(function() {
  $('body').keydown(function (event) {
                      if (fKeyPressed(event))
                        return createRowFilterButtons();
                      });
});
</script>


<!-- ################## Everything related to showing plots of the data ################## -->

<script type="text/javascript" src="http://www.sosy-lab.org/lib/jquery.jqplot-1.0.0b2_r1012/jquery.jqplot.min.js"></script>
<script type="text/javascript" src="http://www.sosy-lab.org/lib/jquery.jqplot-1.0.0b2_r1012/jqplot.highlighter.min.js"></script>
<script type="text/javascript" src="http://www.sosy-lab.org/lib/jquery.jqplot-1.0.0b2_r1012/jqplot.cursor.min.js"></script>
<script type="text/javascript" src="http://www.sosy-lab.org/lib/jquery.jqplot-1.0.0b2_r1012/jqplot.canvasTextRenderer.min.js"></script>
<script type="text/javascript" src="http://www.sosy-lab.org/lib/jquery.jqplot-1.0.0b2_r1012/jqplot.canvasAxisTickRenderer.min.js"></script>
<script type="text/javascript" src="http://www.sosy-lab.org/lib/jquery.jqplot-1.0.0b2_r1012/jqplot.enhancedLegendRenderer.min.js"></script>
<script type="text/javascript" src="http://www.sosy-lab.org/lib/jquery.jqplot-1.0.0b2_r1012/jqplot.logAxisRenderer.min.js"></script>
<script type="text/javascript" src="http://www.sosy-lab.org/lib/jquery.jqplot-1.0.0b2_r1012/jqplot.canvasAxisLabelRenderer.min.js"></script>
<script type="text/javascript" src="http://www.sosy-lab.org/lib/jquery.jqplot-1.0.0b2_r1012/jqplot.canvasOverlay.min.js"></script>
<link rel="stylesheet" type="text/css" href="http://www.sosy-lab.org/lib/jquery.jqplot-1.0.0b2_r1012/jquery.jqplot.min.css"/>

<style type="text/css">
  .jqplot-title {font-family:arial, sans serif; font-size:large; z-index:10 }
  .jqplot-table-legend-swatch {width:20px; height:15px }
  .jqplot-table-legend { border-style:none; outline:none }
  .jqplot-table-legend tbody { border-style:none }
  .jqplot-table-legend tbody tr td { border-top:none; cursor:pointer }
  .jqplot-highlighter-tooltip {font-family:arial, sans serif; font-size:large;
           border:solid 1px black; padding:2px;
           border-radius:8px; border-bottom-left-radius:0px;
           background-color:white; opacity:0.8; }
  .jqplot-table-legend { text-align: left; }
  table.jqplot-table-legend[style] { position:absolute; left:auto !important; right:0px !important; } /* overrides inner css-style */
  #chart { height:100%; width:100% }
  #button-quantile { position:absolute; bottom:50px; }
  #button-logScale { position:absolute; bottom:25px; }
  #button-showCorrectOnly { position:absolute; bottom:0px; }
  .scatterplot-selector { width:30%; }
</style>

<script type="text/javascript">

// simple structure, that contains all data for the plot
var graphData = {
  target : null,
  isRunSet : null,
  filenames : null,
  indices : null, // columns from table
  data : null, // values are sorted if quantilePlot else not sorted, indizes always from 0 to N
  originalData : null, // values are equal to data, but indizes are not sorted
  integerOnly : null,
  minValue : null,
  maxValue : null,
  isQuantile : true,
  isLogScale : true,
  showCorrectOnly : true,
};

// this function collects the indices of columns with target as cell above the column
function getColumnIndicesForTarget(target) {
  var columnIndizes = [];
  var cells = document.getElementById('columnTitles').cells;

  if (graphData.isRunSet) {
    var index = $(target).index(); // index of runset relative to table-row
    for (i = 1; i < cells.length; i++) { // skip first cell
      if ($(cells[i]).is(":visible")) {
        if ("status" != cells[i].textContent
            && tests[index-1] === columnsToTest[i-1]) {
          columnIndizes.push(i);
        }
      }
    }
  } else {
    for (i = 1; i < cells.length; i++) { // skip first cell
      if ($(cells[i]).is(":visible")) {
        if (target.textContent == cells[i].textContent) {
          columnIndizes.push(i);
        }
      }
    }
  }

  return columnIndizes;
};

// collectTableData collects some data for the graphData,
// this function must be called as first function for working with the plot
function collectTableData() {
  var data = [];

  graphData.indices = getColumnIndicesForTarget(graphData.target);
  for (j = 0; j < graphData.indices.length; j++) {
    data.push([]);
  }

  // reset graphData
  graphData.filenames = [];
  graphData.integerOnly = true;
  graphData.minValue = Number.POSITIVE_INFINITY;
  graphData.maxValue = Number.NEGATIVE_INFINITY;

  var rows = $('#dataTable > tbody > tr:visible');
  for (i = 0; i < rows.length; i++) {
    var currentRow = rows[i];
    graphData.filenames.push(currentRow.cells[0].textContent);
    
    for (j = 0; j < graphData.indices.length; j++) {
      var index = graphData.indices[j];
      var currentCell = $(currentRow.cells[index]);
      var value = getValue(currentCell, graphData.target.textContent);

      // each array is of the form: [[id1, value1], [id2, value2], ...]
      data[j].push([i, value]);
    }
  }

  graphData.originalData = data;
  graphData.data = graphData.isQuantile ? sortData(data) : data;
};


// this method returns sorted data for showQuantile().
function sortData(data) {
  var newData = [];
  for (i = 0; i < data.length; i++) {
    var line = data[i];

    // line has the structur [[0, v0],[1, v1],[2, v2]]
    // we sort the second entry of each element
    // we sort 'inplace', important for highlighting points,
    // compare numbers, NaN and Null are handled as positive infinity
    line.sort( function(a, b) {
      if (a[1] == null || isNaN(a[1])) return 1;
      if (b[1] == null || isNaN(b[1])) return -1;
      return a[1] - b[1];
    } );

    // create new indizes
    var newLine = [];
    for (j = 0; j < line.length; j++) {
      newLine.push([j, line[j][1]]);
    }

    newData.push(newLine);
  }
  return newData;
}


// returns the textcontent of a cell as numeral
function getValue(cell, title) {
    var value;
    if (graphData.showCorrectOnly && !cell.hasClass('correct')) {
        value = Number.NaN;  // using 'null' as unknown value causes problems in the plot

    } else if (title === 'status') {
        if (cell.hasClass('correct'))     value = 1;
        else if (cell.hasClass('wrong'))  value = -1;
        else                              value = 0;

    } else {
        value = parseFloat(cell.text());
        valueInt = parseInt(cell.text());

        // collect some information, used later for tick-formatter
        if (!isNaN(value)) {
            if (value != valueInt){ graphData.integerOnly = false; }
            if (value < graphData.minValue) { graphData.minValue = value; }
            if (value > graphData.maxValue) { graphData.maxValue = value; }
        }

        if (value == 0 && graphData.isLogScale) {
            value = 0.00001; // zero is not part of log-scale
        }
    }
    return value;
}


// this functions collects a list of pairs (a,b) where a and b are the entires for the scatterplot.
// this function must be called as first function for working with the plot.
// collectTableData collects some data for the graphData,
// this function must be called as first function for working with the plot
function collectTableDataForScatter(index1, title1, index2, title2) {
  var data = [[]];

  // reset graphData
  graphData.indices = [];
  graphData.filenames = [];
  graphData.integerOnly = true;
  graphData.minValue = Number.POSITIVE_INFINITY;
  graphData.maxValue = Number.NEGATIVE_INFINITY;

  var rows = $('#dataTable > tbody > tr:visible');
  for (i = 0; i < rows.length; i++) {
    var currentRow = rows[i];
    
    var cell1 = $(currentRow.cells[index1]);
    var value1 = getValue(cell1, title1);
    
    var cell2 = $(currentRow.cells[index2]);
    var value2 = getValue(cell2, title2);

    // we need two real numbers
    if (value1 != null && value2 != null && !isNaN(value1) && !isNaN(value2)) {
        var filename = currentRow.cells[0].textContent;
       
        // each array is of the form: [[id1, value1], [id2, value2], ...], 
        // the third entry is additional info and is used for the highlighter,
        data[0].push([value1, value2, filename]);
    }
  }

  graphData.originalData = data;
  graphData.data = data;
};


// Create a list which indicates at which ticks to draw grid lines
// and which labels to put at the x-axis.
function getXTicks() {
  var xTicks = [];
  var maxLength = 40;

  var numRows = graphData.filenames.length;
  var labelStep = 1;
  var gridStep = 1;
  if (numRows > 30) { labelStep = 5; }
  if (numRows > 200) { labelStep = 10; gridStep = 5; }
  if (numRows > 1000) { labelStep = 20; gridStep = 10; }

  function getLabel(name, index) {
    if (graphData.isQuantile) {
      return index.toString();
    } else {
      if (name.length > maxLength) { name = name.substring(0, maxLength) + "..."; }
      return name;
    }
  }

  for (i = 0; i < numRows; i++) {
    if (!(i%gridStep)) {
        xTicks.push([i, ((i%labelStep)?" ":getLabel(graphData.filenames[i], i))]);
    }
  }

  return xTicks;
}


// get labels for y-direction
function getYTicks() {
  if (graphData.target.textContent == "status") {
    return [[-1.5, " "], [-1, "wrong"], [0, "unknown"], [1, "correct"], [1.5, " "]];
  } else {
    return [];
  }
}

// returns label of a test: 'tool+test+date'.
function getLabels() {
  var labels = [];
  if (graphData.isRunSet) {
      var cells = document.getElementById('columnTitles').cells;
      for (i = 0; i < graphData.indices.length; i++) {
        var index = graphData.indices[i];
        labels.push(cells[index].textContent);
      }
  } else {
      for (i = 0; i < graphData.indices.length; i++) {
        var index = graphData.indices[i];
        labels.push(getNameOfTest(index));
      }
  }
  return labels;
};


function addLegendActions() {
  var legendButtons = $('tr.jqplot-table-legend');
  var seriesLines = $('canvas.jqplot-series-canvas');

  // assertion
  if (legendButtons.length != seriesLines.length) {
    debug("ERROR: number of series does not match buttons!");
  }

  for (i = 0; i<legendButtons.length; i++) {
    var currentButton = legendButtons[i];
    var currentLine = seriesLines[i];

    currentButton.onclick = function(event) {
      var hideOpacity = 0.3;
      if (this.style.opacity == hideOpacity) {
        this.style.opacity = 1;
      } else {
        this.style.opacity = hideOpacity;
      }
    }

    currentButton.onmouseover = function(line) {
      return function(event) { line.style.zIndex = 5; }
    }(currentLine);

    currentButton.onmouseout = function(line) {
      return function(event) { line.style.zIndex = 0; }
    }(currentLine);
  }
}


function highlightFormatter(str, seriesIndex, pointIndex) {
    var numberOfFile = graphData.originalData[seriesIndex][pointIndex][0];
    var filename = graphData.filenames[numberOfFile];
    if (graphData.target.textContent == "status") {
      if (str == 1)       str = "correct";
      else if (str == 0)  str = "unknown";
      else                str = "wrong";
    }
    return filename + "<br>" + str;
}


function highlightFormatterForScatter(str, seriesIndex, pointIndex, plot) {
    var point = plot.series[seriesIndex].data[pointIndex]; // POINT=[x,y,filename]
    // console.log(point);
    if (graphData.target.textContent == "status") { // TODO not working, we have 2 independent values
      if (str == 1)       str = "correct";
      else if (str == 0)  str = "unknown";
      else                str = "wrong";
    }
    return point[2] + "<br>X: " + point[0] + "<br>Y: " + point[1]; // + "<br>STR: " + str;
}


function getYTicksFormat() {
    if (graphData.integerOnly) { return '%.0f'; }
    if (graphData.isLogScale) {
        if (graphData.minValue >= 1) { return '%.0f'; }
        else if (graphData.minValue >= 0.1) { return '%.1f'; }
        else { return '%.2f'; }
    } else {
        return (graphData.maxValue >= 10) ? '%.0f' : '%.2f';
    }
}


function addButtons(target, callback, showQuantileButton) {
    if (showQuantileButton) {
        $('<button>', {id:'button-quantile'}).appendTo(target)
            .click(function() { graphData.isQuantile = !graphData.isQuantile; callback();})
            .text(graphData.isQuantile ? 'Switch to Direct Plot' : 'Switch to Quantile Plot');
    }

    $('<button>', {id:'button-logScale'}).appendTo(target)
        .click(function() { graphData.isLogScale = !graphData.isLogScale; callback();})
        .text(graphData.isLogScale ?  'Switch to Linear Scale' : 'Switch to Logarithmic Scale');

    $('<button>', {id:'button-showCorrectOnly'}).appendTo(target)
        .click(function() { graphData.showCorrectOnly = !graphData.showCorrectOnly; callback();})
        .text(graphData.showCorrectOnly ?  'Switch to All Results' : 'Switch to Correct Results Only');
}


function getSelectorForScatter(identifier) {
    var select = $('<select>', {class:'scatterplot-selector'});
    var columnIndex = 1; // columns start with 1
    for (var i = 0; i < tests.length; i++) {
        var test = tests[i];
        var group = $('<optgroup>', {label:getNameOfTestDirect(test)})
                .appendTo(select);
        for (var j = 0; j < test.columns.length; j++, columnIndex++) {
            var column = test.columns[j];
            var option = $('<option>', {
                            value:columnIndex, 
                            selected:(graphData.target[identifier] == columnIndex)})
                        .text(column).appendTo(group);
        }
    }
    
    select.change(function(){
        var selectedValue = Number(select.find(':selected')[0].value);
        graphData.target[identifier] = selectedValue;
        showScatterPlot();
    });
    
    return select;
}

function showScatterPlot() {
  $('#contentPaneBackground').trigger('click'); // cleanup
  var contentPane = $('#contentPane').append('<div id="chart"></div>');
  addButtons(contentPane, showScatterPlot, false);
  showContentPane();

  // the identifier '0/1' is the arrayindex in 'graphData.target',
  // it identifies the first and second selector
  var selector0 = getSelectorForScatter(0); 
  var selector1 = getSelectorForScatter(1);
  var index0 = graphData.target[0];
  var index1 = graphData.target[1];
  var titles = $('#columnTitles').children();
  var title0 = titles[index0].textContent;
  var title1 = titles[index1].textContent;
  var label0 = getNameOfTest(index0) + " " + title0;
  var label1 = getNameOfTest(index1) + " " + title1;
  
  collectTableDataForScatter(index0, title0, index1, title1);

  var maxValue = graphData.maxValue * 100; // should be bigger than all measurable values
  var minValue = graphData.isLogScale ? 0.0000001 : (-maxValue); // there is no zero in logscale

  var plot = $.jqplot('chart', graphData.data, {
    title: 'ScatterPlot: ',
    legend: {
      show:false,
    },
    highlighter:{
      yvalues: 2,   // we have one extra value in the array
      show: true,
      sizeAdjust: 10,
      showMarker: true,
      tooltipAxes: 'y',
      tooltipLocation: 'ne',
      tooltipContentEditor: highlightFormatterForScatter, // functionPointer!
      tooltipFormatString: '%s', // how to format the y-value
      useAxesFormatters: false
    },
    seriesDefaults:{
      showLine:false,
      shadow: false,
    },
    cursor:{
      show: false,
      zoom: false,
      showTooltip: false,
    },
    axes:{
      xaxis:{
        label:label0,
        labelRenderer: $.jqplot.CanvasAxisLabelRenderer,
        labelOptions:{ textColor:'Black' },
        renderer: (graphData.isLogScale && title0 !== 'status') ? $.jqplot.LogAxisRenderer : $.jqplot.LinearAxisRenderer,
        tickRenderer: $.jqplot.CanvasAxisTickRenderer,
        tickOptions: {
          angle: -60,
        }
      },
      yaxis:{
        label:label1,
        labelRenderer: $.jqplot.CanvasAxisLabelRenderer,
        labelOptions:{ textColor:'Black' },
        renderer: (graphData.isLogScale && title1 !== 'status') ? $.jqplot.LogAxisRenderer : $.jqplot.LinearAxisRenderer,
        pad: 1.2,
        tickRenderer: $.jqplot.CanvasAxisTickRenderer,
        tickOptions:{
          formatString: getYTicksFormat()
        }
      }
    },
    canvasOverlay: {
        show: true,
        objects: [
            {line: {
                name: 'diagonalLine',
                lineWidth: 1,
                color: 'red',
                shadow: false,
                start: [minValue, minValue],
                stop: [maxValue, maxValue],
            } },
        ]
    }
  });

  $('.jqplot-title').empty()
        .append('X: ').append(selector0)
        .append('<span style="padding-left:50px"></span>') // some space between the selectors
        .append('Y: ').append(selector1);

  $('#contentPaneBackground').click(function(event) {
    plot.destroy();
    $('#chart').empty();
  });
};


function showPlot() {
  $('#contentPaneBackground').trigger('click'); // cleanup
  $('#contentPane').append('<div id="chart"></div>');
  addButtons($('#contentPane'), showPlot, true);
  showContentPane();
  collectTableData();

  var plot = $.jqplot('chart', graphData.data, {
    title: graphData.target.textContent,
    legend: {
      show:true,
      placement: 'outsideGrid',
      renderer: $.jqplot.EnhancedLegendRenderer,
      labels: getLabels(),
      location: 's',
      rowSpacing: "0px",
      showSwatches: true,
    },
    highlighter:{
      show: true,
      sizeAdjust: 10,
      showMarker: true,
      tooltipAxes: 'y',
      tooltipLocation: 'ne',
      tooltipContentEditor: highlightFormatter, // functionPointer!
      tooltipFormatString: '%s',
      useAxesFormatters: false
    },
    seriesDefaults:{
      shadow: false,
    },
    cursor:{
      show: false,
      zoom: false,
      showTooltip: false,
    },
    axes:{
      xaxis:{
        ticks: getXTicks(),
        tickRenderer: $.jqplot.CanvasAxisTickRenderer,
        tickOptions: {
          fontSize: '9px',
          angle: -60,
        }
      },
      yaxis:{
        ticks: getYTicks(),
        renderer: (graphData.isLogScale && graphData.target.textContent !== 'status') ? $.jqplot.LogAxisRenderer : $.jqplot.LinearAxisRenderer,
        pad: 1.2,
        tickOptions:{
          formatString: getYTicksFormat()
        }
      }
    },
  });

  addLegendActions();
  
  $('#contentPaneBackground').click(function(event) {
    plot.destroy();
    $('#chart').empty();
  });
};


// this function adds the listeners to the table
$(document).ready(function() {
  $('.columnTitles > td:not(:first-child)') // do not use first column
      .addClass("clickable")
      .attr("title", "Click here to show a graph of this column")
      .click(function (event) {
            graphData.target = event.target;
            graphData.isRunSet = false;
            showPlot();
      });
  
  $('.run > td:not(:first-child)') // do not use first column
      .addClass("clickable")
      .attr("title", "Click here to show a graph of this run-set")
      .click(function (event) {
            graphData.target = event.target;
            graphData.isRunSet = true;
            showPlot();
      });
  
  $('.run > td:first-child')
      .addClass("clickable")
      .attr("title", "Click here to show some scatter-graphs")
      .click(function (event) {
            graphData.target = [1,1]; // default indices of the columns in the plot
            graphData.isRunSet = false;
            showScatterPlot();
      });
});

</script>


<!-- ################## Base HTML ################## -->

<title>results.13-08-26_1418 differences</title>

</head>

<body>

<div id="contentPaneBackground"></div>
<div id="contentPane"></div>

<table id="dataTable">
<thead>
  <tr id="tool" class="tool">
    <td>Tool</td>
    <td colspan="12">CPAchecker 1.2-svn e5c9ef1+</td>
  </tr>
  <tr id="limits" class="limits">
    <td>Limits</td>
    <td colspan="12">timelimit: 300 s, memlimit: 12000 MB, CPU core limit: None</td>
  </tr>
  <tr id="host" class="host">
    <td>Host</td>
    <td colspan="12">molnar</td>
  </tr>
  <tr id="os" class="os">
    <td>OS</td>
    <td colspan="12">Linux 3.2.0-52-generic x86_64</td>
  </tr>
  <tr id="system" class="system">
    <td>System</td>
    <td colspan="12">CPU: Intel(R) Core(TM) i7-3770 CPU @ 3.40GHz with 4 cores, frequency: 3401 MHz; RAM: 16385312 kB</td>
  </tr>
  <tr id="date" class="date">
    <td>Date of execution</td>
    <td colspan="6">13-08-23 20:34</td>
    <td colspan="6">13-08-23 21:24</td>
  </tr>
  <tr id="run" class="run">
    <td>Run set</td>
    <td colspan="6">benchmark-cpachecker-bitvector-ppreds-integrated.with-output-files</td>
    <td colspan="6">benchmark-cpachecker-bitvector-predicate.with-output-files</td>
  </tr>
  <tr id="options" class="options">
    <td>Options</td>
    <td colspan="6">-heap 9000M<br/>-config /home/mikhail/repos/cpachecker/config/predicateAnalysis-PredAbsRefiner-ABEl-UF.properties<br/>-spec /home/mikhail/repos/cpachecker/config/specification/sv-comp.spc<br/>-setprop output.path=<wbr/>test/results/${benchmark_name}.${benchmark_date}.output/${sourcefile_name}/<br/>-setprop analysis.machineModel=<wbr/>LINUX32<br/>-setprop cpa.predicate.memoryAllocationsAlwaysSucceed=<wbr/>true<br/>-setprop output.disable=<wbr/>true<br/>-setprop log.level=<wbr/>OFF<br/>-setprop cpa.predicate.refinement.dumpInterpolationProblems=<wbr/>false<br/>-disable-java-assertions</td>
    <td colspan="6">-heap 9000M<br/>-config /home/mikhail/repos/cpachecker/config/predicateAnalysis-PredAbsRefiner-ABEl-bv.properties<br/>-spec /home/mikhail/repos/cpachecker/config/specification/sv-comp.spc<br/>-setprop output.path=<wbr/>test/results/${benchmark_name}.${benchmark_date}.output/${sourcefile_name}/<br/>-setprop analysis.machineModel=<wbr/>LINUX32<br/>-setprop cpa.predicate.memoryAllocationsAlwaysSucceed=<wbr/>true<br/>-setprop output.disable=<wbr/>true<br/>-setprop log.level=<wbr/>OFF<br/>-setprop cpa.predicate.refinement.dumpInterpolationProblems=<wbr/>false<br/>-setprop analysis.summaryEdges=<wbr/>true<br/>-setprop analysis.functionPointerCalls=<wbr/>true<br/>-setprop cpa.callstack.skipRecursion=<wbr/>true<br/>-setprop cpa.conditions.global.time.wall=<wbr/>-1<br/>-disable-java-assertions</td>
  </tr>
  <tr id="columnTitles" class="columnTitles">
    <td>bitvector/</td>
    <td colspan="1">status</td>
    <td colspan="1">cputime</td>
    <td colspan="1">walltime</td>
    <td colspan="1">memUsage</td>
    <td colspan="1">total</td>
    <td colspan="1">reached</td>
    <td colspan="1">status</td>
    <td colspan="1">cputime</td>
    <td colspan="1">walltime</td>
    <td colspan="1">memUsage</td>
    <td colspan="1">total</td>
    <td colspan="1">reached</td>
  </tr>
</thead>

<tbody>
<tr><td title="Click here to show source code"><a href="../../bitvector/s3_clnt_1_safe.BV.c.cil.c">s3_clnt_1_safe.BV.c.cil.c</a></td>
    <td class="status error" title="Click here to show output of tool"><a href="benchmark-cpachecker-bitvector-ppreds-integrated.13-08-23_2034.logfiles/with-output-files.s3_clnt_1_safe.BV.c.cil.c.log">timeout</a></td>
  <td class="errorValue">299.68</td>
  <td class="errorValue">256.44</td>
  <td class="errorValue">1562513408</td>
  <td class="errorValue">-</td>
  <td class="errorValue">-</td>
    <td class="status correct safe" title="Click here to show output of tool"><a href="benchmark-cpachecker-bitvector-predicate.13-08-23_2124.logfiles/with-output-files.s3_clnt_1_safe.BV.c.cil.c.log">safe</a></td>
  <td class="correct safeValue">132.69</td>
  <td class="correct safeValue">113.09</td>
  <td class="correct safeValue">709668864</td>
  <td class="correct safeValue">112.6</td>
  <td class="correct safeValue">0.076s</td>
</tr>
<tr><td title="Click here to show source code"><a href="../../bitvector/s3_clnt_2_safe.BV.c.cil.c">s3_clnt_2_safe.BV.c.cil.c</a></td>
    <td class="status correct safe" title="Click here to show output of tool"><a href="benchmark-cpachecker-bitvector-ppreds-integrated.13-08-23_2034.logfiles/with-output-files.s3_clnt_2_safe.BV.c.cil.c.log">safe</a></td>
  <td class="correct safeValue">19.21</td>
  <td class="correct safeValue">16.05</td>
  <td class="correct safeValue">244072448</td>
  <td class="correct safeValue">15.6</td>
  <td class="correct safeValue">0.080s</td>
    <td class="status error" title="Click here to show output of tool"><a href="benchmark-cpachecker-bitvector-predicate.13-08-23_2124.logfiles/with-output-files.s3_clnt_2_safe.BV.c.cil.c.log">timeout</a></td>
  <td class="errorValue">298.71</td>
  <td class="errorValue">228.93</td>
  <td class="errorValue">3337900032</td>
  <td class="errorValue">-</td>
  <td class="errorValue">-</td>
</tr>
</tbody>

<tfoot>
<tr class="columnTitles">
  <td>bitvector/</td>
  <td colspan="1">status</td>
  <td colspan="1">cputime</td>
  <td colspan="1">walltime</td>
  <td colspan="1">memUsage</td>
  <td colspan="1">total</td>
  <td colspan="1">reached</td>
  <td colspan="1">status</td>
  <td colspan="1">cputime</td>
  <td colspan="1">walltime</td>
  <td colspan="1">memUsage</td>
  <td colspan="1">total</td>
  <td colspan="1">reached</td>
</tr>
  <tr>
    <td >total files</td>
    <td >2</td>
    <td title="Min: 19.21, Max: 299.68, Average: 159.445, Median: 299.68">318.89</td>
    <td title="Min: 16.05, Max: 256.44, Average: 136.245, Median: 256.44">272.49</td>
    <td title="Min: 244072448, Max: 1562513408, Average: 903292928.000, Median: 1562513408">1806585856</td>
    <td title="Min: 0, Max: 15.6, Average: 7.800, Median: 15.6">15.6</td>
    <td title="Min: 0, Max: 0.080, Average: 0.040, Median: 0.080">0.080</td>
    <td >2</td>
    <td title="Min: 132.69, Max: 298.71, Average: 215.700, Median: 298.71">431.40</td>
    <td title="Min: 113.09, Max: 228.93, Average: 171.010, Median: 228.93">342.02</td>
    <td title="Min: 709668864, Max: 3337900032, Average: 2023784448.000, Median: 3337900032">4047568896</td>
    <td title="Min: 0, Max: 112.6, Average: 56.300, Median: 112.6">112.6</td>
    <td title="Min: 0, Max: 0.076, Average: 0.038, Median: 0.076">0.076</td>
  </tr>
  <tr>
    <td title="(no bug exists + result is SAFE) OR (bug exists + result is UNSAFE)">correct results</td>
    <td >1</td>
    <td title="Min: 19.21, Max: 19.21, Average: 19.210, Median: 19.21">19.21</td>
    <td title="Min: 16.05, Max: 16.05, Average: 16.050, Median: 16.05">16.05</td>
    <td title="Min: 244072448, Max: 244072448, Average: 244072448.000, Median: 244072448">244072448</td>
    <td title="Min: 15.6, Max: 15.6, Average: 15.600, Median: 15.6">15.6</td>
    <td title="Min: 0.080, Max: 0.080, Average: 0.080, Median: 0.080">0.080</td>
    <td >1</td>
    <td title="Min: 132.69, Max: 132.69, Average: 132.690, Median: 132.69">132.69</td>
    <td title="Min: 113.09, Max: 113.09, Average: 113.090, Median: 113.09">113.09</td>
    <td title="Min: 709668864, Max: 709668864, Average: 709668864.000, Median: 709668864">709668864</td>
    <td title="Min: 112.6, Max: 112.6, Average: 112.600, Median: 112.6">112.6</td>
    <td title="Min: 0.076, Max: 0.076, Average: 0.076, Median: 0.076">0.076</td>
  </tr>
  <tr>
    <td title="bug exists + result is SAFE">false negatives</td>
    <td >0</td>
    <td >0</td>
    <td >0</td>
    <td >0</td>
    <td >0</td>
    <td >0</td>
    <td >0</td>
    <td >0</td>
    <td >0</td>
    <td >0</td>
    <td >0</td>
    <td >0</td>
  </tr>
  <tr>
    <td title="no bug exists + result is UNSAFE">false positives</td>
    <td >0</td>
    <td >0</td>
    <td >0</td>
    <td >0</td>
    <td >0</td>
    <td >0</td>
    <td >0</td>
    <td >0</td>
    <td >0</td>
    <td >0</td>
    <td >0</td>
    <td >0</td>
  </tr>
  <tr>
    <td title="2 safe files, 0 unsafe files">score (2 files, max score: 4)</td>
    <td class="score">2</td>
    <td class="score"></td>
    <td class="score"></td>
    <td class="score"></td>
    <td class="score"></td>
    <td class="score"></td>
    <td class="score">2</td>
    <td class="score"></td>
    <td class="score"></td>
    <td class="score"></td>
    <td class="score"></td>
    <td class="score"></td>
  </tr>
<tr class="run">
  <td>Run set</td>
  <td colspan="6">benchmark-cpachecker-bitvector-ppreds-integrated.with-output-files</td>
  <td colspan="6">benchmark-cpachecker-bitvector-predicate.with-output-files</td>
</tr>
</tfoot>
</table>

</body>

</html>