text:
package org.vash.vate.server;

import java.awt.Toolkit;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
// import java.security.Security;
// import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;

import javax.imageio.ImageIO;
import javax.sound.sampled.AudioFormat;

import org.vash.vate.VT;
import org.vash.vate.audio.VTAudioSystem;
import org.vash.vate.console.VTConsole;
import org.vash.vate.exception.VTUncaughtExceptionHandler;
import org.vash.vate.graphics.message.VTTrayIconInterface;
import org.vash.vate.help.VTHelpManager;
import org.vash.vate.nativeutils.VTNativeUtils;
import org.vash.vate.network.ssl.SSLVerificationDisabler;
import org.vash.vate.parser.VTArgumentParser;
import org.vash.vate.parser.VTConfigurationProperties;
import org.vash.vate.parser.VTPropertiesBuilder;
import org.vash.vate.security.VTBlake3Digest;
import org.vash.vate.server.connection.VTServerConnector;
import org.vash.vate.server.console.local.VTServerLocalConsoleReader;
import org.vash.vate.server.console.local.VTServerLocalGraphicalConsoleMenuBar;
import org.vash.vate.server.dialog.VTServerSettingsDialog;
import org.vash.vate.server.session.VTServerSessionListener;

public class VTServer implements Runnable
{
  private boolean passive = true;
  private String hostAddress = "";
  private Integer hostPort = null;
  private Integer natPort = null;
  private String proxyType = "None";
  private String proxyAddress = "";
  private Integer proxyPort = null;
  private boolean useProxyAuthentication = false;
  private String proxyUser = "";
  private String proxyPassword = "";
  private String encryptionType = "None";
  private byte[] encryptionKey = new byte[] {};
  private boolean daemon = false;
  private String sessionUsers = "";
  private int sessionsMaximum = 0;
  private String sessionShell = "";
  private final String vtURL = System.getenv("VT_PATH");
  //private MessageDigest sha256Digester;
  private VTBlake3Digest blake3Digester = new VTBlake3Digest();
  // private File userDatabaseFile;
  private File serverSettingsFile;
  private final Map<byte[], Credential> userCredentials = new LinkedHashMap<byte[], Credential>();
  // private Properties fileUserCredentials;
  // private Properties argumentsServerSettings = new Properties();
  private VTConfigurationProperties fileServerSettings;
  private final Runtime runtime = Runtime.getRuntime();
  // private Thread consoleThread;
  private InputStream userCredentialsReader;
  private InputStream serverSettingsReader;
  private VTServerConnector serverConnector;
  private VTServerLocalConsoleReader consoleReader;
  private VTServerLocalGraphicalConsoleMenuBar inputMenuBar;
  private VTAudioSystem[] audioSystem;
  private VTServerSettingsDialog connectionDialog;
  private ExecutorService threads;
  private VTTrayIconInterface trayIconInterface;
  private volatile boolean skipConfiguration;
  private volatile boolean echoCommands = false;
  private volatile boolean running = true;
  private volatile boolean reconfigure = false;
  private List<VTServerSessionListener> listeners = new LinkedList<VTServerSessionListener>();
  private static final String VT_SERVER_SETTINGS_COMMENTS =
  "Variable-Terminal server settings file, supports UTF-8\r\n" +
  "#vate.server.connection.mode      values: default passive(P), active(A)\r\n" +
  "#vate.server.proxy.type           values: default none, HTTP(H), SOCKS(S)\r\n" +
  "#vate.server.proxy.authentication values: default disabled(D), enabled(E)\r\n" +
  "#vate.server.encryption.type      values: default none/RC4(R)/AES(A)/ISAAC(I)/SALSA(S)/HC256(H)/GRAIN(G)\r\n" +
  "#vate.server.session.users        format: user1/password1;user2/password2;...";

  static
  {
    ImageIO.setUseCache(false);
    VTHelpManager.initialize();
    SSLVerificationDisabler.install();
    //com.github.luben.zstd.util.Native.load();
  }

  public class Credential
  {
    public String user;
    public String password;

    public Credential(String user, String password)
    {
      this.user = user;
      this.password = password;
    }
  }

  public VTServer()
  {
    // VTServerLocalConsoleCommandSelector.initialize();
    // VTServerRemoteConsoleCommandSelector.initialize();
    //try
    //{
      //sha256Digester = MessageDigest.getInstance("SHA-256");
    //}
    //catch (NoSuchAlgorithmException e)
    //{
      // e.printStackTrace();
    //}
    this.threads = Executors.newCachedThreadPool(new ThreadFactory()
    {
      public Thread newThread(Runnable r)
      {
        Thread created = new Thread(null, r, r.getClass().getSimpleName());
        created.setDaemon(true);
        return created;
      }
    });
    this.audioSystem = new VTAudioSystem[5];
    this.audioSystem[0] = new VTAudioSystem(threads);
    this.audioSystem[1] = new VTAudioSystem(threads);
    this.audioSystem[2] = new VTAudioSystem(threads);
    this.audioSystem[3] = new VTAudioSystem(threads);
    this.audioSystem[4] = new VTAudioSystem(threads);
    try
    {
      Toolkit.getDefaultToolkit().setDynamicLayout(false);
    }
    catch (Throwable t)
    {

    }
    loadServerSettingsFile();
  }

  public void stop()
  {
    try
    {
      running = false;
      if (trayIconInterface != null)
      {
        trayIconInterface.removeTrayIcon();
      }
      serverConnector.stop();
      threads.shutdownNow();
    }
    catch (Throwable t)
    {
      //t.printStackTrace();
    }
  }

  public boolean isRunning()
  {
    return running;
  }

  public ExecutorService getServerThreads()
  {
    return threads;
  }

  public void setSkipConfiguration(boolean skipConfiguration)
  {
    this.skipConfiguration = skipConfiguration;
  }

  public VTAudioSystem getAudioSystem(AudioFormat format)
  {
    if (format.getSampleRate() == VT.VT_AUDIO_FORMAT_8000.getSampleRate())
    {
      return this.audioSystem[0];
    }
    if (format.getSampleRate() == VT.VT_AUDIO_FORMAT_16000.getSampleRate())
    {
      return this.audioSystem[1];
    }
    if (format.getSampleRate() == VT.VT_AUDIO_FORMAT_48000.getSampleRate())
    {
      return this.audioSystem[2];
    }
    if (format.getSampleRate() == VT.VT_AUDIO_FORMAT_24000.getSampleRate())
    {
      return this.audioSystem[3];
    }
    if (format.getSampleRate() == VT.VT_AUDIO_FORMAT_32000.getSampleRate())
    {
      return this.audioSystem[4];
    }

    return null;
  }

  public Runtime getRuntime()
  {
    return runtime;
  }

  public Map<byte[], Credential> getUserCredentials()
  {
    return userCredentials;
  }

  public VTServerConnector getServerConnector()
  {
    return serverConnector;
  }

  public void setPassive(boolean passive)
  {
    this.passive = passive;
  }

  public void setDaemon(boolean daemon)
  {
    this.daemon = daemon;
    if (daemon && hostPort == null)
    {
      hostPort = 6060;
    }
    VTConsole.setDaemon(daemon);
  }

  public void setSessionsMaximum(int sessionsMaximum)
  {
    this.sessionsMaximum = sessionsMaximum;
  }

  public void setAddress(String address)
  {
    this.hostAddress = address;
  }

  public void setPort(Integer port)
  {
    if (port != null && (port < 1 || port > 65535))
    {
      return;
    }
    this.hostPort = port;
  }

  public void setProxyType(String proxyType)
  {
    this.proxyType = proxyType;
  }

  public void setProxyAddress(String proxyAddress)
  {
    this.proxyAddress = proxyAddress;
  }

  public void setProxyPort(Integer proxyPort)
  {
    if (proxyPort != null && (proxyPort < 1 || proxyPort > 65535))
    {
      return;
    }
    this.proxyPort = proxyPort;
  }

  public void setUseProxyAuthentication(boolean useProxyAuthentication)
  {
    this.useProxyAuthentication = useProxyAuthentication;
  }

  public void setProxyUser(String proxyUser)
  {
    this.proxyUser = proxyUser;
  }

  public void setProxyPassword(String proxyPassword)
  {
    this.proxyPassword = proxyPassword;
  }

  public void setEncryptionType(String encryptionType)
  {
    this.encryptionType = encryptionType;
  }

  public void setEncryptionKey(byte[] encryptionKey)
  {
    this.encryptionKey = encryptionKey;
  }

  public Integer getNatPort()
  {
    return natPort;
  }

  public void setNatPort(Integer natPort)
  {
    if (natPort != null && (natPort < 1 || natPort > 65535))
    {
      return;
    }
    this.natPort = natPort;
  }

  public InputStream getUserCredentialsReader()
  {
    return userCredentialsReader;
  }

  public void setUserCredentialsReader(InputStream userCredentialsReader)
  {
    this.userCredentialsReader = userCredentialsReader;
  }

  public InputStream getServerSettingsReader()
  {
    return serverSettingsReader;
  }

  public void setServerSettingsReader(InputStream serverSettingsReader)
  {
    this.serverSettingsReader = serverSettingsReader;
  }

  public VTServerLocalConsoleReader getConsoleReader()
  {
    return consoleReader;
  }

  public void setConsoleReader(VTServerLocalConsoleReader consoleReader)
  {
    this.consoleReader = consoleReader;
  }

  public boolean isPassive()
  {
    return passive;
  }

  public boolean isDaemon()
  {
    return daemon;
  }

  public int getSessionsMaximum()
  {
    return sessionsMaximum;
  }

  public String getAddress()
  {
    return hostAddress;
  }

  public Integer getPort()
  {
    return hostPort;
  }

  public String getProxyType()
  {
    return proxyType;
  }

  public String getProxyAddress()
  {
    return proxyAddress;
  }

  public Integer getProxyPort()
  {
    return proxyPort;
  }

  public boolean isUseProxyAuthentication()
  {
    return useProxyAuthentication;
  }

  public String getProxyUser()
  {
    return proxyUser;
  }

  public String getProxyPassword()
  {
    return proxyPassword;
  }

  public String getEncryptionType()
  {
    return encryptionType;
  }

  public byte[] getEncryptionKey()
  {
    return encryptionKey;
  }

  public String getVTURL()
  {
    return vtURL;
  }

  public void setServerConnector(VTServerConnector serverConnector)
  {
    this.serverConnector = serverConnector;
  }

  public void setInputMenuBar(VTServerLocalGraphicalConsoleMenuBar inputMenuBar)
  {
    this.inputMenuBar = inputMenuBar;
  }

  public VTServerLocalGraphicalConsoleMenuBar getInputMenuBar()
  {
    return inputMenuBar;
  }

  public void setUniqueUserCredential(String user, String password)
  {
    byte[] credential = new byte[128];
    try
    {
      System.arraycopy(blake3Digester.digest(user.getBytes("UTF-8")), 0, credential, 0, 64);
      System.arraycopy(blake3Digester.digest(password.getBytes("UTF-8")), 0, credential, 64, 64);
      userCredentials.clear();
      userCredentials.put(credential, new Credential(user, password));
    }
    catch (Throwable e)
    {

    }
  }

  public void addUserCredential(String user, String password) throws UnsupportedEncodingException
  {
    byte[] credential = new byte[128];
    System.arraycopy(blake3Digester.digest(user.getBytes("UTF-8")), 0, credential, 0, 64);
    System.arraycopy(blake3Digester.digest(password.getBytes("UTF-8")), 0, credential, 64, 64);
    userCredentials.put(credential, new Credential(user, password));
  }

  public void displayTrayIconMessage(String caption, String text)
  {
    if (trayIconInterface != null)
    {
      trayIconInterface.displayMessage(caption, text);
    }
  }

  public void enableTrayIcon()
  {
    if (trayIconInterface != null)
    {
      trayIconInterface.install(VTConsole.getFrame(), "Variable-Terminal - Server");
    }
  }

  public void disableTrayIcon()
  {
    if (trayIconInterface != null)
    {
      trayIconInterface.removeTrayIcon();
    }
  }

  public void saveServerSettingsFile(String settingsFile) throws Exception
  {
    loadFromConnectorToServer();
    if (vtURL != null)
    {
      serverSettingsFile = new File(vtURL, settingsFile);
      if (!serverSettingsFile.exists())
      {
        serverSettingsFile = new File(settingsFile);
      }
    }
    else
    {
      serverSettingsFile = new File(settingsFile);
    }

    if (fileServerSettings == null)
    {
      fileServerSettings = new VTConfigurationProperties();
    }

    fileServerSettings.clear();
    fileServerSettings.setProperty("vate.server.connection.mode", passive ? "Passive" : "Active");
    fileServerSettings.setProperty("vate.server.connection.port", hostPort != null ? String.valueOf(hostPort) : "");
    fileServerSettings.setProperty("vate.server.connection.host", hostAddress);
    fileServerSettings.setProperty("vate.server.connection.nat.port", natPort != null ? String.valueOf(natPort) : "");
    fileServerSettings.setProperty("vate.server.proxy.type", proxyType);
    fileServerSettings.setProperty("vate.server.proxy.host", proxyAddress);
    fileServerSettings.setProperty("vate.server.proxy.port", proxyPort != null ? String.valueOf(proxyPort) : "");
    fileServerSettings.setProperty("vate.server.proxy.authentication", useProxyAuthentication ? "Enabled" : "Disabled");
    fileServerSettings.setProperty("vate.server.proxy.user", proxyUser);
    fileServerSettings.setProperty("vate.server.proxy.password", proxyPassword);
    fileServerSettings.setProperty("vate.server.encryption.type", encryptionType);
    fileServerSettings.setProperty("vate.server.encryption.password", new String(encryptionKey, "UTF-8"));
    fileServerSettings.setProperty("vate.server.session.shell", sessionShell);
    fileServerSettings.setProperty("vate.server.session.maximum", String.valueOf(sessionsMaximum));
    fileServerSettings.setProperty("vate.server.session.users", sessionUsers);

    FileOutputStream out = new FileOutputStream(settingsFile);
    VTPropertiesBuilder.saveProperties(out, fileServerSettings, VT_SERVER_SETTINGS_COMMENTS, "UTF-8");
    out.flush();
    out.close();
  }

  public void loadServerSettingsFile(String settingsFile) throws Exception
  {
    loadFromConnectorToServer();
    if (vtURL != null)
    {
      serverSettingsFile = new File(vtURL, settingsFile);
      if (!serverSettingsFile.exists())
      {
        serverSettingsFile = new File(settingsFile);
      }
    }
    else
    {
      serverSettingsFile = new File(settingsFile);
    }
    serverSettingsReader = new FileInputStream(serverSettingsFile);
    fileServerSettings = VTPropertiesBuilder.loadProperties(serverSettingsReader, "UTF-8");
    // rawSecuritySettings.load(securitySettingsReader);
    serverSettingsReader.close();

    sessionUsers = fileServerSettings.getProperty("vate.server.session.users", null);

    if (sessionUsers != null)
    {
      try
      {
        String[] users = VTArgumentParser.parseParameter(sessionUsers, ';');
        for (String user : users)
        {
          String[] credentials = VTArgumentParser.parseParameter(user, '/');
          if (credentials.length >= 2)
          {
            addUserCredential(credentials[0], credentials[1]);
          }
        }
      }
      catch (Throwable e)
      {

      }
    }

    if (fileServerSettings.getProperty("vate.server.connection.mode") != null)
    {
      try
      {
        String mode = fileServerSettings.getProperty("vate.server.connection.mode");
        if (mode.toUpperCase().startsWith("A"))
        {
          passive = false;
        }
        else
        {
          passive = true;
        }
      }
      catch (Throwable e)
      {

      }
    }

    if (fileServerSettings.getProperty("vate.server.connection.port") != null)
    {
      try
      {
        int filePort = Integer.parseInt(fileServerSettings.getProperty("vate.server.connection.port"));
        if (filePort > 0 && filePort < 65536)
        {
          hostPort = filePort;
        }
      }
      catch (Throwable e)
      {

      }
    }

    if (fileServerSettings.getProperty("vate.server.connection.host") != null)
    {
      try
      {
        hostAddress = fileServerSettings.getProperty("vate.server.connection.host", hostAddress);
      }
      catch (Throwable e)
      {

      }
    }

    if (fileServerSettings.getProperty("vate.server.connection.nat.port") != null)
    {
      try
      {
        int fileNatPort = Integer.parseInt(fileServerSettings.getProperty("vate.server.connection.nat.port"));
        if (fileNatPort > 0 && fileNatPort < 65536)
        {
          natPort = fileNatPort;
        }
      }
      catch (Throwable e)
      {

      }
    }

    if (fileServerSettings.getProperty("vate.server.encryption.type") != null)
    {
      try
      {
        encryptionType = fileServerSettings.getProperty("vate.server.encryption.type", encryptionType);
      }
      catch (Throwable e)
      {

      }
    }

    if (fileServerSettings.getProperty("vate.server.encryption.password") != null)
    {
      try
      {
        encryptionKey = fileServerSettings.getProperty("vate.server.encryption.password", "").getBytes("UTF-8");
      }
      catch (Throwable e)
      {

      }
    }

    if (fileServerSettings.getProperty("vate.server.proxy.type") != null)
    {
      try
      {
        proxyType = fileServerSettings.getProperty("vate.server.proxy.type", proxyType);
      }
      catch (Throwable e)
      {

      }
    }

    if (fileServerSettings.getProperty("vate.server.proxy.host") != null)
    {
      try
      {
        proxyAddress = fileServerSettings.getProperty("vate.server.proxy.host", proxyAddress);
      }
      catch (Throwable e)
      {

      }
    }

    if (fileServerSettings.getProperty("vate.server.proxy.port") != null)
    {
      try
      {
        int fileProxyPort = Integer.parseInt(fileServerSettings.getProperty("vate.server.proxy.port"));
        if (fileProxyPort > 0 && fileProxyPort < 65536)
        {
          proxyPort = fileProxyPort;
        }
      }
      catch (Throwable e)
      {

      }
    }

    if (fileServerSettings.getProperty("vate.server.proxy.authentication") != null)
    {
      try
      {
        if (fileServerSettings.getProperty("vate.server.proxy.authentication").toUpperCase().startsWith("E"))
        {
          useProxyAuthentication = true;
        }
        else
        {
          useProxyAuthentication = false;
        }
      }
      catch (Throwable e)
      {

      }
    }

    if (fileServerSettings.getProperty("vate.server.proxy.user") != null)
    {
      try
      {
        proxyUser = fileServerSettings.getProperty("vate.server.proxy.user");
      }
      catch (Throwable e)
      {

      }
    }

    if (fileServerSettings.getProperty("vate.server.proxy.password") != null)
    {
      try
      {
        proxyPassword = fileServerSettings.getProperty("vate.server.proxy.password");
      }
      catch (Throwable e)
      {

      }
    }

    if (fileServerSettings.getProperty("vate.server.session.limit") != null)
    {
      try
      {
        int fileSessionsMaximum = Integer.parseInt(fileServerSettings.getProperty("vate.server.session.maximum"));
        if (fileSessionsMaximum < 0)
        {
          fileSessionsMaximum = 0;
        }
        sessionsMaximum = fileSessionsMaximum;
      }
      catch (Throwable e)
      {

      }
    }

    if (fileServerSettings.getProperty("vate.server.session.shell") != null)
    {
      try
      {
        sessionShell = fileServerSettings.getProperty("vate.server.session.shell");
      }
      catch (Throwable e)
      {

      }
    }

    saveFromServerToConnector();
  }

  private void loadServerSettingsFile()
  {
    if (fileServerSettings != null)
    {
      return;
    }
    try
    {
      if (vtURL != null)
      {
        serverSettingsFile = new File(vtURL, "vate-server.properties");
        if (!serverSettingsFile.exists())
        {
          serverSettingsFile = new File("vate-server.properties");
        }
      }
      else
      {
        serverSettingsFile = new File("vate-server.properties");
      }
      serverSettingsReader = new FileInputStream(serverSettingsFile);
      fileServerSettings = VTPropertiesBuilder.loadProperties(serverSettingsReader, "UTF-8");
      // rawSecuritySettings.load(securitySettingsReader);
      serverSettingsReader.close();

      sessionUsers = fileServerSettings.getProperty("vate.server.session.users", null);

      if (sessionUsers != null)
      {
        try
        {
          String[] users = VTArgumentParser.parseParameter(sessionUsers, ';');
          for (String user : users)
          {
            String[] credentials = VTArgumentParser.parseParameter(user, '/');
            if (credentials.length >= 2)
            {
              addUserCredential(credentials[0], credentials[1]);
            }
          }
        }
        catch (Throwable e)
        {

        }
      }

      if (fileServerSettings.getProperty("vate.server.connection.mode") != null)
      {
        try
        {
          String mode = fileServerSettings.getProperty("vate.server.connection.mode");
          if (mode.toUpperCase().startsWith("A"))
          {
            passive = false;
          }
          else
          {
            passive = true;
          }
        }
        catch (Throwable e)
        {

        }
      }

      if (fileServerSettings.getProperty("vate.server.connection.port") != null)
      {
        try
        {
          int filePort = Integer.parseInt(fileServerSettings.getProperty("vate.server.connection.port"));
          if (filePort > 0 && filePort < 65536)
          {
            hostPort = filePort;
          }
        }
        catch (Throwable e)
        {

        }
      }

      if (fileServerSettings.getProperty("vate.server.connection.host") != null)
      {
        try
        {
          hostAddress = fileServerSettings.getProperty("vate.server.connection.host", hostAddress);
        }
        catch (Throwable e)
        {

        }
      }

      if (fileServerSettings.getProperty("vate.server.connection.nat.port") != null)
      {
        try
        {
          int fileNatPort = Integer.parseInt(fileServerSettings.getProperty("vate.server.connection.nat.port"));
          if (fileNatPort > 0 && fileNatPort < 65536)
          {
            natPort = fileNatPort;
          }
        }
        catch (Throwable e)
        {

        }
      }

      if (fileServerSettings.getProperty("vate.server.encryption.type") != null)
      {
        try
        {
          encryptionType = fileServerSettings.getProperty("vate.server.encryption.type", encryptionType);
        }
        catch (Throwable e)
        {

        }
      }

      if (fileServerSettings.getProperty("vate.server.encryption.password") != null)
      {
        try
        {
          encryptionKey = fileServerSettings.getProperty("vate.server.encryption.password", "").getBytes("UTF-8");
        }
        catch (Throwable e)
        {

        }
      }

      if (fileServerSettings.getProperty("vate.server.proxy.type") != null)
      {
        try
        {
          proxyType = fileServerSettings.getProperty("vate.server.proxy.type", proxyType);
        }
        catch (Throwable e)
        {

        }
      }

      if (fileServerSettings.getProperty("vate.server.proxy.host") != null)
      {
        try
        {
          proxyAddress = fileServerSettings.getProperty("vate.server.proxy.host", proxyAddress);
        }
        catch (Throwable e)
        {

        }
      }

      if (fileServerSettings.getProperty("vate.server.proxy.port") != null)
      {
        try
        {
          int fileProxyPort = Integer.parseInt(fileServerSettings.getProperty("vate.server.proxy.port"));
          if (fileProxyPort > 0 && fileProxyPort < 65536)
          {
            proxyPort = fileProxyPort;
          }
        }
        catch (Throwable e)
        {

        }
      }

      if (fileServerSettings.getProperty("vate.server.proxy.authentication") != null)
      {
        try
        {
          if (fileServerSettings.getProperty("vate.server.proxy.authentication").toUpperCase().startsWith("E"))
          {
            useProxyAuthentication = true;
          }
          else
          {
            useProxyAuthentication = false;
          }
        }
        catch (Throwable e)
        {

        }
      }

      if (fileServerSettings.getProperty("vate.server.proxy.user") != null)
      {
        try
        {
          proxyUser = fileServerSettings.getProperty("vate.server.proxy.user");
        }
        catch (Throwable e)
        {

        }
      }

      if (fileServerSettings.getProperty("vate.server.proxy.password") != null)
      {
        try
        {
          proxyPassword = fileServerSettings.getProperty("vate.server.proxy.password");
        }
        catch (Throwable e)
        {

        }
      }

      if (fileServerSettings.getProperty("vate.server.session.limit") != null)
      {
        try
        {
          int fileSessionsMaximum = Integer.parseInt(fileServerSettings.getProperty("vate.server.session.maximum"));
          if (fileSessionsMaximum < 0)
          {
            fileSessionsMaximum = 0;
          }
          sessionsMaximum = fileSessionsMaximum;
        }
        catch (Throwable e)
        {

        }
      }

      if (fileServerSettings.getProperty("vate.server.session.shell") != null)
      {
        try
        {
          sessionShell = fileServerSettings.getProperty("vate.server.session.shell");
        }
        catch (Throwable e)
        {

        }
      }
    }
    catch (Throwable e)
    {

    }
  }

  public void loadServerSettingsProperties(Properties properties) throws Exception
  {
    loadFromConnectorToServer();

    sessionUsers = properties.getProperty("vate.server.session.users", null);

    if (sessionUsers != null)
    {
      try
      {
        String[] users = VTArgumentParser.parseParameter(sessionUsers, ';');
        for (String user : users)
        {
          String[] credentials = VTArgumentParser.parseParameter(user, '/');
          if (credentials.length >= 2)
          {
            addUserCredential(credentials[0], credentials[1]);
          }
        }
      }
      catch (Throwable e)
      {

      }
    }

    if (properties.getProperty("vate.server.connection.mode") != null)
    {
      try
      {
        String mode = properties.getProperty("vate.server.connection.mode");
        if (mode.toUpperCase().startsWith("A"))
        {
          passive = false;
        }
        else
        {
          passive = true;
        }
      }
      catch (Throwable e)
      {

      }
    }

    if (properties.getProperty("vate.server.connection.port") != null)
    {
      try
      {
        int filePort = Integer.parseInt(properties.getProperty("vate.server.connection.port"));
        if (filePort > 0 && filePort < 65536)
        {
          hostPort = filePort;
        }
      }
      catch (Throwable e)
      {

      }
    }

    if (properties.getProperty("vate.server.connection.host") != null)
    {
      try
      {
        hostAddress = properties.getProperty("vate.server.connection.host", hostAddress);
      }
      catch (Throwable e)
      {

      }
    }

    if (properties.getProperty("vate.server.connection.nat.port") != null)
    {
      try
      {
        int fileNatPort = Integer.parseInt(properties.getProperty("vate.server.connection.nat.port"));
        if (fileNatPort > 0 && fileNatPort < 65536)
        {
          natPort = fileNatPort;
        }
      }
      catch (Throwable e)
      {

      }
    }

    if (properties.getProperty("vate.server.encryption.type") != null)
    {
      try
      {
        encryptionType = properties.getProperty("vate.server.encryption.type", encryptionType);
      }
      catch (Throwable e)
      {

      }
    }

    if (properties.getProperty("vate.server.encryption.password") != null)
    {
      try
      {
        encryptionKey = properties.getProperty("vate.server.encryption.password", "").getBytes("UTF-8");
      }
      catch (Throwable e)
      {

      }
    }

    if (properties.getProperty("vate.server.proxy.type") != null)
    {
      try
      {
        proxyType = properties.getProperty("vate.server.proxy.type", proxyType);
      }
      catch (Throwable e)
      {

      }
    }

    if (properties.getProperty("vate.server.proxy.host") != null)
    {
      try
      {
        proxyAddress = properties.getProperty("vate.server.proxy.host", proxyAddress);
      }
      catch (Throwable e)
      {

      }
    }

    if (properties.getProperty("vate.server.proxy.port") != null)
    {
      try
      {
        int fileProxyPort = Integer.parseInt(properties.getProperty("vate.server.proxy.port"));
        if (fileProxyPort > 0 && fileProxyPort < 65536)
        {
          proxyPort = fileProxyPort;
        }
      }
      catch (Throwable e)
      {

      }
    }

    if (properties.getProperty("vate.server.proxy.authentication") != null)
    {
      try
      {
        if (properties.getProperty("vate.server.proxy.authentication").toUpperCase().startsWith("E"))
        {
          useProxyAuthentication = true;
        }
        else
        {
          useProxyAuthentication = false;
        }
      }
      catch (Throwable e)
      {

      }
    }

    if (properties.getProperty("vate.server.proxy.user") != null)
    {
      try
      {
        proxyUser = properties.getProperty("vate.server.proxy.user");
      }
      catch (Throwable e)
      {

      }
    }

    if (properties.getProperty("vate.server.proxy.password") != null)
    {
      try
      {
        proxyPassword = properties.getProperty("vate.server.proxy.password");
      }
      catch (Throwable e)
      {

      }
    }

    if (properties.getProperty("vate.server.session.limit") != null)
    {
      try
      {
        int fileSessionsMaximum = Integer.parseInt(properties.getProperty("vate.server.session.maximum"));
        if (fileSessionsMaximum < 0)
        {
          fileSessionsMaximum = 0;
        }
        sessionsMaximum = fileSessionsMaximum;
      }
      catch (Throwable e)
      {

      }
    }

    if (fileServerSettings.getProperty("vate.server.session.shell") != null)
    {
      try
      {
        sessionShell = fileServerSettings.getProperty("vate.server.session.shell");
      }
      catch (Throwable e)
      {

      }
    }

    saveFromServerToConnector();
  }

  public void reconfigure()
  {
    reconfigure = true;
    skipConfiguration = false;
    loadFromConnectorToServer();
    hostPort = null;
    configure();
    saveFromServerToConnector();
    reconfigure = false;
  }

  private void configure()
  {
    while ((passive && hostPort == null) || (!passive && (hostAddress == null || hostPort == null)) || sessionsMaximum < 0)
    {
      if (skipConfiguration)
      {
        skipConfiguration = false;
        return;
      }

      if (!reconfigure)
      {
        VTConsole.print("VT>Press enter to start server:");
        try
        {
          if (inputMenuBar != null)
          {
            inputMenuBar.setEnabledDialogMenu(false);
          }
          VTConsole.readLine(true);
          if (inputMenuBar != null)
          {
            inputMenuBar.setEnabledDialogMenu(true);
          }
          if (skipConfiguration)
          {
            return;
          }
        }
        catch (Throwable e)
        {
          System.exit(0);
        }
      }
      else
      {
        //if (inputMenuBar != null)
        //{
          //inputMenuBar.setEnabledDialogMenu(true);
        //}
      }

      if (connectionDialog != null)
      {
        if ((passive && hostPort == null) || (!passive && (hostAddress == null || hostPort == null)) || sessionsMaximum < 0)
        {
          connectionDialog.open();
          if (skipConfiguration)
          {
            skipConfiguration = false;
            if (reconfigure)
            {
              reconfigure = false;
              loadFromConnectorToServer();
            }
            return;
          }
        }
      }
      if (reconfigure)
      {
        reconfigure = false;
        VTConsole.print("\r");
      }
      VTConsole.print("VT>Enter settings file(if available):");
      try
      {
        String line = VTConsole.readLine(true);
        if (line == null)
        {
          System.exit(0);
        }
        else if (skipConfiguration)
        {
          return;
        }
        else if (line.length() > 0)
        {
          loadServerSettingsFile(line);
          return;
        }
      }
      catch (Throwable e)
      {

      }
      if (!(userCredentials.size() > 0))
      {
        if (!daemon)
        {
          try
          {
            VTConsole.print("VT>Configure a session user account on server?(Y/N, default:Y):");
            String line = VTConsole.readLine(true);
            if (line == null || line.toUpperCase().startsWith("N"))
            {
              System.exit(0);
            }
            else if (skipConfiguration)
            {
              return;
            }
            VTConsole.print("VT>Enter session user:");
            String user = VTConsole.readLine(false);
            if (user == null)
            {
              System.exit(0);
            }
            else if (skipConfiguration)
            {
              return;
            }
            VTConsole.print("VT>Enter session password:");
            String password = VTConsole.readLine(false);
            if (password == null)
            {
              System.exit(0);
            }
            else if (skipConfiguration)
            {
              return;
            }
            addUserCredential(user, password);
          }
          catch (InterruptedException e)
          {
            if (skipConfiguration)
            {
              return;
            }
          }
          catch (Throwable e)
          {
            System.exit(0);
          }
        }
        else
        {
          // System.exit(0);
          // try
          // {
          // addUserCredential("", "");
          // }
          // catch (UnsupportedEncodingException e)
          // {

          // }
        }
      }
      VTConsole.print("VT>Enter connection mode(active as A or passive as P, default:P):");
      try
      {
        String line = VTConsole.readLine(true);
        if (line == null)
        {
          System.exit(0);
        }
        else if (skipConfiguration)
        {
          return;
        }
        if (line.toUpperCase().startsWith("A"))
        {
          passive = false;
          VTConsole.print("VT>Enter host address(default:any):");
          line = VTConsole.readLine(true);
          if (line == null)
          {
            System.exit(0);
          }
          else if (skipConfiguration)
          {
            return;
          }
          hostAddress = line;
          VTConsole.print("VT>Enter host port(from 1 to 65535, default:6060):");
          line = VTConsole.readLine(true);
          if (line == null)
          {
            System.exit(0);
          }
          else if (skipConfiguration)
          {
            return;
          }
          if (line.length() > 0)
          {
            hostPort = Integer.parseInt(line);
          }
          else
          {
            hostPort = 6060;
          }
          if (hostPort > 65535 || hostPort < 1)
          {
            VTConsole.print("VT>Invalid port!\n");
            hostPort = null;
          }
          if (hostPort != null)
          {
            if (proxyType == null)
            {
              VTConsole.print("VT>Use proxy in connection?(Y/N, default:N):");
              line = VTConsole.readLine(true);
              if (line == null)
              {
                System.exit(0);
              }
              else if (skipConfiguration)
              {
                return;
              }
              if (line.toUpperCase().startsWith("Y"))
              {
                VTConsole.print("VT>Enter proxy type(SOCKS as S, HTTP as H, default:S):");
                line = VTConsole.readLine(true);
                if (line == null)
                {
                  System.exit(0);
                }
                else if (skipConfiguration)
                {
                  return;
                }
                if (line.toUpperCase().startsWith("H"))
                {
                  proxyType = "HTTP";
                }
                else
                {
                  proxyType = "SOCKS";
                }
                VTConsole.print("VT>Enter proxy host address(default:any):");
                line = VTConsole.readLine(true);
                if (line == null)
                {
                  System.exit(0);
                }
                else if (skipConfiguration)
                {
                  return;
                }
                proxyAddress = line;
                if (proxyType.equals("SOCKS"))
                {
                  VTConsole.print("VT>Enter proxy port(from 1 to 65535, default:1080):");
                  line = VTConsole.readLine(true);
                  if (line == null)
                  {
                    System.exit(0);
                  }
                  else if (skipConfiguration)
                  {
                    return;
                  }
                  if (line.length() > 0)
                  {
                    proxyPort = Integer.parseInt(line);
                  }
                  else
                  {
                    proxyPort = 1080;
                  }
                }
                else if (proxyType.equals("HTTP"))
                {
                  VTConsole.print("VT>Enter proxy port(from 1 to 65535, default:8080):");
                  line = VTConsole.readLine(true);
                  if (line == null)
                  {
                    System.exit(0);
                  }
                  else if (skipConfiguration)
                  {
                    return;
                  }
                  if (line.length() > 0)
                  {
                    proxyPort = Integer.parseInt(line);
                  }
                  else
                  {
                    proxyPort = 8080;
                  }
                }
                if (proxyPort > 65535 || proxyPort < 1)
                {
                  VTConsole.print("VT>Invalid port!\n");
                  proxyPort = null;
                  useProxyAuthentication = false;
                  hostPort = null;
                }
                if (proxyPort != null && hostPort != null)
                {
                  VTConsole.print("VT>Use authentication for proxy?(Y/N, default:N):");
                  line = VTConsole.readLine(true);
                  if (line == null)
                  {
                    System.exit(0);
                  }
                  else if (skipConfiguration)
                  {
                    return;
                  }
                  if (line.toUpperCase().startsWith("Y"))
                  {
                    useProxyAuthentication = true;
                    VTConsole.print("VT>Enter proxy username:");
                    line = VTConsole.readLine(false);
                    if (line == null)
                    {
                      System.exit(0);
                    }
                    else if (skipConfiguration)
                    {
                      return;
                    }
                    proxyUser = line;
                    VTConsole.print("VT>Enter proxy password:");
                    line = VTConsole.readLine(false);
                    if (line == null)
                    {
                      System.exit(0);
                    }
                    else if (skipConfiguration)
                    {
                      return;
                    }
                    proxyPassword = line;
                  }
                  else
                  {
                    useProxyAuthentication = false;
                  }
                }
                else
                {
                  useProxyAuthentication = false;
                }
              }
              else
              {
                proxyType = "None";
              }
            }
            VTConsole.print("VT>Use encryption in connection?(Y/N, default:N):");
            line = VTConsole.readLine(true);
            if (line == null)
            {
              System.exit(0);
            }
            else if (skipConfiguration)
            {
              return;
            }
            if (line.toUpperCase().startsWith("Y"))
            {
              VTConsole.print("VT>Enter encryption type(R(RC4)/A(AES)/I(ISAAC)/S(SALSA)/H(HC256)/G(GRAIN)):");
              line = VTConsole.readLine(false);
              if (line == null)
              {
                System.exit(0);
              }
              else if (skipConfiguration)
              {
                return;
              }
              encryptionType = "RC4";
              if (line.toUpperCase().startsWith("A"))
              {
                encryptionType = "AES";
              }
              //if (line.toUpperCase().startsWith("B"))
              //{
                //encryptionType = "BLOWFISH";
              //}
              if (line.toUpperCase().startsWith("S"))
              {
                encryptionType = "SALSA";
              }
              if (line.toUpperCase().startsWith("H"))
              {
                encryptionType = "HC256";
              }
              if (line.toUpperCase().startsWith("G"))
              {
                encryptionType = "GRAIN";
              }
              if (line.toUpperCase().startsWith("I"))
              {
                encryptionType = "ISAAC";
              }
              VTConsole.print("VT>Enter encryption password:");
              line = VTConsole.readLine(false);
              if (line == null)
              {
                System.exit(0);
              }
              else if (skipConfiguration)
              {
                return;
              }
              encryptionKey = line.getBytes("UTF-8");
            }
            else
            {
              encryptionType = "None";
            }
          }
        }
        else
        {
          passive = true;
          sessionsMaximum = 0;
          // hostAddress = "";
          VTConsole.print("VT>Enter host address(default:any):");
          line = VTConsole.readLine(true);
          if (line == null)
          {
            System.exit(0);
          }
          else if (skipConfiguration)
          {
            return;
          }
          hostAddress = line;
          VTConsole.print("VT>Enter listening port(from 1 to 65535, default:6060):");
          line = VTConsole.readLine(true);
          if (line == null)
          {
            System.exit(0);
          }
          else if (skipConfiguration)
          {
            return;
          }
          if (line.length() > 0)
          {
            hostPort = Integer.parseInt(line);
          }
          else
          {
            hostPort = 6060;
          }
          if (hostPort > 65535 || hostPort < 1)
          {
            VTConsole.print("VT>Invalid port!\n");
            hostPort = null;
            sessionsMaximum = 0;
          }
          else
          {
            VTConsole.print("VT>Use nat port in connection?(Y/N, default:N):");
            line = VTConsole.readLine(true);
            if (line == null)
            {
              System.exit(0);
            }
            else if (skipConfiguration)
            {
              return;
            }
            if (line.toUpperCase().startsWith("Y"))
            {
              VTConsole.print("VT>Enter connection nat port(from 1 to 65535, default:" + hostPort + "):");
              line = VTConsole.readLine(true);
              if (line == null)
              {
                System.exit(0);
              }
              else if (skipConfiguration)
              {
                return;
              }
              if (line.length() > 0)
              {
                natPort = Integer.parseInt(line);
              }
              else
              {
                natPort = hostPort;
              }
              if (natPort > 65535 || natPort < 1)
              {
                VTConsole.print("VT>Invalid port!\n");
                natPort = null;
                hostPort = null;
              }
            }
            VTConsole.print("VT>Use encryption in connection?(Y/N, default:N):");
            line = VTConsole.readLine(true);
            if (line == null)
            {
              System.exit(0);
            }
            else if (skipConfiguration)
            {
              return;
            }
            if (line.toUpperCase().startsWith("Y"))
            {
              VTConsole.print("VT>Enter encryption type(R(RC4)/A(AES)/I(ISAAC)/S(SALSA)/H(HC256)/G(GRAIN)):");
              line = VTConsole.readLine(false);
              if (line == null)
              {
                System.exit(0);
              }
              else if (skipConfiguration)
              {
                return;
              }
              encryptionType = "RC4";
              if (line.toUpperCase().startsWith("A"))
              {
                encryptionType = "AES";
              }
              //if (line.toUpperCase().startsWith("B"))
              //{
                //encryptionType = "BLOWFISH";
              //}
              if (line.toUpperCase().startsWith("S"))
              {
                encryptionType = "SALSA";
              }
              if (line.toUpperCase().startsWith("H"))
              {
                encryptionType = "HC256";
              }
              if (line.toUpperCase().startsWith("G"))
              {
                encryptionType = "GRAIN";
              }
              if (line.toUpperCase().startsWith("I"))
              {
                encryptionType = "ISAAC";
              }
              VTConsole.print("VT>Enter encryption password:");
              line = VTConsole.readLine(false);
              if (line == null)
              {
                System.exit(0);
              }
              else if (skipConfiguration)
              {
                return;
              }
              encryptionKey = line.getBytes("UTF-8");
            }
            else
            {
              encryptionType = "None";
            }
            VTConsole.print("VT>Enter session shell(null for default):");
            line = VTConsole.readLine(false);
            if (line == null)
            {
              System.exit(0);
            }
            else if (skipConfiguration)
            {
              return;
            }
            sessionShell = line;
            /*
             * if (proxyType == null) { VTTerminal.
             * print("VT>Use SOCKS proxy to connect?(Y/N, default:N):" ); line =
             * VTTerminal.readLine(true); if (line == null) { System.exit(0); } if
             * (line.toUpperCase().startsWith("Y")) { proxyType = "SOCKS"; VTTerminal.
             * print("VT>Enter proxy host address(default:localhost):" ); line =
             * VTTerminal.readLine(true); if (line == null) { System.exit(0); } proxyAddress
             * = line; if (proxyType.equals("SOCKS")) { VTTerminal.
             * print("VT>Enter proxy port(from 1 to 65535, default:1080):" ); line =
             * VTTerminal.readLine(true); if (line == null) { System.exit(0); } if
             * (line.length() > 0) { proxyPort = Integer.parseInt(line); } else { proxyPort
             * = 1080; } } if (proxyPort > 65535 || proxyPort < 1) {
             * VTTerminal.print("VT>Invalid port!\n"); proxyPort = null;
             * UseProxyAuthentication = false; port = null; } if (proxyPort != null && port
             * != null) { VTTerminal.
             * print("VT>Use authentication for proxy?(Y/N, default:N):" ); line =
             * VTTerminal.readLine(true); if (line == null) { System.exit(0); } if
             * (line.toUpperCase().startsWith("Y")) { UseProxyAuthentication = true;
             * VTTerminal.print("VT>Enter proxy username:"); line =
             * VTTerminal.readLine(true); if (line == null) { System.exit(0); } proxyUser =
             * line; VTTerminal.print("VT>Enter proxy password:"); line =
             * VTTerminal.readLine(true); if (line == null) { System.exit(0); }
             * proxyPassword = line; } else { UseProxyAuthentication = false; } } else {
             * UseProxyAuthentication = false; } } else { proxyType = "None"; } }
             */
            try
            {
              VTConsole.print("VT>Enter session maximum(from 0 to 65535, default:0):");
              line = VTConsole.readLine(true);
              if (line == null)
              {
                System.exit(0);
              }
              else if (skipConfiguration)
              {
                return;
              }
              if (!line.trim().equals(""))
              {
                sessionsMaximum = Integer.parseInt(line);
                if (sessionsMaximum < 0)
                {
                  sessionsMaximum = 0;
                }
              }
              else
              {
                sessionsMaximum = 0;
              }
            }
            catch (NumberFormatException e)
            {
              sessionsMaximum = 0;
            }
            catch (Throwable e)
            {
              sessionsMaximum = 0;
            }
          }
          if (sessionsMaximum < 0)
          {
            VTConsole.print("VT>Invalid session maximum!\n");
          }
        }
      }
      catch (NumberFormatException e)
      {
        VTConsole.print("VT>Invalid port!\n");
        hostPort = null;
        proxyPort = null;
        useProxyAuthentication = false;
      }
      catch (Throwable e)
      {

      }
      if (hostAddress == null || hostPort == null || sessionsMaximum < 0)
      {
        VTConsole.print("VT>Try configuring again?(Y/N, default:N):");
        try
        {
          String line = VTConsole.readLine(true);
          if (line == null || !line.toUpperCase().startsWith("Y"))
          {
            System.exit(0);
          }
          else if (skipConfiguration)
          {
            return;
          }
        }
        catch (Throwable e)
        {
          System.exit(0);
        }
      }
    }
  }

  public void parseParameters(String[] parameters) throws Exception
  {
    int i;
    String parameterName;
    String parameterValue;
    String parameterUser = null;
    String parameterPassword = null;
    for (i = 0; i < parameters.length; i++)
    {
      parameterName = parameters[i].toUpperCase();
      if (!parameterName.startsWith("-"))
      {
        try
        {
          loadServerSettingsFile(parameterName);
        }
        catch (Throwable t)
        {

        }
      }
      if (parameterName.contains("-LF"))
      {
        parameterValue = parameters[++i];
        try
        {
          loadServerSettingsFile(parameterValue);
        }
        catch (Throwable t)
        {

        }
      }
      if (parameterName.contains("-CM"))
      {
        parameterValue = parameters[++i];
        if (parameterValue.toUpperCase().startsWith("A"))
        {
          passive = false;
        }
        else
        {
          passive = true;
        }
      }
      if (parameterName.contains("-CH"))
      {
        parameterValue = parameters[++i];
        hostAddress = parameterValue;
      }
      if (parameterName.contains("-CP"))
      {
        parameterValue = parameters[++i];
        try
        {
          int intValue = Integer.parseInt(parameterValue);
          if (intValue > 0 && intValue < 65536)
          {
            hostPort = intValue;
          }
        }
        catch (Throwable t)
        {

        }
      }
      if (parameterName.contains("-NP"))
      {
        parameterValue = parameters[++i];
        try
        {
          int intValue = Integer.parseInt(parameterValue);
          if (intValue > 0 && intValue < 65536)
          {
            natPort = intValue;
          }
        }
        catch (Throwable t)
        {

        }
      }
      if (parameterName.contains("-ET"))
      {
        parameterValue = parameters[++i];
        encryptionType = parameterValue;
      }
      if (parameterName.contains("-EK"))
      {
        parameterValue = parameters[++i];
        encryptionKey = parameterValue.getBytes("UTF-8");
      }
      if (parameterName.contains("-PT"))
      {
        parameterValue = parameters[++i];
        proxyType = parameterValue;
      }
      if (parameterName.contains("-PH"))
      {
        parameterValue = parameters[++i];
        proxyAddress = parameterValue;
      }
      if (parameterName.contains("-PP"))
      {
        parameterValue = parameters[++i];
        try
        {
          int intValue = Integer.parseInt(parameterValue);
          if (intValue > 0 && intValue < 65536)
          {
            proxyPort = intValue;
          }
        }
        catch (Throwable t)
        {

        }
      }
      if (parameterName.contains("-PA"))
      {
        parameterValue = parameters[++i];
        if (parameterValue.toUpperCase().startsWith("E"))
        {
          useProxyAuthentication = true;
        }
        else
        {
          useProxyAuthentication = false;
        }
      }
      if (parameterName.contains("-PU"))
      {
        parameterValue = parameters[++i];
        proxyUser = parameterValue;
      }
      if (parameterName.contains("-PK"))
      {
        parameterValue = parameters[++i];
        proxyPassword = parameterValue;
      }
      if (parameterName.contains("-SM"))
      {
        parameterValue = parameters[++i];
        try
        {
          int intValue = Integer.parseInt(parameterValue);
          if (intValue > 0)
          {
            sessionsMaximum = intValue;
          }
        }
        catch (Throwable t)
        {

        }
      }
      if (parameterName.contains("-SU"))
      {
        parameterValue = parameters[++i];
        parameterUser = parameterValue;
        if (parameterPassword != null)
        {
          setUniqueUserCredential(parameterUser, parameterPassword);
        }
      }
      if (parameterName.contains("-SK"))
      {
        parameterValue = parameters[++i];
        parameterPassword = parameterValue;
        if (parameterUser != null)
        {
          setUniqueUserCredential(parameterUser, parameterPassword);
        }
      }
      if (parameterName.contains("-SS"))
      {
        parameterValue = parameters[++i];
        sessionShell = parameterValue;
      }
    }
  }

  public void startThread()
  {
    threads.execute(new Runnable()
    {
      public void run()
      {
        start();
      }
    });
  }

  public void start()
  {
    Thread.setDefaultUncaughtExceptionHandler(new VTUncaughtExceptionHandler());
    // loadFileServerSettings();
    VTNativeUtils.initialize();
    if (!VTConsole.isDaemon() && VTConsole.isGraphical())
    {
      VTConsole.initialize();
      VTConsole.setTitle("Variable-Terminal " + VT.VT_VERSION + " - Server - Console");
      if (!VTConsole.isDaemon() && !daemon)
      {
        connectionDialog = new VTServerSettingsDialog(VTConsole.getFrame(), "Variable-Terminal " + VT.VT_VERSION + " - Server - Connection", true, this);
        inputMenuBar = new VTServerLocalGraphicalConsoleMenuBar(connectionDialog);
        VTConsole.getFrame().setMenuBar(inputMenuBar);
        VTConsole.getFrame().pack();
        try
        {
          trayIconInterface = new VTTrayIconInterface();
          trayIconInterface.install(VTConsole.getFrame(), "Variable-Terminal - Server");
        }
        catch (Throwable t)
        {
          trayIconInterface = null;
        }
      }
    }
    else
    {
//			if (!GraphicsEnvironment.isHeadless())
//			{
//				Frame invisible = new Frame();
//				invisible.setUndecorated(true);
//				invisible.pack();
//				connectionDialog = new VTServerConnectionDialog(invisible, "Variable-Terminal Server " + VT.VT_VERSION + " - Connection", false, this);
//			}
      VTConsole.initialize();
      VTConsole.setTitle("Variable-Terminal " + VT.VT_VERSION + " - Server - Console");
    }
    VTConsole.clear();
    VTConsole.print("VT>Variable-Terminal " + VT.VT_VERSION + " - Server\n" +
    "VT>Copyright (c) " + VT.VT_YEAR + " - wknishio@gmail.com\n" +
    "VT>This software is under MIT license, see license.txt!\n" +
    "VT>This software comes with no warranty, use at your own risk!\n");
    if (!VTConsole.isDaemon() && !daemon)
    {
      configure();
    }
    if (skipConfiguration)
    {
      skipConfiguration = false;
    }
    Thread.currentThread().setName(this.getClass().getSimpleName());
    run();
  }

  private void loadFromConnectorToServer()
  {
    if (serverConnector != null)
    {
      this.passive = serverConnector.isPassive();
      this.hostAddress = serverConnector.getAddress();
      this.hostPort = serverConnector.getPort();
      this.natPort = serverConnector.getNatPort();
      this.proxyType = serverConnector.getProxyType();
      this.proxyAddress = serverConnector.getProxyAddress();
      this.proxyPort = serverConnector.getProxyPort();
      this.useProxyAuthentication = serverConnector.isUseProxyAuthentication();
      this.proxyUser = serverConnector.getProxyUser();
      this.proxyPassword = serverConnector.getProxyPassword();
      this.encryptionType = serverConnector.getEncryptionType();
      this.encryptionKey = serverConnector.getEncryptionKey();
      this.sessionsMaximum = serverConnector.getSessionsMaximum();
      this.sessionShell = serverConnector.getSessionShell();
    }
  }

  private void saveFromServerToConnector()
  {
    if (serverConnector != null)
    {
      serverConnector.setPassive(passive);
      serverConnector.setAddress(hostAddress);
      serverConnector.setPort(hostPort);
      serverConnector.setNatPort(natPort);
      serverConnector.setProxyType(proxyType);
      serverConnector.setProxyAddress(proxyAddress);
      serverConnector.setProxyPort(proxyPort);
      serverConnector.setUseProxyAuthentication(useProxyAuthentication);
      serverConnector.setProxyUser(proxyUser);
      serverConnector.setProxyPassword(proxyPassword);
      serverConnector.setSessionsMaximum(sessionsMaximum);
      serverConnector.setSessionShell(sessionShell);
      if (encryptionType != null && encryptionKey != null)
      {
        serverConnector.setEncryptionType(encryptionType);
        serverConnector.setEncryptionKey(encryptionKey);
      }
      else
      {
        serverConnector.setEncryptionType("None");
        serverConnector.setEncryptionKey(encryptionKey);
      }
      if (!(userCredentials.size() > 0))
      {
        this.setUniqueUserCredential("", "");
      }
    }
  }

  public void run()
  {
    serverConnector = new VTServerConnector(this);
    serverConnector.setPassive(passive);
    serverConnector.setAddress(hostAddress);
    serverConnector.setPort(hostPort);
    serverConnector.setNatPort(natPort);
    serverConnector.setProxyType(proxyType);
    serverConnector.setProxyAddress(proxyAddress);
    serverConnector.setProxyPort(proxyPort);
    serverConnector.setUseProxyAuthentication(useProxyAuthentication);
    serverConnector.setProxyUser(proxyUser);
    serverConnector.setProxyPassword(proxyPassword);
    serverConnector.setSessionsMaximum(sessionsMaximum);
    serverConnector.setSessionShell(sessionShell);
    if (encryptionType != null && encryptionKey != null)
    {
      serverConnector.setEncryptionType(encryptionType);
      serverConnector.setEncryptionKey(encryptionKey);
    }
    else
    {
      serverConnector.setEncryptionType("None");
      serverConnector.setEncryptionKey(encryptionKey);
    }
    if (!(userCredentials.size() > 0))
    {
      this.setUniqueUserCredential("", "");
    }
    if (!daemon)
    {
      consoleReader = new VTServerLocalConsoleReader(this);
      consoleReader.startThread();
    }
    for (VTServerSessionListener listener : listeners)
    {
      serverConnector.addSessionListener(listener);
    }
    serverConnector.run();
  }

  public void setEchoCommands(boolean echoCommands)
  {
    this.echoCommands = echoCommands;
  }

  public boolean isEchoCommands()
  {
    return echoCommands;
  }

  public boolean isReconfigure()
  {
    return reconfigure;
  }

  public void addSessionListener(VTServerSessionListener listener)
  {
    if (serverConnector != null)
    {
      serverConnector.addSessionListener(listener);
    }
    else
    {
      listeners.add(listener);
    }
  }

  public void removeSessionListener(VTServerSessionListener listener)
  {
    if (serverConnector != null)
    {
      serverConnector.removeSessionListener(listener);
    }
    else
    {
      listeners.add(listener);
    }
  }

  public String getSessionShell()
  {
    return sessionShell;
  }

  public void setSessionShell(String sessionShell)
  {
    this.sessionShell = sessionShell;
  }
}


text:
// Copyright 2014 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.facebook.buck.query;

import java.util.ArrayList;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import javax.annotation.Nullable;

/**
 * A tokenizer for the Buck query language.
 *
 *
Note, we can avoid a lot of quoting by noting that the characters [() ,] do not appear in any
 * label, filename, function name, or regular expression we care about.
 *
 *
No string escapes are allowed ("\"). Given the domain, that's not currently a problem.
 */
final class Lexer {

  /** Discriminator for different kinds of tokens. */
  public enum TokenKind {
    WORD("word"),
    EOF("EOF"),

    COMMA(","),
    EQUALS("="),
    LPAREN("("),
    MINUS("-"),
    PLUS("+"),
    RPAREN(")"),
    CARET("^"),
    LBRACKET("["),
    RBRACKET("]"),

    __ALL_IDENTIFIERS_FOLLOW(""), // See below

    IN("in"),
    LET("let"),
    SET("set"),

    INTERSECT("intersect"),
    EXCEPT("except"),
    UNION("union");

    private final String prettyName;

    TokenKind(String prettyName) {
      this.prettyName = prettyName;
    }

    public String getPrettyName() {
      return prettyName;
    }
  }

  public static final Set<TokenKind> BINARY_OPERATORS =
      EnumSet.of(
          TokenKind.INTERSECT,
          TokenKind.CARET,
          TokenKind.UNION,
          TokenKind.PLUS,
          TokenKind.EXCEPT,
          TokenKind.MINUS);

  private static final Map<String, TokenKind> keywordMap = new HashMap<>();

  static {
    for (TokenKind kind : EnumSet.allOf(TokenKind.class)) {
      if (kind.ordinal() > TokenKind.__ALL_IDENTIFIERS_FOLLOW.ordinal()) {
        keywordMap.put(kind.getPrettyName(), kind);
      }
    }
  }

  /** Returns true iff 'word' is a reserved word of the language. */
  static boolean isReservedWord(String word) {
    return keywordMap.containsKey(word);
  }

  /** Tokens returned by the Lexer. */
  static class Token {

    public final TokenKind kind;

    @Nullable public final String word;

    Token(TokenKind kind) {
      this.kind = kind;
      this.word = null;
    }

    Token(String word) {
      this.kind = TokenKind.WORD;
      this.word = word;
    }

    @Override
    public boolean equals(Object other) {
      return (other instanceof Token) && equalTo((Token) other);
    }

    boolean equalTo(Token other) {
      return this.kind.equals(other.kind)
          && ((word != null && word.equals(other.word)) || (word == null && other.word == null));
    }

    @Override
    public int hashCode() {
      int h = 31;
      h = h * 17 + kind.hashCode();
      if (word != null) {
        h = h * 17 + word.hashCode();
      }
      return h;
    }

    @Override
    public String toString() {
      return kind == TokenKind.WORD ? Objects.requireNonNull(word) : kind.getPrettyName();
    }
  }

  /**
   * Entry point to the lexer. Returns the list of tokens for the specified input, or throws
   * QueryException.
   */
  public static List<Token> scan(char[] buffer) throws QueryException {
    Lexer lexer = new Lexer(buffer);
    lexer.tokenize();
    return lexer.tokens;
  }

  // Input buffer and position
  private final char[] buffer;
  private int pos;

  private final List<Token> tokens = new ArrayList<>();

  private Lexer(char[] buffer) {
    this.buffer = Objects.requireNonNull(buffer);
    this.pos = 0;
  }

  private void addToken(Token s) {
    tokens.add(s);
  }

  /**
   * Scans a quoted word delimited by 'quot'.
   *
   *
ON ENTRY: 'pos' is 1 + the index of the first delimiter ON EXIT: 'pos' is 1 + the index of
   * the last delimiter.
   *
   * @return the word token.
   */
  private Token quotedWord(char quot) throws QueryException {
    int oldPos = pos - 1;
    while (pos < buffer.length) {
      char c = buffer[pos++];
      switch (c) {
        case '\'':
        case '"':
          if (c == quot) {
            // close-quote, all done.
            return new Token(bufferSlice(oldPos + 1, pos - 1));
          }
      }
    }
    throw new QueryException("unclosed quotation");
  }

  private TokenKind getTokenKindForWord(String word) {
    TokenKind kind = keywordMap.get(word);
    return kind == null ? TokenKind.WORD : kind;
  }

  // Unquoted words may contain [-*$], but not start with them.  For user convenience, unquoted
  // words must include UNIX filenames, labels and target label patterns, and simple regexps
  // (e.g. cc_.*). Keep consistent with TargetLiteral.toString()!
  private String scanWord() {
    int oldPos = pos - 1;
    while (pos < buffer.length) {
      switch (buffer[pos]) {
        case 'a':
        case 'b':
        case 'c':
        case 'd':
        case 'e':
        case 'f':
        case 'g':
        case 'h':
        case 'i':
        case 'j':
        case 'k':
        case 'l':
        case 'm':
        case 'n':
        case 'o':
        case 'p':
        case 'q':
        case 'r':
        case 's':
        case 't':
        case 'u':
        case 'v':
        case 'w':
        case 'x':
        case 'y':
        case 'z':
        case 'A':
        case 'B':
        case 'C':
        case 'D':
        case 'E':
        case 'F':
        case 'G':
        case 'H':
        case 'I':
        case 'J':
        case 'K':
        case 'L':
        case 'M':
        case 'N':
        case 'O':
        case 'P':
        case 'Q':
        case 'R':
        case 'S':
        case 'T':
        case 'U':
        case 'V':
        case 'W':
        case 'X':
        case 'Y':
        case 'Z':
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
        case '*':
        case '/':
        case '@':
        case '.':
        case '-':
        case '_':
        case ':':
        case '$':
        case '#':
          pos++;
          break;
        default:
          return bufferSlice(oldPos, pos);
      }
    }
    return bufferSlice(oldPos, pos);
  }

  /**
   * Scans a word or keyword.
   *
   *
ON ENTRY: 'pos' is 1 + the index of the first char in the word. ON EXIT: 'pos' is 1 + the
   * index of the last char in the word.
   *
   * @return the word or keyword token.
   */
  private Token wordOrKeyword() {
    String word = scanWord();
    TokenKind kind = getTokenKindForWord(word);
    return kind == TokenKind.WORD ? new Token(word) : new Token(kind);
  }

  /** Performs tokenization of the character buffer of file contents provided to the constructor. */
  private void tokenize() throws QueryException {
    while (pos < buffer.length) {
      char c = buffer[pos];
      pos++;
      switch (c) {
        case '(':
          {
            addToken(new Token(TokenKind.LPAREN));
            break;
          }
        case ')':
          {
            addToken(new Token(TokenKind.RPAREN));
            break;
          }
        case '[':
          {
            addToken(new Token((TokenKind.LBRACKET)));
            break;
          }
        case ']':
          {
            addToken(new Token((TokenKind.RBRACKET)));
            break;
          }
        case ',':
          {
            addToken(new Token(TokenKind.COMMA));
            break;
          }
        case '+':
          {
            addToken(new Token(TokenKind.PLUS));
            break;
          }
        case '-':
          {
            addToken(new Token(TokenKind.MINUS));
            break;
          }
        case '=':
          {
            addToken(new Token(TokenKind.EQUALS));
            break;
          }
        case '^':
          {
            addToken(new Token(TokenKind.CARET));
            break;
          }
        case '\n':
        case ' ':
        case '\t':
        case '\r':
          {
            /* ignore */
            break;
          }
        case '\'':
        case '\"':
          {
            addToken(quotedWord(c));
            break;
          }
        default:
          {
            addToken(wordOrKeyword());
            break;
          } // default
      } // switch
    } // while

    addToken(new Token(TokenKind.EOF));
  }

  private String bufferSlice(int start, int end) {
    return new String(this.buffer, start, end - start);
  }
}

redpajama_set_name: RedPajamaGithub


text:
package com.twitter.grabbyhands

import java.nio.ByteBuffer
import java.util.concurrent.{CountDownLatch, TimeUnit}

/** Wraps outgoing messages. */
class Write(val message: ByteBuffer, val watcher: Boolean => Unit) {
  def this(read: Read) = this(read.message, read.complete(_: Boolean))
  def this(message: ByteBuffer) = this(message, (Boolean) => false)
  def this(str: String) = this(ByteBuffer.wrap(str.getBytes()))
  def this(bytes: Array[Byte]) = this(ByteBuffer.wrap(bytes))
  protected val writtenLatch = new CountDownLatch(1)
  protected val cancelLatch = new CountDownLatch(1)

  /** Returns true iff the message has been sent to a Kestrel server. */
  def written(): Boolean = {
    writtenLatch.getCount == 0
  }

  def getMessage(): ByteBuffer = message
  def getWatcher(): Function[Boolean, Unit] = watcher

  /** Returns only once the message has been sent to a Kestrel server or timeout occurs. */
  def awaitWrite(timeout: Int, units: TimeUnit) {
    writtenLatch.await(timeout, units)
  }

  /** Returns only once the message has been sent to a Kestrel. */
  def awaitWrite() {
    writtenLatch.await(99999, TimeUnit.DAYS)
  }

  protected[grabbyhands] def write() {
    watcher(true)
    writtenLatch.countDown()
  }

  /** Cancels a write waiting in the local queue. */
  def cancel() {
    cancelLatch.countDown()
    watcher(false)
  }

  /** Returns true if write was cancelled before it could be sent to a Kestrel server. */
  def cancelled(): Boolean = {
    cancelLatch.getCount == 0
  }

  def close() {
    write()
  }

}


text:
namespace TestFirst.Net
{
    public interface IInvokable
    {
        void Invoke();
    }

    public interface IInvokable<T>
    {
        T Invoke();
    }
}


text:
#ifndef SCRVIEW_INCLUDED
#define SCRVIEW_INCLUDED

/////////////////////////////////////////////////////////////////////////////
// CScrView view

class CScrView : public CView
{
protected:
		CScrView();           // protected constructor used by dynamic creation
		DECLARE_DYNAMIC(CScrView)

// Attributes
public:

// Operations
public:
	virtual BOOL MovePos(UINT nChar, UINT nRepCnt, BOOL, BOOL, BOOL);

// Overrides
		// ClassWizard generated virtual function overrides
		//{{AFX_VIRTUAL(CScrView)
		public:
		virtual void OnInitialUpdate();
		virtual void OnPrepareDC(CDC* pDC, CPrintInfo* pInfo = NULL);
		protected:
		virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
		//}}AFX_VIRTUAL

public:
	static const CSizeAp null_size;
	static const CPointAp null_point;

	void SetSize(CSizeAp total, CSizeAp page = null_size, CSizeAp line = null_size);
	void SetTSize(CSizeAp total, CSizeAp page = null_size, CSizeAp line = null_size);
	void GetSize(CSizeAp &total, CSizeAp &page, CSizeAp &line) const
	{
		total = total_;
		page = page_;
		line = line_;
	}
	void GetDisplayRect(CRect * rct) const
	{
		GetClientRect(rct);
		rct->DeflateRect(bdr_left_, bdr_top_, bdr_right_, bdr_bottom_);
		if (rct->bottom < rct->top) rct->bottom = rct->top;     // make sure deflate does not invert rect
	}

	void SetScroll(CPointAp, BOOL strict=FALSE);
	void SetTScroll(CPointAp);    // set upper left in text units
	CPointAp GetScroll() const    // get upper left pos of display
	{
		return scrollpos_;
	}
	BOOL ScrollUp() const       // Was last scroll direction upwards?
	{
		return scroll_up_;
	}
	void SetScrollPastEnds(BOOL v = FALSE) { scroll_past_ends_ = v; }
	BOOL GetScrollPastEnds() { return scroll_past_ends_; }
	void SetAutoscroll(int aa = 10) { autoscroll_accel_ = aa; }

	void CaretMode();           // Set caret mode (arrow keys move caret)
	void ScrollMode();          // Set scroll mode (arrow keys scroll)

	void LineCaret();           // Make the caret a line to the left of the current char
	void BlockCaret();          // Make a solid block caret ove the current char

	void SetCaret(CPointAp);    // set pos of caret (move display if nec.)
	void SetTCaret(CPointAp);   // set pos of caret in text units
	CPointAp GetCaret() const   // get pos of caret
	{
		return caretpos_;
	}
	CRectAp GetCaretRect()        // get rectangle bounding the caret
	{
		return CRectAp(caretpos_, caret_size());
	}
	virtual void DisplayCaret(int char_width = -1);
	BOOL CaretDisplayed(CSizeAp win_size = null_size);
	void EnableCaret();
	void DisableCaret();
	void CaretShow();

	void SetHorzBufferZone(int n = 1) { horz_buffer_zone_ = n; }
	int GetHorzBufferZone() { return horz_buffer_zone_; }
	void SetVertBufferZone(int n = 0) { vert_buffer_zone_ = n; }
	int GetVertBufferZone() { return vert_buffer_zone_; }

	virtual void SetSel(CPointAp, CPointAp, bool base1 = false);  // set selection
	void SetTSel(CPointAp, CPointAp); // set selection in text units
	// Return start and end of current selection
	BOOL GetSel(CPointAp &start, CPointAp &end) const
	{
		start = caretpos_;
		end = selpos_;
		return basepos_ == selpos_;
	}

	void DisplayPart(CPointAp pos, CSizeAp size = null_size, BOOL show_end = FALSE);

//    void ConvertToDP(CRect &rr);
//    void ConvertToDP(CPoint &pp);
//    void ConvertFromDP(CRect &rr);
//    void ConvertFromDP(CPoint &pp);
	CRect ConvertToDP(CRectAp rr);
	CSize ConvertToDP(CSizeAp ss);
	CPoint ConvertToDP(CPointAp pp);
	CRectAp ConvertFromDP(CRect rr);
	CSizeAp ConvertFromDP(CSize ss);
	CPointAp ConvertFromDP(CPoint pp);
	bool negx() { ASSERT(init_coord_); return negx_; }
	bool negy() { ASSERT(init_coord_); return negy_; }

	CPen *SetPen(CPen *pp) { CPen *rv = pen_; pen_ = pp; return rv; }
	CBrush *SetBrush(CBrush *bb) { CBrush *rv = brush_; brush_ = bb; return rv; }
	CFont *SetFont(CFont *ff) { CFont *rv = font_; font_ = ff; return rv; }
	CBitmap *SetBitmap(CBitmap *bb) { CBitmap *rv = bitmap_; bitmap_ = bb; return rv; }
	CRgn *SetRgn(CRgn *rr) { CRgn *rv = rgn_; rgn_ = rr; return rv; }
	int SetMapMode(int mm);

	// Implementation
protected:
	virtual ~CScrView();
	void OnSelUpdate(CPoint);
	virtual void ValidateCaret(CPointAp &pos, BOOL inside=TRUE);
	virtual void ValidateScroll(CPointAp &pos, BOOL strict=FALSE);
	virtual void InvalidateRange(CPointAp start, CPointAp end, bool f = false);

	// We need to add these as virtual functions so that we can override them
	// in derived classes.  (For example, to allow turning off refresh in
	// HexEditView.)  This is necessary since the corresponding MFC functions
	// (Invalidate, ScrollWindow etc) are not virtual.
	virtual void DoInvalidate() { Invalidate(); }
	virtual void DoInvalidateRect(LPCRECT lpRect) { InvalidateRect(lpRect); }
	virtual void DoInvalidateRgn(CRgn* pRgn) { InvalidateRgn(pRgn); }
	virtual void DoScrollWindow(int xx, int yy)
	{
		CRect rct;
		GetDisplayRect(&rct);
		ScrollWindow(xx, yy, &rct, &rct);
	}
	virtual void AfterScroll(CPointAp newpos) { }
	virtual void DoUpdateWindow() { UpdateWindow(); }
	virtual void DoHScroll(int total, int page, int pos);
	virtual void DoVScroll(int total, int page, int pos);
	virtual void DoSetCaretPos(POINT pt) { SetCaretPos(pt); }

	// Allow derived classes to check left mouse button, shift and control key state
	BOOL mouse_down()   { return mouse_down_; }
	BOOL shift_down()   { return ::GetKeyState(VK_SHIFT) < 0; }
	BOOL control_down() { return ::GetKeyState(VK_CONTROL) < 0; }
#ifdef _DEBUG
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif

	int bdr_top_, bdr_left_, bdr_bottom_, bdr_right_; // Borders reserved for ruler etc

	void track_mouse(unsigned long);    // Turns on receipt of mouse hover/leave messages

protected:
	// The following determine the current position in the doc of the top left
	// of the display, the caret and the selection.  caretpos_ is the start of
	// the selection, selpos_ is the end.  caretpos_ == selpos_ if there is
	// nothing selected.  basepos_ is used as the base position when a mouse
	// selection is in progress.
	CPointAp scrollpos_, caretpos_, selpos_, basepos_;

private:
	// The following are in logical units for the window.
	// They determine the total size of the document, the size
	// of a page and a line, for purposes of scrolling and
	// drawing the scrollbar.
	CSizeAp total_, page_, line_;

	// If page or line scroll sizes have been specified we use those
	// values, otherwise we recalculate them when the window size changes.
	BOOL page_specified_, line_specified_;

	// maxbar_ is the number of scrollbar positions.
	// Windows supports only 32768 scrollbar positions so this
	// is necessary if total_.cx/cy is greater than this.
	CSizeAp maxbar_;

	// The following are attributes of the device context
	CPen *pen_;
	CBrush *brush_;
	CFont *font_;
	CBitmap *bitmap_;
	CRgn *rgn_;
	int mapmode_;

	// The following are used to convert between device and logical units
	// (since DPtoLP and LPtoDP in Windows 95 are limited to 16 bit values!!!)
	CPoint dev_;                        // device units
	CPoint log_;                        // logical units

	// The following are just cached for improved scroll bar performance
	__int64 win_height_;
	int win_width_;

	BOOL in_update_;            // internal state for OnSize callback

	BOOL caret_mode_;           // Arrows move caret when on (else arrows just scroll)
	BOOL caret_changes_;        // Is the caret allowed to be changed (moved, deleted etc)?
//    BOOL caret_visible_;      // Has caret been shown? (ie. caretpos_ is in display)
	int caret_level_;           // 0 means caret is visible, > 0 means caret is hidden
	BOOL caret_seen_;           // Is caret actually on (when caret_level_ == 0)
	BOOL caret_block_;          // Is the caret a line or block?

	BOOL scroll_up_;            // Tracks which last scroll dirn so that screen refreshes are drawn to match
	BOOL scroll_past_ends_;     // Allow scroll past ends?
	int autoscroll_accel_;      // Rate at which autoscroll increases as you move past window edge

	int horz_buffer_zone_;      // When displaying caret how many characters from right edge to buffer
	int vert_buffer_zone_;      // Make sure caret stays this many lines from bottom/top edge

//    CPoint valid_pos(const CPoint) const;
	void update_bars(CPointAp newpos = null_point);
	CSizeAp caret_size();
	void caret_show();
	void caret_hide();

	void check_coords();        // Updates values of negx_ and negy_
	bool init_coord_;           // Have we initialised negx_ and negy_
	bool negx_, negy_;          // Are our axes opposite to logical coords?

	// The following used while selectin with mouse
	BOOL mouse_down_;           // Left mouse button is down?
	UINT timer_id_;             // Timer id for auto scroll timer (set in mouse down)

		// Generated message map functions
protected:
//      virtual void CalcWindowRect(LPRECT lpClientRect,UINT nAdjustType = adjustBorder);

		// scrolling implementation support for OLE
		virtual BOOL OnScroll(UINT nScrollCode, UINT nPos, BOOL bDoScroll = TRUE);
		virtual BOOL OnScrollBy(CSize sizeScroll, BOOL bDoScroll = TRUE);

		//{{AFX_MSG(CScrView)
		afx_msg void OnSize(UINT nType, int cx, int cy);
		afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
		afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
		afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
		afx_msg void OnSetFocus(CWnd* pOldWnd);
		afx_msg void OnKillFocus(CWnd* pNewWnd);
		afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
		afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
		afx_msg void OnMouseMove(UINT nFlags, CPoint point);
		afx_msg void OnTimer(UINT nIDEvent);
	afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);
	//}}AFX_MSG
		DECLARE_MESSAGE_MAP()
};

/////////////////////////////////////////////////////////////////////////////
#endif // SCRVIEW_INCLUDED


text:
package io.beanmother.core.util;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;

/**
 * This code is from spring framework org.springframework.util.NumberUtils
 *
 * Miscellaneous utility methods for number conversion and parsing.
 *
Mainly for internal use within the framework; consider Apache's
 * Commons Lang for a more comprehensive suite of number utilities.
 *
 * @author Juergen Hoeller
 * @author Rob Harrop
 * @since 1.1.2
 */
public abstract class NumberUtils {

    private static final BigInteger LONG_MIN = BigInteger.valueOf(Long.MIN_VALUE);

    private static final BigInteger LONG_MAX = BigInteger.valueOf(Long.MAX_VALUE);

    /**
     * Standard number types (all immutable):
     * Byte, Short, Integer, Long, BigInteger, Float, Double, BigDecimal.
     */
    public static final Set<Class<?>> STANDARD_NUMBER_TYPES;

    static {
        Set<Class<?>> numberTypes = new HashSet<>(8);
        numberTypes.add(Byte.class);
        numberTypes.add(Short.class);
        numberTypes.add(Integer.class);
        numberTypes.add(Long.class);
        numberTypes.add(BigInteger.class);
        numberTypes.add(Float.class);
        numberTypes.add(Double.class);
        numberTypes.add(BigDecimal.class);
        STANDARD_NUMBER_TYPES = Collections.unmodifiableSet(numberTypes);
    }

    /**
     * Convert the given number into an instance of the given target class.
     * @param number the number to convert
     * @param targetClass the target class to convert to
     * @return the converted number
     * @throws IllegalArgumentException if the target class is not supported
     * (i.e. not a standard Number subclass as included in the JDK)
     * @see java.lang.Byte
     * @see java.lang.Short
     * @see java.lang.Integer
     * @see java.lang.Long
     * @see java.math.BigInteger
     * @see java.lang.Float
     * @see java.lang.Double
     * @see java.math.BigDecimal
     */
    @SuppressWarnings("unchecked")
    public static <T extends Number> T convertNumberToTargetClass(Number number, Class<T> targetClass)
            throws IllegalArgumentException {

        if (targetClass.isInstance(number)) {
            return (T) number;
        }
        else if (Byte.class == targetClass) {
            long value = checkedLongValue(number, targetClass);
            if (value < Byte.MIN_VALUE || value > Byte.MAX_VALUE) {
                raiseOverflowException(number, targetClass);
            }
            return (T) Byte.valueOf(number.byteValue());
        }
        else if (Short.class == targetClass) {
            long value = checkedLongValue(number, targetClass);
            if (value < Short.MIN_VALUE || value > Short.MAX_VALUE) {
                raiseOverflowException(number, targetClass);
            }
            return (T) Short.valueOf(number.shortValue());
        }
        else if (Integer.class == targetClass) {
            long value = checkedLongValue(number, targetClass);
            if (value < Integer.MIN_VALUE || value > Integer.MAX_VALUE) {
                raiseOverflowException(number, targetClass);
            }
            return (T) Integer.valueOf(number.intValue());
        }
        else if (Long.class == targetClass) {
            long value = checkedLongValue(number, targetClass);
            return (T) Long.valueOf(value);
        }
        else if (BigInteger.class == targetClass) {
            if (number instanceof BigDecimal) {
                // do not lose precision - use BigDecimal's own conversion
                return (T) ((BigDecimal) number).toBigInteger();
            }
            else {
                // original value is not a Big* number - use standard long conversion
                return (T) BigInteger.valueOf(number.longValue());
            }
        }
        else if (Float.class == targetClass) {
            return (T) Float.valueOf(number.floatValue());
        }
        else if (Double.class == targetClass) {
            return (T) Double.valueOf(number.doubleValue());
        }
        else if (BigDecimal.class == targetClass) {
            // always use BigDecimal(String) here to avoid unpredictability of BigDecimal(double)
            // (see BigDecimal javadoc for details)
            return (T) new BigDecimal(number.toString());
        }
        else if (AtomicInteger.class == targetClass) {
            return (T) new AtomicInteger(number.intValue());
        }
        else if (AtomicLong.class == targetClass) {
            return (T) new AtomicLong(number.longValue());
        }
        else {
            throw new IllegalArgumentException("Could not convert number [" + number + "] of type [" +
                    number.getClass().getName() + "] to unsupported target class [" + targetClass.getName() + "]");
        }
    }

    /**
     * Check for a {@code BigInteger}/{@code BigDecimal} long overflow
     * before returning the given number as a long value.
     * @param number the number to convert
     * @param targetClass the target class to convert to
     * @return the long value, if convertible without overflow
     * @throws IllegalArgumentException if there is an overflow
     * @see #raiseOverflowException
     */
    private static long checkedLongValue(Number number, Class<? extends Number> targetClass) {
        BigInteger bigInt = null;
        if (number instanceof BigInteger) {
            bigInt = (BigInteger) number;
        }
        else if (number instanceof BigDecimal) {
            bigInt = ((BigDecimal) number).toBigInteger();
        }
        // Effectively analogous to JDK 8's BigInteger.longValueExact()
        if (bigInt != null && (bigInt.compareTo(LONG_MIN) < 0 || bigInt.compareTo(LONG_MAX) > 0)) {
            raiseOverflowException(number, targetClass);
        }
        return number.longValue();
    }

    /**
     * Raise an overflow exception for the given number and target class.
     * @param number the number we tried to convert
     * @param targetClass the target class we tried to convert to
     * @throws IllegalArgumentException if there is an overflow
     */
    private static void raiseOverflowException(Number number, Class<?> targetClass) {
        throw new IllegalArgumentException("Could not convert number [" + number + "] of type [" +
                number.getClass().getName() + "] to target class [" + targetClass.getName() + "]: overflow");
    }

    /**
     * Parse the given {@code text} into a {@link Number} instance of the given
     * target class, using the corresponding {@code decode} / {@code valueOf} method.
     *
Trims the input {@code String} before attempting to parse the number.
     *
Supports numbers in hex format (with leading "0x", "0X", or "#") as well.
     * @param text the text to convert
     * @param targetClass the target class to parse into
     * @return the parsed number
     * @throws IllegalArgumentException if the target class is not supported
     * (i.e. not a standard Number subclass as included in the JDK)
     * @see Byte#decode
     * @see Short#decode
     * @see Integer#decode
     * @see Long#decode
     * @see #decodeBigInteger(String)
     * @see Float#valueOf
     * @see Double#valueOf
     * @see java.math.BigDecimal#BigDecimal(String)
     */
    @SuppressWarnings("unchecked")
    public static <T extends Number> T parseNumber(String text, Class<T> targetClass) {
        String trimmed = trimAllWhitespace(text);

        if (Byte.class == targetClass) {
            return (T) (isHexNumber(trimmed) ? Byte.decode(trimmed) : Byte.valueOf(trimmed));
        }
        else if (Short.class == targetClass) {
            return (T) (isHexNumber(trimmed) ? Short.decode(trimmed) : Short.valueOf(trimmed));
        }
        else if (Integer.class == targetClass) {
            return (T) (isHexNumber(trimmed) ? Integer.decode(trimmed) : Integer.valueOf(trimmed));
        }
        else if (Long.class == targetClass) {
            return (T) (isHexNumber(trimmed) ? Long.decode(trimmed) : Long.valueOf(trimmed));
        }
        else if (BigInteger.class == targetClass) {
            return (T) (isHexNumber(trimmed) ? decodeBigInteger(trimmed) : new BigInteger(trimmed));
        }
        else if (Float.class == targetClass) {
            return (T) Float.valueOf(trimmed);
        }
        else if (Double.class == targetClass) {
            return (T) Double.valueOf(trimmed);
        }
        else if (BigDecimal.class == targetClass || Number.class == targetClass) {
            return (T) new BigDecimal(trimmed);
        }
        else {
            throw new IllegalArgumentException(
                    "Cannot convert String [" + text + "] to target class [" + targetClass.getName() + "]");
        }
    }

    /**
     * Determine whether the given {@code value} String indicates a hex number,
     * i.e. needs to be passed into {@code Integer.decode} instead of
     * {@code Integer.valueOf}, etc.
     */
    private static boolean isHexNumber(String value) {
        int index = (value.startsWith("-") ? 1 : 0);
        return (value.startsWith("0x", index) || value.startsWith("0X", index) || value.startsWith("#", index));
    }

    /**
     * Decode a {@link java.math.BigInteger} from the supplied {@link String} value.
     *
Supports decimal, hex, and octal notation.
     * @see BigInteger#BigInteger(String, int)
     */
    private static BigInteger decodeBigInteger(String value) {
        int radix = 10;
        int index = 0;
        boolean negative = false;

        // Handle minus sign, if present.
        if (value.startsWith("-")) {
            negative = true;
            index++;
        }

        // Handle radix specifier, if present.
        if (value.startsWith("0x", index) || value.startsWith("0X", index)) {
            index += 2;
            radix = 16;
        }
        else if (value.startsWith("#", index)) {
            index++;
            radix = 16;
        }
        else if (value.startsWith("0", index) && value.length() > 1 + index) {
            index++;
            radix = 8;
        }

        BigInteger result = new BigInteger(value.substring(index), radix);
        return (negative ? result.negate() : result);
    }

    public static String trimAllWhitespace(String str) {
        if (str == null || str.length() == 0) {
            return str;
        }

        int len = str.length();
        StringBuilder sb = new StringBuilder(str.length());
        for (int i = 0; i < len; i++) {
            char c = str.charAt(i);
            if (!Character.isWhitespace(c)) {
                sb.append(c);
            }
        }
        return sb.toString();
    }

}