internal TableViewPageResult Generate( IEnumerable<LayoutedContainerInfo> layoutedContainers, TableViewPage lastGeneratedPage )
      {
        m_generator = m_itemsHost.CustomItemContainerGenerator;
        Debug.Assert( m_generator != null );

        m_generator.IsRecyclingEnabled = true;

        m_itemCount = m_generator.ItemCount;
        m_focusedContainer = DataGridItemsHost.GetItemsHostContainerFromElement( m_itemsHost, Keyboard.FocusedElement as DependencyObject );

        var lastGeneratedPageSize = lastGeneratedPage.OuterPage.Length;
        m_oldLayoutedContainers = new Dictionary<UIElement, int>( lastGeneratedPageSize );
        m_newLayoutedContainers = null;

        // Figure out the realized index of all currently layouted containers.
        foreach( var container in layoutedContainers.Select( item => item.Container ) )
        {
          var newRealizedIndex = m_generator.GetRealizedIndexForContainer( container );

          if( ( newRealizedIndex >= 0 ) || ( container == m_focusedContainer ) )
          {
            m_oldLayoutedContainers.Add( container, newRealizedIndex );
          }
          // The container is lost, recycle it.
          else
          {
            m_itemsHost.RecycleContainer( m_generator, new LayoutedContainerInfo( newRealizedIndex, container ) );
          }
        }

        TableViewPageResult result;

        if( m_itemCount > 0 )
        {
          m_newLayoutedContainers = new List<LayoutedContainerInfo>( lastGeneratedPageSize );

          var extendedHeight = Math.Max( m_availableHeight, lastGeneratedPage.ViewportHeight );

          this.PrepareRecycleCandidates( extendedHeight );

          var dataGridContext = DataGridControl.GetDataGridContext( m_itemsHost );
          var fillLastPage = ( dataGridContext != null ) && TableView.GetAutoFillLastPage( dataGridContext );
          var pageInfo = this.GenerateContainers( m_startIndex, m_itemCount, m_availableHeight, extendedHeight, fillLastPage );

          // Keep the focused container active by putting it in the layouted containers collection.
          if( m_focusedContainer != null )
          {
            int newRealizedIndex;
            if( m_oldLayoutedContainers.TryGetValue( m_focusedContainer, out newRealizedIndex ) )
            {
              m_oldLayoutedContainers.Remove( m_focusedContainer );
              m_newLayoutedContainers.Add( new LayoutedContainerInfo( newRealizedIndex, m_focusedContainer ) );
            }
          }

          result = new TableViewPageResult( pageInfo, m_newLayoutedContainers );
        }
        else
        {
          result = new TableViewPageResult( TableViewPage.Empty, Enumerable.Empty<LayoutedContainerInfo>() );
        }

        // Recycle the containers that have not been reused.
        foreach( var entry in m_oldLayoutedContainers )
        {
          m_itemsHost.RecycleContainer( m_generator, new LayoutedContainerInfo( entry.Value, entry.Key ) );
        }

        return result;
      }
    private Size GetNewDesiredSize( TableViewPage pageInfo )
    {
      double desiredHeight;
      double availableHeight = m_lastMeasureAvailableSize.Height;

      if( pageInfo == TableViewPage.Empty )
      {
        desiredHeight = 0d;
      }
      // The current generated page displays only a subset of the data source. 
      else if( pageInfo.InnerPage.Length < this.ScrollInfo.ExtentHeight )
      {
        if( double.IsPositiveInfinity( availableHeight ) )
        {
          desiredHeight = pageInfo.InnerPage.Size;
        }
        else
        {
          desiredHeight = availableHeight;
        }
      }
      // The current generated page displays all containers.
      else
      {
        var pageHeight = pageInfo.OuterPage.Size;

        if( double.IsPositiveInfinity( availableHeight ) )
        {
          desiredHeight = pageHeight;
        }
        else
        {
          desiredHeight = Math.Min( availableHeight, pageHeight );
        }
      }

      return new Size( m_viewportWidth, desiredHeight );
    }
      internal TableViewPageResult( TableViewPage pageInfo, IEnumerable<LayoutedContainerInfo> layoutedContainers )
      {
        if( pageInfo == null )
          throw new ArgumentNullException( "pageInfo" );

        if( layoutedContainers == null )
          throw new ArgumentNullException( "layoutedContainers" );

        m_pageInfo = pageInfo;
        m_layoutedContainers = layoutedContainers;
      }