+}
+
+// wxWindow's GetBestVirtualSize returns the actual window size,
+// whereas we want to return the virtual size
+wxSize wxScrollHelper::ScrollGetBestVirtualSize() const
+{
+    wxSize clientSize(m_win->GetClientSize());
+    if ( m_win->GetSizer() )
+        clientSize.IncTo(m_win->GetSizer()->CalcMin());
+
+    return clientSize;
+}
+
+// return the window best size from the given best virtual size
+wxSize
+wxScrollHelper::ScrollGetWindowSizeForVirtualSize(const wxSize& size) const
+{
+    // Only use the content to set the window size in the direction
+    // where there's no scrolling; otherwise we're going to get a huge
+    // window in the direction in which scrolling is enabled
+    int ppuX, ppuY;
+    GetScrollPixelsPerUnit(&ppuX, &ppuY);
+
+    wxSize minSize = m_win->GetMinSize();
+    if ( !minSize.IsFullySpecified() )
+        minSize = m_win->GetSize();
+
+    wxSize best(size);
+    if (ppuX > 0)
+        best.x = minSize.x;
+    if (ppuY > 0)
+        best.y = minSize.y;
+
+    return best;
+}
+
+// ----------------------------------------------------------------------------
+// event handlers
+// ----------------------------------------------------------------------------
+
+// Default OnSize resets scrollbars, if any
+void wxScrollHelper::HandleOnSize(wxSizeEvent& WXUNUSED(event))
+{
+    if ( m_targetWindow->GetAutoLayout() )
+    {
+        wxSize size = m_targetWindow->GetBestVirtualSize();
+
+        // This will call ::Layout() and ::AdjustScrollbars()
+        m_win->SetVirtualSize( size );
+    }
+    else
+    {
+        AdjustScrollbars();
+    }