whole_func_string: function _layout(size, scrollOffset, nested) {
  
          // Track the number of times the layout-function was executed
          this._debug.layoutCount++;
          //_log.call(this, 'Layout, scrollOffset: ', scrollOffset, ', particle: ', this._scroll.particle.getPosition1D());
  
          // Determine start & end
          var scrollStart = 0 - Math.max(this.options.extraBoundsSpace[0], 1);
          var scrollEnd = size[this._direction] + Math.max(this.options.extraBoundsSpace[1], 1);
          if (this.options.paginated && (this.options.paginationMode === PaginationMode.PAGE)) {
              scrollStart = scrollOffset - this.options.extraBoundsSpace[0];
              scrollEnd = scrollOffset + size[this._direction] + this.options.extraBoundsSpace[1];
              if ((scrollOffset + size[this._direction]) < 0) {
                  scrollStart += size[this._direction];
                  scrollEnd += size[this._direction];
              }
              else if ((scrollOffset - size[this._direction]) > 0) {
                  scrollStart -= size[this._direction];
                  scrollEnd -= size[this._direction];
              }
          }
          if (this.options.layoutAll) {
              scrollStart = -1000000;
              scrollEnd = 1000000;
          }
  
          // Prepare for layout
          var layoutContext = this._nodes.prepareForLayout(
              this._viewSequence,     // first node to layout
              this._nodesById, {      // so we can do fast id lookups
                  size: size,
                  direction: this._direction,
                  reverse: this.options.alignment ? true : false,
                  scrollOffset: this.options.alignment ? (scrollOffset + size[this._direction]) : scrollOffset,
                  scrollStart: scrollStart,
                  scrollEnd: scrollEnd
              }
          );
  
          // Layout objects
          if (this._layout._function) {
              this._layout._function(
                  layoutContext,          // context which the layout-function can use
                  this._layout.options    // additional layout-options
              );
          }
          this._scroll.unnormalizedScrollOffset = scrollOffset;
  
          // Call post-layout function
          if (this._postLayout) {
              this._postLayout(size, scrollOffset);
          }
  
          // Mark non-invalidated nodes for removal
          this._nodes.removeNonInvalidatedNodes(this.options.flowOptions.removeSpec);
  
          // Check whether the bounds have been reached
          //var oldBoundsReached = this._scroll.boundsReached;
          _calcBounds.call(this, size, scrollOffset);
          //if (oldBoundsReached !== this._scroll.boundsReached) {
          //    _log.call(this, 'bounds reached changed (', oldBoundsReached, ' != ', this._scroll.boundsReached, ')');
          //}
  
          // Update scroll-to spring
          _calcScrollToOffset.call(this, size, scrollOffset);
  
          // When pagination is enabled, snap to page
          _snapToPage.call(this);
  
          // If the bounds have changed, and the scroll-offset would be different
          // than before, then re-layout entirely using the new offset.
          var newScrollOffset = _calcScrollOffset.call(this, true);
          if (!nested && (newScrollOffset !== scrollOffset)) {
              //_log.call(this, 'offset changed, re-layouting... (', scrollOffset, ' != ', newScrollOffset, ')');
              return _layout.call(this, size, newScrollOffset, true);
          }
  
          // Normalize scroll offset so that the current viewsequence node is as close to the
          // top as possible and the layout function will need to process the least amount
          // of renderables.
          scrollOffset = _normalizeViewSequence.call(this, size, scrollOffset);
  
          // Update spring
          _updateSpring.call(this);
  
          // Cleanup any nodes in case of a VirtualViewSequence
          this._nodes.removeVirtualViewSequenceNodes();
  
          // Calculate scroll-length and use that as the true-size (height)
          if (this.options.size && (this.options.size[this._direction] === true)) {
              var scrollLength = 0;
              var node = this._nodes.getStartEnumNode();
              while (node) {
                  if (node._invalidated && node.scrollLength) {
                      scrollLength += node.scrollLength;
                  }
                  node = node._next;
              }
              this._size = this._size || [0, 0];
              this._size[0] = this.options.size[0];
              this._size[1] = this.options.size[1];
              this._size[this._direction] = scrollLength;
          }
  
          return scrollOffset;
      }
func_code_string: function _layout(size, scrollOffset, nested) {
  
          // Track the number of times the layout-function was executed
          this._debug.layoutCount++;
          //_log.call(this, 'Layout, scrollOffset: ', scrollOffset, ', particle: ', this._scroll.particle.getPosition1D());
  
          // Determine start & end
          var scrollStart = 0 - Math.max(this.options.extraBoundsSpace[0], 1);
          var scrollEnd = size[this._direction] + Math.max(this.options.extraBoundsSpace[1], 1);
          if (this.options.paginated && (this.options.paginationMode === PaginationMode.PAGE)) {
              scrollStart = scrollOffset - this.options.extraBoundsSpace[0];
              scrollEnd = scrollOffset + size[this._direction] + this.options.extraBoundsSpace[1];
              if ((scrollOffset + size[this._direction]) < 0) {
                  scrollStart += size[this._direction];
                  scrollEnd += size[this._direction];
              }
              else if ((scrollOffset - size[this._direction]) > 0) {
                  scrollStart -= size[this._direction];
                  scrollEnd -= size[this._direction];
              }
          }
          if (this.options.layoutAll) {
              scrollStart = -1000000;
              scrollEnd = 1000000;
          }
  
          // Prepare for layout
          var layoutContext = this._nodes.prepareForLayout(
              this._viewSequence,     // first node to layout
              this._nodesById, {      // so we can do fast id lookups
                  size: size,
                  direction: this._direction,
                  reverse: this.options.alignment ? true : false,
                  scrollOffset: this.options.alignment ? (scrollOffset + size[this._direction]) : scrollOffset,
                  scrollStart: scrollStart,
                  scrollEnd: scrollEnd
              }
          );
  
          // Layout objects
          if (this._layout._function) {
              this._layout._function(
                  layoutContext,          // context which the layout-function can use
                  this._layout.options    // additional layout-options
              );
          }
          this._scroll.unnormalizedScrollOffset = scrollOffset;
  
          // Call post-layout function
          if (this._postLayout) {
              this._postLayout(size, scrollOffset);
          }
  
          // Mark non-invalidated nodes for removal
          this._nodes.removeNonInvalidatedNodes(this.options.flowOptions.removeSpec);
  
          // Check whether the bounds have been reached
          //var oldBoundsReached = this._scroll.boundsReached;
          _calcBounds.call(this, size, scrollOffset);
          //if (oldBoundsReached !== this._scroll.boundsReached) {
          //    _log.call(this, 'bounds reached changed (', oldBoundsReached, ' != ', this._scroll.boundsReached, ')');
          //}
  
          // Update scroll-to spring
          _calcScrollToOffset.call(this, size, scrollOffset);
  
          // When pagination is enabled, snap to page
          _snapToPage.call(this);
  
          // If the bounds have changed, and the scroll-offset would be different
          // than before, then re-layout entirely using the new offset.
          var newScrollOffset = _calcScrollOffset.call(this, true);
          if (!nested && (newScrollOffset !== scrollOffset)) {
              //_log.call(this, 'offset changed, re-layouting... (', scrollOffset, ' != ', newScrollOffset, ')');
              return _layout.call(this, size, newScrollOffset, true);
          }
  
          // Normalize scroll offset so that the current viewsequence node is as close to the
          // top as possible and the layout function will need to process the least amount
          // of renderables.
          scrollOffset = _normalizeViewSequence.call(this, size, scrollOffset);
  
          // Update spring
          _updateSpring.call(this);
  
          // Cleanup any nodes in case of a VirtualViewSequence
          this._nodes.removeVirtualViewSequenceNodes();
  
          // Calculate scroll-length and use that as the true-size (height)
          if (this.options.size && (this.options.size[this._direction] === true)) {
              var scrollLength = 0;
              var node = this._nodes.getStartEnumNode();
              while (node) {
                  if (node._invalidated && node.scrollLength) {
                      scrollLength += node.scrollLength;
                  }
                  node = node._next;
              }
              this._size = this._size || [0, 0];
              this._size[0] = this.options.size[0];
              this._size[1] = this.options.size[1];
              this._size[this._direction] = scrollLength;
          }
  
          return scrollOffset;
      }
func_documentation_string: Executes the layout and updates the state of the scrollview.