class ScrollController implements TerminalScrollController {
        private int scrollValue;

        @Override
        public void updateModel(final int totalSize, final int screenHeight) {<FILL_FUNCTION_BODY>}

        @Override
        public int getScrollingOffset() {
            return scrollValue;
        }
    }

            if(!EventQueue.isDispatchThread()) {
                EventQueue.invokeLater(() -> updateModel(totalSize, screenHeight));
                return;
            }
            try {
                scrollModelUpdateBySystem = true;
                int value = scrollBar.getValue();
                int maximum = scrollBar.getMaximum();
                int visibleAmount = scrollBar.getVisibleAmount();

                if(maximum != totalSize) {
                    int lastMaximum = maximum;
                    maximum = totalSize > screenHeight ? totalSize : screenHeight;
                    if(lastMaximum < maximum &&
                            lastMaximum - visibleAmount - value == 0) {
                        value = scrollBar.getValue() + (maximum - lastMaximum);
                    }
                }
                if(value + screenHeight > maximum) {
                    value = maximum - screenHeight;
                }
                if(visibleAmount != screenHeight) {
                    if(visibleAmount > screenHeight) {
                        value += visibleAmount - screenHeight;
                    }
                    visibleAmount = screenHeight;
                }
                if(value > maximum - visibleAmount) {
                    value = maximum - visibleAmount;
                }
                if(value < 0) {
                    value = 0;
                }

                this.scrollValue = value;

                if(scrollBar.getMaximum() != maximum) {
                    scrollBar.setMaximum(maximum);
                }
                if(scrollBar.getVisibleAmount() != visibleAmount) {
                    scrollBar.setVisibleAmount(visibleAmount);
                }
                if(scrollBar.getValue() != value) {
                    scrollBar.setValue(value);
                }
            }
            finally {
                scrollModelUpdateBySystem = false;
            }
        
<methods>public void <init>() ,public java.awt.Component add(java.awt.Component) ,public java.awt.Component add(java.lang.String, java.awt.Component) ,public java.awt.Component add(java.awt.Component, int) ,public void add(java.awt.Component, java.lang.Object) ,public void add(java.awt.Component, java.lang.Object, int) ,public synchronized void addContainerListener(java.awt.event.ContainerListener) ,public void addNotify() ,public void addPropertyChangeListener(java.beans.PropertyChangeListener) ,public void addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener) ,public void applyComponentOrientation(java.awt.ComponentOrientation) ,public boolean areFocusTraversalKeysSet(int) ,public int countComponents() ,public void deliverEvent(java.awt.Event) ,public void doLayout() ,public java.awt.Component findComponentAt(java.awt.Point) ,public java.awt.Component findComponentAt(int, int) ,public float getAlignmentX() ,public float getAlignmentY() ,public java.awt.Component getComponent(int) ,public java.awt.Component getComponentAt(java.awt.Point) ,public java.awt.Component getComponentAt(int, int) ,public int getComponentCount() ,public int getComponentZOrder(java.awt.Component) ,public java.awt.Component[] getComponents() ,public synchronized java.awt.event.ContainerListener[] getContainerListeners() ,public Set<java.awt.AWTKeyStroke> getFocusTraversalKeys(int) ,public java.awt.FocusTraversalPolicy getFocusTraversalPolicy() ,public java.awt.Insets getInsets() ,public java.awt.LayoutManager getLayout() ,public T[] getListeners(Class<T>) ,public java.awt.Dimension getMaximumSize() ,public java.awt.Dimension getMinimumSize() ,public java.awt.Point getMousePosition(boolean) throws java.awt.HeadlessException,public java.awt.Dimension getPreferredSize() ,public java.awt.Insets insets() ,public void invalidate() ,public boolean isAncestorOf(java.awt.Component) ,public boolean isFocusCycleRoot() ,public boolean isFocusCycleRoot(java.awt.Container) ,public final boolean isFocusTraversalPolicyProvider() ,public boolean isFocusTraversalPolicySet() ,public boolean isValidateRoot() ,public void layout() ,public void list(java.io.PrintStream, int) ,public void list(java.io.PrintWriter, int) ,public java.awt.Component locate(int, int) ,public java.awt.Dimension minimumSize() ,public void paint(java.awt.Graphics) ,public void paintComponents(java.awt.Graphics) ,public java.awt.Dimension preferredSize() ,public void print(java.awt.Graphics) ,public void printComponents(java.awt.Graphics) ,public void remove(int) ,public void remove(java.awt.Component) ,public void removeAll() ,public synchronized void removeContainerListener(java.awt.event.ContainerListener) ,public void removeNotify() ,public void setComponentZOrder(java.awt.Component, int) ,public void setFocusCycleRoot(boolean) ,public void setFocusTraversalKeys(int, Set<? extends java.awt.AWTKeyStroke>) ,public void setFocusTraversalPolicy(java.awt.FocusTraversalPolicy) ,public final void setFocusTraversalPolicyProvider(boolean) ,public void setFont(java.awt.Font) ,public void setLayout(java.awt.LayoutManager) ,public void transferFocusDownCycle() ,public void update(java.awt.Graphics) ,public void validate() <variables>private static final java.awt.Component[] EMPTY_ARRAY,static final boolean INCLUDE_SELF,static final boolean SEARCH_HEAVYWEIGHTS,private List<java.awt.Component> component,transient java.awt.event.ContainerListener containerListener,private int containerSerializedDataVersion,private static boolean descendUnconditionallyWhenValidating,transient int descendantsCount,private java.awt.LightweightDispatcher dispatcher,private static final sun.util.logging.PlatformLogger eventLog,private boolean focusCycleRoot,private transient java.awt.FocusTraversalPolicy focusTraversalPolicy,private boolean focusTraversalPolicyProvider,private static final boolean isJavaAwtSmartInvalidate,java.awt.LayoutManager layoutMgr,transient int listeningBoundsChildren,transient int listeningChildren,private static final sun.util.logging.PlatformLogger log,private static final sun.util.logging.PlatformLogger mixingLog,transient sun.awt.AppContext modalAppContext,transient java.awt.Component modalComp,private transient int numOfHWComponents,private transient int numOfLWComponents,transient java.awt.Color preserveBackgroundColor,private transient boolean printing,private transient Set<java.lang.Thread> printingThreads,private static final java.io.ObjectStreamField[] serialPersistentFields,private static final long serialVersionUID