text: import { isPresent, isBlank, looseIdentical } from 'angular2/src/core/facade/lang';
  import { ListWrapper, Map } from 'angular2/src/core/facade/collection';
  import { RecordType, ProtoRecord } from './proto_record';
  /**
   * Removes "duplicate" records. It assuming that record evaluation does not
   * have side-effects.
   *
   * Records that are not last in bindings are removed and all the indices
   * of the records that depend on them are updated.
   *
   * Records that are last in bindings CANNOT be removed, and instead are
   * replaced with very cheap SELF records.
   */
  export function coalesce(records) {
      var res = [];
      var indexMap = new Map();
      for (var i = 0; i < records.length; ++i) {
          var r = records[i];
          var record = _replaceIndices(r, res.length + 1, indexMap);
          var matchingRecord = _findMatching(record, res);
          if (isPresent(matchingRecord) && record.lastInBinding) {
              res.push(_selfRecord(record, matchingRecord.selfIndex, res.length + 1));
              indexMap.set(r.selfIndex, matchingRecord.selfIndex);
              matchingRecord.referencedBySelf = true;
          }
          else if (isPresent(matchingRecord) && !record.lastInBinding) {
              if (record.argumentToPureFunction) {
                  matchingRecord.argumentToPureFunction = true;
              }
              indexMap.set(r.selfIndex, matchingRecord.selfIndex);
          }
          else {
              res.push(record);
              indexMap.set(r.selfIndex, record.selfIndex);
          }
      }
      return res;
  }
  function _selfRecord(r, contextIndex, selfIndex) {
      return new ProtoRecord(RecordType.Self, "self", null, [], r.fixedArgs, contextIndex, r.directiveIndex, selfIndex, r.bindingRecord, r.lastInBinding, r.lastInDirective, false, false, r.propertyBindingIndex);
  }
  function _findMatching(r, rs) {
      return ListWrapper.find(rs, (rr) => rr.mode !== RecordType.DirectiveLifecycle && _sameDirIndex(rr, r) &&
          rr.mode === r.mode && looseIdentical(rr.funcOrValue, r.funcOrValue) &&
          rr.contextIndex === r.contextIndex && looseIdentical(rr.name, r.name) &&
          ListWrapper.equals(rr.args, r.args));
  }
  function _sameDirIndex(a, b) {
      var di1 = isBlank(a.directiveIndex) ? null : a.directiveIndex.directiveIndex;
      var ei1 = isBlank(a.directiveIndex) ? null : a.directiveIndex.elementIndex;
      var di2 = isBlank(b.directiveIndex) ? null : b.directiveIndex.directiveIndex;
      var ei2 = isBlank(b.directiveIndex) ? null : b.directiveIndex.elementIndex;
      return di1 === di2 && ei1 === ei2;
  }
  function _replaceIndices(r, selfIndex, indexMap) {
      var args = ListWrapper.map(r.args, (a) => _map(indexMap, a));
      var contextIndex = _map(indexMap, r.contextIndex);
      return new ProtoRecord(r.mode, r.name, r.funcOrValue, args, r.fixedArgs, contextIndex, r.directiveIndex, selfIndex, r.bindingRecord, r.lastInBinding, r.lastInDirective, r.argumentToPureFunction, r.referencedBySelf, r.propertyBindingIndex);
  }
  function _map(indexMap, value) {
      var r = indexMap.get(value);
      return isPresent(r) ? r : value;
  }
  //# sourceMappingURL=coalesce.js.map