docs: function(sortedInputEvents) {
        var protoIRs = [];
        var currentPIR = undefined;
  
        function isRendererFling(event) {
          return event.title === RENDERER_FLING_TITLE;
        }
        var browserHelper = this.modelHelper.browserHelper;
        var flingEvents = browserHelper.getAllAsyncSlicesMatching(
            isRendererFling);
  
        forEventTypesIn(sortedInputEvents, FLING_TYPE_NAMES, function(event) {
          flingEvents.push(event);
        });
        flingEvents.sort(compareEvents);
  
        flingEvents.forEach(function(event) {
          if (event.title === RENDERER_FLING_TITLE) {
            if (currentPIR) {
              currentPIR.pushEvent(event);
            } else {
              currentPIR = new ProtoIR(ProtoIR.ANIMATION_TYPE, FLING_IR_NAME);
              currentPIR.pushEvent(event);
              protoIRs.push(currentPIR);
            }
            return;
          }
  
          switch (event.typeName) {
            case INPUT_TYPE.FLING_START:
              if (currentPIR) {
                console.error('Another FlingStart? File a bug with this trace!');
                currentPIR.pushEvent(event);
              } else {
                currentPIR = new ProtoIR(ProtoIR.ANIMATION_TYPE, FLING_IR_NAME);
                currentPIR.pushEvent(event);
                // Set end to an invalid value so that it can be noticed and fixed
                // later.
                currentPIR.end = 0;
                protoIRs.push(currentPIR);
              }
              break;
  
            case INPUT_TYPE.FLING_CANCEL:
              if (currentPIR) {
                currentPIR.pushEvent(event);
                // FlingCancel events start when TouchStart events start, which is
                // typically when a Response starts. FlingCancel events end when
                // chrome acknowledges them, not when they update the screen. So
                // there might be one more frame during the FlingCancel, after
                // this Animation ends. That won't affect the scoring algorithms,
                // and it will make the IRs look more correct if they don't
                // overlap unnecessarily.
                currentPIR.end = event.start;
                currentPIR = undefined;
              } else {
                var pir = new ProtoIR(ProtoIR.IGNORED_TYPE);
                pir.pushEvent(event);
                protoIRs.push(pir);
              }
              break;
          }
        });
        // If there was neither a FLING_CANCEL nor a renderer fling after the
        // FLING_START, then assume that it ends at the end of the model, so set
        // the end of currentPIR to the end of the model.
        if (currentPIR && !currentPIR.end)
          currentPIR.end = this.model.bounds.max;
        return protoIRs;
      }