<!DOCTYPE html>
<!--
Copyright (c) 2015 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->

<link rel="import" href="/tracing/base/iteration_helpers.html">
<link rel="import" href="/tracing/ui/base/dom_helpers.html">
<link rel="import" href="/tracing/ui/base/table.html">
<link rel="import" href="/tracing/value/numeric.html">
<link rel="import" href="/tracing/value/ui/scalar_span.html">

<script>
'use strict';

/**
 * @fileoverview Helper code for memory dump sub-views.
 */
tr.exportTo('tr.ui.analysis', function() {

  var NO_BREAK_SPACE = String.fromCharCode(160);
  var RIGHTWARDS_ARROW = String.fromCharCode(8594);

  var COLLATOR = new Intl.Collator(undefined, {numeric: true});

  /**
   * A table column for displaying memory dump row titles.
   *
   * @constructor
   */
  function TitleColumn(title) {
    this.title = title;
  }

  TitleColumn.prototype = {
    supportsCellSelection: false,

    /**
     * Get the title associated with a given row.
     *
     * This method will decorate the title with color and '+++'/'---' prefix if
     * appropriate (as determined by the optional row.contexts field).
     * Examples:
     *
     *   +----------------------+-----------------+--------+--------+
     *   | Contexts provided at | Interpretation  | Prefix | Color  |
     *   +----------------------+-----------------+--------+--------+
     *   | 1111111111           | always present  |        |        |
     *   | 0000111111           | added           | +++    | red    |
     *   | 1111111000           | deleted         | ---    | green  |
     *   | 1100111111*          | flaky           |        | purple |
     *   | 0001001111           | added + flaky   | +++    | purple |
     *   | 1111100010           | deleted + flaky | ---    | purple |
     *   +----------------------+-----------------+--------+--------+
     *
     *   *) This means that, given a selection of 10 memory dumps, a particular
     *      row (e.g. a process) was present in the first 2 and last 6 of them
     *      (but not in the third and fourth dump).
     *
     * This method should therefore NOT be overriden by subclasses. The
     * formatTitle method should be overriden instead when necessary.
     */
    value: function(row) {
      var formattedTitle = this.formatTitle(row);

      var contexts = row.contexts;
      if (contexts === undefined || contexts.length === 0)
        return formattedTitle;

      // Determine if the row was provided in the first and last row and how
      // many times it changed between being provided and not provided.
      var firstContext = contexts[0];
      var lastContext = contexts[contexts.length - 1];
      var changeDefinedContextCount = 0;
      for (var i = 1; i < contexts.length; i++) {
        if ((contexts[i] === undefined) !== (contexts[i - 1] === undefined))
          changeDefinedContextCount++;
      }

      // Determine the color and prefix of the title.
      var color = undefined;
      var prefix = undefined;
      if (!firstContext && lastContext) {
        // The row was added.
        color = 'red';
        prefix = '+++';
      } else if (firstContext && !lastContext) {
        // The row was removed.
        color = 'green';
        prefix = '---';
      }
      if (changeDefinedContextCount > 1) {
        // The row was flaky (added/removed more than once).
        color = 'purple';
      }

      if (color === undefined && prefix === undefined)
        return formattedTitle;

      var titleEl = document.createElement('span');
      if (prefix !== undefined) {
        var prefixEl = tr.ui.b.createSpan({textContent: prefix});
        // Enforce same width of '+++' and '---'.
        prefixEl.style.fontFamily = 'monospace';
        Polymer.dom(titleEl).appendChild(prefixEl);
        Polymer.dom(titleEl).appendChild(
            tr.ui.b.asHTMLOrTextNode(NO_BREAK_SPACE));
      }
      if (color !== undefined)
        titleEl.style.color = color;
      Polymer.dom(titleEl).appendChild(
          tr.ui.b.asHTMLOrTextNode(formattedTitle));
      return titleEl;
    },

    /**
     * Format the title associated with a given row. This method is intended to
     * be overriden by subclasses.
     */
    formatTitle: function(row) {
      return row.title;
    },

    cmp: function(rowA, rowB) {
      return COLLATOR.compare(rowA.title, rowB.title);
    }
  };

  /**
   * Abstract table column for displaying memory dump data.
   *
   * @constructor
   */
  function MemoryColumn(name, cellPath, aggregationMode) {
    this.name = name;
    this.cellPath = cellPath;

    // See MemoryColumn.AggregationMode enum in this file.
    this.aggregationMode = aggregationMode;
  }

  /**
   * Construct columns from cells in a hierarchy of rows and a list of rules.
   *
   * The list of rules contains objects with three fields:
   *
   *   condition: Optional string or regular expression matched against the
   *       name of a cell. If omitted, the rule will match any cell.
   *   importance: Mandatory number which determines the final order of the
   *       columns. The column with the highest importance will be first in the
   *       returned array.
   *   columnConstructor: Mandatory memory column constructor.
   *
   * Example:
   *
   *   var importanceRules = [
   *     {
   *       condition: 'page_size',
   *       columnConstructor: NumericMemoryColumn,
   *       importance: 8
   *     },
   *     {
   *       condition: /size/,
   *       columnConstructor: CustomNumericMemoryColumn,
   *       importance: 10
   *     },
   *     {
   *       // No condition: matches all columns.
   *       columnConstructor: NumericMemoryColumn,
   *       importance: 9
   *     }
   *   ];
   *
   * Given a name of a cell, the corresponding column constructor and
   * importance are determined by the first rule whose condition matches the
   * column's name. For example, given a cell with name 'inner_size', the
   * corresponding column will be constructed using CustomNumericMemoryColumn
   * and its importance (for sorting purposes) will be 10 (second rule).
   *
   * After columns are constructed for all cell names, they are sorted in
   * descending order of importance and the resulting list is returned. In the
   * example above, the constructed columns will be sorted into three groups as
   * follows:
   *
   *      [most important, left in the resulting table]
   *   1. columns whose name contains 'size' excluding 'page_size' because it
   *      would have already matched the first rule (Note that string matches
   *      must be exact so a column named 'page_size2' would not match the
   *      first rule and would therefore belong to this group).
   *   2. columns whose name does not contain 'size'.
   *   3. columns whose name is 'page_size'.
   *      [least important, right in the resulting table]
   *
   * where columns will be sorted alphabetically within each group.
   */
  MemoryColumn.fromRows = function(rows, cellKey, aggregationMode, rules) {
    // Recursively find the names of all cells of the rows (and their sub-rows).
    var cellNames = new Set();
    function gatherCellNames(rows) {
      rows.forEach(function(row) {
        if (row === undefined)
          return;
        var fieldCells = row[cellKey];
        if (fieldCells !== undefined) {
          tr.b.iterItems(fieldCells, function(fieldName, fieldCell) {
            if (fieldCell === undefined || fieldCell.fields === undefined)
              return;
            cellNames.add(fieldName);
          });
        }
        var subRows = row.subRows;
        if (subRows !== undefined)
          gatherCellNames(subRows);
      });
    }
    gatherCellNames(rows);

    // Based on the provided list of rules, construct the columns and calculate
    // their importance.
    var positions = [];
    cellNames.forEach(function(cellName) {
      var cellPath = [cellKey, cellName];
      var matchingRule = MemoryColumn.findMatchingRule(cellName, rules);
      var constructor = matchingRule.columnConstructor;
      var column = new constructor(cellName, cellPath, aggregationMode);
      positions.push({
        importance: matchingRule.importance,
        column: column
      });
    });

    positions.sort(function(a, b) {
      // Sort columns with the same importance alphabetically.
      if (a.importance === b.importance)
        return COLLATOR.compare(a.column.name, b.column.name);

      // Sort columns in descending order of importance.
      return b.importance - a.importance;
    });

    return positions.map(function(position) { return position.column });
  };

  MemoryColumn.spaceEqually = function(columns) {
    var columnWidth = (100 / columns.length).toFixed(3) + '%';
    columns.forEach(function(column) {
      column.width = columnWidth;
    });
  };

  MemoryColumn.findMatchingRule = function(name, rules) {
    for (var i = 0; i < rules.length; i++) {
      var rule = rules[i];
      if (MemoryColumn.nameMatchesCondition(name, rule.condition))
        return rule;
    }
    return undefined;
  };

  MemoryColumn.nameMatchesCondition = function(name, condition) {
    // Rules without conditions match all columns.
    if (condition === undefined)
      return true;

    // String conditions must match the column name exactly.
    if (typeof(condition) === 'string')
      return name === condition;

    // If the condition is not a string, assume it is a RegExp.
    return condition.test(name);
  };

  /** @enum */
  MemoryColumn.AggregationMode = {
    DIFF: 0,
    MAX: 1
  };

  MemoryColumn.SOME_TIMESTAMPS_INFO_QUANTIFIER = 'at some selected timestamps';

  MemoryColumn.prototype = {
    get title() {
      return this.name;
    },

    cell: function(row) {
      var cell = row;
      var cellPath = this.cellPath;
      for (var i = 0; i < cellPath.length; i++) {
        if (cell === undefined)
          return undefined;
        cell = cell[cellPath[i]];
      }
      return cell;
    },

    aggregateCells: function(row, subRows) {
      // No generic aggregation.
    },

    fields: function(row) {
      var cell = this.cell(row);
      if (cell === undefined)
        return undefined;
      return cell.fields;
    },

    /**
     * Format a cell associated with this column from the given row. This
     * method is not intended to be overriden.
     */
    value: function(row) {
      var fields = this.fields(row);
      if (this.hasAllRelevantFieldsUndefined(fields))
        return '';

      // Determine the color and infos of the resulting element.
      var contexts = row.contexts;
      var color = this.color(fields, contexts);
      var infos = [];
      this.addInfos(fields, contexts, infos);

      // Format the actual fields.
      var formattedFields = this.formatFields(fields);

      // If no color is specified and there are no infos, there is no need to
      // wrap the value in a span element.#
      if ((color === undefined || formattedFields === '') && infos.length === 0)
        return formattedFields;

      var fieldEl = document.createElement('span');
      fieldEl.style.display = 'flex';
      fieldEl.style.alignItems = 'center';
      fieldEl.style.justifyContent = 'flex-end';
      Polymer.dom(fieldEl).appendChild(
          tr.ui.b.asHTMLOrTextNode(formattedFields));

      // Add info icons with tooltips.
      infos.forEach(function(info) {
        var infoEl = document.createElement('span');
        infoEl.style.paddingLeft = '4px';
        infoEl.style.cursor = 'help';
        infoEl.style.fontWeight = 'bold';
        Polymer.dom(infoEl).textContent = info.icon;
        if (info.color !== undefined)
          infoEl.style.color = info.color;
        infoEl.title = info.message;
        Polymer.dom(fieldEl).appendChild(infoEl);
      }, this);

      // Set the color of the element.
      if (color !== undefined)
        fieldEl.style.color = color;

      return fieldEl;
    },

    /**
     * Returns true iff all fields of a row which are relevant for the current
     * aggregation mode (e.g. first and last field for diff mode) are undefined.
     */
    hasAllRelevantFieldsUndefined: function(fields) {
      if (fields === undefined)
        return true;

      switch (this.aggregationMode) {
        case MemoryColumn.AggregationMode.DIFF:
          // Only the first and last field are relevant.
          return fields[0] === undefined &&
              fields[fields.length - 1] === undefined;

        case MemoryColumn.AggregationMode.MAX:
        default:
          // All fields are relevant.
          return fields.every(function(field) { return field === undefined; });
      }
    },

    /**
     * Get the color of the given fields formatted by this column. At least one
     * field relevant for the current aggregation mode is guaranteed to be
     * defined.
     */
    color: function(fields, contexts) {
      return undefined;
    },

    /**
     * Format an arbitrary number of fields. At least one field relevant for
     * the current aggregation mode is guaranteed to be defined.
     */
    formatFields: function(fields) {
      if (fields.length === 1)
        return this.formatSingleField(fields[0]);
      else
        return this.formatMultipleFields(fields);
    },

    /**
     * Format a single defined field.
     *
     * This method is intended to be overriden by field type specific columns
     * (e.g. show '1.0 KiB' instead of '1024' for ScalarNumeric(s) representing
     * bytes).
     */
    formatSingleField: function(field) {
      throw new Error('Not implemented');
    },

    /**
     * Format multiple fields. At least one field relevant for the current
     * aggregation mode is guaranteed to be defined.
     *
     * The aggregation mode specializations of this method (e.g.
     * formatMultipleFieldsDiff) are intended to be overriden by field type
     * specific columns.
     */
    formatMultipleFields: function(fields) {
      switch (this.aggregationMode) {
        case MemoryColumn.AggregationMode.DIFF:
          return this.formatMultipleFieldsDiff(
              fields[0], fields[fields.length - 1]);

        case MemoryColumn.AggregationMode.MAX:
          return this.formatMultipleFieldsMax(fields);

        default:
          return tr.ui.b.createSpan({
            textContent: '(unsupported aggregation mode)',
            italic: true
          });
      }
    },

    formatMultipleFieldsDiff: function(firstField, lastField) {
      throw new Error('Not implemented');
    },

    formatMultipleFieldsMax: function(fields) {
      return this.formatSingleField(this.getMaxField(fields));
    },

    cmp: function(rowA, rowB) {
      var fieldsA = this.fields(rowA);
      var fieldsB = this.fields(rowB);

      // Sanity check.
      if (fieldsA !== undefined && fieldsB !== undefined &&
          fieldsA.length !== fieldsB.length)
        throw new Error('Different number of fields');

      // Handle empty fields.
      var undefinedA = this.hasAllRelevantFieldsUndefined(fieldsA);
      var undefinedB = this.hasAllRelevantFieldsUndefined(fieldsB);
      if (undefinedA && undefinedB)
        return 0;
      if (undefinedA)
        return -1;
      if (undefinedB)
        return 1;

      return this.compareFields(fieldsA, fieldsB);
    },

    /**
     * Compare a pair of single or multiple fields. At least one field relevant
     * for the current aggregation mode is guaranteed to be defined in each of
     * the two lists.
     */
    compareFields: function(fieldsA, fieldsB) {
      if (fieldsA.length === 1)
        return this.compareSingleFields(fieldsA[0], fieldsB[0]);
      else
        return this.compareMultipleFields(fieldsA, fieldsB);
    },

    /**
     * Compare a pair of single defined fields.
     *
     * This method is intended to be overriden by field type specific columns.
     */
    compareSingleFields: function(fieldA, fieldB) {
      throw new Error('Not implemented');
    },

    /**
     * Compare a pair of multiple fields. At least one field relevant for the
     * current aggregation mode is guaranteed to be defined in each of the two
     * lists.
     *
     * The aggregation mode specializations of this method (e.g.
     * compareMultipleFieldsDiff) are intended to be overriden by field type
     * specific columns.
     */
    compareMultipleFields: function(fieldsA, fieldsB) {
      switch (this.aggregationMode) {
        case MemoryColumn.AggregationMode.DIFF:
          return this.compareMultipleFieldsDiff(
              fieldsA[0], fieldsA[fieldsA.length - 1],
              fieldsB[0], fieldsB[fieldsB.length - 1]);

        case MemoryColumn.AggregationMode.MAX:
          return this.compareMultipleFieldsMax(fieldsA, fieldsB);

        default:
          return 0;
      }
    },

    compareMultipleFieldsDiff: function(firstFieldA, lastFieldA, firstFieldB,
        lastFieldB) {
      throw new Error('Not implemented');
    },

    compareMultipleFieldsMax: function(fieldsA, fieldsB) {
      return this.compareSingleFields(
          this.getMaxField(fieldsA), this.getMaxField(fieldsB));
    },

    getMaxField: function(fields) {
      return fields.reduce(function(accumulator, field) {
        if (field === undefined)
          return accumulator;
        if (accumulator === undefined ||
            this.compareSingleFields(field, accumulator) > 0) {
          return field;
        }
        return accumulator;
      }.bind(this), undefined);
    },

    addInfos: function(fields, contexts, infos) {
      // No generic infos.
    },

    getImportance: function(importanceRules) {
      if (importanceRules.length === 0)
        return 0;

      // Find the first matching rule.
      var matchingRule =
          MemoryColumn.findMatchingRule(this.name, importanceRules);
      if (matchingRule !== undefined)
        return matchingRule.importance;

      // No matching rule. Return lower importance than all rules.
      var minImportance = importanceRules[0].importance;
      for (var i = 1; i < importanceRules.length; i++)
        minImportance = Math.min(minImportance, importanceRules[i].importance);
      return minImportance - 1;
    }
  };

  /**
   * @constructor
   */
  function StringMemoryColumn(name, cellPath, aggregationMode) {
    MemoryColumn.call(this, name, cellPath, aggregationMode);
  }

  StringMemoryColumn.prototype = {
    __proto__: MemoryColumn.prototype,

    formatSingleField: function(string) {
      return string;
    },

    formatMultipleFieldsDiff: function(firstString, lastString) {
      if (firstString === undefined) {
        // String was added ("+NEW_VALUE" in red).
        var spanEl = tr.ui.b.createSpan({color: 'red'});
        Polymer.dom(spanEl).appendChild(tr.ui.b.asHTMLOrTextNode('+'));
        Polymer.dom(spanEl).appendChild(tr.ui.b.asHTMLOrTextNode(
            this.formatSingleField(lastString)));
        return spanEl;
      } else if (lastString === undefined) {
        // String was removed ("-OLD_VALUE" in green).
        var spanEl = tr.ui.b.createSpan({color: 'green'});
        Polymer.dom(spanEl).appendChild(tr.ui.b.asHTMLOrTextNode('-'));
        Polymer.dom(spanEl).appendChild(tr.ui.b.asHTMLOrTextNode(
            this.formatSingleField(firstString)));
        return spanEl;
      } else if (firstString === lastString) {
        // String didn't change ("VALUE" with unchanged color).
        return this.formatSingleField(firstString);
      } else {
        // String changed ("OLD_VALUE -> NEW_VALUE" in orange).
        var spanEl = tr.ui.b.createSpan({color: 'DarkOrange'});
        Polymer.dom(spanEl).appendChild(tr.ui.b.asHTMLOrTextNode(
            this.formatSingleField(firstString)));
        Polymer.dom(spanEl).appendChild(tr.ui.b.asHTMLOrTextNode(
            ' ' + RIGHTWARDS_ARROW + ' '));
        Polymer.dom(spanEl).appendChild(tr.ui.b.asHTMLOrTextNode(
            this.formatSingleField(lastString)));
        return spanEl;
      }
    },

    compareSingleFields: function(stringA, stringB) {
      return COLLATOR.compare(stringA, stringB);
    },

    compareMultipleFieldsDiff: function(firstStringA, lastStringA, firstStringB,
        lastStringB) {
      // If one of the strings was added (and the other one wasn't), mark the
      // corresponding diff as greater.
      if (firstStringA === undefined && firstStringB !== undefined)
        return 1;
      if (firstStringA !== undefined && firstStringB === undefined)
        return -1;

      // If both strings were added, compare the last values (greater last
      // value implies greater diff).
      if (firstStringA === undefined && firstStringB === undefined)
        return this.compareSingleFields(lastStringA, lastStringB);

      // If one of the strings was removed (and the other one wasn't), mark the
      // corresponding diff as lower.
      if (lastStringA === undefined && lastStringB !== undefined)
        return -1;
      if (lastStringA !== undefined && lastStringB === undefined)
        return 1;

      // If both strings were removed, compare the first values (greater first
      // value implies smaller (!) diff).
      if (lastStringA === undefined && lastStringB === undefined)
        return this.compareSingleFields(firstStringB, firstStringA);

      var areStringsAEqual = firstStringA === lastStringA;
      var areStringsBEqual = firstStringB === lastStringB;

      // Consider diffs of strings that did not change to be smaller than diffs
      // of strings that did change.
      if (areStringsAEqual && areStringsBEqual)
        return 0;
      if (areStringsAEqual)
        return -1;
      if (areStringsBEqual)
        return 1;

      // Both strings changed. We are unable to determine the ordering of the
      // diffs.
      return 0;
    }
  };

  /**
   * @constructor
   */
  function NumericMemoryColumn(name, cellPath, aggregationMode) {
    MemoryColumn.call(this, name, cellPath, aggregationMode);
  }

  // Avoid tiny positive/negative diffs (displayed in the UI as '+0.0 B' and
  // '-0.0 B') due to imprecise floating-point arithmetic by treating all diffs
  // within the (-DIFF_EPSILON, DIFF_EPSILON) range as zeros.
  NumericMemoryColumn.DIFF_EPSILON = 0.0001;

  NumericMemoryColumn.prototype = {
    __proto__: MemoryColumn.prototype,

    align: tr.ui.b.TableFormat.ColumnAlignment.RIGHT,

    aggregateCells: function(row, subRows) {
      var subRowCells = subRows.map(this.cell, this);

      // Determine if there is at least one defined numeric in the sub-row
      // cells and the timestamp count.
      var hasDefinedSubRowNumeric = false;
      var timestampCount = undefined;
      subRowCells.forEach(function(subRowCell) {
        if (subRowCell === undefined)
          return;

        var subRowNumerics = subRowCell.fields;
        if (subRowNumerics === undefined)
          return;

        if (timestampCount === undefined)
          timestampCount = subRowNumerics.length;
        else if (timestampCount !== subRowNumerics.length)
          throw new Error('Sub-rows have different numbers of timestamps');

        if (hasDefinedSubRowNumeric)
          return;  // Avoid unnecessary traversals of the numerics.
        hasDefinedSubRowNumeric = subRowNumerics.some(function(numeric) {
          return numeric !== undefined;
        });
      });
      if (!hasDefinedSubRowNumeric)
        return;  // No numeric to aggregate.

      // Get or create the row cell.
      var cellPath = this.cellPath;
      var rowCell = row;
      for (var i = 0; i < cellPath.length; i++) {
        var nextStepName = cellPath[i];
        var nextStep = rowCell[nextStepName];
        if (nextStep === undefined) {
          if (i < cellPath.length - 1)
            nextStep = {};
          else
            nextStep = new MemoryCell(undefined);
          rowCell[nextStepName] = nextStep;
        }
        rowCell = nextStep;
      }
      if (rowCell.fields === undefined) {
        rowCell.fields = new Array(timestampCount);
      } else if (rowCell.fields.length !== timestampCount) {
        throw new Error(
            'Row has a different number of timestamps than sub-rows');
      }

      for (var i = 0; i < timestampCount; i++) {
        if (rowCell.fields[i] !== undefined)
          continue;
        rowCell.fields[i] = tr.model.MemoryAllocatorDump.aggregateNumerics(
            subRowCells.map(function(subRowCell) {
              if (subRowCell === undefined || subRowCell.fields === undefined)
                return undefined;
              return subRowCell.fields[i];
            }));
      }
    },

    formatSingleField: function(numeric) {
      var formattingContext = this.getFormattingContext(numeric.unit);
      var config = formattingContext !== undefined ?
          { context: formattingContext } : undefined;
      return tr.v.ui.createScalarSpan(numeric, config);
    },

    getFormattingContext: function(unit) {
      return undefined;
    },

    formatMultipleFieldsDiff: function(firstNumeric, lastNumeric) {
      return this.formatSingleField(
          this.getDiffField_(firstNumeric, lastNumeric));
    },

    compareSingleFields: function(numericA, numericB) {
      return numericA.value - numericB.value;
    },

    compareMultipleFieldsDiff: function(firstNumericA, lastNumericA,
        firstNumericB, lastNumericB) {
      return this.getDiffFieldValue_(firstNumericA, lastNumericA) -
          this.getDiffFieldValue_(firstNumericB, lastNumericB);
    },

    getDiffField_: function(firstNumeric, lastNumeric) {
      var definedNumeric = firstNumeric || lastNumeric;
      return new tr.v.ScalarNumeric(definedNumeric.unit.correspondingDeltaUnit,
          this.getDiffFieldValue_(firstNumeric, lastNumeric));
    },

    getDiffFieldValue_: function(firstNumeric, lastNumeric) {
      var firstValue = firstNumeric === undefined ? 0 : firstNumeric.value;
      var lastValue = lastNumeric === undefined ? 0 : lastNumeric.value;
      var diff = lastValue - firstValue;
      return Math.abs(diff) < NumericMemoryColumn.DIFF_EPSILON ? 0 : diff;
    }
  };

  /**
   * @constructor
   */
  function MemoryCell(fields) {
    this.fields = fields;
  }

  MemoryCell.extractFields = function(cell) {
    if (cell === undefined)
      return undefined;
    return cell.fields;
  };

  /** Limit for the number of sub-rows for recursive table row expansion. */
  var RECURSIVE_EXPANSION_MAX_VISIBLE_ROW_COUNT = 10;

  function expandTableRowsRecursively(table) {
    var currentLevelRows = table.tableRows;
    var totalVisibleRowCount = currentLevelRows.length;

    while (currentLevelRows.length > 0) {
      // Calculate the total number of sub-rows on the current level.
      var nextLevelRowCount = 0;
      currentLevelRows.forEach(function(currentLevelRow) {
        var subRows = currentLevelRow.subRows;
        if (subRows === undefined || subRows.length === 0)
          return;
        nextLevelRowCount += subRows.length;
      });

      // Determine whether expanding all rows on the current level would cause
      // the total number of visible rows go over the limit.
      if (totalVisibleRowCount + nextLevelRowCount >
          RECURSIVE_EXPANSION_MAX_VISIBLE_ROW_COUNT) {
        break;
      }

      // Expand all rows on the current level and gather their sub-rows.
      var nextLevelRows = new Array(nextLevelRowCount);
      var nextLevelRowIndex = 0;
      currentLevelRows.forEach(function(currentLevelRow) {
        var subRows = currentLevelRow.subRows;
        if (subRows === undefined || subRows.length === 0)
          return;
        table.setExpandedForTableRow(currentLevelRow, true);
        subRows.forEach(function(subRow) {
          nextLevelRows[nextLevelRowIndex++] = subRow;
        });
      });

      // Update the total number of visible rows and progress to the next level.
      totalVisibleRowCount += nextLevelRowCount;
      currentLevelRows = nextLevelRows;
    }
  }

  function aggregateTableRowCellsRecursively(row, columns, opt_predicate) {
    var subRows = row.subRows;
    if (subRows === undefined || subRows.length === 0)
      return;

    subRows.forEach(function(subRow) {
      aggregateTableRowCellsRecursively(subRow, columns, opt_predicate);
    });

    if (opt_predicate === undefined || opt_predicate(row.contexts))
      aggregateTableRowCells(row, subRows, columns);
  }

  function aggregateTableRowCells(row, subRows, columns) {
    columns.forEach(function(column) {
      if (!(column instanceof MemoryColumn))
        return;
      column.aggregateCells(row, subRows);
    });
  }

  function createCells(timeToValues, valueFieldsGetter, opt_this) {
    opt_this = opt_this || this;
    var fieldNameToFields = tr.b.invertArrayOfDicts(
        timeToValues, valueFieldsGetter, opt_this);
    return tr.b.mapItems(fieldNameToFields, function(fieldName, fields) {
      return new tr.ui.analysis.MemoryCell(fields);
    });
  }

  function createWarningInfo(message) {
    return {
      message: message,
      icon: String.fromCharCode(9888),
      color: 'red'
    };
  }

  // TODO(petrcermak): Use a context manager instead
  // (https://github.com/catapult-project/catapult/issues/2420).
  function DetailsNumericMemoryColumn(name, cellPath, aggregationMode) {
    NumericMemoryColumn.call(this, name, cellPath, aggregationMode);
  }

  DetailsNumericMemoryColumn.prototype = {
    __proto__: NumericMemoryColumn.prototype,

    getFormattingContext: function(unit) {
      if (unit.baseUnit === tr.b.Unit.byName.sizeInBytes)
        return { unitPrefix: tr.b.UnitScale.Binary.KIBI };
      return undefined;
    }
  };

  return {
    TitleColumn: TitleColumn,
    MemoryColumn: MemoryColumn,
    StringMemoryColumn: StringMemoryColumn,
    NumericMemoryColumn: NumericMemoryColumn,
    MemoryCell: MemoryCell,
    expandTableRowsRecursively: expandTableRowsRecursively,
    aggregateTableRowCellsRecursively: aggregateTableRowCellsRecursively,
    aggregateTableRowCells: aggregateTableRowCells,
    createCells: createCells,
    createWarningInfo: createWarningInfo,
    DetailsNumericMemoryColumn: DetailsNumericMemoryColumn
  };
});
</script>
