changeset 438:d29cce60f393

migrate from Eclipse to Android Studio
author Carl Byington <carl@five-ten-sg.com>
date Thu, 03 Dec 2015 11:23:55 -0800
parents 208b31032318
children 50d28338ae6e
files .classpath .hgignore .project .settings/org.eclipse.jdt.core.prefs .settings/org.eclipse.jdt.ui.prefs AndroidManifest.xml Makefile ant.properties app/build.gradle app/lint.xml app/src/main/AndroidManifest.xml app/src/main/java/ch/ethz/ssh2/AbstractSFTPClient.java app/src/main/java/ch/ethz/ssh2/AuthAgentCallback.java app/src/main/java/ch/ethz/ssh2/AuthenticationResult.java app/src/main/java/ch/ethz/ssh2/ChannelCondition.java app/src/main/java/ch/ethz/ssh2/Connection.java app/src/main/java/ch/ethz/ssh2/ConnectionInfo.java app/src/main/java/ch/ethz/ssh2/ConnectionMonitor.java app/src/main/java/ch/ethz/ssh2/DHGexParameters.java app/src/main/java/ch/ethz/ssh2/DynamicPortForwarder.java app/src/main/java/ch/ethz/ssh2/HTTPProxyData.java app/src/main/java/ch/ethz/ssh2/HTTPProxyException.java app/src/main/java/ch/ethz/ssh2/InteractiveCallback.java app/src/main/java/ch/ethz/ssh2/KnownHosts.java app/src/main/java/ch/ethz/ssh2/LocalPortForwarder.java app/src/main/java/ch/ethz/ssh2/LocalStreamForwarder.java app/src/main/java/ch/ethz/ssh2/PacketFormatException.java app/src/main/java/ch/ethz/ssh2/PacketListener.java app/src/main/java/ch/ethz/ssh2/PacketTypeException.java app/src/main/java/ch/ethz/ssh2/ProxyData.java app/src/main/java/ch/ethz/ssh2/PtySettings.java app/src/main/java/ch/ethz/ssh2/RequestMismatchException.java app/src/main/java/ch/ethz/ssh2/SCPClient.java app/src/main/java/ch/ethz/ssh2/SCPInputStream.java app/src/main/java/ch/ethz/ssh2/SCPOutputStream.java app/src/main/java/ch/ethz/ssh2/SFTPClient.java app/src/main/java/ch/ethz/ssh2/SFTPDirectoryEntry.java app/src/main/java/ch/ethz/ssh2/SFTPException.java app/src/main/java/ch/ethz/ssh2/SFTPFileAttributes.java app/src/main/java/ch/ethz/ssh2/SFTPFileHandle.java app/src/main/java/ch/ethz/ssh2/SFTPInputStream.java app/src/main/java/ch/ethz/ssh2/SFTPOutputStream.java app/src/main/java/ch/ethz/ssh2/SFTPv3Client.java app/src/main/java/ch/ethz/ssh2/SFTPv3DirectoryEntry.java app/src/main/java/ch/ethz/ssh2/SFTPv3FileAttributes.java app/src/main/java/ch/ethz/ssh2/SFTPv3FileHandle.java app/src/main/java/ch/ethz/ssh2/SFTPv6Client.java app/src/main/java/ch/ethz/ssh2/SFTPv6DirectoryEntry.java app/src/main/java/ch/ethz/ssh2/SFTPv6FileAttributes.java app/src/main/java/ch/ethz/ssh2/ServerAuthenticationCallback.java app/src/main/java/ch/ethz/ssh2/ServerConnection.java app/src/main/java/ch/ethz/ssh2/ServerConnectionCallback.java app/src/main/java/ch/ethz/ssh2/ServerHostKeyVerifier.java app/src/main/java/ch/ethz/ssh2/ServerSession.java app/src/main/java/ch/ethz/ssh2/ServerSessionCallback.java app/src/main/java/ch/ethz/ssh2/Session.java app/src/main/java/ch/ethz/ssh2/SimpleServerSessionCallback.java app/src/main/java/ch/ethz/ssh2/StreamGobbler.java app/src/main/java/ch/ethz/ssh2/Version.java app/src/main/java/ch/ethz/ssh2/auth/AgentIdentity.java app/src/main/java/ch/ethz/ssh2/auth/AgentProxy.java app/src/main/java/ch/ethz/ssh2/auth/AuthenticationManager.java app/src/main/java/ch/ethz/ssh2/auth/ServerAuthenticationManager.java app/src/main/java/ch/ethz/ssh2/channel/AuthAgentForwardThread.java app/src/main/java/ch/ethz/ssh2/channel/Channel.java app/src/main/java/ch/ethz/ssh2/channel/ChannelClosedException.java app/src/main/java/ch/ethz/ssh2/channel/ChannelInputStream.java app/src/main/java/ch/ethz/ssh2/channel/ChannelManager.java app/src/main/java/ch/ethz/ssh2/channel/ChannelOutputStream.java app/src/main/java/ch/ethz/ssh2/channel/DynamicAcceptThread.java app/src/main/java/ch/ethz/ssh2/channel/IChannelWorkerThread.java app/src/main/java/ch/ethz/ssh2/channel/LocalAcceptThread.java app/src/main/java/ch/ethz/ssh2/channel/RemoteAcceptThread.java app/src/main/java/ch/ethz/ssh2/channel/RemoteForwardingData.java app/src/main/java/ch/ethz/ssh2/channel/RemoteX11AcceptThread.java app/src/main/java/ch/ethz/ssh2/channel/ServerSessionImpl.java app/src/main/java/ch/ethz/ssh2/channel/StreamForwarder.java app/src/main/java/ch/ethz/ssh2/channel/X11ServerData.java app/src/main/java/ch/ethz/ssh2/compression/CompressionFactory.java app/src/main/java/ch/ethz/ssh2/compression/Compressor.java app/src/main/java/ch/ethz/ssh2/compression/Zlib.java app/src/main/java/ch/ethz/ssh2/compression/ZlibOpenSSH.java app/src/main/java/ch/ethz/ssh2/crypto/Base64.java app/src/main/java/ch/ethz/ssh2/crypto/CryptoWishList.java app/src/main/java/ch/ethz/ssh2/crypto/KeyMaterial.java app/src/main/java/ch/ethz/ssh2/crypto/PEMDecoder.java app/src/main/java/ch/ethz/ssh2/crypto/PEMDecryptException.java app/src/main/java/ch/ethz/ssh2/crypto/PEMStructure.java app/src/main/java/ch/ethz/ssh2/crypto/SecureRandomFix.java app/src/main/java/ch/ethz/ssh2/crypto/SimpleDERReader.java app/src/main/java/ch/ethz/ssh2/crypto/cipher/AES.java app/src/main/java/ch/ethz/ssh2/crypto/cipher/BlockCipher.java app/src/main/java/ch/ethz/ssh2/crypto/cipher/BlockCipherFactory.java app/src/main/java/ch/ethz/ssh2/crypto/cipher/BlowFish.java app/src/main/java/ch/ethz/ssh2/crypto/cipher/CBCMode.java app/src/main/java/ch/ethz/ssh2/crypto/cipher/CTRMode.java app/src/main/java/ch/ethz/ssh2/crypto/cipher/CipherInputStream.java app/src/main/java/ch/ethz/ssh2/crypto/cipher/CipherOutputStream.java app/src/main/java/ch/ethz/ssh2/crypto/cipher/DES.java app/src/main/java/ch/ethz/ssh2/crypto/cipher/DESede.java app/src/main/java/ch/ethz/ssh2/crypto/cipher/NullCipher.java app/src/main/java/ch/ethz/ssh2/crypto/dh/DhExchange.java app/src/main/java/ch/ethz/ssh2/crypto/dh/DhGroupExchange.java app/src/main/java/ch/ethz/ssh2/crypto/dh/EcDhExchange.java app/src/main/java/ch/ethz/ssh2/crypto/dh/GenericDhExchange.java app/src/main/java/ch/ethz/ssh2/crypto/digest/Digest.java app/src/main/java/ch/ethz/ssh2/crypto/digest/HMAC.java app/src/main/java/ch/ethz/ssh2/crypto/digest/HashForSSH2Types.java app/src/main/java/ch/ethz/ssh2/crypto/digest/MAC.java app/src/main/java/ch/ethz/ssh2/crypto/digest/MD5.java app/src/main/java/ch/ethz/ssh2/crypto/digest/SHA1.java app/src/main/java/ch/ethz/ssh2/crypto/digest/SHA256.java app/src/main/java/ch/ethz/ssh2/crypto/digest/SHA512.java app/src/main/java/ch/ethz/ssh2/log/Logger.java app/src/main/java/ch/ethz/ssh2/packets/PacketChannelAuthAgentReq.java app/src/main/java/ch/ethz/ssh2/packets/PacketChannelFailure.java app/src/main/java/ch/ethz/ssh2/packets/PacketChannelOpenConfirmation.java app/src/main/java/ch/ethz/ssh2/packets/PacketChannelOpenFailure.java app/src/main/java/ch/ethz/ssh2/packets/PacketChannelSuccess.java app/src/main/java/ch/ethz/ssh2/packets/PacketChannelWindowAdjust.java app/src/main/java/ch/ethz/ssh2/packets/PacketDisconnect.java app/src/main/java/ch/ethz/ssh2/packets/PacketGlobalCancelForwardRequest.java app/src/main/java/ch/ethz/ssh2/packets/PacketGlobalForwardRequest.java app/src/main/java/ch/ethz/ssh2/packets/PacketIgnore.java app/src/main/java/ch/ethz/ssh2/packets/PacketKexDHInit.java app/src/main/java/ch/ethz/ssh2/packets/PacketKexDHReply.java app/src/main/java/ch/ethz/ssh2/packets/PacketKexDhGexGroup.java app/src/main/java/ch/ethz/ssh2/packets/PacketKexDhGexInit.java app/src/main/java/ch/ethz/ssh2/packets/PacketKexDhGexReply.java app/src/main/java/ch/ethz/ssh2/packets/PacketKexDhGexRequest.java app/src/main/java/ch/ethz/ssh2/packets/PacketKexDhGexRequestOld.java app/src/main/java/ch/ethz/ssh2/packets/PacketKexInit.java app/src/main/java/ch/ethz/ssh2/packets/PacketNewKeys.java app/src/main/java/ch/ethz/ssh2/packets/PacketOpenDirectTCPIPChannel.java app/src/main/java/ch/ethz/ssh2/packets/PacketOpenSessionChannel.java app/src/main/java/ch/ethz/ssh2/packets/PacketServiceAccept.java app/src/main/java/ch/ethz/ssh2/packets/PacketServiceRequest.java app/src/main/java/ch/ethz/ssh2/packets/PacketSessionExecCommand.java app/src/main/java/ch/ethz/ssh2/packets/PacketSessionPtyRequest.java app/src/main/java/ch/ethz/ssh2/packets/PacketSessionStartShell.java app/src/main/java/ch/ethz/ssh2/packets/PacketSessionSubsystemRequest.java app/src/main/java/ch/ethz/ssh2/packets/PacketSessionX11Request.java app/src/main/java/ch/ethz/ssh2/packets/PacketUserauthBanner.java app/src/main/java/ch/ethz/ssh2/packets/PacketUserauthFailure.java app/src/main/java/ch/ethz/ssh2/packets/PacketUserauthInfoRequest.java app/src/main/java/ch/ethz/ssh2/packets/PacketUserauthInfoResponse.java app/src/main/java/ch/ethz/ssh2/packets/PacketUserauthRequestInteractive.java app/src/main/java/ch/ethz/ssh2/packets/PacketUserauthRequestNone.java app/src/main/java/ch/ethz/ssh2/packets/PacketUserauthRequestPassword.java app/src/main/java/ch/ethz/ssh2/packets/PacketUserauthRequestPublicKey.java app/src/main/java/ch/ethz/ssh2/packets/PacketUserauthSuccess.java app/src/main/java/ch/ethz/ssh2/packets/PacketWindowChange.java app/src/main/java/ch/ethz/ssh2/packets/Packets.java app/src/main/java/ch/ethz/ssh2/packets/TypesReader.java app/src/main/java/ch/ethz/ssh2/packets/TypesWriter.java app/src/main/java/ch/ethz/ssh2/server/ServerConnectionState.java app/src/main/java/ch/ethz/ssh2/sftp/AceFlags.java app/src/main/java/ch/ethz/ssh2/sftp/AceMask.java app/src/main/java/ch/ethz/ssh2/sftp/AceType.java app/src/main/java/ch/ethz/ssh2/sftp/AclFlags.java app/src/main/java/ch/ethz/ssh2/sftp/AttrTextHints.java app/src/main/java/ch/ethz/ssh2/sftp/AttribBits.java app/src/main/java/ch/ethz/ssh2/sftp/AttribFlags.java app/src/main/java/ch/ethz/ssh2/sftp/AttribPermissions.java app/src/main/java/ch/ethz/ssh2/sftp/AttribTypes.java app/src/main/java/ch/ethz/ssh2/sftp/ErrorCodes.java app/src/main/java/ch/ethz/ssh2/sftp/OpenFlags.java app/src/main/java/ch/ethz/ssh2/sftp/Packet.java app/src/main/java/ch/ethz/ssh2/signature/DSASHA1Verify.java app/src/main/java/ch/ethz/ssh2/signature/ECDSASHA2Verify.java app/src/main/java/ch/ethz/ssh2/signature/RSASHA1Verify.java app/src/main/java/ch/ethz/ssh2/transport/ClientKexManager.java app/src/main/java/ch/ethz/ssh2/transport/ClientServerHello.java app/src/main/java/ch/ethz/ssh2/transport/ClientTransportManager.java app/src/main/java/ch/ethz/ssh2/transport/DisconnectException.java app/src/main/java/ch/ethz/ssh2/transport/HTTPProxyClientTransportManager.java app/src/main/java/ch/ethz/ssh2/transport/KexManager.java app/src/main/java/ch/ethz/ssh2/transport/KexParameters.java app/src/main/java/ch/ethz/ssh2/transport/KexState.java app/src/main/java/ch/ethz/ssh2/transport/MessageHandler.java app/src/main/java/ch/ethz/ssh2/transport/NegotiateException.java app/src/main/java/ch/ethz/ssh2/transport/NegotiatedParameters.java app/src/main/java/ch/ethz/ssh2/transport/ServerKexManager.java app/src/main/java/ch/ethz/ssh2/transport/ServerTransportManager.java app/src/main/java/ch/ethz/ssh2/transport/TransportConnection.java app/src/main/java/ch/ethz/ssh2/transport/TransportManager.java app/src/main/java/ch/ethz/ssh2/util/StringEncoder.java app/src/main/java/ch/ethz/ssh2/util/TimeoutService.java app/src/main/java/com/five_ten_sg/connectbot/ActionBarWrapper.java app/src/main/java/com/five_ten_sg/connectbot/ColorsActivity.java app/src/main/java/com/five_ten_sg/connectbot/ConsoleActivity.java app/src/main/java/com/five_ten_sg/connectbot/GeneratePubkeyActivity.java app/src/main/java/com/five_ten_sg/connectbot/HelpActivity.java app/src/main/java/com/five_ten_sg/connectbot/HelpTopicActivity.java app/src/main/java/com/five_ten_sg/connectbot/HostEditorActivity.java app/src/main/java/com/five_ten_sg/connectbot/HostListActivity.java app/src/main/java/com/five_ten_sg/connectbot/PortForwardListActivity.java app/src/main/java/com/five_ten_sg/connectbot/PubkeyListActivity.java app/src/main/java/com/five_ten_sg/connectbot/SettingsActivity.java app/src/main/java/com/five_ten_sg/connectbot/StrictModeSetup.java app/src/main/java/com/five_ten_sg/connectbot/TerminalView.java app/src/main/java/com/five_ten_sg/connectbot/WizardActivity.java app/src/main/java/com/five_ten_sg/connectbot/bean/AbstractBean.java app/src/main/java/com/five_ten_sg/connectbot/bean/HostBean.java app/src/main/java/com/five_ten_sg/connectbot/bean/PortForwardBean.java app/src/main/java/com/five_ten_sg/connectbot/bean/PubkeyBean.java app/src/main/java/com/five_ten_sg/connectbot/bean/SelectionArea.java app/src/main/java/com/five_ten_sg/connectbot/service/AuthAgentService.java app/src/main/java/com/five_ten_sg/connectbot/service/BackupAgent.java app/src/main/java/com/five_ten_sg/connectbot/service/BridgeDisconnectedListener.java app/src/main/java/com/five_ten_sg/connectbot/service/ConnectionNotifier.java app/src/main/java/com/five_ten_sg/connectbot/service/ConnectivityReceiver.java app/src/main/java/com/five_ten_sg/connectbot/service/FontSizeChangedListener.java app/src/main/java/com/five_ten_sg/connectbot/service/PromptHelper.java app/src/main/java/com/five_ten_sg/connectbot/service/Relay.java app/src/main/java/com/five_ten_sg/connectbot/service/TerminalBridge.java app/src/main/java/com/five_ten_sg/connectbot/service/TerminalKeyListener.java app/src/main/java/com/five_ten_sg/connectbot/service/TerminalManager.java app/src/main/java/com/five_ten_sg/connectbot/service/TerminalMonitor.java app/src/main/java/com/five_ten_sg/connectbot/transport/AbsTransport.java app/src/main/java/com/five_ten_sg/connectbot/transport/Local.java app/src/main/java/com/five_ten_sg/connectbot/transport/SSH.java app/src/main/java/com/five_ten_sg/connectbot/transport/TN5250.java app/src/main/java/com/five_ten_sg/connectbot/transport/Telnet.java app/src/main/java/com/five_ten_sg/connectbot/transport/TransportFactory.java app/src/main/java/com/five_ten_sg/connectbot/util/Colors.java app/src/main/java/com/five_ten_sg/connectbot/util/Encryptor.java app/src/main/java/com/five_ten_sg/connectbot/util/EntropyDialog.java app/src/main/java/com/five_ten_sg/connectbot/util/EntropyView.java app/src/main/java/com/five_ten_sg/connectbot/util/FileChooser.java app/src/main/java/com/five_ten_sg/connectbot/util/FileChooserCallback.java app/src/main/java/com/five_ten_sg/connectbot/util/HelpTopicView.java app/src/main/java/com/five_ten_sg/connectbot/util/HostDatabase.java app/src/main/java/com/five_ten_sg/connectbot/util/OnDbWrittenListener.java app/src/main/java/com/five_ten_sg/connectbot/util/OnEntropyGatheredListener.java app/src/main/java/com/five_ten_sg/connectbot/util/PreferenceConstants.java app/src/main/java/com/five_ten_sg/connectbot/util/PubkeyDatabase.java app/src/main/java/com/five_ten_sg/connectbot/util/PubkeyUtils.java app/src/main/java/com/five_ten_sg/connectbot/util/RobustSQLiteOpenHelper.java app/src/main/java/com/five_ten_sg/connectbot/util/StringPickerDialog.java app/src/main/java/com/five_ten_sg/connectbot/util/TransferThread.java app/src/main/java/com/five_ten_sg/connectbot/util/UberColorPickerDialog.java app/src/main/java/com/five_ten_sg/connectbot/util/VolumePreference.java app/src/main/java/com/five_ten_sg/connectbot/util/XmlBuilder.java app/src/main/java/com/google/ase/Exec.java app/src/main/java/com/jcraft/jzlib/Adler32.java app/src/main/java/com/jcraft/jzlib/CRC32.java app/src/main/java/com/jcraft/jzlib/Checksum.java app/src/main/java/com/jcraft/jzlib/Deflate.java app/src/main/java/com/jcraft/jzlib/Deflater.java app/src/main/java/com/jcraft/jzlib/DeflaterOutputStream.java app/src/main/java/com/jcraft/jzlib/GZIPException.java app/src/main/java/com/jcraft/jzlib/GZIPHeader.java app/src/main/java/com/jcraft/jzlib/GZIPInputStream.java app/src/main/java/com/jcraft/jzlib/GZIPOutputStream.java app/src/main/java/com/jcraft/jzlib/InfBlocks.java app/src/main/java/com/jcraft/jzlib/InfCodes.java app/src/main/java/com/jcraft/jzlib/InfTree.java app/src/main/java/com/jcraft/jzlib/Inflate.java app/src/main/java/com/jcraft/jzlib/Inflater.java app/src/main/java/com/jcraft/jzlib/InflaterInputStream.java app/src/main/java/com/jcraft/jzlib/JZlib.java app/src/main/java/com/jcraft/jzlib/StaticTree.java app/src/main/java/com/jcraft/jzlib/Tree.java app/src/main/java/com/jcraft/jzlib/ZInputStream.java app/src/main/java/com/jcraft/jzlib/ZOutputStream.java app/src/main/java/com/jcraft/jzlib/ZStream.java app/src/main/java/com/jcraft/jzlib/ZStreamException.java app/src/main/java/com/lamerman/FileDialog.java app/src/main/java/com/lamerman/SelectionMode.java app/src/main/java/com/madgag/ssh/android/authagent/AndroidAuthAgent.java app/src/main/java/de/mud/telnet/TelnetProtocolHandler.java app/src/main/java/de/mud/terminal/Precomposer.java app/src/main/java/de/mud/terminal/VDUBuffer.java app/src/main/java/de/mud/terminal/VDUDisplay.java app/src/main/java/de/mud/terminal/VDUInput.java app/src/main/java/de/mud/terminal/vt320.java app/src/main/java/net/sourceforge/jsocks/Authentication.java app/src/main/java/net/sourceforge/jsocks/AuthenticationNone.java app/src/main/java/net/sourceforge/jsocks/CProxy.java app/src/main/java/net/sourceforge/jsocks/InetRange.java app/src/main/java/net/sourceforge/jsocks/ProxyMessage.java app/src/main/java/net/sourceforge/jsocks/ProxyServer.java app/src/main/java/net/sourceforge/jsocks/Socks4Message.java app/src/main/java/net/sourceforge/jsocks/Socks4Proxy.java app/src/main/java/net/sourceforge/jsocks/Socks5DatagramSocket.java app/src/main/java/net/sourceforge/jsocks/Socks5Message.java app/src/main/java/net/sourceforge/jsocks/Socks5Proxy.java app/src/main/java/net/sourceforge/jsocks/SocksException.java app/src/main/java/net/sourceforge/jsocks/SocksServerSocket.java app/src/main/java/net/sourceforge/jsocks/SocksSocket.java app/src/main/java/net/sourceforge/jsocks/UDPEncapsulation.java app/src/main/java/net/sourceforge/jsocks/UDPRelayServer.java app/src/main/java/net/sourceforge/jsocks/UserPasswordAuthentication.java app/src/main/java/net/sourceforge/jsocks/server/Ident.java app/src/main/java/net/sourceforge/jsocks/server/IdentAuthenticator.java app/src/main/java/net/sourceforge/jsocks/server/ServerAuthenticator.java app/src/main/java/net/sourceforge/jsocks/server/ServerAuthenticatorNone.java app/src/main/java/net/sourceforge/jsocks/server/UserPasswordAuthenticator.java app/src/main/java/net/sourceforge/jsocks/server/UserValidation.java app/src/main/java/org/apache/harmony/niochar/charset/additional/IBM437.java app/src/main/java/org/keyczar/jce/EcCore.java app/src/main/java/org/openintents/intents/FileManagerIntents.java app/src/main/java/org/tn5250j/TN5250jConstants.java app/src/main/java/org/tn5250j/encoding/AbstractCodePage.java app/src/main/java/org/tn5250j/encoding/BuiltInCodePageFactory.java app/src/main/java/org/tn5250j/encoding/CharMappings.java app/src/main/java/org/tn5250j/encoding/ICodePage.java app/src/main/java/org/tn5250j/encoding/JavaCodePageFactory.java app/src/main/java/org/tn5250j/encoding/ToolboxCodePageFactory.java app/src/main/java/org/tn5250j/encoding/builtin/CCSID1025.java app/src/main/java/org/tn5250j/encoding/builtin/CCSID1026.java app/src/main/java/org/tn5250j/encoding/builtin/CCSID1112.java app/src/main/java/org/tn5250j/encoding/builtin/CCSID1140.java app/src/main/java/org/tn5250j/encoding/builtin/CCSID1141.java app/src/main/java/org/tn5250j/encoding/builtin/CCSID1147.java app/src/main/java/org/tn5250j/encoding/builtin/CCSID1148.java app/src/main/java/org/tn5250j/encoding/builtin/CCSID273.java app/src/main/java/org/tn5250j/encoding/builtin/CCSID277.java app/src/main/java/org/tn5250j/encoding/builtin/CCSID278.java app/src/main/java/org/tn5250j/encoding/builtin/CCSID280.java app/src/main/java/org/tn5250j/encoding/builtin/CCSID284.java app/src/main/java/org/tn5250j/encoding/builtin/CCSID285.java app/src/main/java/org/tn5250j/encoding/builtin/CCSID297.java app/src/main/java/org/tn5250j/encoding/builtin/CCSID37.java app/src/main/java/org/tn5250j/encoding/builtin/CCSID424.java app/src/main/java/org/tn5250j/encoding/builtin/CCSID500.java app/src/main/java/org/tn5250j/encoding/builtin/CCSID870.java app/src/main/java/org/tn5250j/encoding/builtin/CCSID871.java app/src/main/java/org/tn5250j/encoding/builtin/CCSID875.java app/src/main/java/org/tn5250j/encoding/builtin/CodepageConverterAdapter.java app/src/main/java/org/tn5250j/encoding/builtin/ICodepageConverter.java app/src/main/java/org/tn5250j/event/ScreenOIAListener.java app/src/main/java/org/tn5250j/framework/tn5250/DataStreamProducer.java app/src/main/java/org/tn5250j/framework/tn5250/KbdTypesCodePages.java app/src/main/java/org/tn5250j/framework/tn5250/KeyStrokenizer.java app/src/main/java/org/tn5250j/framework/tn5250/Rect.java app/src/main/java/org/tn5250j/framework/tn5250/Screen5250.java app/src/main/java/org/tn5250j/framework/tn5250/ScreenField.java app/src/main/java/org/tn5250j/framework/tn5250/ScreenFields.java app/src/main/java/org/tn5250j/framework/tn5250/ScreenOIA.java app/src/main/java/org/tn5250j/framework/tn5250/ScreenPlanes.java app/src/main/java/org/tn5250j/framework/tn5250/Stream5250.java app/src/main/java/org/tn5250j/framework/tn5250/WTDSFParser.java app/src/main/java/org/tn5250j/framework/tn5250/tnvt.java app/src/main/java/org/tn5250j/framework/transport/SSL/SSLImplementation.java app/src/main/java/org/tn5250j/framework/transport/SSL/X509CertificateTrustManager.java app/src/main/java/org/tn5250j/framework/transport/SSLInterface.java app/src/main/java/org/tn5250j/framework/transport/SocketConnector.java app/src/main/jni/Android.mk app/src/main/jni/Application.mk app/src/main/jni/Exec/Android.mk app/src/main/jni/Exec/com_google_ase_Exec.cpp app/src/main/jni/Exec/com_google_ase_Exec.h app/src/main/res/anim/fade_out_delayed.xml app/src/main/res/anim/fade_stay_hidden.xml app/src/main/res/anim/keyboard_fade_in.xml app/src/main/res/anim/keyboard_fade_out.xml app/src/main/res/anim/slide_left_in.xml app/src/main/res/anim/slide_left_out.xml app/src/main/res/anim/slide_right_in.xml app/src/main/res/anim/slide_right_out.xml app/src/main/res/color/blue.xml app/src/main/res/color/green.xml app/src/main/res/color/red.xml app/src/main/res/drawable-hdpi/btn_close_normal.png app/src/main/res/drawable-hdpi/btn_close_pressed.png app/src/main/res/drawable-hdpi/btn_close_selected.png app/src/main/res/drawable-hdpi/icon.png app/src/main/res/drawable-hdpi/keyboard_popup_panel_trans_background.9.png app/src/main/res/drawable-hdpi/notification_icon.png app/src/main/res/drawable-ldpi/btn_close_normal.png app/src/main/res/drawable-ldpi/btn_close_pressed.png app/src/main/res/drawable-ldpi/btn_close_selected.png app/src/main/res/drawable-ldpi/icon.png app/src/main/res/drawable-ldpi/keyboard_popup_panel_trans_background.9.png app/src/main/res/drawable-ldpi/notification_icon.png app/src/main/res/drawable-mdpi/btn_close_normal.png app/src/main/res/drawable-mdpi/btn_close_pressed.png app/src/main/res/drawable-mdpi/btn_close_selected.png app/src/main/res/drawable-mdpi/button_ctrl.png app/src/main/res/drawable-mdpi/button_esc.png app/src/main/res/drawable-mdpi/button_input.png app/src/main/res/drawable-mdpi/button_keyboard.png app/src/main/res/drawable-mdpi/button_sym.png app/src/main/res/drawable-mdpi/file.png app/src/main/res/drawable-mdpi/folder.png app/src/main/res/drawable-mdpi/highlight_disabled_pressed.9.png app/src/main/res/drawable-mdpi/ic_btn_back.png app/src/main/res/drawable-mdpi/ic_btn_next.png app/src/main/res/drawable-mdpi/icon.png app/src/main/res/drawable-mdpi/keyboard_popup_panel_trans_background.9.png app/src/main/res/drawable-mdpi/notification_icon.png app/src/main/res/drawable-mdpi/pubkey_locked.png app/src/main/res/drawable-mdpi/pubkey_unlocked.png app/src/main/res/drawable-xhdpi/btn_close_normal.png app/src/main/res/drawable-xhdpi/btn_close_pressed.png app/src/main/res/drawable-xhdpi/btn_close_selected.png app/src/main/res/drawable-xhdpi/icon.png app/src/main/res/drawable-xhdpi/keyboard_popup_panel_trans_background.9.png app/src/main/res/drawable-xhdpi/notification_icon.png app/src/main/res/drawable-xxhdpi/icon.png app/src/main/res/drawable-xxhdpi/notification_icon.png app/src/main/res/drawable-xxxhdpi/icon.png app/src/main/res/drawable-xxxhdpi/notification_icon.png app/src/main/res/drawable/btn_close.xml app/src/main/res/drawable/connected.xml app/src/main/res/drawable/pubkey.xml app/src/main/res/layout-land/item_host.xml app/src/main/res/layout-port/item_host.xml app/src/main/res/layout/act_colors.xml app/src/main/res/layout/act_console.xml app/src/main/res/layout/act_generatepubkey.xml app/src/main/res/layout/act_help.xml app/src/main/res/layout/act_help_topic.xml app/src/main/res/layout/act_hostlist.xml app/src/main/res/layout/act_portforwardlist.xml app/src/main/res/layout/act_pubkeylist.xml app/src/main/res/layout/act_wizard.xml app/src/main/res/layout/dia_changepassword.xml app/src/main/res/layout/dia_gatherentropy.xml app/src/main/res/layout/dia_password.xml app/src/main/res/layout/dia_portforward.xml app/src/main/res/layout/dia_resize.xml app/src/main/res/layout/file_dialog_main.xml app/src/main/res/layout/file_dialog_row.xml app/src/main/res/layout/item_portforward.xml app/src/main/res/layout/item_pubkey.xml app/src/main/res/layout/item_terminal.xml app/src/main/res/layout/string_picker.xml app/src/main/res/layout/string_picker_button.xml app/src/main/res/layout/wiz_eula.xml app/src/main/res/raw/bell.ogg app/src/main/res/values-af/strings.xml app/src/main/res/values-ar/strings.xml app/src/main/res/values-be/strings.xml app/src/main/res/values-bg/strings.xml app/src/main/res/values-ca/strings.xml app/src/main/res/values-cs/strings.xml app/src/main/res/values-da/strings.xml app/src/main/res/values-de/strings.xml app/src/main/res/values-el/strings.xml app/src/main/res/values-en-rCA/strings.xml app/src/main/res/values-en-rGB/strings.xml app/src/main/res/values-es/strings.xml app/src/main/res/values-eu/strings.xml app/src/main/res/values-fa/strings.xml app/src/main/res/values-fi/strings.xml app/src/main/res/values-fr/strings.xml app/src/main/res/values-gl/strings.xml app/src/main/res/values-he/strings.xml app/src/main/res/values-hr/strings.xml app/src/main/res/values-hu/strings.xml app/src/main/res/values-id/strings.xml app/src/main/res/values-is/strings.xml app/src/main/res/values-it/strings.xml app/src/main/res/values-ja/strings.xml app/src/main/res/values-ka/strings.xml app/src/main/res/values-ko/strings.xml app/src/main/res/values-lt/strings.xml app/src/main/res/values-lv/strings.xml app/src/main/res/values-mk/strings.xml app/src/main/res/values-nb/strings.xml app/src/main/res/values-nl/strings.xml app/src/main/res/values-oc/strings.xml app/src/main/res/values-pl/strings.xml app/src/main/res/values-pt-rBR/strings.xml app/src/main/res/values-pt/strings.xml app/src/main/res/values-ro/strings.xml app/src/main/res/values-ru/strings.xml app/src/main/res/values-sk/strings.xml app/src/main/res/values-sl/strings.xml app/src/main/res/values-sv/strings.xml app/src/main/res/values-tr/strings.xml app/src/main/res/values-uk/strings.xml app/src/main/res/values-v11/styles.xml app/src/main/res/values-v14/styles.xml app/src/main/res/values-vi/strings.xml app/src/main/res/values-zh-rCN/strings.xml app/src/main/res/values-zh-rHK/strings.xml app/src/main/res/values-zh-rTW/strings.xml app/src/main/res/values/arrays.xml app/src/main/res/values/notrans.xml app/src/main/res/values/strings.xml app/src/main/res/values/styles.xml app/src/main/res/xml/host_prefs.xml app/src/main/res/xml/preferences.xml build.gradle build.xml gradle/wrapper/gradle-wrapper.jar gradle/wrapper/gradle-wrapper.properties gradlew help/Makefile jni/Android.mk jni/Application.mk jni/Exec/Android.mk jni/Exec/com_google_ase_Exec.cpp jni/Exec/com_google_ase_Exec.h lint.xml locale/.gitignore project.properties res/anim/fade_out_delayed.xml res/anim/fade_stay_hidden.xml res/anim/keyboard_fade_in.xml res/anim/keyboard_fade_out.xml res/anim/slide_left_in.xml res/anim/slide_left_out.xml res/anim/slide_right_in.xml res/anim/slide_right_out.xml res/color/blue.xml res/color/green.xml res/color/red.xml res/drawable-hdpi/btn_close_normal.png res/drawable-hdpi/btn_close_pressed.png res/drawable-hdpi/btn_close_selected.png res/drawable-hdpi/icon.png res/drawable-hdpi/keyboard_popup_panel_trans_background.9.png res/drawable-hdpi/notification_icon.png res/drawable-ldpi/btn_close_normal.png res/drawable-ldpi/btn_close_pressed.png res/drawable-ldpi/btn_close_selected.png res/drawable-ldpi/icon.png res/drawable-ldpi/keyboard_popup_panel_trans_background.9.png res/drawable-ldpi/notification_icon.png res/drawable-mdpi/btn_close_normal.png res/drawable-mdpi/btn_close_pressed.png res/drawable-mdpi/btn_close_selected.png res/drawable-mdpi/button_ctrl.png res/drawable-mdpi/button_esc.png res/drawable-mdpi/button_input.png res/drawable-mdpi/button_keyboard.png res/drawable-mdpi/button_sym.png res/drawable-mdpi/file.png res/drawable-mdpi/folder.png res/drawable-mdpi/highlight_disabled_pressed.9.png res/drawable-mdpi/ic_btn_back.png res/drawable-mdpi/ic_btn_next.png res/drawable-mdpi/icon.png res/drawable-mdpi/keyboard_popup_panel_trans_background.9.png res/drawable-mdpi/notification_icon.png res/drawable-mdpi/pubkey_locked.png res/drawable-mdpi/pubkey_unlocked.png res/drawable-xhdpi/btn_close_normal.png res/drawable-xhdpi/btn_close_pressed.png res/drawable-xhdpi/btn_close_selected.png res/drawable-xhdpi/icon.png res/drawable-xhdpi/keyboard_popup_panel_trans_background.9.png res/drawable-xhdpi/notification_icon.png res/drawable-xxhdpi/icon.png res/drawable-xxhdpi/notification_icon.png res/drawable-xxxhdpi/icon.png res/drawable-xxxhdpi/notification_icon.png res/drawable/btn_close.xml res/drawable/connected.xml res/drawable/pubkey.xml res/layout-land/item_host.xml res/layout-port/item_host.xml res/layout/act_colors.xml res/layout/act_console.xml res/layout/act_generatepubkey.xml res/layout/act_help.xml res/layout/act_help_topic.xml res/layout/act_hostlist.xml res/layout/act_portforwardlist.xml res/layout/act_pubkeylist.xml res/layout/act_wizard.xml res/layout/dia_changepassword.xml res/layout/dia_gatherentropy.xml res/layout/dia_password.xml res/layout/dia_portforward.xml res/layout/dia_resize.xml res/layout/file_dialog_main.xml res/layout/file_dialog_row.xml res/layout/item_portforward.xml res/layout/item_pubkey.xml res/layout/item_terminal.xml res/layout/string_picker.xml res/layout/string_picker_button.xml res/layout/wiz_eula.xml res/raw/bell.ogg res/values-af/strings.xml res/values-ar/strings.xml res/values-be/strings.xml res/values-bg/strings.xml res/values-ca/strings.xml res/values-cs/strings.xml res/values-da/strings.xml res/values-de/strings.xml res/values-el/strings.xml res/values-en-rCA/strings.xml res/values-en-rGB/strings.xml res/values-es/strings.xml res/values-eu/strings.xml res/values-fa/strings.xml res/values-fi/strings.xml res/values-fr/strings.xml res/values-gl/strings.xml res/values-he/strings.xml res/values-hr/strings.xml res/values-hu/strings.xml res/values-id/strings.xml res/values-is/strings.xml res/values-it/strings.xml res/values-ja/strings.xml res/values-ka/strings.xml res/values-ko/strings.xml res/values-lt/strings.xml res/values-lv/strings.xml res/values-mk/strings.xml res/values-nb/strings.xml res/values-nl/strings.xml res/values-oc/strings.xml res/values-pl/strings.xml res/values-pt-rBR/strings.xml res/values-pt/strings.xml res/values-ro/strings.xml res/values-ru/strings.xml res/values-sk/strings.xml res/values-sl/strings.xml res/values-sv/strings.xml res/values-tr/strings.xml res/values-uk/strings.xml res/values-v11/styles.xml res/values-v14/styles.xml res/values-vi/strings.xml res/values-zh-rCN/strings.xml res/values-zh-rHK/strings.xml res/values-zh-rTW/strings.xml res/values/arrays.xml res/values/notrans.xml res/values/strings.xml res/values/styles.xml res/xml/host_prefs.xml res/xml/preferences.xml settings.gradle src/ch/ethz/ssh2/AbstractSFTPClient.java src/ch/ethz/ssh2/AuthAgentCallback.java src/ch/ethz/ssh2/AuthenticationResult.java src/ch/ethz/ssh2/ChannelCondition.java src/ch/ethz/ssh2/Connection.java src/ch/ethz/ssh2/ConnectionInfo.java src/ch/ethz/ssh2/ConnectionMonitor.java src/ch/ethz/ssh2/DHGexParameters.java src/ch/ethz/ssh2/DynamicPortForwarder.java src/ch/ethz/ssh2/HTTPProxyData.java src/ch/ethz/ssh2/HTTPProxyException.java src/ch/ethz/ssh2/InteractiveCallback.java src/ch/ethz/ssh2/KnownHosts.java src/ch/ethz/ssh2/LocalPortForwarder.java src/ch/ethz/ssh2/LocalStreamForwarder.java src/ch/ethz/ssh2/PacketFormatException.java src/ch/ethz/ssh2/PacketListener.java src/ch/ethz/ssh2/PacketTypeException.java src/ch/ethz/ssh2/ProxyData.java src/ch/ethz/ssh2/PtySettings.java src/ch/ethz/ssh2/RequestMismatchException.java src/ch/ethz/ssh2/SCPClient.java src/ch/ethz/ssh2/SCPInputStream.java src/ch/ethz/ssh2/SCPOutputStream.java src/ch/ethz/ssh2/SFTPClient.java src/ch/ethz/ssh2/SFTPDirectoryEntry.java src/ch/ethz/ssh2/SFTPException.java src/ch/ethz/ssh2/SFTPFileAttributes.java src/ch/ethz/ssh2/SFTPFileHandle.java src/ch/ethz/ssh2/SFTPInputStream.java src/ch/ethz/ssh2/SFTPOutputStream.java src/ch/ethz/ssh2/SFTPv3Client.java src/ch/ethz/ssh2/SFTPv3DirectoryEntry.java src/ch/ethz/ssh2/SFTPv3FileAttributes.java src/ch/ethz/ssh2/SFTPv3FileHandle.java src/ch/ethz/ssh2/SFTPv6Client.java src/ch/ethz/ssh2/SFTPv6DirectoryEntry.java src/ch/ethz/ssh2/SFTPv6FileAttributes.java src/ch/ethz/ssh2/ServerAuthenticationCallback.java src/ch/ethz/ssh2/ServerConnection.java src/ch/ethz/ssh2/ServerConnectionCallback.java src/ch/ethz/ssh2/ServerHostKeyVerifier.java src/ch/ethz/ssh2/ServerSession.java src/ch/ethz/ssh2/ServerSessionCallback.java src/ch/ethz/ssh2/Session.java src/ch/ethz/ssh2/SimpleServerSessionCallback.java src/ch/ethz/ssh2/StreamGobbler.java src/ch/ethz/ssh2/Version.java src/ch/ethz/ssh2/auth/AgentIdentity.java src/ch/ethz/ssh2/auth/AgentProxy.java src/ch/ethz/ssh2/auth/AuthenticationManager.java src/ch/ethz/ssh2/auth/ServerAuthenticationManager.java src/ch/ethz/ssh2/channel/AuthAgentForwardThread.java src/ch/ethz/ssh2/channel/Channel.java src/ch/ethz/ssh2/channel/ChannelClosedException.java src/ch/ethz/ssh2/channel/ChannelInputStream.java src/ch/ethz/ssh2/channel/ChannelManager.java src/ch/ethz/ssh2/channel/ChannelOutputStream.java src/ch/ethz/ssh2/channel/DynamicAcceptThread.java src/ch/ethz/ssh2/channel/IChannelWorkerThread.java src/ch/ethz/ssh2/channel/LocalAcceptThread.java src/ch/ethz/ssh2/channel/RemoteAcceptThread.java src/ch/ethz/ssh2/channel/RemoteForwardingData.java src/ch/ethz/ssh2/channel/RemoteX11AcceptThread.java src/ch/ethz/ssh2/channel/ServerSessionImpl.java src/ch/ethz/ssh2/channel/StreamForwarder.java src/ch/ethz/ssh2/channel/X11ServerData.java src/ch/ethz/ssh2/compression/CompressionFactory.java src/ch/ethz/ssh2/compression/Compressor.java src/ch/ethz/ssh2/compression/Zlib.java src/ch/ethz/ssh2/compression/ZlibOpenSSH.java src/ch/ethz/ssh2/crypto/Base64.java src/ch/ethz/ssh2/crypto/CryptoWishList.java src/ch/ethz/ssh2/crypto/KeyMaterial.java src/ch/ethz/ssh2/crypto/PEMDecoder.java src/ch/ethz/ssh2/crypto/PEMDecryptException.java src/ch/ethz/ssh2/crypto/PEMStructure.java src/ch/ethz/ssh2/crypto/SecureRandomFix.java src/ch/ethz/ssh2/crypto/SimpleDERReader.java src/ch/ethz/ssh2/crypto/cipher/AES.java src/ch/ethz/ssh2/crypto/cipher/BlockCipher.java src/ch/ethz/ssh2/crypto/cipher/BlockCipherFactory.java src/ch/ethz/ssh2/crypto/cipher/BlowFish.java src/ch/ethz/ssh2/crypto/cipher/CBCMode.java src/ch/ethz/ssh2/crypto/cipher/CTRMode.java src/ch/ethz/ssh2/crypto/cipher/CipherInputStream.java src/ch/ethz/ssh2/crypto/cipher/CipherOutputStream.java src/ch/ethz/ssh2/crypto/cipher/DES.java src/ch/ethz/ssh2/crypto/cipher/DESede.java src/ch/ethz/ssh2/crypto/cipher/NullCipher.java src/ch/ethz/ssh2/crypto/dh/DhExchange.java src/ch/ethz/ssh2/crypto/dh/DhGroupExchange.java src/ch/ethz/ssh2/crypto/dh/EcDhExchange.java src/ch/ethz/ssh2/crypto/dh/GenericDhExchange.java src/ch/ethz/ssh2/crypto/digest/Digest.java src/ch/ethz/ssh2/crypto/digest/HMAC.java src/ch/ethz/ssh2/crypto/digest/HashForSSH2Types.java src/ch/ethz/ssh2/crypto/digest/MAC.java src/ch/ethz/ssh2/crypto/digest/MD5.java src/ch/ethz/ssh2/crypto/digest/SHA1.java src/ch/ethz/ssh2/crypto/digest/SHA256.java src/ch/ethz/ssh2/crypto/digest/SHA512.java src/ch/ethz/ssh2/log/Logger.java src/ch/ethz/ssh2/packets/PacketChannelAuthAgentReq.java src/ch/ethz/ssh2/packets/PacketChannelFailure.java src/ch/ethz/ssh2/packets/PacketChannelOpenConfirmation.java src/ch/ethz/ssh2/packets/PacketChannelOpenFailure.java src/ch/ethz/ssh2/packets/PacketChannelSuccess.java src/ch/ethz/ssh2/packets/PacketChannelWindowAdjust.java src/ch/ethz/ssh2/packets/PacketDisconnect.java src/ch/ethz/ssh2/packets/PacketGlobalCancelForwardRequest.java src/ch/ethz/ssh2/packets/PacketGlobalForwardRequest.java src/ch/ethz/ssh2/packets/PacketIgnore.java src/ch/ethz/ssh2/packets/PacketKexDHInit.java src/ch/ethz/ssh2/packets/PacketKexDHReply.java src/ch/ethz/ssh2/packets/PacketKexDhGexGroup.java src/ch/ethz/ssh2/packets/PacketKexDhGexInit.java src/ch/ethz/ssh2/packets/PacketKexDhGexReply.java src/ch/ethz/ssh2/packets/PacketKexDhGexRequest.java src/ch/ethz/ssh2/packets/PacketKexDhGexRequestOld.java src/ch/ethz/ssh2/packets/PacketKexInit.java src/ch/ethz/ssh2/packets/PacketNewKeys.java src/ch/ethz/ssh2/packets/PacketOpenDirectTCPIPChannel.java src/ch/ethz/ssh2/packets/PacketOpenSessionChannel.java src/ch/ethz/ssh2/packets/PacketServiceAccept.java src/ch/ethz/ssh2/packets/PacketServiceRequest.java src/ch/ethz/ssh2/packets/PacketSessionExecCommand.java src/ch/ethz/ssh2/packets/PacketSessionPtyRequest.java src/ch/ethz/ssh2/packets/PacketSessionStartShell.java src/ch/ethz/ssh2/packets/PacketSessionSubsystemRequest.java src/ch/ethz/ssh2/packets/PacketSessionX11Request.java src/ch/ethz/ssh2/packets/PacketUserauthBanner.java src/ch/ethz/ssh2/packets/PacketUserauthFailure.java src/ch/ethz/ssh2/packets/PacketUserauthInfoRequest.java src/ch/ethz/ssh2/packets/PacketUserauthInfoResponse.java src/ch/ethz/ssh2/packets/PacketUserauthRequestInteractive.java src/ch/ethz/ssh2/packets/PacketUserauthRequestNone.java src/ch/ethz/ssh2/packets/PacketUserauthRequestPassword.java src/ch/ethz/ssh2/packets/PacketUserauthRequestPublicKey.java src/ch/ethz/ssh2/packets/PacketUserauthSuccess.java src/ch/ethz/ssh2/packets/PacketWindowChange.java src/ch/ethz/ssh2/packets/Packets.java src/ch/ethz/ssh2/packets/TypesReader.java src/ch/ethz/ssh2/packets/TypesWriter.java src/ch/ethz/ssh2/server/ServerConnectionState.java src/ch/ethz/ssh2/sftp/AceFlags.java src/ch/ethz/ssh2/sftp/AceMask.java src/ch/ethz/ssh2/sftp/AceType.java src/ch/ethz/ssh2/sftp/AclFlags.java src/ch/ethz/ssh2/sftp/AttrTextHints.java src/ch/ethz/ssh2/sftp/AttribBits.java src/ch/ethz/ssh2/sftp/AttribFlags.java src/ch/ethz/ssh2/sftp/AttribPermissions.java src/ch/ethz/ssh2/sftp/AttribTypes.java src/ch/ethz/ssh2/sftp/ErrorCodes.java src/ch/ethz/ssh2/sftp/OpenFlags.java src/ch/ethz/ssh2/sftp/Packet.java src/ch/ethz/ssh2/signature/DSASHA1Verify.java src/ch/ethz/ssh2/signature/ECDSASHA2Verify.java src/ch/ethz/ssh2/signature/RSASHA1Verify.java src/ch/ethz/ssh2/transport/ClientKexManager.java src/ch/ethz/ssh2/transport/ClientServerHello.java src/ch/ethz/ssh2/transport/ClientTransportManager.java src/ch/ethz/ssh2/transport/DisconnectException.java src/ch/ethz/ssh2/transport/HTTPProxyClientTransportManager.java src/ch/ethz/ssh2/transport/KexManager.java src/ch/ethz/ssh2/transport/KexParameters.java src/ch/ethz/ssh2/transport/KexState.java src/ch/ethz/ssh2/transport/MessageHandler.java src/ch/ethz/ssh2/transport/NegotiateException.java src/ch/ethz/ssh2/transport/NegotiatedParameters.java src/ch/ethz/ssh2/transport/ServerKexManager.java src/ch/ethz/ssh2/transport/ServerTransportManager.java src/ch/ethz/ssh2/transport/TransportConnection.java src/ch/ethz/ssh2/transport/TransportManager.java src/ch/ethz/ssh2/util/StringEncoder.java src/ch/ethz/ssh2/util/TimeoutService.java src/com/five_ten_sg/connectbot/ActionBarWrapper.java src/com/five_ten_sg/connectbot/ColorsActivity.java src/com/five_ten_sg/connectbot/ConsoleActivity.java src/com/five_ten_sg/connectbot/GeneratePubkeyActivity.java src/com/five_ten_sg/connectbot/HelpActivity.java src/com/five_ten_sg/connectbot/HelpTopicActivity.java src/com/five_ten_sg/connectbot/HostEditorActivity.java src/com/five_ten_sg/connectbot/HostListActivity.java src/com/five_ten_sg/connectbot/PortForwardListActivity.java src/com/five_ten_sg/connectbot/PubkeyListActivity.java src/com/five_ten_sg/connectbot/SettingsActivity.java src/com/five_ten_sg/connectbot/StrictModeSetup.java src/com/five_ten_sg/connectbot/TerminalView.java src/com/five_ten_sg/connectbot/WizardActivity.java src/com/five_ten_sg/connectbot/bean/AbstractBean.java src/com/five_ten_sg/connectbot/bean/HostBean.java src/com/five_ten_sg/connectbot/bean/PortForwardBean.java src/com/five_ten_sg/connectbot/bean/PubkeyBean.java src/com/five_ten_sg/connectbot/bean/SelectionArea.java src/com/five_ten_sg/connectbot/service/AuthAgentService.java src/com/five_ten_sg/connectbot/service/BackupAgent.java src/com/five_ten_sg/connectbot/service/BridgeDisconnectedListener.java src/com/five_ten_sg/connectbot/service/ConnectionNotifier.java src/com/five_ten_sg/connectbot/service/ConnectivityReceiver.java src/com/five_ten_sg/connectbot/service/FontSizeChangedListener.java src/com/five_ten_sg/connectbot/service/PromptHelper.java src/com/five_ten_sg/connectbot/service/Relay.java src/com/five_ten_sg/connectbot/service/TerminalBridge.java src/com/five_ten_sg/connectbot/service/TerminalKeyListener.java src/com/five_ten_sg/connectbot/service/TerminalManager.java src/com/five_ten_sg/connectbot/service/TerminalMonitor.java src/com/five_ten_sg/connectbot/transport/AbsTransport.java src/com/five_ten_sg/connectbot/transport/Local.java src/com/five_ten_sg/connectbot/transport/SSH.java src/com/five_ten_sg/connectbot/transport/TN5250.java src/com/five_ten_sg/connectbot/transport/Telnet.java src/com/five_ten_sg/connectbot/transport/TransportFactory.java src/com/five_ten_sg/connectbot/util/Colors.java src/com/five_ten_sg/connectbot/util/Encryptor.java src/com/five_ten_sg/connectbot/util/EntropyDialog.java src/com/five_ten_sg/connectbot/util/EntropyView.java src/com/five_ten_sg/connectbot/util/FileChooser.java src/com/five_ten_sg/connectbot/util/FileChooserCallback.java src/com/five_ten_sg/connectbot/util/HelpTopicView.java src/com/five_ten_sg/connectbot/util/HostDatabase.java src/com/five_ten_sg/connectbot/util/OnDbWrittenListener.java src/com/five_ten_sg/connectbot/util/OnEntropyGatheredListener.java src/com/five_ten_sg/connectbot/util/PreferenceConstants.java src/com/five_ten_sg/connectbot/util/PubkeyDatabase.java src/com/five_ten_sg/connectbot/util/PubkeyUtils.java src/com/five_ten_sg/connectbot/util/RobustSQLiteOpenHelper.java src/com/five_ten_sg/connectbot/util/StringPickerDialog.java src/com/five_ten_sg/connectbot/util/TransferThread.java src/com/five_ten_sg/connectbot/util/UberColorPickerDialog.java src/com/five_ten_sg/connectbot/util/VolumePreference.java src/com/five_ten_sg/connectbot/util/XmlBuilder.java src/com/google/ase/Exec.java src/com/jcraft/jzlib/Adler32.java src/com/jcraft/jzlib/CRC32.java src/com/jcraft/jzlib/Checksum.java src/com/jcraft/jzlib/Deflate.java src/com/jcraft/jzlib/Deflater.java src/com/jcraft/jzlib/DeflaterOutputStream.java src/com/jcraft/jzlib/GZIPException.java src/com/jcraft/jzlib/GZIPHeader.java src/com/jcraft/jzlib/GZIPInputStream.java src/com/jcraft/jzlib/GZIPOutputStream.java src/com/jcraft/jzlib/InfBlocks.java src/com/jcraft/jzlib/InfCodes.java src/com/jcraft/jzlib/InfTree.java src/com/jcraft/jzlib/Inflate.java src/com/jcraft/jzlib/Inflater.java src/com/jcraft/jzlib/InflaterInputStream.java src/com/jcraft/jzlib/JZlib.java src/com/jcraft/jzlib/StaticTree.java src/com/jcraft/jzlib/Tree.java src/com/jcraft/jzlib/ZInputStream.java src/com/jcraft/jzlib/ZOutputStream.java src/com/jcraft/jzlib/ZStream.java src/com/jcraft/jzlib/ZStreamException.java src/com/lamerman/FileDialog.java src/com/lamerman/SelectionMode.java src/com/madgag/ssh/android/authagent/AndroidAuthAgent.java src/de/mud/telnet/TelnetProtocolHandler.java src/de/mud/terminal/Precomposer.java src/de/mud/terminal/VDUBuffer.java src/de/mud/terminal/VDUDisplay.java src/de/mud/terminal/VDUInput.java src/de/mud/terminal/vt320.java src/net/sourceforge/jsocks/Authentication.java src/net/sourceforge/jsocks/AuthenticationNone.java src/net/sourceforge/jsocks/CProxy.java src/net/sourceforge/jsocks/InetRange.java src/net/sourceforge/jsocks/ProxyMessage.java src/net/sourceforge/jsocks/ProxyServer.java src/net/sourceforge/jsocks/Socks4Message.java src/net/sourceforge/jsocks/Socks4Proxy.java src/net/sourceforge/jsocks/Socks5DatagramSocket.java src/net/sourceforge/jsocks/Socks5Message.java src/net/sourceforge/jsocks/Socks5Proxy.java src/net/sourceforge/jsocks/SocksException.java src/net/sourceforge/jsocks/SocksServerSocket.java src/net/sourceforge/jsocks/SocksSocket.java src/net/sourceforge/jsocks/UDPEncapsulation.java src/net/sourceforge/jsocks/UDPRelayServer.java src/net/sourceforge/jsocks/UserPasswordAuthentication.java src/net/sourceforge/jsocks/server/Ident.java src/net/sourceforge/jsocks/server/IdentAuthenticator.java src/net/sourceforge/jsocks/server/ServerAuthenticator.java src/net/sourceforge/jsocks/server/ServerAuthenticatorNone.java src/net/sourceforge/jsocks/server/UserPasswordAuthenticator.java src/net/sourceforge/jsocks/server/UserValidation.java src/org/apache/harmony/niochar/charset/additional/IBM437.java src/org/keyczar/jce/EcCore.java src/org/openintents/intents/FileManagerIntents.java src/org/tn5250j/TN5250jConstants.java src/org/tn5250j/encoding/AbstractCodePage.java src/org/tn5250j/encoding/BuiltInCodePageFactory.java src/org/tn5250j/encoding/CharMappings.java src/org/tn5250j/encoding/ICodePage.java src/org/tn5250j/encoding/JavaCodePageFactory.java src/org/tn5250j/encoding/ToolboxCodePageFactory.java src/org/tn5250j/encoding/builtin/CCSID1025.java src/org/tn5250j/encoding/builtin/CCSID1026.java src/org/tn5250j/encoding/builtin/CCSID1112.java src/org/tn5250j/encoding/builtin/CCSID1140.java src/org/tn5250j/encoding/builtin/CCSID1141.java src/org/tn5250j/encoding/builtin/CCSID1147.java src/org/tn5250j/encoding/builtin/CCSID1148.java src/org/tn5250j/encoding/builtin/CCSID273.java src/org/tn5250j/encoding/builtin/CCSID277.java src/org/tn5250j/encoding/builtin/CCSID278.java src/org/tn5250j/encoding/builtin/CCSID280.java src/org/tn5250j/encoding/builtin/CCSID284.java src/org/tn5250j/encoding/builtin/CCSID285.java src/org/tn5250j/encoding/builtin/CCSID297.java src/org/tn5250j/encoding/builtin/CCSID37.java src/org/tn5250j/encoding/builtin/CCSID424.java src/org/tn5250j/encoding/builtin/CCSID500.java src/org/tn5250j/encoding/builtin/CCSID870.java src/org/tn5250j/encoding/builtin/CCSID871.java src/org/tn5250j/encoding/builtin/CCSID875.java src/org/tn5250j/encoding/builtin/CodepageConverterAdapter.java src/org/tn5250j/encoding/builtin/ICodepageConverter.java src/org/tn5250j/event/ScreenOIAListener.java src/org/tn5250j/framework/tn5250/DataStreamProducer.java src/org/tn5250j/framework/tn5250/KbdTypesCodePages.java src/org/tn5250j/framework/tn5250/KeyStrokenizer.java src/org/tn5250j/framework/tn5250/Rect.java src/org/tn5250j/framework/tn5250/Screen5250.java src/org/tn5250j/framework/tn5250/ScreenField.java src/org/tn5250j/framework/tn5250/ScreenFields.java src/org/tn5250j/framework/tn5250/ScreenOIA.java src/org/tn5250j/framework/tn5250/ScreenPlanes.java src/org/tn5250j/framework/tn5250/Stream5250.java src/org/tn5250j/framework/tn5250/WTDSFParser.java src/org/tn5250j/framework/tn5250/tnvt.java src/org/tn5250j/framework/transport/SSL/SSLImplementation.java src/org/tn5250j/framework/transport/SSL/X509CertificateTrustManager.java src/org/tn5250j/framework/transport/SSLInterface.java src/org/tn5250j/framework/transport/SocketConnector.java xml/Makefile
diffstat 974 files changed, 85486 insertions(+), 85891 deletions(-) [+]
line wrap: on
line diff
--- a/.classpath	Fri Jun 19 13:41:57 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
-	<classpathentry kind="src" path="gen"/>
-	<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
-	<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
-	<classpathentry kind="output" path="bin/classes"/>
-</classpath>
--- a/.hgignore	Fri Jun 19 13:41:57 2015 -0700
+++ b/.hgignore	Thu Dec 03 11:23:55 2015 -0800
@@ -1,8 +1,11 @@
 syntax: glob
 
 .git
-bin
-gen
+.gradle
+.idea
+html
+app/build
+app/src/main/assets/help
 launchpad-*.tar.gz
 local.properties
 *~
--- a/.project	Fri Jun 19 13:41:57 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>510Connectbot</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>com.android.ide.eclipse.adt.ApkBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-	</natures>
-</projectDescription>
--- a/.settings/org.eclipse.jdt.core.prefs	Fri Jun 19 13:41:57 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,284 +0,0 @@
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
-org.eclipse.jdt.core.compiler.compliance=1.5
-org.eclipse.jdt.core.compiler.source=1.5
-org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
-org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
-org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
-org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
-org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
-org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
-org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
-org.eclipse.jdt.core.formatter.alignment_for_assignment=0
-org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
-org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
-org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
-org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
-org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
-org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
-org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
-org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
-org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
-org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
-org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
-org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
-org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
-org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
-org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
-org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
-org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
-org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
-org.eclipse.jdt.core.formatter.blank_lines_after_package=1
-org.eclipse.jdt.core.formatter.blank_lines_before_field=0
-org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
-org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
-org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
-org.eclipse.jdt.core.formatter.blank_lines_before_method=1
-org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
-org.eclipse.jdt.core.formatter.blank_lines_before_package=0
-org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
-org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
-org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
-org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
-org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
-org.eclipse.jdt.core.formatter.comment.format_block_comments=true
-org.eclipse.jdt.core.formatter.comment.format_header=false
-org.eclipse.jdt.core.formatter.comment.format_html=true
-org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
-org.eclipse.jdt.core.formatter.comment.format_line_comments=true
-org.eclipse.jdt.core.formatter.comment.format_source_code=true
-org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
-org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
-org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
-org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
-org.eclipse.jdt.core.formatter.comment.line_length=80
-org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
-org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
-org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
-org.eclipse.jdt.core.formatter.compact_else_if=true
-org.eclipse.jdt.core.formatter.continuation_indentation=2
-org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
-org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
-org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
-org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
-org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
-org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
-org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
-org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
-org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
-org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
-org.eclipse.jdt.core.formatter.indent_empty_lines=false
-org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
-org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
-org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
-org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
-org.eclipse.jdt.core.formatter.indentation.size=4
-org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
-org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
-org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
-org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
-org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
-org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
-org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
-org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
-org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
-org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
-org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
-org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
-org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
-org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
-org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
-org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
-org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
-org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
-org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
-org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
-org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
-org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
-org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
-org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
-org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
-org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
-org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
-org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
-org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
-org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
-org.eclipse.jdt.core.formatter.join_lines_in_comments=true
-org.eclipse.jdt.core.formatter.join_wrapped_lines=true
-org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
-org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
-org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
-org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
-org.eclipse.jdt.core.formatter.lineSplit=100
-org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
-org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
-org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
-org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
-org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
-org.eclipse.jdt.core.formatter.tabulation.char=tab
-org.eclipse.jdt.core.formatter.tabulation.size=4
-org.eclipse.jdt.core.formatter.use_on_off_tags=false
-org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
-org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
-org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
-org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
--- a/.settings/org.eclipse.jdt.ui.prefs	Fri Jun 19 13:41:57 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,113 +0,0 @@
-cleanup.add_default_serial_version_id=true
-cleanup.add_generated_serial_version_id=false
-cleanup.add_missing_annotations=true
-cleanup.add_missing_deprecated_annotations=true
-cleanup.add_missing_methods=false
-cleanup.add_missing_nls_tags=false
-cleanup.add_missing_override_annotations=true
-cleanup.add_serial_version_id=false
-cleanup.always_use_blocks=false
-cleanup.always_use_parentheses_in_expressions=false
-cleanup.always_use_this_for_non_static_field_access=false
-cleanup.always_use_this_for_non_static_method_access=false
-cleanup.convert_to_enhanced_for_loop=false
-cleanup.correct_indentation=true
-cleanup.format_source_code=true
-cleanup.format_source_code_changes_only=false
-cleanup.make_local_variable_final=true
-cleanup.make_parameters_final=false
-cleanup.make_private_fields_final=true
-cleanup.make_type_abstract_if_missing_method=false
-cleanup.make_variable_declarations_final=false
-cleanup.never_use_blocks=false
-cleanup.never_use_parentheses_in_expressions=true
-cleanup.organize_imports=true
-cleanup.qualify_static_field_accesses_with_declaring_class=false
-cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
-cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
-cleanup.qualify_static_member_accesses_with_declaring_class=true
-cleanup.qualify_static_method_accesses_with_declaring_class=false
-cleanup.remove_private_constructors=true
-cleanup.remove_trailing_whitespaces=true
-cleanup.remove_trailing_whitespaces_all=true
-cleanup.remove_trailing_whitespaces_ignore_empty=false
-cleanup.remove_unnecessary_casts=true
-cleanup.remove_unnecessary_nls_tags=true
-cleanup.remove_unused_imports=true
-cleanup.remove_unused_local_variables=false
-cleanup.remove_unused_private_fields=true
-cleanup.remove_unused_private_members=false
-cleanup.remove_unused_private_methods=true
-cleanup.remove_unused_private_types=true
-cleanup.sort_members=true
-cleanup.sort_members_all=true
-cleanup.use_blocks=true
-cleanup.use_blocks_only_for_return_and_throw=true
-cleanup.use_parentheses_in_expressions=false
-cleanup.use_this_for_non_static_field_access=true
-cleanup.use_this_for_non_static_field_access_only_if_necessary=true
-cleanup.use_this_for_non_static_method_access=true
-cleanup.use_this_for_non_static_method_access_only_if_necessary=true
-cleanup_profile=_ConnectBot Light Cleanup
-cleanup_settings_version=2
-eclipse.preferences.version=1
-editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_profile=_ConnectBot
-formatter_settings_version=12
-org.eclipse.jdt.ui.ignorelowercasenames=true
-org.eclipse.jdt.ui.importorder=java;javax;org;com;
-org.eclipse.jdt.ui.javadoc=true
-org.eclipse.jdt.ui.ondemandthreshold=99
-org.eclipse.jdt.ui.staticondemandthreshold=99
-org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8"?><templates><template autoinsert\="true" context\="gettercomment_context" deleted\="false" description\="Comment for getter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.gettercomment" name\="gettercomment">/**\n * @return the ${bare_field_name}\n */</template><template autoinsert\="true" context\="settercomment_context" deleted\="false" description\="Comment for setter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.settercomment" name\="settercomment">/**\n * @param ${param} the ${bare_field_name} to set\n */</template><template autoinsert\="true" context\="constructorcomment_context" deleted\="false" description\="Comment for created constructors" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorcomment" name\="constructorcomment">/**\n * ${tags}\n */</template><template autoinsert\="true" context\="filecomment_context" deleted\="false" description\="Comment for created Java files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.filecomment" name\="filecomment">/**\n * \n */</template><template autoinsert\="true" context\="typecomment_context" deleted\="false" description\="Comment for created types" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.typecomment" name\="typecomment">/**\n * @author ${user}\n *\n * ${tags}\n */</template><template autoinsert\="true" context\="fieldcomment_context" deleted\="false" description\="Comment for fields" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.fieldcomment" name\="fieldcomment">/**\n * \n */</template><template autoinsert\="true" context\="methodcomment_context" deleted\="false" description\="Comment for non-overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodcomment" name\="methodcomment">/**\n * ${tags}\n */</template><template autoinsert\="true" context\="overridecomment_context" deleted\="false" description\="Comment for overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.overridecomment" name\="overridecomment">/* (non-Javadoc)\n * ${see_to_overridden}\n */</template><template autoinsert\="true" context\="delegatecomment_context" deleted\="false" description\="Comment for delegate methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.delegatecomment" name\="delegatecomment">/**\n * ${tags}\n * ${see_to_target}\n */</template><template autoinsert\="true" context\="newtype_context" deleted\="false" description\="Newly created files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.newtype" name\="newtype">${filecomment}\n${package_declaration}\n\n${typecomment}\n${type_declaration}</template><template autoinsert\="true" context\="classbody_context" deleted\="false" description\="Code in new class type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.classbody" name\="classbody">\n</template><template autoinsert\="true" context\="interfacebody_context" deleted\="false" description\="Code in new interface type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.interfacebody" name\="interfacebody">\n</template><template autoinsert\="true" context\="enumbody_context" deleted\="false" description\="Code in new enum type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.enumbody" name\="enumbody">\n</template><template autoinsert\="true" context\="annotationbody_context" deleted\="false" description\="Code in new annotation type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.annotationbody" name\="annotationbody">\n</template><template autoinsert\="true" context\="catchblock_context" deleted\="false" description\="Code in new catch blocks" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.catchblock" name\="catchblock">// ${todo} Auto-generated catch block\n${exception_var}.printStackTrace();</template><template autoinsert\="true" context\="methodbody_context" deleted\="false" description\="Code in created method stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodbody" name\="methodbody">// ${todo} Auto-generated method stub\n${body_statement}</template><template autoinsert\="true" context\="constructorbody_context" deleted\="false" description\="Code in created constructor stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorbody" name\="constructorbody">${body_statement}\n// ${todo} Auto-generated constructor stub</template><template autoinsert\="true" context\="getterbody_context" deleted\="false" description\="Code in created getters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.getterbody" name\="getterbody">return ${field};</template><template autoinsert\="true" context\="setterbody_context" deleted\="false" description\="Code in created setters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.setterbody" name\="setterbody">${field} \= ${param};</template><template autoinsert\="true" context\="gettercomment_context" deleted\="false" description\="Comment for getter function" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.gettercomment" name\="gettercomment">/**\n * @return the ${bare_field_name}\n */</template><template autoinsert\="true" context\="settercomment_context" deleted\="false" description\="Comment for setter function" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.settercomment" name\="settercomment">/**\n * @param ${param} the ${bare_field_name} to set\n */</template><template autoinsert\="true" context\="constructorcomment_context" deleted\="false" description\="Comment for created constructors" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.constructorcomment" name\="constructorcomment">/**\n * ${tags}\n */</template><template autoinsert\="true" context\="filecomment_context" deleted\="false" description\="Comment for created JavaScript files" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.filecomment" name\="filecomment">/**\n * \n */</template><template autoinsert\="true" context\="typecomment_context" deleted\="false" description\="Comment for created types" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.typecomment" name\="typecomment">/**\n * @author ${user}\n *\n * ${tags}\n */</template><template autoinsert\="true" context\="fieldcomment_context" deleted\="false" description\="Comment for vars" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.fieldcomment" name\="fieldcomment">/**\n * \n */</template><template autoinsert\="true" context\="methodcomment_context" deleted\="false" description\="Comment for non-overriding function" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.methodcomment" name\="methodcomment">/**\n * ${tags}\n */</template><template autoinsert\="true" context\="overridecomment_context" deleted\="false" description\="Comment for overriding functions" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.overridecomment" name\="overridecomment">/* (non-Jsdoc)\n * ${see_to_overridden}\n */</template><template autoinsert\="true" context\="delegatecomment_context" deleted\="false" description\="Comment for delegate functions" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.delegatecomment" name\="delegatecomment">/**\n * ${tags}\n * ${see_to_target}\n */</template><template autoinsert\="true" context\="newtype_context" deleted\="false" description\="Newly created files" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.newtype" name\="newtype">${filecomment}\n${package_declaration}\n\n${typecomment}\n${type_declaration}</template><template autoinsert\="true" context\="classbody_context" deleted\="false" description\="Code in new class type bodies" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.classbody" name\="classbody">\n</template><template autoinsert\="true" context\="catchblock_context" deleted\="false" description\="Code in new catch blocks" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.catchblock" name\="catchblock">// ${todo} Auto-generated catch block\n${exception_var}.printStackTrace();</template><template autoinsert\="true" context\="methodbody_context" deleted\="false" description\="Code in created function stubs" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.methodbody" name\="methodbody">// ${todo} Auto-generated function stub\n${body_statement}</template><template autoinsert\="true" context\="constructorbody_context" deleted\="false" description\="Code in created constructor stubs" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.constructorbody" name\="constructorbody">${body_statement}\n// ${todo} Auto-generated constructor stub</template><template autoinsert\="true" context\="getterbody_context" deleted\="false" description\="Code in created getters" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.getterbody" name\="getterbody">return ${field};</template><template autoinsert\="true" context\="setterbody_context" deleted\="false" description\="Code in created setters" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.setterbody" name\="setterbody">${field} \= ${param};</template></templates>
-sp_cleanup.add_default_serial_version_id=true
-sp_cleanup.add_generated_serial_version_id=false
-sp_cleanup.add_missing_annotations=true
-sp_cleanup.add_missing_deprecated_annotations=true
-sp_cleanup.add_missing_methods=false
-sp_cleanup.add_missing_nls_tags=false
-sp_cleanup.add_missing_override_annotations=true
-sp_cleanup.add_serial_version_id=false
-sp_cleanup.always_use_blocks=true
-sp_cleanup.always_use_parentheses_in_expressions=false
-sp_cleanup.always_use_this_for_non_static_field_access=false
-sp_cleanup.always_use_this_for_non_static_method_access=false
-sp_cleanup.convert_to_enhanced_for_loop=false
-sp_cleanup.correct_indentation=false
-sp_cleanup.format_source_code=false
-sp_cleanup.format_source_code_changes_only=true
-sp_cleanup.make_local_variable_final=false
-sp_cleanup.make_parameters_final=false
-sp_cleanup.make_private_fields_final=true
-sp_cleanup.make_type_abstract_if_missing_method=false
-sp_cleanup.make_variable_declarations_final=false
-sp_cleanup.never_use_blocks=false
-sp_cleanup.never_use_parentheses_in_expressions=true
-sp_cleanup.on_save_use_additional_actions=true
-sp_cleanup.organize_imports=true
-sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
-sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
-sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
-sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
-sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
-sp_cleanup.remove_private_constructors=true
-sp_cleanup.remove_trailing_whitespaces=true
-sp_cleanup.remove_trailing_whitespaces_all=true
-sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
-sp_cleanup.remove_unnecessary_casts=true
-sp_cleanup.remove_unnecessary_nls_tags=false
-sp_cleanup.remove_unused_imports=false
-sp_cleanup.remove_unused_local_variables=false
-sp_cleanup.remove_unused_private_fields=true
-sp_cleanup.remove_unused_private_members=false
-sp_cleanup.remove_unused_private_methods=true
-sp_cleanup.remove_unused_private_types=true
-sp_cleanup.sort_members=false
-sp_cleanup.sort_members_all=false
-sp_cleanup.use_blocks=false
-sp_cleanup.use_blocks_only_for_return_and_throw=false
-sp_cleanup.use_parentheses_in_expressions=false
-sp_cleanup.use_this_for_non_static_field_access=false
-sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
-sp_cleanup.use_this_for_non_static_method_access=false
-sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
--- a/AndroidManifest.xml	Fri Jun 19 13:41:57 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,122 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ConnectBot: simple, powerful, open-source SSH client for Android
- Copyright 2007 Kenny Root, Jeffrey Sharkey
-
- 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.
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-	package="com.five_ten_sg.connectbot"
-	android:versionName="1.9.2-0"
-	android:versionCode="1920"
-	android:installLocation="auto">
-
-	<uses-sdk android:targetSdkVersion="15" android:minSdkVersion="8" />
-
-	<uses-permission android:name="android.permission.INTERNET" />
-	<uses-permission android:name="android.permission.VIBRATE" />
-	<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
-	<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
-	<uses-permission android:name="android.permission.WAKE_LOCK" />
-
-	<permission
-		android:name="org.openintents.ssh.permission.ACCESS_SSH_AGENT"
-		android:protectionLevel="dangerous"
-		android:permissionGroup="android.permission-group.PERSONAL_INFO"
-		android:label="@string/ssh_agent_permission_label"
-		android:description="@string/ssh_agent_permission_desc"
-		android:icon="@drawable/pubkey">
-	</permission>
-
-	<uses-feature android:name="android.hardware.touchscreen" android:required="false"/>
-
-	<supports-screens />
-
-	<application
-        android:debuggable="true"
-		android:icon="@drawable/icon"
-		android:label="@string/app_name"
-		android:description="@string/app_desc"
-		android:allowBackup="false"
-		android:backupAgent=".service.BackupAgent"
-		android:killAfterRestore="true">
-
-		<activity android:name=".HostListActivity" >
-			<intent-filter>
-				<action android:name="android.intent.action.MAIN" />
-				<category android:name="android.intent.category.LAUNCHER" />
-			</intent-filter>
-			<intent-filter>
-				<action android:name="android.intent.action.CREATE_SHORTCUT" />
-				<category android:name="android.intent.category.DEFAULT" />
-			</intent-filter>
-			<intent-filter>
-				<action android:name="android.intent.action.PICK" />
-				<category android:name="android.intent.category.DEFAULT" />
-				<data android:scheme="tn5250" />
-				<data android:scheme="ssh"    />
-				<data android:scheme="telnet" />
-				<data android:scheme="local"  />
-			</intent-filter>
-		</activity>
-
-		<activity android:name=".PubkeyListActivity" android:configChanges="keyboardHidden|orientation" >
-			<intent-filter>
-				<action android:name="org.openintents.ssh.agent.IDENTITY_ADMIN" />
-				<category android:name="android.intent.category.DEFAULT" />
-			</intent-filter>
-		</activity>
-		<activity android:name=".GeneratePubkeyActivity" android:configChanges="keyboardHidden|orientation" />
-		<activity android:name=".HostEditorActivity" android:configChanges="keyboardHidden|orientation" />
-		<activity android:name=".PortForwardListActivity" android:configChanges="keyboardHidden|orientation" />
-		<activity android:name=".SettingsActivity" android:configChanges="keyboardHidden|orientation" />
-		<activity android:name=".WizardActivity" android:configChanges="keyboardHidden|orientation" />
-		<activity android:name=".HelpActivity" android:configChanges="keyboardHidden|orientation" />
-		<activity android:name=".HelpTopicActivity" android:configChanges="keyboardHidden|orientation" />
-		<activity android:name=".ColorsActivity" android:configChanges="keyboardHidden|orientation" />
-		<activity android:name="com.lamerman.FileDialog" android:configChanges="keyboardHidden|orientation" />
-
-		<service android:name="com.five_ten_sg.connectbot.service.TerminalManager"
-			android:configChanges="keyboardHidden|orientation"
-			android:description="@string/service_desc" />
-
-		<service android:name="com.five_ten_sg.connectbot.service.AuthAgentService"
-			android:description="@string/auth_agent_service_desc"
-			android:permission="org.openintents.ssh.permission.ACCESS_SSH_AGENT">
-			<intent-filter>
-				<action android:name="org.openintents.ssh.BIND_SSH_AGENT_SERVICE" />
-			</intent-filter>
-		</service>
-
-		<activity android:name=".ConsoleActivity" android:configChanges="keyboardHidden|orientation"
-			android:theme="@style/NoTitle" android:windowSoftInputMode="stateAlwaysVisible|adjustResize"
-			android:launchMode="singleTop" android:hardwareAccelerated="false">
-			<intent-filter>
-				<action android:name="android.intent.action.VIEW" />
-				<category android:name="android.intent.category.DEFAULT" />
-				<category android:name="android.intent.category.BROWSABLE" />
-				<data android:scheme="tn5250" />
-				<data android:scheme="ssh"    />
-				<data android:scheme="telnet" />
-				<data android:scheme="local"  />
-				<!-- format:  ssh://user@host:port/#nickname  -->
-				<!-- format:  telnet://host:port/#nickname  -->
-				<!-- format:  local://  -->
-			</intent-filter>
-		</activity>
-
-		<meta-data android:name="com.google.android.backup.api_key"
-			android:value="AEdPqrEAAAAIDlFz9nSUr2g0gSytW0t2cNnYAGHDkptlVohsBA" />
-
-	</application>
-</manifest>
--- a/Makefile	Fri Jun 19 13:41:57 2015 -0700
+++ b/Makefile	Thu Dec 03 11:23:55 2015 -0800
@@ -1,13 +1,22 @@
 #mc40 is "On Device Storage"
 #tc55 is "Internal Storage"
 
-style=release
-dest=/run/user/1000/gvfs/mtp*/*torage/Download
-apk='bin/510Connectbot-$(style).apk'
+style:=release
+dest:=/run/user/1000/gvfs/mtp*/*torage/Download
+apk:='app/build/outputs/apk/510Connectbot-$(style).apk'
+ver:=$(shell grep versionName app/src/main/AndroidManifest.xml | cut -d'"' -f2)
+id:=$(shell hg id --id)
+da:=$(shell date +%Y-%m-%d)
+version:=\
+<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\
+<resources>\n\
+	<string name=\"msg_version\" translatable=\"false\">510Connectbot $(ver) ($(id) $(da))</string>\n\
+</resources>\n
+
 ifeq ($(style),release)
-    debuggable=false
+    task=assembleRelease
 else
-	debuggable=true
+	task=assembleDebug
 endif
 
 
@@ -16,11 +25,12 @@
 	make builder
 
 builder: prep
-	sed -i -e 's/android:debuggable=".*"/android:debuggable="$(debuggable)"/g' AndroidManifest.xml
-	rm -rf gen bin
-	ndk-build clean; V=1 ndk-build
-	android update project -p . -t android-16
-	ant $(style)
+	rm -rf app/build/*
+	echo -e "$(version)" >app/src/main/res/values/version.xml
+	cat app/src/main/res/values/version.xml
+	./gradlew $(task)
+	mv app/build/outputs/apk/app-arm-$(style).apk $(apk)
+	ls -al app/build/outputs/apk
 
 prep:
 	(cd help; make)
@@ -38,19 +48,19 @@
 
 buildicon:
 	convert base.510.icon.png -background white -resize 500x500 -extent 1024x500 google.play.store/feature.510.icon.png
-	cp -a   base.510.icon.png                 res/drawable-xxxhdpi/icon.png
-	convert base.510.icon.png -resize 144x144 res/drawable-xxhdpi/icon.png
-	convert base.510.icon.png -resize 96x96   res/drawable-xhdpi/icon.png
-	convert base.510.icon.png -resize 72x72   res/drawable-hdpi/icon.png
-	convert base.510.icon.png -resize 48x48   res/drawable-mdpi/icon.png
-	convert base.510.icon.png -resize 36x36   res/drawable-ldpi/icon.png
+	cp -a   base.510.icon.png                 app/src/main/res/drawable-xxxhdpi/icon.png
+	convert base.510.icon.png -resize 144x144 app/src/main/res/drawable-xxhdpi/icon.png
+	convert base.510.icon.png -resize 96x96   app/src/main/res/drawable-xhdpi/icon.png
+	convert base.510.icon.png -resize 72x72   app/src/main/res/drawable-hdpi/icon.png
+	convert base.510.icon.png -resize 48x48   app/src/main/res/drawable-mdpi/icon.png
+	convert base.510.icon.png -resize 36x36   app/src/main/res/drawable-ldpi/icon.png
 
-	convert res/drawable-xxxhdpi/icon.png -resize 50% -colorspace Gray res/drawable-xxxhdpi/notification_icon.png
-	convert res/drawable-xxhdpi/icon.png  -resize 50% -colorspace Gray res/drawable-xxhdpi/notification_icon.png
-	convert res/drawable-xhdpi/icon.png   -resize 50% -colorspace Gray res/drawable-xhdpi/notification_icon.png
-	convert res/drawable-hdpi/icon.png    -resize 50% -colorspace Gray res/drawable-hdpi/notification_icon.png
-	convert res/drawable-mdpi/icon.png    -resize 50% -colorspace Gray res/drawable-mdpi/notification_icon.png
-	convert res/drawable-ldpi/icon.png    -resize 50% -colorspace Gray res/drawable-ldpi/notification_icon.png
+	convert app/src/main/res/drawable-xxxhdpi/icon.png -resize 50% -colorspace Gray app/src/main/res/drawable-xxxhdpi/notification_icon.png
+	convert app/src/main/res/drawable-xxhdpi/icon.png  -resize 50% -colorspace Gray app/src/main/res/drawable-xxhdpi/notification_icon.png
+	convert app/src/main/res/drawable-xhdpi/icon.png   -resize 50% -colorspace Gray app/src/main/res/drawable-xhdpi/notification_icon.png
+	convert app/src/main/res/drawable-hdpi/icon.png    -resize 50% -colorspace Gray app/src/main/res/drawable-hdpi/notification_icon.png
+	convert app/src/main/res/drawable-mdpi/icon.png    -resize 50% -colorspace Gray app/src/main/res/drawable-mdpi/notification_icon.png
+	convert app/src/main/res/drawable-ldpi/icon.png    -resize 50% -colorspace Gray app/src/main/res/drawable-ldpi/notification_icon.png
 
 indentc:
 	indent --line-length100 \
--- a/ant.properties	Fri Jun 19 13:41:57 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-# This file is used to override default values used by the Ant build system.
-#
-# This file must be checked in Version Control Systems, as it is
-# integral to the build system of your project.
-
-# This file is only used by the Ant script.
-
-# You can use this to override default values such as
-#  'source.dir' for the location of your java source folder and
-#  'out.dir' for the location of your output folder.
-
-# You can also use it define how the release builds are signed by declaring
-# the following properties:
-#  'key.store' for the location of your keystore and
-#  'key.alias' for the name of the key to use.
-# The password will be asked during the build when you use the 'release' target.
-
-source.dir=src
-out.dir=bin
-key.store=510Connectbot.keystore
-key.alias=510Connectbot
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/build.gradle	Thu Dec 03 11:23:55 2015 -0800
@@ -0,0 +1,75 @@
+tasks.whenTaskAdded { task ->
+    if (task.name.contains("lint")) {
+        task.enabled = false
+    }
+}
+
+apply plugin: 'com.android.model.application'
+
+model {
+    def signConf
+
+    android {
+        compileSdkVersion = 16
+        buildToolsVersion = "23.0.2"
+
+        defaultConfig.with {
+            applicationId = "com.five_ten_sg.connectbot"
+            minSdkVersion.apiLevel = 8
+            targetSdkVersion.apiLevel = 15
+        }
+    }
+
+    compileOptions.with {
+        sourceCompatibility = JavaVersion.VERSION_1_7
+        targetCompatibility = JavaVersion.VERSION_1_7
+    }
+
+    android.ndk {
+        moduleName = "com_google_ase_Exec"
+        cppFlags.add("-Werror")
+        ldLibs.add("log")
+    }
+
+    android.sources {
+        main {
+            jni {
+                source {
+                    srcDir "Exec"
+                }
+            }
+        }
+    }
+
+    android.signingConfigs {
+        create("signed") {
+            storeFile = file("../510Connectbot.keystore")
+            storePassword = new String(System.console().readPassword("\n\$ Enter keystore password: "))
+            storeType = "jks"
+            keyAlias = "510Connectbot"
+            keyPassword = new String(System.console().readPassword("\n\$ Enter key password: "))
+            signConf = it
+        }
+    }
+
+    android.buildTypes {
+        release {
+            minifyEnabled = false
+            signingConfig = signConf
+            //proguardFiles.add(file('proguard-rules.txt'))
+        }
+        debug {
+            debuggable = true
+        }
+    }
+
+    android.productFlavors {
+        create("arm") {
+            ndk.abiFilters.add("armeabi")
+        }
+        create("x86") {
+            ndk.abiFilters.add("x86")
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/lint.xml	Thu Dec 03 11:23:55 2015 -0800
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<lint>
+    <issue id="MissingTranslation" severity="warning" />
+    <issue id="NewApi" severity="warning" />
+</lint>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/src/main/AndroidManifest.xml	Thu Dec 03 11:23:55 2015 -0800
@@ -0,0 +1,122 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ConnectBot: simple, powerful, open-source SSH client for Android
+ Copyright 2007 Kenny Root, Jeffrey Sharkey
+
+ 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+	package="com.five_ten_sg.connectbot"
+	android:versionName="1.9.2-0"
+	android:versionCode="1920"
+	android:installLocation="auto">
+
+	<uses-sdk android:targetSdkVersion="15" android:minSdkVersion="8" />
+
+	<uses-permission android:name="android.permission.INTERNET" />
+	<uses-permission android:name="android.permission.VIBRATE" />
+	<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+	<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+	<uses-permission android:name="android.permission.WAKE_LOCK" />
+
+	<permission
+		android:name="org.openintents.ssh.permission.ACCESS_SSH_AGENT"
+		android:protectionLevel="dangerous"
+		android:permissionGroup="android.permission-group.PERSONAL_INFO"
+		android:label="@string/ssh_agent_permission_label"
+		android:description="@string/ssh_agent_permission_desc"
+		android:icon="@drawable/pubkey">
+	</permission>
+
+	<uses-feature android:name="android.hardware.touchscreen" android:required="false"/>
+
+	<supports-screens />
+
+	<application
+        android:debuggable="true"
+		android:icon="@drawable/icon"
+		android:label="@string/app_name"
+		android:description="@string/app_desc"
+		android:allowBackup="false"
+		android:backupAgent=".service.BackupAgent"
+		android:killAfterRestore="true">
+
+		<activity android:name=".HostListActivity" >
+			<intent-filter>
+				<action android:name="android.intent.action.MAIN" />
+				<category android:name="android.intent.category.LAUNCHER" />
+			</intent-filter>
+			<intent-filter>
+				<action android:name="android.intent.action.CREATE_SHORTCUT" />
+				<category android:name="android.intent.category.DEFAULT" />
+			</intent-filter>
+			<intent-filter>
+				<action android:name="android.intent.action.PICK" />
+				<category android:name="android.intent.category.DEFAULT" />
+				<data android:scheme="tn5250" />
+				<data android:scheme="ssh"    />
+				<data android:scheme="telnet" />
+				<data android:scheme="local"  />
+			</intent-filter>
+		</activity>
+
+		<activity android:name=".PubkeyListActivity" android:configChanges="keyboardHidden|orientation" >
+			<intent-filter>
+				<action android:name="org.openintents.ssh.agent.IDENTITY_ADMIN" />
+				<category android:name="android.intent.category.DEFAULT" />
+			</intent-filter>
+		</activity>
+		<activity android:name=".GeneratePubkeyActivity" android:configChanges="keyboardHidden|orientation" />
+		<activity android:name=".HostEditorActivity" android:configChanges="keyboardHidden|orientation" />
+		<activity android:name=".PortForwardListActivity" android:configChanges="keyboardHidden|orientation" />
+		<activity android:name=".SettingsActivity" android:configChanges="keyboardHidden|orientation" />
+		<activity android:name=".WizardActivity" android:configChanges="keyboardHidden|orientation" />
+		<activity android:name=".HelpActivity" android:configChanges="keyboardHidden|orientation" />
+		<activity android:name=".HelpTopicActivity" android:configChanges="keyboardHidden|orientation" />
+		<activity android:name=".ColorsActivity" android:configChanges="keyboardHidden|orientation" />
+		<activity android:name="com.lamerman.FileDialog" android:configChanges="keyboardHidden|orientation" />
+
+		<service android:name="com.five_ten_sg.connectbot.service.TerminalManager"
+			android:configChanges="keyboardHidden|orientation"
+			android:description="@string/service_desc" />
+
+		<service android:name="com.five_ten_sg.connectbot.service.AuthAgentService"
+			android:description="@string/auth_agent_service_desc"
+			android:permission="org.openintents.ssh.permission.ACCESS_SSH_AGENT">
+			<intent-filter>
+				<action android:name="org.openintents.ssh.BIND_SSH_AGENT_SERVICE" />
+			</intent-filter>
+		</service>
+
+		<activity android:name=".ConsoleActivity" android:configChanges="keyboardHidden|orientation"
+			android:theme="@style/NoTitle" android:windowSoftInputMode="stateAlwaysVisible|adjustResize"
+			android:launchMode="singleTop" android:hardwareAccelerated="false">
+			<intent-filter>
+				<action android:name="android.intent.action.VIEW" />
+				<category android:name="android.intent.category.DEFAULT" />
+				<category android:name="android.intent.category.BROWSABLE" />
+				<data android:scheme="tn5250" />
+				<data android:scheme="ssh"    />
+				<data android:scheme="telnet" />
+				<data android:scheme="local"  />
+				<!-- format:  ssh://user@host:port/#nickname  -->
+				<!-- format:  telnet://host:port/#nickname  -->
+				<!-- format:  local://  -->
+			</intent-filter>
+		</activity>
+
+		<meta-data android:name="com.google.android.backup.api_key"
+			android:value="AEdPqrEAAAAIDlFz9nSUr2g0gSytW0t2cNnYAGHDkptlVohsBA" />
+
+	</application>
+</manifest>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/src/main/java/ch/ethz/ssh2/AbstractSFTPClient.java	Thu Dec 03 11:23:55 2015 -0800
@@ -0,0 +1,690 @@
+package ch.ethz.ssh2;
+
+import java.io.BufferedOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.SocketException;
+import java.nio.charset.Charset;
+import java.nio.charset.UnsupportedCharsetException;
+import java.util.HashMap;
+import java.util.Map;
+
+import ch.ethz.ssh2.channel.Channel;
+import ch.ethz.ssh2.log.Logger;
+import ch.ethz.ssh2.packets.TypesReader;
+import ch.ethz.ssh2.packets.TypesWriter;
+import ch.ethz.ssh2.sftp.AttribFlags;
+import ch.ethz.ssh2.sftp.ErrorCodes;
+import ch.ethz.ssh2.sftp.Packet;
+import ch.ethz.ssh2.util.StringEncoder;
+
+/**
+ * @version $Id: AbstractSFTPClient.java 151 2014-04-28 10:03:39Z dkocher@sudo.ch $
+ */
+public abstract class AbstractSFTPClient implements SFTPClient {
+
+    private static final Logger log = Logger.getLogger(SFTPv3Client.class);
+
+    private Session sess;
+
+    private InputStream is;
+    private OutputStream os;
+
+    private int next_request_id = 1000;
+
+    private String charset;
+
+    /**
+     * Parallel read requests maximum size.
+     */
+    private static final int DEFAULT_MAX_PARALLELISM = 64;
+
+    /**
+     * Parallel read requests.
+     */
+    private int parallelism = DEFAULT_MAX_PARALLELISM;
+
+    public void setRequestParallelism(int parallelism) {
+        this.parallelism = Math.min(parallelism, DEFAULT_MAX_PARALLELISM);
+    }
+
+    /**
+     * Mapping request ID to request.
+     */
+    private Map<Integer, OutstandingReadRequest> pendingReadQueue
+        = new HashMap<Integer, OutstandingReadRequest>();
+
+    /**
+     * Mapping request ID to request.
+     */
+    private Map<Integer, OutstandingStatusRequest> pendingStatusQueue
+        = new HashMap<Integer, OutstandingStatusRequest>();
+
+    private PacketListener listener;
+
+    protected AbstractSFTPClient(final Connection conn, final int version, final PacketListener listener) throws IOException {
+        this.listener = listener;
+        log.debug("Opening session and starting SFTP subsystem.");
+        sess = conn.openSession();
+        sess.startSubSystem("sftp");
+        is = sess.getStdout();
+        os = new BufferedOutputStream(sess.getStdin(), 2048);
+        init(version);
+    }
+
+    private void init(final int client_version) throws IOException {
+        // Send SSH_FXP_INIT with client version
+        TypesWriter tw = new TypesWriter();
+        tw.writeUINT32(client_version);
+        sendMessage(Packet.SSH_FXP_INIT, 0, tw.getBytes());
+        /* Receive SSH_FXP_VERSION */
+        log.debug("Waiting for SSH_FXP_VERSION...");
+        TypesReader tr = new TypesReader(receiveMessage(34000)); /* Should be enough for any reasonable server */
+        int t = tr.readByte();
+        listener.read(Packet.forName(t));
+
+        if (t != Packet.SSH_FXP_VERSION) {
+            log.warning(String.format("The server did not send a SSH_FXP_VERSION but %d", t));
+            throw new PacketTypeException(t);
+        }
+
+        final int protocol_version = tr.readUINT32();
+        log.debug("SSH_FXP_VERSION: protocol_version = " + protocol_version);
+
+        if (protocol_version != client_version) {
+            throw new IOException(String.format("Server protocol version %d does not match %d",
+                                                protocol_version, client_version));
+        }
+
+        // Both parties should from then on adhere to particular version of the protocol
+
+        // Read and save extensions (if any) for later use
+        while (tr.remain() != 0) {
+            String name = tr.readString();
+            listener.read(name);
+            byte[] value = tr.readByteString();
+            log.debug(String.format("SSH_FXP_VERSION: extension: %s = '%s'", name, StringEncoder.GetString(value)));
+        }
+    }
+
+    /**
+     * Queries the channel state
+     *
+     * @return True if the underlying session is in open state
+     */
+    public boolean isConnected() {
+        return sess.getState() == Channel.STATE_OPEN;
+    }
+
+    /**
+     * Close this SFTP session. NEVER forget to call this method to free up
+     * resources - even if you got an exception from one of the other methods.
+     * Sometimes these other methods may throw an exception, saying that the
+     * underlying channel is closed (this can happen, e.g., if the other server
+     * sent a close message.) However, as long as you have not called the
+     * <code>close()</code> method, you are likely wasting resources.
+     */
+    public void close() {
+        sess.close();
+    }
+
+    /**
+     * Set the charset used to convert between Java Unicode Strings and byte encodings
+     * used by the server for paths and file names.
+     *
+     * @param charset the name of the charset to be used or <code>null</code> to use UTF-8.
+     * @throws java.io.IOException
+     * @see #getCharset()
+     */
+    public void setCharset(String charset) throws IOException {
+        if (charset == null) {
+            this.charset = null;
+            return;
+        }
+
+        try {
+            Charset.forName(charset);
+        }
+        catch (UnsupportedCharsetException e) {
+            throw new IOException("This charset is not supported", e);
+        }
+
+        this.charset = charset;
+    }
+
+    /**
+     * The currently used charset for filename encoding/decoding.
+     *
+     * @return The name of the charset (<code>null</code> if UTF-8 is used).
+     * @see #setCharset(String)
+     */
+    public String getCharset() {
+        return charset;
+    }
+
+    public abstract SFTPFileHandle openFile(String fileName, int flags, SFTPFileAttributes attr) throws IOException;
+
+    public void mkdir(String dirName, int posixPermissions) throws IOException {
+        int req_id = generateNextRequestID();
+        TypesWriter tw = new TypesWriter();
+        tw.writeString(dirName, this.getCharset());
+        tw.writeUINT32(AttribFlags.SSH_FILEXFER_ATTR_PERMISSIONS);
+        tw.writeUINT32(posixPermissions);
+        sendMessage(Packet.SSH_FXP_MKDIR, req_id, tw.getBytes());
+        expectStatusOKMessage(req_id);
+    }
+
+    public void rm(String fileName) throws IOException {
+        int req_id = generateNextRequestID();
+        TypesWriter tw = new TypesWriter();
+        tw.writeString(fileName, this.getCharset());
+        sendMessage(Packet.SSH_FXP_REMOVE, req_id, tw.getBytes());
+        expectStatusOKMessage(req_id);
+    }
+
+    public void rmdir(String dirName) throws IOException {
+        int req_id = generateNextRequestID();
+        TypesWriter tw = new TypesWriter();
+        tw.writeString(dirName, this.getCharset());
+        sendMessage(Packet.SSH_FXP_RMDIR, req_id, tw.getBytes());
+        expectStatusOKMessage(req_id);
+    }
+
+    public void mv(String oldPath, String newPath) throws IOException {
+        int req_id = generateNextRequestID();
+        TypesWriter tw = new TypesWriter();
+        tw.writeString(oldPath, this.getCharset());
+        tw.writeString(newPath, this.getCharset());
+        sendMessage(Packet.SSH_FXP_RENAME, req_id, tw.getBytes());
+        expectStatusOKMessage(req_id);
+    }
+
+    public String readLink(String path) throws IOException {
+        int req_id = generateNextRequestID();
+        TypesWriter tw = new TypesWriter();
+        tw.writeString(path, charset);
+        sendMessage(Packet.SSH_FXP_READLINK, req_id, tw.getBytes());
+        byte[] resp = receiveMessage(34000);
+        TypesReader tr = new TypesReader(resp);
+        int t = tr.readByte();
+        listener.read(Packet.forName(t));
+        int rep_id = tr.readUINT32();
+
+        if (rep_id != req_id) {
+            throw new RequestMismatchException();
+        }
+
+        if (t == Packet.SSH_FXP_NAME) {
+            int count = tr.readUINT32();
+
+            if (count != 1) {
+                throw new PacketTypeException(t);
+            }
+
+            return tr.readString(charset);
+        }
+
+        if (t != Packet.SSH_FXP_STATUS) {
+            throw new PacketTypeException(t);
+        }
+
+        int errorCode = tr.readUINT32();
+        String errorMessage = tr.readString();
+        listener.read(errorMessage);
+        throw new SFTPException(errorMessage, errorCode);
+    }
+
+    public void setstat(String path, SFTPFileAttributes attr) throws IOException {
+        int req_id = generateNextRequestID();
+        TypesWriter tw = new TypesWriter();
+        tw.writeString(path, charset);
+        tw.writeBytes(attr.toBytes());
+        sendMessage(Packet.SSH_FXP_SETSTAT, req_id, tw.getBytes());
+        expectStatusOKMessage(req_id);
+    }
+
+    public void fsetstat(SFTPFileHandle handle, SFTPFileAttributes attr) throws IOException {
+        int req_id = generateNextRequestID();
+        TypesWriter tw = new TypesWriter();
+        tw.writeString(handle.getHandle(), 0, handle.getHandle().length);
+        tw.writeBytes(attr.toBytes());
+        sendMessage(Packet.SSH_FXP_FSETSTAT, req_id, tw.getBytes());
+        expectStatusOKMessage(req_id);
+    }
+
+    public void createSymlink(String src, String target) throws IOException {
+        int req_id = generateNextRequestID();
+        TypesWriter tw = new TypesWriter();
+        tw.writeString(src, charset);
+        tw.writeString(target, charset);
+        sendMessage(Packet.SSH_FXP_SYMLINK, req_id, tw.getBytes());
+        expectStatusOKMessage(req_id);
+    }
+
+    public void createHardlink(String src, String target) throws IOException {
+        int req_id = generateNextRequestID();
+        TypesWriter tw = new TypesWriter();
+        tw.writeString("hardlink@openssh.com", charset);
+        tw.writeString(target, charset);
+        tw.writeString(src, charset);
+        sendMessage(Packet.SSH_FXP_EXTENDED, req_id, tw.getBytes());
+        expectStatusOKMessage(req_id);
+    }
+
+    public String canonicalPath(String path) throws IOException {
+        int req_id = generateNextRequestID();
+        TypesWriter tw = new TypesWriter();
+        tw.writeString(path, charset);
+        sendMessage(Packet.SSH_FXP_REALPATH, req_id, tw.getBytes());
+        byte[] resp = receiveMessage(34000);
+        TypesReader tr = new TypesReader(resp);
+        int t = tr.readByte();
+        listener.read(Packet.forName(t));
+        int rep_id = tr.readUINT32();
+
+        if (rep_id != req_id) {
+            throw new RequestMismatchException();
+        }
+
+        if (t == Packet.SSH_FXP_NAME) {
+            int count = tr.readUINT32();
+
+            if (count != 1) {
+                throw new PacketFormatException("The server sent an invalid SSH_FXP_NAME packet.");
+            }
+
+            final String name = tr.readString(charset);
+            listener.read(name);
+            return name;
+        }
+
+        if (t != Packet.SSH_FXP_STATUS) {
+            throw new PacketTypeException(t);
+        }
+
+        int errorCode = tr.readUINT32();
+        String errorMessage = tr.readString();
+        listener.read(errorMessage);
+        throw new SFTPException(errorMessage, errorCode);
+    }
+
+    private void sendMessage(int type, int requestId, byte[] msg, int off, int len) throws IOException {
+        if (log.isDebugEnabled()) {
+            log.debug(String.format("Send message of type %d with request id %d", type, requestId));
+        }
+
+        listener.write(Packet.forName(type));
+        int msglen = len + 1;
+
+        if (type != Packet.SSH_FXP_INIT) {
+            msglen += 4;
+        }
+
+        os.write(msglen >> 24);
+        os.write(msglen >> 16);
+        os.write(msglen >> 8);
+        os.write(msglen);
+        os.write(type);
+
+        if (type != Packet.SSH_FXP_INIT) {
+            os.write(requestId >> 24);
+            os.write(requestId >> 16);
+            os.write(requestId >> 8);
+            os.write(requestId);
+        }
+
+        os.write(msg, off, len);
+        os.flush();
+    }
+
+    protected void sendMessage(int type, int requestId, byte[] msg) throws IOException {
+        sendMessage(type, requestId, msg, 0, msg.length);
+    }
+
+    private void readBytes(byte[] buff, int pos, int len) throws IOException {
+        while (len > 0) {
+            int count = is.read(buff, pos, len);
+
+            if (count < 0) {
+                throw new SocketException("Unexpected end of stream.");
+            }
+
+            len -= count;
+            pos += count;
+        }
+    }
+
+    /**
+     * Read a message and guarantee that the <b>contents</b> is not larger than
+     * <code>maxlen</code> bytes.
+     * <p/>
+     * Note: receiveMessage(34000) actually means that the message may be up to 34004
+     * bytes (the length attribute preceding the contents is 4 bytes).
+     *
+     * @param maxlen
+     * @return the message contents
+     * @throws IOException
+     */
+    protected byte[] receiveMessage(int maxlen) throws IOException {
+        byte[] msglen = new byte[4];
+        readBytes(msglen, 0, 4);
+        int len = (((msglen[0] & 0xff) << 24) | ((msglen[1] & 0xff) << 16) | ((msglen[2] & 0xff) << 8) | (msglen[3] & 0xff));
+
+        if ((len > maxlen) || (len <= 0)) {
+            throw new PacketFormatException(String.format("Illegal SFTP packet length %d", len));
+        }
+
+        byte[] msg = new byte[len];
+        readBytes(msg, 0, len);
+        return msg;
+    }
+
+    protected int generateNextRequestID() {
+        synchronized (this) {
+            return next_request_id++;
+        }
+    }
+
+    protected void closeHandle(byte[] handle) throws IOException {
+        int req_id = generateNextRequestID();
+        TypesWriter tw = new TypesWriter();
+        tw.writeString(handle, 0, handle.length);
+        sendMessage(Packet.SSH_FXP_CLOSE, req_id, tw.getBytes());
+        expectStatusOKMessage(req_id);
+    }
+
+    private void readStatus() throws IOException {
+        byte[] resp = receiveMessage(34000);
+        TypesReader tr = new TypesReader(resp);
+        int t = tr.readByte();
+        listener.read(Packet.forName(t));
+        // Search the pending queue
+        OutstandingStatusRequest status = pendingStatusQueue.remove(tr.readUINT32());
+
+        if (null == status) {
+            throw new RequestMismatchException();
+        }
+
+        // Evaluate the answer
+        if (t == Packet.SSH_FXP_STATUS) {
+            // In any case, stop sending more packets
+            int code = tr.readUINT32();
+
+            if (log.isDebugEnabled()) {
+                String[] desc = ErrorCodes.getDescription(code);
+                log.debug("Got SSH_FXP_STATUS (" + status.req_id + ") (" + ((desc != null) ? desc[0] : "UNKNOWN") + ")");
+            }
+
+            if (code == ErrorCodes.SSH_FX_OK) {
+                return;
+            }
+
+            String msg = tr.readString();
+            listener.read(msg);
+            throw new SFTPException(msg, code);
+        }
+
+        throw new PacketTypeException(t);
+    }
+
+    private void readPendingReadStatus() throws IOException {
+        byte[] resp = receiveMessage(34000);
+        TypesReader tr = new TypesReader(resp);
+        int t = tr.readByte();
+        listener.read(Packet.forName(t));
+        // Search the pending queue
+        OutstandingReadRequest status = pendingReadQueue.remove(tr.readUINT32());
+
+        if (null == status) {
+            throw new RequestMismatchException();
+        }
+
+        // Evaluate the answer
+        if (t == Packet.SSH_FXP_STATUS) {
+            // In any case, stop sending more packets
+            int code = tr.readUINT32();
+
+            if (log.isDebugEnabled()) {
+                String[] desc = ErrorCodes.getDescription(code);
+                log.debug("Got SSH_FXP_STATUS (" + status.req_id + ") (" + ((desc != null) ? desc[0] : "UNKNOWN") + ")");
+            }
+
+            if (code == ErrorCodes.SSH_FX_OK) {
+                return;
+            }
+
+            if (code == ErrorCodes.SSH_FX_EOF) {
+                return;
+            }
+
+            String msg = tr.readString();
+            listener.read(msg);
+            throw new SFTPException(msg, code);
+        }
+
+        throw new PacketTypeException(t);
+    }
+
+    protected void expectStatusOKMessage(int id) throws IOException {
+        byte[] resp = receiveMessage(34000);
+        TypesReader tr = new TypesReader(resp);
+        int t = tr.readByte();
+        listener.read(Packet.forName(t));
+        int rep_id = tr.readUINT32();
+
+        if (rep_id != id) {
+            throw new RequestMismatchException();
+        }
+
+        if (t != Packet.SSH_FXP_STATUS) {
+            throw new PacketTypeException(t);
+        }
+
+        int errorCode = tr.readUINT32();
+
+        if (errorCode == ErrorCodes.SSH_FX_OK) {
+            return;
+        }
+
+        String errorMessage = tr.readString();
+        listener.read(errorMessage);
+        throw new SFTPException(errorMessage, errorCode);
+    }
+
+    public void closeFile(SFTPFileHandle handle) throws IOException {
+        while (!pendingReadQueue.isEmpty()) {
+            this.readPendingReadStatus();
+        }
+
+        while (!pendingStatusQueue.isEmpty()) {
+            this.readStatus();
+        }
+
+        closeHandle(handle.getHandle());
+    }
+
+    public int read(SFTPFileHandle handle, long fileOffset, byte[] dst, int dstoff, int len) throws IOException {
+        boolean errorOccured = false;
+        int remaining = len * parallelism;
+        //int clientOffset = dstoff;
+        long serverOffset = fileOffset;
+
+        for (OutstandingReadRequest r : pendingReadQueue.values()) {
+            // Server offset should take pending requests into account.
+            serverOffset += r.len;
+        }
+
+        while (true) {
+            // Stop if there was an error and no outstanding request
+            if ((pendingReadQueue.size() == 0) && errorOccured) {
+                break;
+            }
+
+            // Send as many requests as we are allowed to
+            while (pendingReadQueue.size() < parallelism) {
+                if (errorOccured) {
+                    break;
+                }
+
+                // Send the next read request
+                OutstandingReadRequest req = new OutstandingReadRequest();
+                req.req_id = generateNextRequestID();
+                req.serverOffset = serverOffset;
+                req.len = (remaining > len) ? len : remaining;
+                req.buffer = dst;
+                req.dstOffset = dstoff;
+                serverOffset += req.len;
+                //clientOffset += req.len;
+                remaining -= req.len;
+                sendReadRequest(req.req_id, handle, req.serverOffset, req.len);
+                pendingReadQueue.put(req.req_id, req);
+            }
+
+            if (pendingReadQueue.size() == 0) {
+                break;
+            }
+
+            // Receive a single answer
+            byte[] resp = receiveMessage(34000);
+            TypesReader tr = new TypesReader(resp);
+            int t = tr.readByte();
+            listener.read(Packet.forName(t));
+            // Search the pending queue
+            OutstandingReadRequest req = pendingReadQueue.remove(tr.readUINT32());
+
+            if (null == req) {
+                throw new RequestMismatchException();
+            }
+
+            // Evaluate the answer
+            if (t == Packet.SSH_FXP_STATUS) {
+                /* In any case, stop sending more packets */
+                int code = tr.readUINT32();
+                String msg = tr.readString();
+                listener.read(msg);
+
+                if (log.isDebugEnabled()) {
+                    String[] desc = ErrorCodes.getDescription(code);
+                    log.debug("Got SSH_FXP_STATUS (" + req.req_id + ") (" + ((desc != null) ? desc[0] : "UNKNOWN") + ")");
+                }
+
+                // Flag to read all pending requests but don't send any more.
+                errorOccured = true;
+
+                if (pendingReadQueue.isEmpty()) {
+                    if (ErrorCodes.SSH_FX_EOF == code) {
+                        return -1;
+                    }
+
+                    throw new SFTPException(msg, code);
+                }
+            }
+            else if (t == Packet.SSH_FXP_DATA) {
+                // OK, collect data
+                int readLen = tr.readUINT32();
+
+                if ((readLen < 0) || (readLen > req.len)) {
+                    throw new PacketFormatException("The server sent an invalid length field in a SSH_FXP_DATA packet.");
+                }
+
+                if (log.isDebugEnabled()) {
+                    log.debug("Got SSH_FXP_DATA (" + req.req_id + ") " + req.serverOffset + "/" + readLen
+                              + " (requested: " + req.len + ")");
+                }
+
+                // Read bytes into buffer
+                tr.readBytes(req.buffer, req.dstOffset, readLen);
+
+                if (readLen < req.len) {
+                    /* Send this request packet again to request the remaing data in this slot. */
+                    req.req_id = generateNextRequestID();
+                    req.serverOffset += readLen;
+                    req.len -= readLen;
+                    log.debug("Requesting again: " + req.serverOffset + "/" + req.len);
+                    sendReadRequest(req.req_id, handle, req.serverOffset, req.len);
+                    pendingReadQueue.put(req.req_id, req);
+                }
+
+                return readLen;
+            }
+            else {
+                throw new PacketTypeException(t);
+            }
+        }
+
+        // Should never reach here.
+        throw new SFTPException("No EOF reached", -1);
+    }
+
+    private void sendReadRequest(int id, SFTPFileHandle handle, long offset, int len) throws IOException {
+        TypesWriter tw = new TypesWriter();
+        tw.writeString(handle.getHandle(), 0, handle.getHandle().length);
+        tw.writeUINT64(offset);
+        tw.writeUINT32(len);
+        sendMessage(Packet.SSH_FXP_READ, id, tw.getBytes());
+    }
+
+    public void write(SFTPFileHandle handle, long fileOffset, byte[] src, int srcoff, int len) throws IOException {
+        while (len > 0) {
+            int writeRequestLen = len;
+
+            if (writeRequestLen > 32768) {
+                writeRequestLen = 32768;
+            }
+
+            // Send the next write request
+            OutstandingStatusRequest req = new OutstandingStatusRequest();
+            req.req_id = generateNextRequestID();
+            TypesWriter tw = new TypesWriter();
+            tw.writeString(handle.getHandle(), 0, handle.getHandle().length);
+            tw.writeUINT64(fileOffset);
+            tw.writeString(src, srcoff, writeRequestLen);
+            sendMessage(Packet.SSH_FXP_WRITE, req.req_id, tw.getBytes());
+            pendingStatusQueue.put(req.req_id, req);
+
+            // Only read next status if parallelism reached
+            while (pendingStatusQueue.size() >= parallelism) {
+                this.readStatus();
+            }
+
+            fileOffset += writeRequestLen;
+            srcoff += writeRequestLen;
+            len -= writeRequestLen;
+        }
+    }
+
+
+    /**
+     * A read  is divided into multiple requests sent sequentially before
+     * reading any status from the server
+     */
+    private static class OutstandingReadRequest {
+        int req_id;
+        /**
+         * Read offset to request on server starting at the file offset for the first request.
+         */
+        long serverOffset;
+        /**
+         * Length of requested data
+         */
+        int len;
+        /**
+         * Offset in destination buffer
+         */
+        int dstOffset;
+        /**
+         * Temporary buffer
+         */
+        byte[] buffer;
+    }
+
+    /**
+     * A read  is divided into multiple requests sent sequentially before
+     * reading any status from the server
+     */
+    private static final class OutstandingStatusRequest {
+        int req_id;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/src/main/java/ch/ethz/ssh2/AuthAgentCallback.java	Thu Dec 03 11:23:55 2015 -0800
@@ -0,0 +1,64 @@
+package ch.ethz.ssh2;
+
+import java.security.KeyPair;
+import java.util.Map;
+
+/**
+ * AuthAgentCallback.
+ *
+ * @author Kenny Root
+ * @version $Id$
+ */
+public interface AuthAgentCallback {
+
+    /**
+     * @return array of blobs containing the OpenSSH-format encoded public keys
+     */
+    Map<String, byte[]> retrieveIdentities();
+
+    /**
+     * @param pair A <code>RSAPrivateKey</code> or <code>DSAPrivateKey</code> or <code>ECPrivateKey</code>
+     *            containing a DSA or RSA or EC private key of
+     *            the user in standard java key format.
+     * @param comment comment associated with this key
+     * @param confirmUse whether to prompt before using this key
+     * @param lifetime lifetime in seconds for key to be remembered
+     * @return success or failure
+     */
+    boolean addIdentity(KeyPair pair, String comment, boolean confirmUse, int lifetime);
+
+    /**
+     * @param publicKey byte blob containing the OpenSSH-format encoded public key
+     * @return success or failure
+     */
+    boolean removeIdentity(byte[] publicKey);
+
+    /**
+     * @return success or failure
+     */
+    boolean removeAllIdentities();
+
+    /**
+     * @param publicKey byte blob containing the OpenSSH-format encoded public key
+     * @return A <code>RSAPrivateKey</code> or <code>DSAPrivateKey</code>
+     *         containing a DSA or RSA or EC private key of
+     *         the user in standard java key format.
+     */
+    KeyPair getKeyPair(byte[] publicKey);
+
+    /**
+     * @return
+     */
+    boolean isAgentLocked();
+
+    /**
+     * @param lockPassphrase
+     */
+    boolean setAgentLock(String lockPassphrase);
+
+    /**
+     * @param unlockPassphrase
+     * @return
+     */
+    boolean requestAgentUnlock(String unlockPassphrase);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/src/main/java/ch/ethz/ssh2/AuthenticationResult.java	Thu Dec 03 11:23:55 2015 -0800
@@ -0,0 +1,21 @@
+
+package ch.ethz.ssh2;
+
+public enum AuthenticationResult {
+
+    /**
+     *
+     */
+    SUCCESS,
+    /**
+     * The authentication request to which this is a response was successful, however, more
+     * authentication requests are needed (multi-method authentication sequence).
+     *
+     * @see ServerAuthenticationCallback#getRemainingAuthMethods(ServerConnection)
+     */
+    PARTIAL_SUCCESS,
+    /**
+     * The server rejected the authentication request.
+     */
+    FAILURE
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/src/main/java/ch/ethz/ssh2/ChannelCondition.java	Thu Dec 03 11:23:55 2015 -0800
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2006-2011 Christian Plattner. All rights reserved.
+ * Please refer to the LICENSE.txt for licensing details.
+ */
+package ch.ethz.ssh2;
+
+/**
+ * Contains constants that can be used to specify what conditions to wait for on
+ * a SSH-2 channel (e.g., represented by a {@link Session}).
+ *
+ * @see Session#waitForCondition(int, long)
+ *
+ * @author Christian Plattner
+ * @version 2.50, 03/15/10
+ */
+
+public abstract interface ChannelCondition {
+    /**
+     * A timeout has occurred, none of your requested conditions is fulfilled.
+     * However, other conditions may be true - therefore, NEVER use the "=="
+     * operator to test for this (or any other) condition. Always use
+     * something like <code>((cond &amp; ChannelCondition.CLOSED) != 0)</code>.
+     */
+    public static final int TIMEOUT = 1;
+
+    /**
+     * The underlying SSH-2 channel, however not necessarily the whole connection,
+     * has been closed. This implies <code>EOF</code>. Note that there may still
+     * be unread stdout or stderr data in the local window, i.e, <code>STDOUT_DATA</code>
+     * or/and <code>STDERR_DATA</code> may be set at the same time.
+     */
+    public static final int CLOSED = 2;
+
+    /**
+     * There is stdout data available that is ready to be consumed.
+     */
+    public static final int STDOUT_DATA = 4;
+
+    /**
+     * There is stderr data available that is ready to be consumed.
+     */
+    public static final int STDERR_DATA = 8;
+
+    /**
+     * EOF on has been reached, no more _new_ stdout or stderr data will arrive
+     * from the remote server. However, there may be unread stdout or stderr
+     * data, i.e, <code>STDOUT_DATA</code> or/and <code>STDERR_DATA</code>
+     * may be set at the same time.
+     */
+    public static final int EOF = 16;
+
+    /**
+     * The exit status of the remote process is available.
+     * Some servers never send the exist status, or occasionally "forget" to do so.
+     */
+    public static final int EXIT_STATUS = 32;
+
+    /**
+     * The exit signal of the remote process is available.
+     */
+    public static final int EXIT_SIGNAL = 64;
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/src/main/java/ch/ethz/ssh2/Connection.java	Thu Dec 03 11:23:55 2015 -0800
@@ -0,0 +1,1452 @@
+/*
+ * Copyright (c) 2006-2011 Christian Plattner. All rights reserved.
+ * Please refer to the LICENSE.txt for licensing details.
+ */
+
+package ch.ethz.ssh2;
+
+import java.io.CharArrayWriter;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.SocketTimeoutException;
+import java.security.KeyPair;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import ch.ethz.ssh2.auth.AgentProxy;
+import ch.ethz.ssh2.auth.AuthenticationManager;
+import ch.ethz.ssh2.channel.ChannelManager;
+import ch.ethz.ssh2.compression.CompressionFactory;
+import ch.ethz.ssh2.crypto.CryptoWishList;
+import ch.ethz.ssh2.crypto.SecureRandomFix;
+import ch.ethz.ssh2.crypto.cipher.BlockCipherFactory;
+import ch.ethz.ssh2.crypto.digest.MAC;
+import ch.ethz.ssh2.log.Logger;
+import ch.ethz.ssh2.packets.PacketIgnore;
+import ch.ethz.ssh2.transport.ClientTransportManager;
+import ch.ethz.ssh2.transport.HTTPProxyClientTransportManager;
+import ch.ethz.ssh2.transport.KexManager;
+import ch.ethz.ssh2.util.TimeoutService.TimeoutToken;
+import ch.ethz.ssh2.util.TimeoutService;
+
+/**
+ * A <code>Connection</code> is used to establish an encrypted TCP/IP
+ * connection to a SSH-2 server.
+ * <p/>
+ * Typically, one
+ * <ol>
+ * <li>creates a {@link #Connection(String) Connection} object.</li>
+ * <li>calls the {@link #connect() connect()} method.</li>
+ * <li>calls some of the authentication methods (e.g., {@link #authenticateWithPublicKey(String, File, String) authenticateWithPublicKey()}).</li>
+ * <li>calls one or several times the {@link #openSession() openSession()} method.</li>
+ * <li>finally, one must close the connection and release resources with the {@link #close() close()} method.</li>
+ * </ol>
+ *
+ * @author Christian Plattner
+ * @version $Id: Connection.java 160 2014-05-01 14:30:26Z dkocher@sudo.ch $
+ */
+
+public class Connection {
+    protected static final Logger log = Logger.getLogger(Connection.class);
+
+    /**
+     * The identifier presented to the SSH-2 server. This is the same
+     * as the "softwareversion" defined in RFC 4253.
+     * <p/>
+     * <b>NOTE: As per the RFC, the "softwareversion" string MUST consist of printable
+     * US-ASCII characters, with the exception of whitespace characters and the minus sign (-).</b>
+     */
+    private String softwareversion
+        = String.format("Ganymed_%s", Version.getSpecification());
+
+    /* Will be used to generate all random data needed for the current connection.
+     * Note: SecureRandom.nextBytes() is thread safe.
+     */
+
+    private SecureRandomFix generator;
+
+    /**
+     * Unless you know what you are doing, you will never need this.
+     *
+     * @return The list of supported cipher algorithms by this implementation.
+     */
+
+    public static synchronized String[] getAvailableCiphers() {
+        return BlockCipherFactory.getDefaultCipherList();
+    }
+
+    /**
+     * Unless you know what you are doing, you will never need this.
+     *
+     * @return The list of supported MAC algorthims by this implementation.
+     */
+
+    public static synchronized String[] getAvailableMACs() {
+        return MAC.getMacList();
+    }
+
+    /**
+     * Unless you know what you are doing, you will never need this.
+     *
+     * @return The list of supported server host key algorthims by this implementation.
+     */
+
+    public static synchronized String[] getAvailableServerHostKeyAlgorithms() {
+        return KexManager.getDefaultServerHostkeyAlgorithmList();
+    }
+
+    private AuthenticationManager am;
+
+    private boolean authenticated;
+    private ChannelManager cm;
+
+    private CryptoWishList cryptoWishList
+        = new CryptoWishList();
+
+    private DHGexParameters dhgexpara
+        = new DHGexParameters();
+
+    private final String hostname;
+
+    private final int port;
+
+    private ClientTransportManager tm;
+
+    private boolean tcpNoDelay = false;
+
+    private HTTPProxyData proxy;
+
+    private List<ConnectionMonitor> connectionMonitors
+        = new ArrayList<ConnectionMonitor>();
+
+    /**
+     * Prepares a fresh <code>Connection</code> object which can then be used
+     * to establish a connection to the specified SSH-2 server.
+     * <p/>
+     * Same as {@link #Connection(String, int) Connection(hostname, 22)}.
+     *
+     * @param hostname the hostname of the SSH-2 server.
+     */
+    public Connection(String hostname) {
+        this(hostname, 22);
+    }
+
+    /**
+     * Prepares a fresh <code>Connection</code> object which can then be used
+     * to establish a connection to the specified SSH-2 server.
+     *
+     * @param hostname the host where we later want to connect to.
+     * @param port     port on the server, normally 22.
+     */
+    public Connection(String hostname, int port) {
+        this.hostname = hostname;
+        this.port = port;
+    }
+
+    /**
+     * Prepares a fresh <code>Connection</code> object which can then be used
+     * to establish a connection to the specified SSH-2 server.
+     *
+     * @param hostname        the host where we later want to connect to.
+     * @param port            port on the server, normally 22.
+     * @param softwareversion Allows you to set a custom "softwareversion" string as defined in RFC 4253.
+     *                        <b>NOTE: As per the RFC, the "softwareversion" string MUST consist of printable
+     *                        US-ASCII characters, with the exception of whitespace characters and the minus sign (-).</b>
+     */
+    public Connection(String hostname, int port, String softwareversion) {
+        this.hostname = hostname;
+        this.port = port;
+        this.softwareversion = softwareversion;
+    }
+
+    public Connection(String hostname, int port, final HTTPProxyData proxy) {
+        this.hostname = hostname;
+        this.port = port;
+        this.proxy = proxy;
+    }
+
+    public Connection(String hostname, int port, String softwareversion, final HTTPProxyData proxy) {
+        this.hostname = hostname;
+        this.port = port;
+        this.softwareversion = softwareversion;
+        this.proxy = proxy;
+    }
+
+    /**
+     * After a successful connect, one has to authenticate oneself. This method
+     * is based on DSA (it uses DSA to sign a challenge sent by the server).
+     * <p/>
+     * If the authentication phase is complete, <code>true</code> will be
+     * returned. If the server does not accept the request (or if further
+     * authentication steps are needed), <code>false</code> is returned and
+     * one can retry either by using this or any other authentication method
+     * (use the <code>getRemainingAuthMethods</code> method to get a list of
+     * the remaining possible methods).
+     *
+     * @param user     A <code>String</code> holding the username.
+     * @param pem      A <code>String</code> containing the DSA private key of the
+     *                 user in OpenSSH key format (PEM, you can't miss the
+     *                 "-----BEGIN DSA PRIVATE KEY-----" tag). The string may contain
+     *                 linefeeds.
+     * @param password If the PEM string is 3DES encrypted ("DES-EDE3-CBC"), then you
+     *                 must specify the password. Otherwise, this argument will be
+     *                 ignored and can be set to <code>null</code>.
+     * @return whether the connection is now authenticated.
+     * @throws IOException
+     * @deprecated You should use one of the {@link #authenticateWithPublicKey(String, File, String) authenticateWithPublicKey()}
+     * methods, this method is just a wrapper for it and will
+     * disappear in future builds.
+     */
+    @Deprecated
+
+    public synchronized boolean authenticateWithDSA(String user, String pem, String password) throws IOException {
+        if (tm == null) {
+            throw new IllegalStateException("Connection is not established!");
+        }
+
+        if (authenticated) {
+            throw new IllegalStateException("Connection is already authenticated!");
+        }
+
+        if (am == null) {
+            am = new AuthenticationManager(tm);
+        }
+
+        if (cm == null) {
+            cm = new ChannelManager(tm);
+        }
+
+        if (user == null) {
+            throw new IllegalArgumentException("user argument is null");
+        }
+
+        if (pem == null) {
+            throw new IllegalArgumentException("pem argument is null");
+        }
+
+        authenticated = am.authenticatePublicKey(user, pem.toCharArray(), password, getOrCreateSecureRND());
+        return authenticated;
+    }
+
+    /**
+     * A wrapper that calls {@link #authenticateWithKeyboardInteractive(String, String[], InteractiveCallback)
+     * authenticateWithKeyboardInteractivewith} a <code>null</code> submethod list.
+     *
+     * @param user A <code>String</code> holding the username.
+     * @param cb   An <code>InteractiveCallback</code> which will be used to
+     *             determine the responses to the questions asked by the server.
+     * @return whether the connection is now authenticated.
+     * @throws IOException
+     */
+
+    public synchronized boolean authenticateWithKeyboardInteractive(String user, InteractiveCallback cb)
+    throws IOException {
+        return authenticateWithKeyboardInteractive(user, null, cb);
+    }
+
+    /**
+     * After a successful connect, one has to authenticate oneself. This method
+     * is based on "keyboard-interactive", specified in
+     * draft-ietf-secsh-auth-kbdinteract-XX. Basically, you have to define a
+     * callback object which will be feeded with challenges generated by the
+     * server. Answers are then sent back to the server. It is possible that the
+     * callback will be called several times during the invocation of this
+     * method (e.g., if the server replies to the callback's answer(s) with
+     * another challenge...)
+     * <p/>
+     * If the authentication phase is complete, <code>true</code> will be
+     * returned. If the server does not accept the request (or if further
+     * authentication steps are needed), <code>false</code> is returned and
+     * one can retry either by using this or any other authentication method
+     * (use the <code>getRemainingAuthMethods</code> method to get a list of
+     * the remaining possible methods).
+     * <p/>
+     * Note: some SSH servers advertise "keyboard-interactive", however, any
+     * interactive request will be denied (without having sent any challenge to
+     * the client).
+     *
+     * @param user       A <code>String</code> holding the username.
+     * @param submethods An array of submethod names, see
+     *                   draft-ietf-secsh-auth-kbdinteract-XX. May be <code>null</code>
+     *                   to indicate an empty list.
+     * @param cb         An <code>InteractiveCallback</code> which will be used to
+     *                   determine the responses to the questions asked by the server.
+     * @return whether the connection is now authenticated.
+     * @throws IOException
+     */
+
+    public synchronized boolean authenticateWithKeyboardInteractive(String user, String[] submethods,
+            InteractiveCallback cb) throws IOException {
+        if (cb == null) {
+            throw new IllegalArgumentException("Callback may not ne NULL!");
+        }
+
+        if (tm == null) {
+            throw new IllegalStateException("Connection is not established!");
+        }
+
+        if (authenticated) {
+            throw new IllegalStateException("Connection is already authenticated!");
+        }
+
+        if (am == null) {
+            am = new AuthenticationManager(tm);
+        }
+
+        if (cm == null) {
+            cm = new ChannelManager(tm);
+        }
+
+        if (user == null) {
+            throw new IllegalArgumentException("user argument is null");
+        }
+
+        authenticated = am.authenticateInteractive(user, submethods, cb);
+        return authenticated;
+    }
+
+    public synchronized boolean authenticateWithAgent(String user, AgentProxy proxy) throws IOException {
+        if (tm == null) {
+            throw new IllegalStateException("Connection is not established!");
+        }
+
+        if (authenticated) {
+            throw new IllegalStateException("Connection is already authenticated!");
+        }
+
+        if (am == null) {
+            am = new AuthenticationManager(tm);
+        }
+
+        if (cm == null) {
+            cm = new ChannelManager(tm);
+        }
+
+        if (user == null) {
+            throw new IllegalArgumentException("user argument is null");
+        }
+
+        authenticated = am.authenticatePublicKey(user, proxy);
+        return authenticated;
+    }
+
+    /**
+     * After a successful connect, one has to authenticate oneself. This method
+     * sends username and password to the server.
+     * <p/>
+     * If the authentication phase is complete, <code>true</code> will be
+     * returned. If the server does not accept the request (or if further
+     * authentication steps are needed), <code>false</code> is returned and
+     * one can retry either by using this or any other authentication method
+     * (use the <code>getRemainingAuthMethods</code> method to get a list of
+     * the remaining possible methods).
+     * <p/>
+     * Note: if this method fails, then please double-check that it is actually
+     * offered by the server (use {@link #getRemainingAuthMethods(String) getRemainingAuthMethods()}.
+     * <p/>
+     * Often, password authentication is disabled, but users are not aware of it.
+     * Many servers only offer "publickey" and "keyboard-interactive". However,
+     * even though "keyboard-interactive" *feels* like password authentication
+     * (e.g., when using the putty or openssh clients) it is *not* the same mechanism.
+     *
+     * @param user
+     * @param password
+     * @return if the connection is now authenticated.
+     * @throws IOException
+     */
+
+    public synchronized boolean authenticateWithPassword(String user, String password) throws IOException {
+        if (tm == null) {
+            throw new IllegalStateException("Connection is not established!");
+        }
+
+        if (authenticated) {
+            throw new IllegalStateException("Connection is already authenticated!");
+        }
+
+        if (am == null) {
+            am = new AuthenticationManager(tm);
+        }
+
+        if (cm == null) {
+            cm = new ChannelManager(tm);
+        }
+
+        if (user == null) {
+            throw new IllegalArgumentException("user argument is null");
+        }
+
+        if (password == null) {
+            throw new IllegalArgumentException("password argument is null");
+        }
+
+        authenticated = am.authenticatePassword(user, password);
+        return authenticated;
+    }
+
+    /**
+     * After a successful connect, one has to authenticate oneself.
+     * This method can be used to explicitly use the special "none"
+     * authentication method (where only a username has to be specified).
+     * <p/>
+     * Note 1: The "none" method may always be tried by clients, however as by
+     * the specs, the server will not explicitly announce it. In other words,
+     * the "none" token will never show up in the list returned by
+     * {@link #getRemainingAuthMethods(String)}.
+     * <p/>
+     * Note 2: no matter which one of the authenticateWithXXX() methods
+     * you call, the library will always issue exactly one initial "none"
+     * authentication request to retrieve the initially allowed list of
+     * authentication methods by the server. Please read RFC 4252 for the
+     * details.
+     * <p/>
+     * If the authentication phase is complete, <code>true</code> will be
+     * returned. If further authentication steps are needed, <code>false</code>
+     * is returned and one can retry by any other authentication method
+     * (use the <code>getRemainingAuthMethods</code> method to get a list of
+     * the remaining possible methods).
+     *
+     * @param user
+     * @return if the connection is now authenticated.
+     * @throws IOException
+     */
+
+    public synchronized boolean authenticateWithNone(String user) throws IOException {
+        if (tm == null) {
+            throw new IllegalStateException("Connection is not established!");
+        }
+
+        if (authenticated) {
+            throw new IllegalStateException("Connection is already authenticated!");
+        }
+
+        if (am == null) {
+            am = new AuthenticationManager(tm);
+        }
+
+        if (cm == null) {
+            cm = new ChannelManager(tm);
+        }
+
+        if (user == null) {
+            throw new IllegalArgumentException("user argument is null");
+        }
+
+        /* Trigger the sending of the PacketUserauthRequestNone packet */
+        /* (if not already done)                                       */
+        authenticated = am.authenticateNone(user);
+        return authenticated;
+    }
+
+    /**
+     * After a successful connect, one has to authenticate oneself.
+     * The authentication method "publickey" works by signing a challenge
+     * sent by the server. The signature is either DSA or RSA based - it
+     * just depends on the type of private key you specify, either a DSA
+     * or RSA private key in PEM format. And yes, this is may seem to be a
+     * little confusing, the method is called "publickey" in the SSH-2 protocol
+     * specification, however since we need to generate a signature, you
+     * actually have to supply a private key =).
+     * <p/>
+     * The private key contained in the PEM file may also be encrypted ("Proc-Type: 4,ENCRYPTED").
+     * The library supports DES-CBC and DES-EDE3-CBC encryption, as well
+     * as the more exotic PEM encrpytions AES-128-CBC, AES-192-CBC and AES-256-CBC.
+     * <p/>
+     * If the authentication phase is complete, <code>true</code> will be
+     * returned. If the server does not accept the request (or if further
+     * authentication steps are needed), <code>false</code> is returned and
+     * one can retry either by using this or any other authentication method
+     * (use the <code>getRemainingAuthMethods</code> method to get a list of
+     * the remaining possible methods).
+     * <p/>
+     * NOTE PUTTY USERS: Event though your key file may start with "-----BEGIN..."
+     * it is not in the expected format. You have to convert it to the OpenSSH
+     * key format by using the "puttygen" tool (can be downloaded from the Putty
+     * website). Simply load your key and then use the "Conversions/Export OpenSSH key"
+     * functionality to get a proper PEM file.
+     *
+     * @param user          A <code>String</code> holding the username.
+     * @param pemPrivateKey A <code>char[]</code> containing a DSA or RSA private key of the
+     *                      user in OpenSSH key format (PEM, you can't miss the
+     *                      "-----BEGIN DSA PRIVATE KEY-----" or "-----BEGIN RSA PRIVATE KEY-----"
+     *                      tag). The char array may contain linebreaks/linefeeds.
+     * @param password      If the PEM structure is encrypted ("Proc-Type: 4,ENCRYPTED") then
+     *                      you must specify a password. Otherwise, this argument will be ignored
+     *                      and can be set to <code>null</code>.
+     * @return whether the connection is now authenticated.
+     * @throws IOException
+     */
+
+    public synchronized boolean authenticateWithPublicKey(String user, char[] pemPrivateKey, String password)
+    throws IOException {
+        if (tm == null) {
+            throw new IllegalStateException("Connection is not established!");
+        }
+
+        if (authenticated) {
+            throw new IllegalStateException("Connection is already authenticated!");
+        }
+
+        if (am == null) {
+            am = new AuthenticationManager(tm);
+        }
+
+        if (cm == null) {
+            cm = new ChannelManager(tm);
+        }
+
+        if (user == null) {
+            throw new IllegalArgumentException("user argument is null");
+        }
+
+        if (pemPrivateKey == null) {
+            throw new IllegalArgumentException("pemPrivateKey argument is null");
+        }
+
+        authenticated = am.authenticatePublicKey(user, pemPrivateKey, password, getOrCreateSecureRND());
+        return authenticated;
+    }
+
+    /**
+     * After a successful connect, one has to authenticate oneself. The
+     * authentication method "publickey" works by signing a challenge sent by
+     * the server. The signature is either DSA or RSA based - it just depends on
+     * the type of private key you specify, either a DSA or RSA private key in
+     * PEM format. And yes, this is may seem to be a little confusing, the
+     * method is called "publickey" in the SSH-2 protocol specification, however
+     * since we need to generate a signature, you actually have to supply a
+     * private key =).
+     * <p>
+     * If the authentication phase is complete, <code>true</code> will be
+     * returned. If the server does not accept the request (or if further
+     * authentication steps are needed), <code>false</code> is returned and
+     * one can retry either by using this or any other authentication method
+     * (use the <code>getRemainingAuthMethods</code> method to get a list of
+     * the remaining possible methods).
+     *
+     * @param user
+     *            A <code>String</code> holding the username.
+     * @param pair
+     *            A <code>RSAPrivateKey</code> or <code>DSAPrivateKey</code>
+     *            containing a DSA or RSA private key of
+     *            the user in Trilead object format.
+     *
+     * @return whether the connection is now authenticated.
+     * @throws IOException
+     */
+
+    public synchronized boolean authenticateWithPublicKey(String user, KeyPair pair)
+    throws IOException {
+        if (tm == null)
+            throw new IllegalStateException("Connection is not established!");
+
+        if (authenticated)
+            throw new IllegalStateException("Connection is already authenticated!");
+
+        if (am == null)
+            am = new AuthenticationManager(tm);
+
+        if (cm == null)
+            cm = new ChannelManager(tm);
+
+        if (user == null)
+            throw new IllegalArgumentException("user argument is null");
+
+        if (pair == null)
+            throw new IllegalArgumentException("Key pair argument is null");
+
+        authenticated = am.authenticatePublicKey(user, pair, getOrCreateSecureRND());
+        return authenticated;
+    }
+
+    /**
+     * A convenience wrapper function which reads in a private key (PEM format, either DSA or RSA)
+     * and then calls <code>authenticateWithPublicKey(String, char[], String)</code>.
+     * <p/>
+     * NOTE PUTTY USERS: Event though your key file may start with "-----BEGIN..."
+     * it is not in the expected format. You have to convert it to the OpenSSH
+     * key format by using the "puttygen" tool (can be downloaded from the Putty
+     * website). Simply load your key and then use the "Conversions/Export OpenSSH key"
+     * functionality to get a proper PEM file.
+     *
+     * @param user     A <code>String</code> holding the username.
+     * @param pemFile  A <code>File</code> object pointing to a file containing a DSA or RSA
+     *                 private key of the user in OpenSSH key format (PEM, you can't miss the
+     *                 "-----BEGIN DSA PRIVATE KEY-----" or "-----BEGIN RSA PRIVATE KEY-----"
+     *                 tag).
+     * @param password If the PEM file is encrypted then you must specify the password.
+     *                 Otherwise, this argument will be ignored and can be set to <code>null</code>.
+     * @return whether the connection is now authenticated.
+     * @throws IOException
+     */
+
+    public synchronized boolean authenticateWithPublicKey(String user, File pemFile, String password)
+    throws IOException {
+        if (pemFile == null) {
+            throw new IllegalArgumentException("pemFile argument is null");
+        }
+
+        char[] buff = new char[256];
+        CharArrayWriter cw = new CharArrayWriter();
+        FileReader fr = new FileReader(pemFile);
+
+        while (true) {
+            int len = fr.read(buff);
+
+            if (len < 0) {
+                break;
+            }
+
+            cw.write(buff, 0, len);
+        }
+
+        fr.close();
+        return authenticateWithPublicKey(user, cw.toCharArray(), password);
+    }
+
+    /**
+     * Add a {@link ConnectionMonitor} to this connection. Can be invoked at any time,
+     * but it is best to add connection monitors before invoking
+     * <code>connect()</code> to avoid glitches (e.g., you add a connection monitor after
+     * a successful connect(), but the connection has died in the mean time. Then,
+     * your connection monitor won't be notified.)
+     * <p/>
+     * You can add as many monitors as you like. If a monitor has already been added, then
+     * this method does nothing.
+     *
+     * @param cmon An object implementing the {@link ConnectionMonitor} interface.
+     * @see ConnectionMonitor
+     */
+
+    public synchronized void addConnectionMonitor(ConnectionMonitor cmon) {
+        if (!connectionMonitors.contains(cmon)) {
+            connectionMonitors.add(cmon);
+
+            if (tm != null) {
+                tm.setConnectionMonitors(connectionMonitors);
+            }
+        }
+    }
+
+    /**
+     * Remove a {@link ConnectionMonitor} from this connection.
+     *
+     * @param cmon
+     * @return whether the monitor could be removed
+     */
+
+    public synchronized boolean removeConnectionMonitor(ConnectionMonitor cmon) {
+        boolean existed = connectionMonitors.remove(cmon);
+
+        if (tm != null) {
+            tm.setConnectionMonitors(connectionMonitors);
+        }
+
+        return existed;
+    }
+
+    /**
+     * Controls whether compression is used on the link or not.
+     * <p>
+     * Note: This can only be called before connect()
+     * @param enabled whether to enable compression
+     * @throws IOException
+     */
+
+    public synchronized void setCompression(boolean enabled) throws IOException {
+        if (tm != null)
+            throw new IOException("Connection to " + hostname + " is already in connected state!");
+
+        if (enabled) enableCompression();
+        else         disableCompression();
+    }
+
+    /**
+     * Close the connection to the SSH-2 server. All assigned sessions will be
+     * closed, too. Can be called at any time. Don't forget to call this once
+     * you don't need a connection anymore - otherwise the receiver thread may
+     * run forever.
+     */
+
+    // cannot be synchronized, since Connection.connect() is synchronized, and
+    // if the key exchange fails, another thread will try to close().
+
+    public void close() {
+        log.debug("Connection.close()");
+        Throwable t = new Throwable("Closed due to user request.");
+        close(t, false);
+    }
+
+    public void close(Throwable t, boolean hard) {
+        log.debug(String.format("Connection.close(%s hard=%b)", t.getMessage(), hard));
+        if (cm != null) {
+            cm.closeAllChannels();
+        }
+
+        if (tm != null) {
+            tm.close(t, hard == false);
+            tm = null;
+        }
+
+        am = null;
+        cm = null;
+        authenticated = false;
+    }
+
+    /**
+     * Same as {@link #connect(ServerHostKeyVerifier, int, int) connect(null, 0, 0)}.
+     *
+     * @return see comments for the {@link #connect(ServerHostKeyVerifier, int, int) connect(ServerHostKeyVerifier, int, int)} method.
+     * @throws IOException
+     */
+
+    public synchronized ConnectionInfo connect() throws IOException {
+        return connect(null, 0, 0);
+    }
+
+    /**
+     * Same as {@link #connect(ServerHostKeyVerifier, int, int) connect(verifier, 0, 0)}.
+     *
+     * @return see comments for the {@link #connect(ServerHostKeyVerifier, int, int) connect(ServerHostKeyVerifier, int, int)} method.
+     * @throws IOException
+     */
+
+    public synchronized ConnectionInfo connect(ServerHostKeyVerifier verifier) throws IOException {
+        return connect(verifier, 0, 0);
+    }
+
+    /**
+     * Connect to the SSH-2 server and, as soon as the server has presented its
+     * host key, use the {@link ServerHostKeyVerifier#verifyServerHostKey(String,
+     * int, String, byte[]) ServerHostKeyVerifier.verifyServerHostKey()}
+     * method of the <code>verifier</code> to ask for permission to proceed.
+     * If <code>verifier</code> is <code>null</code>, then any host key will be
+     * accepted - this is NOT recommended, since it makes man-in-the-middle attackes
+     * VERY easy (somebody could put a proxy SSH server between you and the real server).
+     * <p/>
+     * Note: The verifier will be called before doing any crypto calculations
+     * (i.e., diffie-hellman). Therefore, if you don't like the presented host key then
+     * no CPU cycles are wasted (and the evil server has less information about us).
+     * <p/>
+     * However, it is still possible that the server presented a fake host key: the server
+     * cheated (typically a sign for a man-in-the-middle attack) and is not able to generate
+     * a signature that matches its host key. Don't worry, the library will detect such
+     * a scenario later when checking the signature (the signature cannot be checked before
+     * having completed the diffie-hellman exchange).
+     * <p/>
+     * Note 2: The  {@link ServerHostKeyVerifier#verifyServerHostKey(String,
+     * int, String, byte[]) ServerHostKeyVerifier.verifyServerHostKey()} method
+     * will *NOT* be called from the current thread, the call is being made from a
+     * background thread (there is a background dispatcher thread for every
+     * established connection).
+     * <p/>
+     * Note 3: This method will block as long as the key exchange of the underlying connection
+     * has not been completed (and you have not specified any timeouts).
+     * <p/>
+     * Note 4: If you want to re-use a connection object that was successfully connected,
+     * then you must call the {@link #close()} method before invoking <code>connect()</code> again.
+     *
+     * @param verifier       An object that implements the
+     *                       {@link ServerHostKeyVerifier} interface. Pass <code>null</code>
+     *                       to accept any server host key - NOT recommended.
+     * @param connectTimeout Connect the underlying TCP socket to the server with the given timeout
+     *                       value (non-negative, in milliseconds). Zero means no timeout.
+     * @param kexTimeout     Timeout for complete connection establishment (non-negative,
+     *                       in milliseconds). Zero means no timeout. The timeout counts from the
+     *                       moment you invoke the connect() method and is cancelled as soon as the
+     *                       first key-exchange round has finished. It is possible that
+     *                       the timeout event will be fired during the invocation of the
+     *                       <code>verifier</code> callback, but it will only have an effect after
+     *                       the <code>verifier</code> returns.
+     * @return A {@link ConnectionInfo} object containing the details of
+     * the established connection.
+     * @throws IOException If any problem occurs, e.g., the server's host key is not
+     *                     accepted by the <code>verifier</code> or there is problem during
+     *                     the initial crypto setup (e.g., the signature sent by the server is wrong).
+     *                     <p/>
+     *                     In case of a timeout (either connectTimeout or kexTimeout)
+     *                     a SocketTimeoutException is thrown.
+     *                     <p/>
+     *                     An exception may also be thrown if the connection was already successfully
+     *                     connected (no matter if the connection broke in the mean time) and you invoke
+     *                     <code>connect()</code> again without having called {@link #close()} first.
+     *                     <p/>
+     *                     If a HTTP proxy is being used and the proxy refuses the connection,
+     *                     then a {@link HTTPProxyException} may be thrown, which
+     *                     contains the details returned by the proxy. If the proxy is buggy and does
+     *                     not return a proper HTTP response, then a normal IOException is thrown instead.
+     */
+
+    public synchronized ConnectionInfo connect(ServerHostKeyVerifier verifier, int connectTimeout, int kexTimeout)
+    throws IOException {
+        final class TimeoutState {
+            boolean isCancelled = false;
+            boolean timeoutSocketClosed = false;
+        }
+
+        if (tm != null) {
+            throw new IllegalStateException(String.format("Connection to %s is already in connected state", hostname));
+        }
+
+        if (connectTimeout < 0) {
+            throw new IllegalArgumentException("connectTimeout must be non-negative!");
+        }
+
+        if (kexTimeout < 0) {
+            throw new IllegalArgumentException("kexTimeout must be non-negative!");
+        }
+
+        final TimeoutState state = new TimeoutState();
+
+        if (null == proxy) {
+            tm = new ClientTransportManager(new Socket());
+        }
+        else {
+            tm = new HTTPProxyClientTransportManager(new Socket(), proxy);
+        }
+
+        tm.setSoTimeout(connectTimeout);
+        tm.setTcpNoDelay(tcpNoDelay);
+        tm.setConnectionMonitors(connectionMonitors);
+
+        try {
+            TimeoutToken token = null;
+
+            if (kexTimeout > 0) {
+                final Runnable timeoutHandler = new Runnable() {
+                    public void run() {
+                        synchronized (state) {
+                            if (state.isCancelled) {
+                                return;
+                            }
+
+                            state.timeoutSocketClosed = true;
+                            tm.close(new SocketTimeoutException("The connect timeout expired"), false);
+                        }
+                    }
+                };
+                long timeoutHorizont = System.currentTimeMillis() + kexTimeout;
+                token = TimeoutService.addTimeoutHandler(timeoutHorizont, timeoutHandler);
+            }
+
+            tm.connect(hostname, port, softwareversion, cryptoWishList, verifier, dhgexpara, connectTimeout,
+                       getOrCreateSecureRND());
+            /* Wait until first KEX has finished */
+            ConnectionInfo ci = tm.getConnectionInfo(1);
+
+            /* Now try to cancel the timeout, if needed */
+
+            if (token != null) {
+                TimeoutService.cancelTimeoutHandler(token);
+
+                /* Were we too late? */
+
+                synchronized (state) {
+                    if (state.timeoutSocketClosed) {
+                        throw new IOException("This exception will be replaced by the one below =)");
+                    }
+
+                    /* Just in case the "cancelTimeoutHandler" invocation came just a little bit
+                     * too late but the handler did not enter the semaphore yet - we can
+                     * still stop it.
+                     */
+                    state.isCancelled = true;
+                }
+            }
+
+            return ci;
+        }
+        catch (SocketTimeoutException e) {
+            throw e;
+        }
+        catch (HTTPProxyException e) {
+            throw e;
+        }
+        catch (IOException e) {
+            // This will also invoke any registered connection monitors
+            close(e, false);
+
+            synchronized (state) {
+                /* Show a clean exception, not something like "the socket is closed!?!" */
+                if (state.timeoutSocketClosed) {
+                    throw new SocketTimeoutException(String.format("The kexTimeout (%d ms) expired.", kexTimeout));
+                }
+            }
+
+            throw e;
+        }
+    }
+
+    /**
+     * Creates a new {@link LocalPortForwarder}.
+     * A <code>LocalPortForwarder</code> forwards TCP/IP connections that arrive at a local
+     * port via the secure tunnel to another host (which may or may not be
+     * identical to the remote SSH-2 server).
+     * <p/>
+     * This method must only be called after one has passed successfully the authentication step.
+     * There is no limit on the number of concurrent forwardings.
+     *
+     * @param local_port      the local port the LocalPortForwarder shall bind to.
+     * @param host_to_connect target address (IP or hostname)
+     * @param port_to_connect target port
+     * @return A {@link LocalPortForwarder} object.
+     * @throws IOException
+     */
+
+    public synchronized LocalPortForwarder createLocalPortForwarder(int local_port, String host_to_connect,
+            int port_to_connect) throws IOException {
+        this.checkConnection();
+        return new LocalPortForwarder(cm, local_port, host_to_connect, port_to_connect);
+    }
+
+    /**
+     * Creates a new {@link LocalPortForwarder}.
+     * A <code>LocalPortForwarder</code> forwards TCP/IP connections that arrive at a local
+     * port via the secure tunnel to another host (which may or may not be
+     * identical to the remote SSH-2 server).
+     * <p/>
+     * This method must only be called after one has passed successfully the authentication step.
+     * There is no limit on the number of concurrent forwardings.
+     *
+     * @param addr            specifies the InetSocketAddress where the local socket shall be bound to.
+     * @param host_to_connect target address (IP or hostname)
+     * @param port_to_connect target port
+     * @return A {@link LocalPortForwarder} object.
+     * @throws IOException
+     */
+
+    public synchronized LocalPortForwarder createLocalPortForwarder(InetSocketAddress addr, String host_to_connect,
+            int port_to_connect) throws IOException {
+        this.checkConnection();
+        return new LocalPortForwarder(cm, addr, host_to_connect, port_to_connect);
+    }
+
+    /**
+     * Creates a new {@link LocalStreamForwarder}.
+     * A <code>LocalStreamForwarder</code> manages an Input/Outputstream pair
+     * that is being forwarded via the secure tunnel into a TCP/IP connection to another host
+     * (which may or may not be identical to the remote SSH-2 server).
+     *
+     * @param host_to_connect
+     * @param port_to_connect
+     * @return A {@link LocalStreamForwarder} object.
+     * @throws IOException
+     */
+
+    public synchronized LocalStreamForwarder createLocalStreamForwarder(String host_to_connect, int port_to_connect)
+    throws IOException {
+        this.checkConnection();
+        return new LocalStreamForwarder(cm, host_to_connect, port_to_connect);
+    }
+
+    /**
+     * Creates a new {@link DynamicPortForwarder}. A
+     * <code>DynamicPortForwarder</code> forwards TCP/IP connections that arrive
+     * at a local port via the secure tunnel to another host that is chosen via
+     * the SOCKS protocol.
+     * <p>
+     * This method must only be called after one has passed successfully the
+     * authentication step. There is no limit on the number of concurrent
+     * forwardings.
+     *
+     * @param local_port
+     * @return A {@link DynamicPortForwarder} object.
+     * @throws IOException
+     */
+
+    public synchronized DynamicPortForwarder createDynamicPortForwarder(int local_port) throws IOException {
+        if (tm == null)
+            throw new IllegalStateException("Cannot forward ports, you need to establish a connection first.");
+
+        if (!authenticated)
+            throw new IllegalStateException("Cannot forward ports, connection is not authenticated.");
+
+        return new DynamicPortForwarder(cm, local_port);
+    }
+
+    /**
+     * Creates a new {@link DynamicPortForwarder}. A
+     * <code>DynamicPortForwarder</code> forwards TCP/IP connections that arrive
+     * at a local port via the secure tunnel to another host that is chosen via
+     * the SOCKS protocol.
+     * <p>
+     * This method must only be called after one has passed successfully the
+     * authentication step. There is no limit on the number of concurrent
+     * forwardings.
+     *
+     * @param addr
+     *            specifies the InetSocketAddress where the local socket shall
+     *            be bound to.
+     * @return A {@link DynamicPortForwarder} object.
+     * @throws IOException
+     */
+
+    public synchronized DynamicPortForwarder createDynamicPortForwarder(InetSocketAddress addr) throws IOException {
+        if (tm == null)
+            throw new IllegalStateException("Cannot forward ports, you need to establish a connection first.");
+
+        if (!authenticated)
+            throw new IllegalStateException("Cannot forward ports, connection is not authenticated.");
+
+        return new DynamicPortForwarder(cm, addr);
+    }
+
+    /**
+     * Create a very basic {@link SCPClient} that can be used to copy
+     * files from/to the SSH-2 server.
+     * <p/>
+     * Works only after one has passed successfully the authentication step.
+     * There is no limit on the number of concurrent SCP clients.
+     * <p/>
+     * Note: This factory method will probably disappear in the future.
+     *
+     * @return A {@link SCPClient} object.
+     * @throws IOException
+     */
+
+    public synchronized SCPClient createSCPClient() throws IOException {
+        this.checkConnection();
+        return new SCPClient(this);
+    }
+
+    /**
+     * Force an asynchronous key re-exchange (the call does not block). The
+     * latest values set for MAC, Cipher and DH group exchange parameters will
+     * be used. If a key exchange is currently in progress, then this method has
+     * the only effect that the so far specified parameters will be used for the
+     * next (server driven) key exchange.
+     * <p/>
+     * Note: This implementation will never start a key exchange (other than the initial one)
+     * unless you or the SSH-2 server ask for it.
+     *
+     * @throws IOException In case of any failure behind the scenes.
+     */
+
+    public synchronized void forceKeyExchange() throws IOException {
+        this.checkConnection();
+        tm.forceKeyExchange(cryptoWishList, dhgexpara, null, null, null);
+    }
+
+    /**
+     * Returns the hostname that was passed to the constructor.
+     *
+     * @return the hostname
+     */
+
+    public synchronized String getHostname() {
+        return hostname;
+    }
+
+    /**
+     * Returns the port that was passed to the constructor.
+     *
+     * @return the TCP port
+     */
+
+    public synchronized int getPort() {
+        return port;
+    }
+
+    /**
+     * Returns a {@link ConnectionInfo} object containing the details of
+     * the connection. Can be called as soon as the connection has been
+     * established (successfully connected).
+     *
+     * @return A {@link ConnectionInfo} object.
+     * @throws IOException In case of any failure behind the scenes.
+     */
+
+    public synchronized ConnectionInfo getConnectionInfo() throws IOException {
+        this.checkConnection();
+        return tm.getConnectionInfo(1);
+    }
+
+    /**
+     * After a successful connect, one has to authenticate oneself. This method
+     * can be used to tell which authentication methods are supported by the
+     * server at a certain stage of the authentication process (for the given
+     * username).
+     * <p/>
+     * Note 1: the username will only be used if no authentication step was done
+     * so far (it will be used to ask the server for a list of possible
+     * authentication methods by sending the initial "none" request). Otherwise,
+     * this method ignores the user name and returns a cached method list
+     * (which is based on the information contained in the last negative server response).
+     * <p/>
+     * Note 2: the server may return method names that are not supported by this
+     * implementation.
+     * <p/>
+     * After a successful authentication, this method must not be called
+     * anymore.
+     *
+     * @param user A <code>String</code> holding the username.
+     * @return a (possibly emtpy) array holding authentication method names.
+     * @throws IOException
+     */
+
+    public synchronized String[] getRemainingAuthMethods(String user) throws IOException {
+        if (user == null) {
+            throw new IllegalArgumentException("user argument may not be NULL!");
+        }
+
+        if (tm == null) {
+            throw new IllegalStateException("Connection is not established!");
+        }
+
+        if (authenticated) {
+            throw new IllegalStateException("Connection is already authenticated!");
+        }
+
+        if (am == null) {
+            am = new AuthenticationManager(tm);
+        }
+
+        if (cm == null) {
+            cm = new ChannelManager(tm);
+        }
+
+        final Set<String> remainingMethods = am.getRemainingMethods(user);
+        return remainingMethods.toArray(new String[remainingMethods.size()]);
+    }
+
+    /**
+     * Determines if the authentication phase is complete. Can be called at any
+     * time.
+     *
+     * @return <code>true</code> if no further authentication steps are
+     * needed.
+     */
+
+    public synchronized boolean isAuthenticationComplete() {
+        return authenticated;
+    }
+
+    /**
+     * Returns true if there was at least one failed authentication request and
+     * the last failed authentication request was marked with "partial success"
+     * by the server. This is only needed in the rare case of SSH-2 server setups
+     * that cannot be satisfied with a single successful authentication request
+     * (i.e., multiple authentication steps are needed.)
+     * <p/>
+     * If you are interested in the details, then have a look at RFC4252.
+     *
+     * @return if the there was a failed authentication step and the last one
+     * was marked as a "partial success".
+     */
+
+    public synchronized boolean isAuthenticationPartialSuccess() {
+        if (am == null) {
+            return false;
+        }
+
+        return am.getPartialSuccess();
+    }
+
+    /**
+     * Checks if a specified authentication method is available. This method is
+     * actually just a wrapper for {@link #getRemainingAuthMethods(String)
+     * getRemainingAuthMethods()}.
+     *
+     * @param user   A <code>String</code> holding the username.
+     * @param method An authentication method name (e.g., "publickey", "password",
+     *               "keyboard-interactive") as specified by the SSH-2 standard.
+     * @return if the specified authentication method is currently available.
+     * @throws IOException
+     */
+
+    public synchronized boolean isAuthMethodAvailable(String user, String method) throws IOException {
+        String methods[] = getRemainingAuthMethods(user);
+
+        for (final String m : methods) {
+            if (m.compareTo(method) == 0) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    private SecureRandomFix getOrCreateSecureRND() {
+        if (generator == null) {
+            generator = new SecureRandomFix();
+        }
+
+        return generator;
+    }
+
+    /**
+     * Open a new {@link Session} on this connection. Works only after one has passed
+     * successfully the authentication step. There is no limit on the number of
+     * concurrent sessions.
+     *
+     * @return A {@link Session} object.
+     * @throws IOException
+     */
+
+    public synchronized Session openSession() throws IOException {
+        this.checkConnection();
+        return new Session(cm, getOrCreateSecureRND());
+    }
+
+    /**
+     * Send an SSH_MSG_IGNORE packet. This method will generate a random data attribute
+     * (length between 0 (invlusive) and 16 (exclusive) bytes, contents are random bytes).
+     * <p/>
+     * This method must only be called once the connection is established.
+     *
+     * @throws IOException
+     */
+
+    public synchronized void sendIgnorePacket() throws IOException {
+        SecureRandomFix rnd = getOrCreateSecureRND();
+        byte[] data = new byte[rnd.nextInt(16)];
+        rnd.nextBytes(data);
+        sendIgnorePacket(data);
+    }
+
+    /**
+     * Send an SSH_MSG_IGNORE packet with the given data attribute.
+     * <p/>
+     * This method must only be called once the connection is established.
+     *
+     * @throws IOException
+     */
+
+    public synchronized void sendIgnorePacket(byte[] data) throws IOException {
+        this.checkConnection();
+        PacketIgnore pi = new PacketIgnore(data);
+        tm.sendMessage(pi.getPayload());
+    }
+
+    /**
+     * Controls whether compression is used on the link or not.
+     */
+
+    public synchronized void setCompression(String[] algorithms) {
+        CompressionFactory.checkCompressorList(algorithms);
+        cryptoWishList.c2s_comp_algos = algorithms;
+    }
+
+    public synchronized void enableCompression() {
+        cryptoWishList.c2s_comp_algos = CompressionFactory.getDefaultCompressorList();
+        cryptoWishList.s2c_comp_algos = CompressionFactory.getDefaultCompressorList();
+    }
+
+    public synchronized void disableCompression() {
+        cryptoWishList.c2s_comp_algos = new String[] {"none"};
+        cryptoWishList.s2c_comp_algos = new String[] {"none"};
+    }
+
+    /**
+     * Unless you know what you are doing, you will never need this.
+     */
+
+    public synchronized void setClient2ServerCiphers(final String[] ciphers) {
+        if ((ciphers == null) || (ciphers.length == 0)) {
+            throw new IllegalArgumentException();
+        }
+
+        BlockCipherFactory.checkCipherList(ciphers);
+        cryptoWishList.c2s_enc_algos = ciphers;
+    }
+
+    /**
+     * Unless you know what you are doing, you will never need this.
+     */
+
+    public synchronized void setClient2ServerMACs(final String[] macs) {
+        MAC.checkMacList(macs);
+        cryptoWishList.c2s_mac_algos = macs;
+    }
+
+    /**
+     * Sets the parameters for the diffie-hellman group exchange. Unless you
+     * know what you are doing, you will never need this. Default values are
+     * defined in the {@link DHGexParameters} class.
+     *
+     * @param dgp {@link DHGexParameters}, non null.
+     */
+
+    public synchronized void setDHGexParameters(DHGexParameters dgp) {
+        if (dgp == null) {
+            throw new IllegalArgumentException();
+        }
+
+        dhgexpara = dgp;
+    }
+
+    /**
+     * Unless you know what you are doing, you will never need this.
+     */
+
+    public synchronized void setServer2ClientCiphers(final String[] ciphers) {
+        BlockCipherFactory.checkCipherList(ciphers);
+        cryptoWishList.s2c_enc_algos = ciphers;
+    }
+
+    /**
+     * Unless you know what you are doing, you will never need this.
+     */
+
+    public synchronized void setServer2ClientMACs(final String[] macs) {
+        MAC.checkMacList(macs);
+        cryptoWishList.s2c_mac_algos = macs;
+    }
+
+    /**
+     * Define the set of allowed server host key algorithms to be used for
+     * the following key exchange operations.
+     * <p/>
+     * Unless you know what you are doing, you will never need this.
+     *
+     * @param algos An array of allowed server host key algorithms.
+     *              SSH-2 defines <code>ssh-dss</code> and <code>ssh-rsa</code>.
+     *              The entries of the array must be ordered after preference, i.e.,
+     *              the entry at index 0 is the most preferred one. You must specify
+     *              at least one entry.
+     */
+
+    public synchronized void setServerHostKeyAlgorithms(final String[] algos) {
+        KexManager.checkServerHostkeyAlgorithmsList(algos);
+        cryptoWishList.serverHostKeyAlgorithms = algos;
+    }
+
+    /**
+     * Enable/disable TCP_NODELAY (disable/enable Nagle's algorithm) on the underlying socket.
+     * <p/>
+     * Can be called at any time. If the connection has not yet been established
+     * then the passed value will be stored and set after the socket has been set up.
+     * The default value that will be used is <code>false</code>.
+     *
+     * @param enable the argument passed to the <code>Socket.setTCPNoDelay()</code> method.
+     * @throws IOException
+     */
+
+    public synchronized void setTCPNoDelay(boolean enable) throws IOException {
+        tcpNoDelay = enable;
+
+        if (tm != null) {
+            tm.setTcpNoDelay(enable);
+        }
+    }
+
+    /**
+     * Used to tell the library that the connection shall be established through
+     * a proxy server. It only makes sense to call this method before calling
+     * the {@link #connect() connect()} method.
+     * <p>
+     * At the moment, only HTTP proxies are supported.
+     * <p>
+     * Note: This method can be called any number of times. The
+     * {@link #connect() connect()} method will use the value set in the last
+     * preceding invocation of this method.
+     *
+     * @see HTTPProxyData
+     *
+     * @param proxy
+     *            Connection information about the proxy. If <code>null</code>,
+     *            then no proxy will be used (non surprisingly, this is also the
+     *            default).
+     */
+
+    public synchronized void setProxyData(HTTPProxyData proxy) {
+        this.proxy = proxy;
+    }
+
+    /**
+     * Request a remote port forwarding.
+     * If successful, then forwarded connections will be redirected to the given target address.
+     * You can cancle a requested remote port forwarding by calling
+     * {@link #cancelRemotePortForwarding(int) cancelRemotePortForwarding()}.
+     * <p/>
+     * A call of this method will block until the peer either agreed or disagreed to your request-
+     * <p/>
+     * Note 1: this method typically fails if you
+     * <ul>
+     * <li>pass a port number for which the used remote user has not enough permissions (i.e., port
+     * &lt; 1024)</li>
+     * <li>or pass a port number that is already in use on the remote server</li>
+     * <li>or if remote port forwarding is disabled on the server.</li>
+     * </ul>
+     * <p/>
+     * Note 2: (from the openssh man page): By default, the listening socket on the server will be
+     * bound to the loopback interface only. This may be overriden by specifying a bind address.
+     * Specifying a remote bind address will only succeed if the server's <b>GatewayPorts</b> option
+     * is enabled (see sshd_config(5)).
+     *
+     * @param bindAddress   address to bind to on the server:
+     *                      <ul>
+     *                      <li>"" means that connections are to be accepted on all protocol families
+     *                      supported by the SSH implementation</li>
+     *                      <li>"0.0.0.0" means to listen on all IPv4 addresses</li>
+     *                      <li>"::" means to listen on all IPv6 addresses</li>
+     *                      <li>"localhost" means to listen on all protocol families supported by the SSH
+     *                      implementation on loopback addresses only, [RFC3330] and RFC3513]</li>
+     *                      <li>"127.0.0.1" and "::1" indicate listening on the loopback interfaces for
+     *                      IPv4 and IPv6 respectively</li>
+     *                      </ul>
+     * @param bindPort      port number to bind on the server (must be &gt; 0)
+     * @param targetAddress the target address (IP or hostname)
+     * @param targetPort    the target port
+     * @throws IOException
+     */
+
+    public synchronized void requestRemotePortForwarding(String bindAddress, int bindPort, String targetAddress,
+            int targetPort) throws IOException {
+        this.checkConnection();
+
+        if ((bindAddress == null) || (targetAddress == null) || (bindPort <= 0) || (targetPort <= 0)) {
+            throw new IllegalArgumentException();
+        }
+
+        cm.requestGlobalForward(bindAddress, bindPort, targetAddress, targetPort);
+    }
+
+    /**
+     * Cancel an earlier requested remote port forwarding.
+     * Currently active forwardings will not be affected (e.g., disrupted).
+     * Note that further connection forwarding requests may be received until
+     * this method has returned.
+     *
+     * @param bindPort the allocated port number on the server
+     * @throws IOException if the remote side refuses the cancel request or another low
+     *                     level error occurs (e.g., the underlying connection is closed)
+     */
+
+    public synchronized void cancelRemotePortForwarding(int bindPort) throws IOException {
+        this.checkConnection();
+        cm.requestCancelGlobalForward(bindPort);
+    }
+
+    /**
+     * Provide your own instance of SecureRandom. Can be used, e.g., if you
+     * want to seed the used SecureRandom generator manually.
+     * <p/>
+     * The SecureRandom instance is used during key exchanges, public key authentication,
+     * x11 cookie generation and the like.
+     *
+     * @param rnd a SecureRandom instance
+     */
+
+    public synchronized void setSecureRandom(SecureRandomFix rnd) {
+        if (rnd == null) {
+            throw new IllegalArgumentException();
+        }
+
+        this.generator = rnd;
+    }
+
+    private void checkConnection() throws IllegalStateException {
+        if (tm == null) {
+            throw new IllegalStateException("You need to establish a connection first.");
+        }
+
+        if (!authenticated) {
+            throw new IllegalStateException("The connection is not authenticated.");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/src/main/java/ch/ethz/ssh2/ConnectionInfo.java	Thu Dec 03 11:23:55 2015 -0800
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2006-2011 Christian Plattner. All rights reserved.
+ * Please refer to the LICENSE.txt for licensing details.
+ */
+package ch.ethz.ssh2;
+
+/**
+ * In most cases you probably do not need the information contained in here.
+ *
+ * @author Christian Plattner
+ * @version 2.50, 03/15/10
+ */
+public class ConnectionInfo {
+    /**
+     * The used key exchange (KEX) algorithm in the latest key exchange.
+     */
+    public String keyExchangeAlgorithm;
+
+    /**
+     * The currently used crypto algorithm for packets from to the client to the
+     * server.
+     */
+    public String clientToServerCryptoAlgorithm;
+    /**
+     * The currently used crypto algorithm for packets from to the server to the
+     * client.
+     */
+    public String serverToClientCryptoAlgorithm;
+
+    /**
+     * The currently used MAC algorithm for packets from to the client to the
+     * server.
+     */
+    public String clientToServerMACAlgorithm;
+    /**
+     * The currently used MAC algorithm for packets from to the server to the
+     * client.
+     */
+    public String serverToClientMACAlgorithm;
+
+    /**
+     * The type of the server host key (currently either "ssh-dss" or
+     * "ssh-rsa").
+     */
+    public String serverHostKeyAlgorithm;
+
+    /**
+     * The server host key that was sent during the latest key exchange.
+     */
+    public byte[] serverHostKey;
+
+    /**
+     * Number of kex exchanges performed on this connection so far.
+     */
+    public int keyExchangeCounter = 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/src/main/java/ch/ethz/ssh2/ConnectionMonitor.java	Thu Dec 03 11:23:55 2015 -0800
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2006-2011 Christian Plattner. All rights reserved.
+ * Please refer to the LICENSE.txt for licensing details.
+ */
+package ch.ethz.ssh2;
+
+/**
+ * A <code>ConnectionMonitor</code> is used to get notified when the
+ * underlying socket of a connection is closed.
+ *
+ * @author Christian Plattner
+ * @version 2.50, 03/15/10
+ */
+
+public interface ConnectionMonitor {
+    /**
+     * This method is called after the connection's underlying
+     * socket has been closed. E.g., due to the {@link Connection#close()} request of the
+     * user, if the peer closed the connection, due to a fatal error during connect()
+     * (also if the socket cannot be established) or if a fatal error occured on
+     * an established connection.
+     * <p>
+     * This is an experimental feature.
+     * <p>
+     * You MUST NOT make any assumption about the thread that invokes this method.
+     * <p>
+     * <b>Please note: if the connection is not connected (e.g., there was no successful
+     * connect() call), then the invocation of {@link Connection#close()} will NOT trigger
+     * this method.</b>
+     *
+     * @see Connection#addConnectionMonitor(ConnectionMonitor)
+     *
+     * @param reason Includes an indication why the socket was closed.
+     */
+    public void connectionLost(Throwable reason);
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/src/main/java/ch/ethz/ssh2/DHGexParameters.java	Thu Dec 03 11:23:55 2015 -0800
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2006-2011 Christian Plattner. All rights reserved.
+ * Please refer to the LICENSE.txt for licensing details.
+ */
+package ch.ethz.ssh2;
+
+/**
+ * A <code>DHGexParameters</code> object can be used to specify parameters for
+ * the diffie-hellman group exchange.
+ * <p>
+ * Depending on which constructor is used, either the use of a
+ * <code>SSH_MSG_KEX_DH_GEX_REQUEST</code> or <code>SSH_MSG_KEX_DH_GEX_REQUEST_OLD</code>
+ * can be forced.
+ *
+ * @see Connection#setDHGexParameters(DHGexParameters)
+ * @author Christian Plattner
+ * @version 2.50, 03/15/10
+ */
+
+public class DHGexParameters {
+    private final int min_group_len;
+    private final int pref_group_len;
+    private final int max_group_len;
+
+    private static final int MIN_ALLOWED = 1024;
+    private static final int MAX_ALLOWED = 8192;
+
+    /**
+     * Same as calling {@link #DHGexParameters(int, int, int) DHGexParameters(1024, 1024, 4096)}.
+     * This is also the default used by the Connection class.
+     *
+     */
+    public DHGexParameters() {
+        this(1024, 1024, 4096);
+    }
+
+    /**
+     * This constructor can be used to force the sending of a
+     * <code>SSH_MSG_KEX_DH_GEX_REQUEST_OLD</code> request.
+     * Internally, the minimum and maximum group lengths will
+     * be set to zero.
+     *
+     * @param pref_group_len has to be &gt= 1024 and &lt;= 8192
+     */
+    public DHGexParameters(int pref_group_len) {
+        if ((pref_group_len < MIN_ALLOWED) || (pref_group_len > MAX_ALLOWED))
+            throw new IllegalArgumentException("pref_group_len out of range!");
+
+        this.pref_group_len = pref_group_len;
+        this.min_group_len = 0;
+        this.max_group_len = 0;
+    }
+
+    /**
+     * This constructor can be used to force the sending of a
+     * <code>SSH_MSG_KEX_DH_GEX_REQUEST</code> request.
+     * <p>
+     * Note: older OpenSSH servers don't understand this request, in which
+     * case you should use the {@link #DHGexParameters(int)} constructor.
+     * <p>
+     * All values have to be &gt= 1024 and &lt;= 8192. Furthermore,
+     * min_group_len &lt;= pref_group_len &lt;= max_group_len.
+     *
+     * @param min_group_len
+     * @param pref_group_len
+     * @param max_group_len
+     */
+    public DHGexParameters(int min_group_len, int pref_group_len, int max_group_len) {
+        if ((min_group_len < MIN_ALLOWED) || (min_group_len > MAX_ALLOWED))
+            throw new IllegalArgumentException("min_group_len out of range!");
+
+        if ((pref_group_len < MIN_ALLOWED) || (pref_group_len > MAX_ALLOWED))
+            throw new IllegalArgumentException("pref_group_len out of range!");
+
+        if ((max_group_len < MIN_ALLOWED) || (max_group_len > MAX_ALLOWED))
+            throw new IllegalArgumentException("max_group_len out of range!");
+
+        if ((pref_group_len < min_group_len) || (pref_group_len > max_group_len))
+            throw new IllegalArgumentException("pref_group_len is incompatible with min and max!");
+
+        if (max_group_len < min_group_len)
+            throw new IllegalArgumentException("max_group_len must not be smaller than min_group_len!");
+
+        this.min_group_len = min_group_len;
+        this.pref_group_len = pref_group_len;
+        this.max_group_len = max_group_len;
+    }
+
+    /**
+     * Get the maximum group length.
+     *
+     * @return the maximum group length, may be <code>zero</code> if
+     *         SSH_MSG_KEX_DH_GEX_REQUEST_OLD should be requested
+     */
+    public int getMax_group_len() {
+        return max_group_len;
+    }
+
+    /**
+     * Get the minimum group length.
+     *
+     * @return minimum group length, may be <code>zero</code> if
+     *         SSH_MSG_KEX_DH_GEX_REQUEST_OLD should be requested
+     */
+    public int getMin_group_len() {
+        return min_group_len;
+    }
+
+    /**
+     * Get the preferred group length.
+     *
+     * @return the preferred group length
+     */
+    public int getPref_group_len() {
+        return pref_group_len;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/src/main/java/ch/ethz/ssh2/DynamicPortForwarder.java	Thu Dec 03 11:23:55 2015 -0800
@@ -0,0 +1,63 @@
+/*
+ * ConnectBot: simple, powerful, open-source SSH client for Android
+ * Copyright 2007 Kenny Root, Jeffrey Sharkey
+ *
+ * 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 ch.ethz.ssh2;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+
+import ch.ethz.ssh2.channel.ChannelManager;
+import ch.ethz.ssh2.channel.DynamicAcceptThread;
+
+/**
+ * A <code>DynamicPortForwarder</code> forwards TCP/IP connections to a local
+ * port via the secure tunnel to another host which is selected via the
+ * SOCKS protocol. Checkout {@link Connection#createDynamicPortForwarder(int)}
+ * on how to create one.
+ *
+ * @author Kenny Root
+ * @version $Id: $
+ */
+public class DynamicPortForwarder {
+    ChannelManager cm;
+
+    DynamicAcceptThread dat;
+
+    DynamicPortForwarder(ChannelManager cm, int local_port)
+    throws IOException {
+        this.cm = cm;
+        dat = new DynamicAcceptThread(cm, local_port);
+        dat.setDaemon(true);
+        dat.start();
+    }
+
+    DynamicPortForwarder(ChannelManager cm, InetSocketAddress addr) throws IOException {
+        this.cm = cm;
+        dat = new DynamicAcceptThread(cm, addr);
+        dat.setDaemon(true);
+        dat.start();
+    }
+
+    /**
+     * Stop TCP/IP forwarding of newly arriving connections.
+     *
+     * @throws IOException
+     */
+    public void close() throws IOException {
+        dat.stopWorking();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/src/main/java/ch/ethz/ssh2/HTTPProxyData.java	Thu Dec 03 11:23:55 2015 -0800
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2006-2011 Christian Plattner. All rights reserved.
+ * Please refer to the LICENSE.txt for licensing details.
+ */
+package ch.ethz.ssh2;
+
+/**
+ * A <code>HTTPProxyData</code> object is used to specify the needed connection data
+ * to connect through a HTTP proxy.
+ *
+ * @see Connection#setProxyData(ProxyData)
+ *
+ * @author Christian Plattner
+ * @version 2.50, 03/15/10
+ */
+
+public class HTTPProxyData implements ProxyData {
+    public final String proxyHost;
+    public final int proxyPort;
+    public final String proxyUser;
+    public final String proxyPass;
+    public final String[] requestHeaderLines;
+
+    /**
+     * Same as calling {@link #HTTPProxyData(String, int, String, String) HTTPProxyData(proxyHost, proxyPort, <code>null</code>, <code>null</code>)}
+     *
+     * @param proxyHost Proxy hostname.
+     * @param proxyPort Proxy port.
+     */
+    public HTTPProxyData(String proxyHost, int proxyPort) {
+        this(proxyHost, proxyPort, null, null);
+    }
+
+    /**
+     * Same as calling {@link #HTTPProxyData(String, int, String, String, String[]) HTTPProxyData(proxyHost, proxyPort, <code>null</code>, <code>null</code>, <code>null</code>)}
+     *
+     * @param proxyHost Proxy hostname.
+     * @param proxyPort Proxy port.
+     * @param proxyUser Username for basic authentication (<code>null</code> if no authentication is needed).
+     * @param proxyPass Password for basic authentication (<code>null</code> if no authentication is needed).
+     */
+    public HTTPProxyData(String proxyHost, int proxyPort, String proxyUser, String proxyPass) {
+        this(proxyHost, proxyPort, proxyUser, proxyPass, null);
+    }
+
+    /**
+     * Connection data for a HTTP proxy. It is possible to specify a username and password
+     * if the proxy requires basic authentication. Also, additional request header lines can
+     * be specified (e.g., "User-Agent: CERN-LineMode/2.15 libwww/2.17b3").
+     * <p>
+     * Please note: if you want to use basic authentication, then both <code>proxyUser</code>
+     * and <code>proxyPass</code> must be non-null.
+     * <p>
+     * Here is an example:
+     * <p>
+     * <code>
+     * new HTTPProxyData("192.168.1.1", "3128", "proxyuser", "secret", new String[] {"User-Agent: GanymedBasedClient/1.0", "X-My-Proxy-Option: something"});
+     * </code>
+     *
+     * @param proxyHost Proxy hostname.
+     * @param proxyPort Proxy port.
+     * @param proxyUser Username for basic authentication (<code>null</code> if no authentication is needed).
+     * @param proxyPass Password for basic authentication (<code>null</code> if no authentication is needed).
+     * @param requestHeaderLines An array with additional request header lines (without end-of-line markers)
+     *        that have to be sent to the server. May be <code>null</code>.
+     */
+
+    public HTTPProxyData(String proxyHost, int proxyPort, String proxyUser, String proxyPass,
+                         String[] requestHeaderLines) {
+        if (proxyHost == null)
+            throw new IllegalArgumentException("proxyHost must be non-null");
+
+        if (proxyPort < 0)
+            throw new IllegalArgumentException("proxyPort must be non-negative");
+
+        this.proxyHost = proxyHost;
+        this.proxyPort = proxyPort;
+        this.proxyUser = proxyUser;
+        this.proxyPass = proxyPass;
+        this.requestHeaderLines = requestHeaderLines;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/src/main/java/ch/ethz/ssh2/HTTPProxyException.java	Thu Dec 03 11:23:55 2015 -0800
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2006-2011 Christian Plattner. All rights reserved.
+ * Please refer to the LICENSE.txt for licensing details.
+ */
+package ch.ethz.ssh2;
+
+import java.io.IOException;
+
+/**
+ * May be thrown upon connect() if a HTTP proxy is being used.
+ *
+ * @see Connection#connect()
+ * @see Connection#setProxyData(ProxyData)
+ *
+ * @author Christian Plattner
+ * @version 2.50, 03/15/10
+ */
+
+public class HTTPProxyException extends IOException {
+    private static final long serialVersionUID = 2241537397104426186L;
+
+    public final String httpResponse;
+    public final int httpErrorCode;
+
+    public HTTPProxyException(String httpResponse, int httpErrorCode) {
+        super("HTTP Proxy Error (" + httpErrorCode + " " + httpResponse + ")");
+        this.httpResponse = httpResponse;
+        this.httpErrorCode = httpErrorCode;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/src/main/java/ch/ethz/ssh2/InteractiveCallback.java	Thu Dec 03 11:23:55 2015 -0800
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2006-2011 Christian Plattner. All rights reserved.
+ * Please refer to the LICENSE.txt for licensing details.
+ */
+package ch.ethz.ssh2;
+
+/**
+ * An <code>InteractiveCallback</code> is used to respond to challenges sent
+ * by the server if authentication mode "keyboard-interactive" is selected.
+ *
+ * @see Connection#authenticateWithKeyboardInteractive(String,
+ *      String[], InteractiveCallback)
+ *
+ * @author Christian Plattner
+ * @version 2.50, 03/15/10
+ */
+
+public interface InteractiveCallback {
+    /**
+     * This callback interface is used during a "keyboard-interactive"
+     * authentication. Every time the server sends a set of challenges (however,
+     * most often just one challenge at a time), this callback function will be
+     * called to give your application a chance to talk to the user and to
+     * determine the response(s).
+     * <p>
+     * Some copy-paste information from the standard: a command line interface
+     * (CLI) client SHOULD print the name and instruction (if non-empty), adding
+     * newlines. Then for each prompt in turn, the client SHOULD display the
+     * prompt and read the user input. The name and instruction fields MAY be
+     * empty strings, the client MUST be prepared to handle this correctly. The
+     * prompt field(s) MUST NOT be empty strings.
+     * <p>
+     * Please refer to draft-ietf-secsh-auth-kbdinteract-XX.txt for the details.
+     * <p>
+     * Note: clients SHOULD use control character filtering as discussed in
+     * RFC4251 to avoid attacks by including
+     * terminal control characters in the fields to be displayed.
+     *
+     * @param name
+     *            the name String sent by the server.
+     * @param instruction
+     *            the instruction String sent by the server.
+     * @param numPrompts
+     *            number of prompts - may be zero (in this case, you should just
+     *            return a String array of length zero).
+     * @param prompt
+     *            an array (length <code>numPrompts</code>) of Strings
+     * @param echo
+     *            an array (length <code>numPrompts</code>) of booleans. For
+     *            each prompt, the corresponding echo field indicates whether or
+     *            not the user input should be echoed as characters are typed.
+     * @return an array of reponses - the array size must match the parameter
+     *         <code>numPrompts</code>.
+     */
+    public String[] replyToChallenge(String name, String instruction, int numPrompts, String[] prompt, boolean[] echo)
+    throws Exception;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/src/main/java/ch/ethz/ssh2/KnownHosts.java	Thu Dec 03 11:23:55 2015 -0800
@@ -0,0 +1,814 @@
+/*
+ * Copyright (c) 2006-2011 Christian Plattner. All rights reserved.
+ * Please refer to the LICENSE.txt for licensing details.
+ */
+
+package ch.ethz.ssh2;
+
+import java.io.BufferedReader;
+import java.io.CharArrayReader;
+import java.io.CharArrayWriter;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.security.DigestException;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+import ch.ethz.ssh2.crypto.Base64;
+import ch.ethz.ssh2.crypto.SecureRandomFix;
+import ch.ethz.ssh2.crypto.digest.Digest;
+import ch.ethz.ssh2.crypto.digest.HMAC;
+import ch.ethz.ssh2.crypto.digest.MD5;
+import ch.ethz.ssh2.crypto.digest.SHA1;
+
+import java.security.KeyPair;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.interfaces.DSAPublicKey;
+import java.security.interfaces.ECPublicKey;
+import java.security.interfaces.RSAPublicKey;
+import ch.ethz.ssh2.signature.DSASHA1Verify;
+import ch.ethz.ssh2.signature.ECDSASHA2Verify;
+import ch.ethz.ssh2.signature.RSASHA1Verify;
+import ch.ethz.ssh2.util.StringEncoder;
+
+/**
+ * The <code>KnownHosts</code> class is a handy tool to verify received server hostkeys
+ * based on the information in <code>known_hosts</code> files (the ones used by OpenSSH).
+ * <p/>
+ * It offers basically an in-memory database for known_hosts entries, as well as some
+ * helper functions. Entries from a <code>known_hosts</code> file can be loaded at construction time.
+ * It is also possible to add more keys later (e.g., one can parse different
+ * <code>known_hosts<code> files).
+ * <p/>
+ * It is a thread safe implementation, therefore, you need only to instantiate one
+ * <code>KnownHosts</code> for your whole application.
+ *
+ * @author Christian Plattner
+ * @version $Id: KnownHosts.java 152 2014-04-28 11:02:23Z dkocher@sudo.ch $
+ */
+
+public class KnownHosts {
+    public static final int HOSTKEY_IS_OK = 0;
+    public static final int HOSTKEY_IS_NEW = 1;
+    public static final int HOSTKEY_HAS_CHANGED = 2;
+
+    private class KnownHostsEntry {
+        String[] patterns;
+        PublicKey key;
+
+        KnownHostsEntry(String[] patterns, PublicKey key) {
+            this.patterns = patterns;
+            this.key = key;
+        }
+    }
+
+    private final LinkedList<KnownHostsEntry> publicKeys = new LinkedList<KnownHosts.KnownHostsEntry>();
+
+    public KnownHosts() {
+    }
+
+    public KnownHosts(char[] knownHostsData) throws IOException {
+        initialize(knownHostsData);
+    }
+
+    public KnownHosts(String knownHosts) throws IOException {
+        initialize(new File(knownHosts));
+    }
+
+    public KnownHosts(File knownHosts) throws IOException {
+        initialize(knownHosts);
+    }
+
+    /**
+     * Adds a single public key entry to the database. Note: this will NOT add the public key
+     * to any physical file (e.g., "~/.ssh/known_hosts") - use <code>addHostkeyToFile()</code> for that purpose.
+     * This method is designed to be used in a {@link ServerHostKeyVerifier}.
+     *
+     * @param hostnames              a list of hostname patterns - at least one most be specified. Check out the
+     *                               OpenSSH sshd man page for a description of the pattern matching algorithm.
+     * @param serverHostKeyAlgorithm as passed to the {@link ServerHostKeyVerifier}.
+     * @param serverHostKey          as passed to the {@link ServerHostKeyVerifier}.
+     * @throws IOException
+     */
+    public void addHostkey(String hostnames[], String serverHostKeyAlgorithm, byte[] serverHostKey) throws IOException {
+        if (hostnames == null) {
+            throw new IllegalArgumentException("hostnames may not be null");
+        }
+
+        if ("ssh-rsa".equals(serverHostKeyAlgorithm)) {
+            RSAPublicKey rpk = RSASHA1Verify.decodeSSHRSAPublicKey(serverHostKey);
+
+            synchronized (publicKeys) {
+                publicKeys.add(new KnownHostsEntry(hostnames, rpk));
+            }
+        }
+        else if ("ssh-dss".equals(serverHostKeyAlgorithm)) {
+            DSAPublicKey dpk = DSASHA1Verify.decodeSSHDSAPublicKey(serverHostKey);
+
+            synchronized (publicKeys) {
+                publicKeys.add(new KnownHostsEntry(hostnames, dpk));
+            }
+        }
+        else if (serverHostKeyAlgorithm.startsWith("ecdsa-sha2-")) {
+            ECPublicKey epk = ECDSASHA2Verify.decodeSSHECDSAPublicKey(serverHostKey);
+
+            synchronized (publicKeys) {
+                publicKeys.add(new KnownHostsEntry(hostnames, epk));
+            }
+        }
+        else {
+            throw new IOException(String.format("Unknown host key type %s", serverHostKeyAlgorithm));
+        }
+    }
+
+    /**
+     * Parses the given known_hosts data and adds entries to the database.
+     *
+     * @param knownHostsData
+     * @throws IOException
+     */
+    public void addHostkeys(char[] knownHostsData) throws IOException {
+        initialize(knownHostsData);
+    }
+
+    /**
+     * Parses the given known_hosts file and adds entries to the database.
+     *
+     * @param knownHosts
+     * @throws IOException
+     */
+    public void addHostkeys(File knownHosts) throws IOException {
+        initialize(knownHosts);
+    }
+
+    /**
+     * Generate the hashed representation of the given hostname. Useful for adding entries
+     * with hashed hostnames to a known_hosts file. (see -H option of OpenSSH key-gen).
+     *
+     * @param hostname
+     * @return the hashed representation, e.g., "|1|cDhrv7zwEUV3k71CEPHnhHZezhA=|Xo+2y6rUXo2OIWRAYhBOIijbJMA="
+     */
+    public static String createHashedHostname(String hostname) throws IOException {
+        SHA1 sha1 = new SHA1();
+        byte[] salt = new byte[sha1.getDigestLength()];
+        new SecureRandomFix().nextBytes(salt);
+        byte[] hash;
+
+        try {
+            hash = hmacSha1Hash(salt, hostname);
+        }
+        catch (IOException e) {
+            throw new IOException(e);
+        }
+
+        String base64_salt = new String(Base64.encode(salt));
+        String base64_hash = new String(Base64.encode(hash));
+        return String.format("|1|%s|%s", base64_salt, base64_hash);
+    }
+
+    private static byte[] hmacSha1Hash(byte[] salt, String hostname) throws IOException {
+        SHA1 sha1 = new SHA1();
+
+        if (salt.length != sha1.getDigestLength()) {
+            throw new IllegalArgumentException("Salt has wrong length (" + salt.length + ")");
+        }
+
+        try {
+            HMAC hmac = new HMAC(sha1, salt, salt.length);
+            hmac.update(StringEncoder.GetBytes(hostname));
+            byte[] dig = new byte[hmac.getDigestLength()];
+            hmac.digest(dig);
+            return dig;
+        }
+        catch (DigestException e) {
+            throw new IOException(e);
+        }
+    }
+
+    private boolean checkHashed(String entry, String hostname) {
+        if (entry.startsWith("|1|") == false) {
+            return false;
+        }
+
+        int delim_idx = entry.indexOf('|', 3);
+
+        if (delim_idx == -1) {
+            return false;
+        }
+
+        String salt_base64 = entry.substring(3, delim_idx);
+        String hash_base64 = entry.substring(delim_idx + 1);
+        byte[] salt;
+        byte[] hash;
+
+        try {
+            salt = Base64.decode(salt_base64.toCharArray());
+            hash = Base64.decode(hash_base64.toCharArray());
+        }
+        catch (IOException e) {
+            return false;
+        }
+
+        SHA1 sha1 = new SHA1();
+
+        if (salt.length != sha1.getDigestLength()) {
+            return false;
+        }
+
+        byte[] dig = new byte[0];
+
+        try {
+            dig = hmacSha1Hash(salt, hostname);
+        }
+        catch (IOException e) {
+            return false;
+        }
+
+        for (int i = 0; i < dig.length; i++) {
+            if (dig[i] != hash[i]) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    private int checkKey(String remoteHostname, PublicKey remoteKey) {
+        int result = HOSTKEY_IS_NEW;
+
+        synchronized (publicKeys) {
+            for (KnownHostsEntry ke : publicKeys) {
+                if (hostnameMatches(ke.patterns, remoteHostname) == false) {
+                    continue;
+                }
+
+                boolean res = matchKeys(ke.key, remoteKey);
+
+                if (res == true) {
+                    return HOSTKEY_IS_OK;
+                }
+
+                result = HOSTKEY_HAS_CHANGED;
+            }
+        }
+
+        return result;
+    }
+
+    private List<Object> getAllKeys(String hostname) {
+        List<Object> keys = new ArrayList<Object>();
+
+        synchronized (publicKeys) {
+            for (KnownHostsEntry ke : publicKeys) {
+                if (hostnameMatches(ke.patterns, hostname) == false) {
+                    continue;
+                }
+
+                keys.add(ke.key);
+            }
+        }
+
+        return keys;
+    }
+
+    /**
+     * Try to find the preferred order of hostkey algorithms for the given hostname.
+     * Based on the type of hostkey that is present in the internal database
+     * (i.e., either <code>ssh-rsa</code> or <code>ssh-dss</code>)
+     * an ordered list of hostkey algorithms is returned which can be passed
+     * to <code>Connection.setServerHostKeyAlgorithms</code>.
+     *
+     * @param hostname
+     * @return <code>null</code> if no key for the given hostname is present or
+     * there are keys of multiple types present for the given hostname. Otherwise,
+     * an array with hostkey algorithms is returned (i.e., an array of length 2).
+     */
+    public String[] getPreferredServerHostkeyAlgorithmOrder(String hostname) {
+        String[] algos = recommendHostkeyAlgorithms(hostname);
+
+        if (algos != null) {
+            return algos;
+        }
+
+        InetAddress[] ipAdresses;
+
+        try {
+            ipAdresses = InetAddress.getAllByName(hostname);
+        }
+        catch (UnknownHostException e) {
+            return null;
+        }
+
+        for (int i = 0; i < ipAdresses.length; i++) {
+            algos = recommendHostkeyAlgorithms(ipAdresses[i].getHostAddress());
+
+            if (algos != null) {
+                return algos;
+            }
+        }
+
+        return null;
+    }
+
+    private boolean hostnameMatches(String[] hostpatterns, String hostname) {
+        boolean isMatch = false;
+        boolean negate;
+        hostname = hostname.toLowerCase();
+
+        for (int k = 0; k < hostpatterns.length; k++) {
+            if (hostpatterns[k] == null) {
+                continue;
+            }
+
+            String pattern;
+
+            /* In contrast to OpenSSH we also allow negated hash entries (as well as hashed
+                            * entries in lines with multiple entries).
+                            */
+
+            if ((hostpatterns[k].length() > 0) && (hostpatterns[k].charAt(0) == '!')) {
+                pattern = hostpatterns[k].substring(1);
+                negate = true;
+            }
+            else {
+                pattern = hostpatterns[k];
+                negate = false;
+            }
+
+            /* Optimize, no need to check this entry */
+
+            if ((isMatch) && (negate == false)) {
+                continue;
+            }
+
+            /* Now compare */
+
+            if (pattern.charAt(0) == '|') {
+                if (checkHashed(pattern, hostname)) {
+                    if (negate) {
+                        return false;
+                    }
+
+                    isMatch = true;
+                }
+            }
+            else {
+                pattern = pattern.toLowerCase();
+
+                if ((pattern.indexOf('?') != -1) || (pattern.indexOf('*') != -1)) {
+                    if (pseudoRegex(pattern.toCharArray(), 0, hostname.toCharArray(), 0)) {
+                        if (negate) {
+                            return false;
+                        }
+
+                        isMatch = true;
+                    }
+                }
+                else if (pattern.compareTo(hostname) == 0) {
+                    if (negate) {
+                        return false;
+                    }
+
+                    isMatch = true;
+                }
+            }
+        }
+
+        return isMatch;
+    }
+
+    private void initialize(char[] knownHostsData) throws IOException {
+        BufferedReader br = new BufferedReader(new CharArrayReader(knownHostsData));
+
+        while (true) {
+            String line = br.readLine();
+
+            if (line == null) {
+                break;
+            }
+
+            line = line.trim();
+
+            if (line.startsWith("#")) {
+                continue;
+            }
+
+            String[] arr = line.split(" ");
+
+            if (arr.length >= 3) {
+                if ((arr[1].compareTo("ssh-rsa") == 0) ||
+                        (arr[1].compareTo("ssh-dss") == 0) ||
+                        (arr[1].startsWith("ecdsa-sha2-"))) {
+                    String[] hostnames = arr[0].split(",");
+                    byte[] msg = Base64.decode(arr[2].toCharArray());
+
+                    try {
+                        addHostkey(hostnames, arr[1], msg);
+                    }
+                    catch (IOException e) {
+                        continue;
+                    }
+                }
+            }
+        }
+    }
+
+    private void initialize(File knownHosts) throws IOException {
+        char[] buff = new char[512];
+        CharArrayWriter cw = new CharArrayWriter();
+        knownHosts.createNewFile();
+        FileReader fr = new FileReader(knownHosts);
+
+        while (true) {
+            int len = fr.read(buff);
+
+            if (len < 0) {
+                break;
+            }
+
+            cw.write(buff, 0, len);
+        }
+
+        fr.close();
+        initialize(cw.toCharArray());
+    }
+
+    private final boolean matchKeys(PublicKey key1, PublicKey key2) {
+        return key1.equals(key2);
+    }
+
+    private boolean pseudoRegex(char[] pattern, int i, char[] match, int j) {
+        /* This matching logic is equivalent to the one present in OpenSSH 4.1 */
+        while (true) {
+            /* Are we at the end of the pattern? */
+            if (pattern.length == i) {
+                return (match.length == j);
+            }
+
+            if (pattern[i] == '*') {
+                i++;
+
+                if (pattern.length == i) {
+                    return true;
+                }
+
+                if ((pattern[i] != '*') && (pattern[i] != '?')) {
+                    while (true) {
+                        if ((pattern[i] == match[j]) && pseudoRegex(pattern, i + 1, match, j + 1)) {
+                            return true;
+                        }
+
+                        j++;
+
+                        if (match.length == j) {
+                            return false;
+                        }
+                    }
+                }
+
+                while (true) {
+                    if (pseudoRegex(pattern, i, match, j)) {
+                        return true;
+                    }
+
+                    j++;
+
+                    if (match.length == j) {
+                        return false;
+                    }
+                }
+            }
+
+            if (match.length == j) {
+                return false;
+            }
+
+            if ((pattern[i] != '?') && (pattern[i] != match[j])) {
+                return false;
+            }
+
+            i++;
+            j++;
+        }
+    }
+
+    private String[] recommendHostkeyAlgorithms(String hostname) {
+        String preferredAlgo = null;
+        List<Object> keys = getAllKeys(hostname);
+
+        for (Object key : keys) {
+            String thisAlgo;
+
+            if (key instanceof RSAPublicKey) {
+                thisAlgo = "ssh-rsa";
+            }
+            else if (key instanceof DSAPublicKey) {
+                thisAlgo = "ssh-dss";
+            }
+            else if (key instanceof ECPublicKey) {
+                ECPublicKey ecPub = (ECPublicKey) key;
+                String keyType = ECDSASHA2Verify.getCurveName(ecPub.getParams().getCurve().getField().getFieldSize());
+                thisAlgo = ECDSASHA2Verify.ECDSA_SHA2_PREFIX + keyType;
+            }
+            else {
+                continue;
+            }
+
+            if (preferredAlgo != null) {
+                /* If we find different key types, then return null */
+                if (preferredAlgo.compareTo(thisAlgo) != 0) {
+                    return null;
+                }
+            }
+            else {
+                preferredAlgo = thisAlgo;
+            }
+        }
+
+        /* If we did not find anything that we know of, return null */
+
+        if (preferredAlgo == null) {
+            return null;
+        }
+
+        /* Now put the preferred algo to the start of the array.
+                   * You may ask yourself why we do it that way - basically, we could just
+                   * return only the preferred algorithm: since we have a saved key of that
+                   * type (sent earlier from the remote host), then that should work out.
+                   * However, imagine that the server is (for whatever reasons) not offering
+                   * that type of hostkey anymore (e.g., "ssh-rsa" was disabled and
+                   * now "ssh-dss" is being used). If we then do not let the server send us
+                   * a fresh key of the new type, then we shoot ourself into the foot:
+                   * the connection cannot be established and hence the user cannot decide
+                   * if he/she wants to accept the new key.
+                   */
+
+        if (preferredAlgo.equals("ssh-rsa")) {
+            return new String[] {"ssh-rsa", "ssh-dss", "ecdsa-sha2-nistp256"};
+        }
+
+        return new String[] {"ssh-dss", "ssh-rsa", "ecdsa-sha2-nistp256"};
+    }
+
+    /**
+     * Checks the internal hostkey database for the given hostkey.
+     * If no matching key can be found, then the hostname is resolved to an IP address
+     * and the search is repeated using that IP address.
+     *
+     * @param hostname               the server's hostname, will be matched with all hostname patterns
+     * @param serverHostKeyAlgorithm type of hostkey, either <code>ssh-rsa</code> or <code>ssh-dss</code>
+     * @param serverHostKey          the key blob
+     * @return <ul>
+     * <li><code>HOSTKEY_IS_OK</code>: the given hostkey matches an entry for the given hostname</li>
+     * <li><code>HOSTKEY_IS_NEW</code>: no entries found for this hostname and this type of hostkey</li>
+     * <li><code>HOSTKEY_HAS_CHANGED</code>: hostname is known, but with another key of the same type
+     * (man-in-the-middle attack?)</li>
+     * </ul>
+     * @throws IOException if the supplied key blob cannot be parsed or does not match the given hostkey type.
+     */
+    public int verifyHostkey(String hostname, String serverHostKeyAlgorithm, byte[] serverHostKey) throws IOException {
+        PublicKey remoteKey;
+
+        if ("ssh-rsa".equals(serverHostKeyAlgorithm)) {
+            remoteKey = RSASHA1Verify.decodeSSHRSAPublicKey(serverHostKey);
+        }
+        else if ("ssh-dss".equals(serverHostKeyAlgorithm)) {
+            remoteKey = DSASHA1Verify.decodeSSHDSAPublicKey(serverHostKey);
+        }
+        else if (serverHostKeyAlgorithm.startsWith("ecdsa-sha2-")) {
+            remoteKey = ECDSASHA2Verify.decodeSSHECDSAPublicKey(serverHostKey);
+        }
+        else {
+            throw new IllegalArgumentException("Unknown hostkey type " + serverHostKeyAlgorithm);
+        }
+
+        int result = checkKey(hostname, remoteKey);
+
+        if (result == HOSTKEY_IS_OK) {
+            return result;
+        }
+
+        InetAddress[] ipAdresses;
+
+        try {
+            ipAdresses = InetAddress.getAllByName(hostname);
+        }
+        catch (UnknownHostException e) {
+            return result;
+        }
+
+        for (int i = 0; i < ipAdresses.length; i++) {
+            int newresult = checkKey(ipAdresses[i].getHostAddress(), remoteKey);
+
+            if (newresult == HOSTKEY_IS_OK) {
+                return newresult;
+            }
+
+            if (newresult == HOSTKEY_HAS_CHANGED) {
+                result = HOSTKEY_HAS_CHANGED;
+            }
+        }
+
+        return result;
+    }
+
+    /**
+     * Adds a single public key entry to the a known_hosts file.
+     * This method is designed to be used in a {@link ServerHostKeyVerifier}.
+     *
+     * @param knownHosts             the file where the publickey entry will be appended.
+     * @param hostnames              a list of hostname patterns - at least one most be specified. Check out the
+     *                               OpenSSH sshd man page for a description of the pattern matching algorithm.
+     * @param serverHostKeyAlgorithm as passed to the {@link ServerHostKeyVerifier}.
+     * @param serverHostKey          as passed to the {@link ServerHostKeyVerifier}.
+     * @throws IOException
+     */
+    public static void addHostkeyToFile(File knownHosts, String[] hostnames, String serverHostKeyAlgorithm,
+                                        byte[] serverHostKey) throws IOException {
+        if ((hostnames == null) || (hostnames.length == 0)) {
+            throw new IllegalArgumentException("Need at least one hostname specification");
+        }
+
+        if ((serverHostKeyAlgorithm == null) || (serverHostKey == null)) {
+            throw new IllegalArgumentException();
+        }
+
+        CharArrayWriter writer = new CharArrayWriter();
+
+        for (int i = 0; i < hostnames.length; i++) {
+            if (i != 0) {
+                writer.write(',');
+            }
+
+            writer.write(hostnames[i]);
+        }
+
+        writer.write(' ');
+        writer.write(serverHostKeyAlgorithm);
+        writer.write(' ');
+        writer.write(Base64.encode(serverHostKey));
+        writer.write("\n");
+        char[] entry = writer.toCharArray();
+        RandomAccessFile raf = new RandomAccessFile(knownHosts, "rw");
+        long len = raf.length();
+
+        if (len > 0) {
+            raf.seek(len - 1);
+            int last = raf.read();
+
+            if (last != '\n') {
+                raf.write('\n');
+            }
+        }
+
+        raf.write(StringEncoder.GetBytes(new String(entry)));
+        raf.close();
+    }
+
+    /**
+     * Generates a "raw" fingerprint of a hostkey.
+     *
+     * @param type    either "md5" or "sha1"
+     * @param keyType either "ssh-rsa" or "ssh-dss" or "ecdsa-sha2..."
+     * @param hostkey the hostkey
+     * @return the raw fingerprint
+     */
+    static private byte[] rawFingerPrint(String type, String keyType, byte[] hostkey) throws IOException {
+        Digest dig;
+
+        if ("md5".equals(type)) {
+            dig = new MD5();
+        }
+        else if ("sha1".equals(type)) {
+            dig = new SHA1();
+        }
+        else {
+            throw new IllegalArgumentException("Unknown hash type " + type);
+        }
+
+        if ("ssh-rsa".equals(keyType)) {
+        }
+        else if ("ssh-dss".equals(keyType)) {
+        }
+        else if (keyType.startsWith("ecdsa-sha2-")) {
+        }
+        else {
+            throw new IllegalArgumentException("Unknown key type " + keyType);
+        }
+
+        if (hostkey == null) {
+            throw new IllegalArgumentException("hostkey is null");
+        }
+
+        dig.update(hostkey);
+        byte[] res = new byte[dig.getDigestLength()];
+
+        try {
+            dig.digest(res);
+        }
+        catch (DigestException e) {
+            throw new IOException(e);
+        }
+
+        return res;
+    }
+
+    /**
+     * Convert a raw fingerprint to hex representation (XX:YY:ZZ...).
+     *
+     * @param fingerprint raw fingerprint
+     * @return the hex representation
+     */
+    static private String rawToHexFingerprint(byte[] fingerprint) {
+        final char[] alpha = "0123456789abcdef".toCharArray();
+        StringBuilder sb = new StringBuilder();
+
+        for (int i = 0; i < fingerprint.length; i++) {
+            if (i != 0) {
+                sb.append(':');
+            }
+
+            int b = fingerprint[i] & 0xff;
+            sb.append(alpha[b >> 4]);
+            sb.append(alpha[b & 15]);
+        }
+
+        return sb.toString();
+    }
+
+    /**
+     * Convert a raw fingerprint to bubblebabble representation.
+     *
+     * @param raw raw fingerprint
+     * @return the bubblebabble representation
+     */
+    static private String rawToBubblebabbleFingerprint(byte[] raw) {
+        final char[] v = "aeiouy".toCharArray();
+        final char[] c = "bcdfghklmnprstvzx".toCharArray();
+        StringBuilder sb = new StringBuilder();
+        int seed = 1;
+        int rounds = (raw.length / 2) + 1;
+        sb.append('x');
+
+        for (int i = 0; i < rounds; i++) {
+            if (((i + 1) < rounds) || ((raw.length) % 2 != 0)) {
+                sb.append(v[(((raw[2 * i] >> 6) & 3) + seed) % 6]);
+                sb.append(c[(raw[2 * i] >> 2) & 15]);
+                sb.append(v[((raw[2 * i] & 3) + (seed / 6)) % 6]);
+
+                if ((i + 1) < rounds) {
+                    sb.append(c[(((raw[(2 * i) + 1])) >> 4) & 15]);
+                    sb.append('-');
+                    sb.append(c[(((raw[(2 * i) + 1]))) & 15]);
+                    // As long as seed >= 0, seed will be >= 0 afterwards
+                    seed = ((seed * 5) + (((raw[2 * i] & 0xff) * 7) + (raw[(2 * i) + 1] & 0xff))) % 36;
+                }
+            }
+            else {
+                sb.append(v[seed % 6]); // seed >= 0, therefore index positive
+                sb.append('x');
+                sb.append(v[seed / 6]);
+            }
+        }
+
+        sb.append('x');
+        return sb.toString();
+    }
+
+    /**
+     * Convert a ssh2 key-blob into a human readable hex fingerprint.
+     * Generated fingerprints are identical to those generated by OpenSSH.
+     * <p/>
+     * Example fingerprint: d0:cb:76:19:99:5a:03:fc:73:10:70:93:f2:44:63:47.
+     *
+     * @param keytype   either "ssh-rsa" or "ssh-dss" or "ecdsa-sha2..."
+     * @param publickey key blob
+     * @return Hex fingerprint
+     */
+    public static String createHexFingerprint(String keytype, byte[] publickey) throws IOException {
+        byte[] raw = rawFingerPrint("md5", keytype, publickey);
+        return rawToHexFingerprint(raw);
+    }
+
+    /**
+     * Convert a ssh2 key-blob into a human readable bubblebabble fingerprint.
+     * The used bubblebabble algorithm (taken from OpenSSH) generates fingerprints
+     * that are easier to remember for humans.
+     * <p/>
+     * Example fingerprint: xofoc-bubuz-cazin-zufyl-pivuk-biduk-tacib-pybur-gonar-hotat-lyxux.
+     *
+     * @param keytype   either "ssh-rsa" or "ssh-dss"
+     * @param publickey key data
+     * @return Bubblebabble fingerprint
+     */
+    public static String createBubblebabbleFingerprint(String keytype, byte[] publickey) throws IOException {
+        byte[] raw = rawFingerPrint("sha1", keytype, publickey);
+        return rawToBubblebabbleFingerprint(raw);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/src/main/java/ch/ethz/ssh2/LocalPortForwarder.java	Thu Dec 03 11:23:55 2015 -0800
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2006-2013 Christian Plattner. All rights reserved.
+ * Please refer to the LICENSE.txt for licensing details.
+ */
+
+package ch.ethz.ssh2;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+
+import ch.ethz.ssh2.channel.ChannelManager;
+import ch.ethz.ssh2.channel.LocalAcceptThread;
+
+/**
+ * A <code>LocalPortForwarder</code> forwards TCP/IP connections to a local
+ * port via the secure tunnel to another host (which may or may not be identical
+ * to the remote SSH-2 server). Checkout {@link Connection#createLocalPortForwarder(int, String, int)}
+ * on how to create one.
+ *
+ * @author Christian Plattner
+ * @version 2.50, 03/15/10
+ */
+public class LocalPortForwarder {
+    final ChannelManager cm;
+
+    final String host_to_connect;
+
+    final int port_to_connect;
+
+    final LocalAcceptThread lat;
+
+    LocalPortForwarder(ChannelManager cm, int local_port, String host_to_connect, int port_to_connect)
+    throws IOException {
+        this.cm = cm;
+        this.host_to_connect = host_to_connect;
+        this.port_to_connect = port_to_connect;
+        lat = new LocalAcceptThread(cm, local_port, host_to_connect, port_to_connect);
+        lat.setDaemon(true);
+        lat.start();
+    }
+
+    LocalPortForwarder(ChannelManager cm, InetSocketAddress addr, String host_to_connect, int port_to_connect)
+    throws IOException {
+        this.cm = cm;
+        this.host_to_connect = host_to_connect;
+        this.port_to_connect = port_to_connect;
+        lat = new LocalAcceptThread(cm, addr, host_to_connect, port_to_connect);
+        lat.setDaemon(true);
+        lat.start();
+    }
+
+    /**
+     * Return the local socket address of the {@link ServerSocket} used to accept connections.
+     * @return
+     */
+    public InetSocketAddress getLocalSocketAddress() {
+        return (InetSocketAddress) lat.getServerSocket().getLocalSocketAddress();
+    }
+
+    /**
+     * Stop TCP/IP forwarding of newly arriving connections.
+     *
+     * @throws IOException
+     */
+    public void close() throws IOException {
+        lat.stopWorking();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/src/main/java/ch/ethz/ssh2/LocalStreamForwarder.java	Thu Dec 03 11:23:55 2015 -0800
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2006-2011 Christian Plattner. All rights reserved.
+ * Please refer to the LICENSE.txt for licensing details.
+ */
+package ch.ethz.ssh2;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetAddress;
+
+import ch.ethz.ssh2.channel.Channel;
+import ch.ethz.ssh2.channel.ChannelManager;
+
+/**
+ * A <code>LocalStreamForwarder</code> forwards an Input- and Outputstream
+ * pair via the secure tunnel to another host (which may or may not be identical
+ * to the remote SSH-2 server).
+ *
+ * @author Christian Plattner
+ * @version 2.50, 03/15/10
+ */
+public class LocalStreamForwarder {
+    private ChannelManager cm;
+
+    private Channel cn;
+
+    LocalStreamForwarder(ChannelManager cm, String host_to_connect, int port_to_connect) throws IOException {
+        this.cm = cm;
+        cn = cm.openDirectTCPIPChannel(host_to_connect, port_to_connect,
+                                       InetAddress.getLocalHost().getHostAddress(), 0);
+    }
+
+    /**
+     * @return An <code>InputStream</code> object.
+     * @throws IOException
+     */
+    public InputStream getInputStream() throws IOException {
+        return cn.getStdoutStream();
+    }
+
+    /**
+     * Get the OutputStream. Please be aware that the implementation MAY use an
+     * internal buffer. To make sure that the buffered data is sent over the
+     * tunnel, you have to call the <code>flush</code> method of the
+     * <code>OutputStream</code>. To signal EOF, please use the
+     * <code>close</code> method of the <code>OutputStream</code>.
+     *
+     * @return An <code>OutputStream</code> object.
+     * @throws IOException
+     */
+    public OutputStream getOutputStream() throws IOException {
+        return cn.getStdinStream();
+    }
+
+    /**
+     * Close the underlying SSH forwarding channel and free up resources.
+     * You can also use this method to force the shutdown of the underlying
+     * forwarding channel. Pending output (OutputStream not flushed) will NOT
+     * be sent. Pending input (InputStream) can still be read. If the shutdown
+     * operation is already in progress (initiated from either side), then this
+     * call is a no-op.
+     *
+     * @throws IOException
+     */
+    public void close() throws IOException {
+        cm.closeChannel(cn, "Closed due to user request.", true);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/src/main/java/ch/ethz/ssh2/PacketFormatException.java	Thu Dec 03 11:23:55 2015 -0800
@@ -0,0 +1,13 @@
+package ch.ethz.ssh2;
+
+import java.io.IOException;
+
+/**
+ * @version $Id: PacketFormatException.java 151 2014-04-28 10:03:39Z dkocher@sudo.ch $
+ */
+public class PacketFormatException extends IOException {
+
+    public PacketFormatException(String message) {
+        super(message);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/src/main/java/ch/ethz/ssh2/PacketListener.java	Thu Dec 03 11:23:55 2015 -0800
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2011 David Kocher. All rights reserved.
+ * Please refer to the LICENSE.txt for licensing details.
+ */
+package ch.ethz.ssh2;
+
+/**
+ * @version $Id: PacketListener.java 151 2014-04-28 10:03:39Z dkocher@sudo.ch $
+ */
+public interface PacketListener {
+    void read(String packet);
+
+    void write(String packet);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/src/main/java/ch/ethz/ssh2/PacketTypeException.java	Thu Dec 03 11:23:55 2015 -0800
@@ -0,0 +1,24 @@
+package ch.ethz.ssh2;
+
+import java.io.IOException;
+
+/**
+ * @version $Id: PacketTypeException.java 151 2014-04-28 10:03:39Z dkocher@sudo.ch $
+ */
+public class PacketTypeException extends IOException {
+
+    public PacketTypeException() {
+    }
+
+    public PacketTypeException(final String message) {
+        super(message);
+    }
+
+    public PacketTypeException(final int packet) {
+        super(String.format("The SFTP server sent an unexpected packet type (%d)", packet));
+    }
+
+    public PacketTypeException(final int packet, final String message) {
+        super(String.format("The SFTP server sent an invalid packet type (%d). %s", packet, message));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/src/main/java/ch/ethz/ssh2/ProxyData.java	Thu Dec 03 11:23:55 2015 -0800
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2006-2011 Christian Plattner. All rights reserved.
+ * Please refer to the LICENSE.txt for licensing details.
+ */
+package ch.ethz.ssh2;
+
+/**
+ * An abstract marker interface implemented by all proxy data implementations.
+ *
+ * @see HTTPProxyData
+ *
+ * @author Christian Plattner
+ * @version 2.50, 03/15/10
+ */
+
+public abstract interface ProxyData {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/src/main/java/ch/ethz/ssh2/PtySettings.java	Thu Dec 03 11:23:55 2015 -0800
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2012-2013 Christian Plattner. All rights reserved.
+ * Please refer to the LICENSE.txt for licensing details.
+ */
+package ch.ethz.ssh2;
+
+/**
+ * PTY settings for a SSH session. Zero dimension parameters are ignored. The character/row dimensions
+ * override the pixel dimensions (when nonzero). Pixel dimensions refer to
+ * the drawable area of the window. The dimension parameters are only
+ * informational. The encoding of terminal modes (parameter
+ * <code>terminal_modes</code>) is described in RFC4254.
+ *
+ * @author Christian
+ */
+public class PtySettings {
+    /**
+     * TERM environment variable value (e.g., vt100)
+     */
+    public String term;
+
+    /**
+     * Terminal width, characters (e.g., 80)
+     */
+    public int term_width_characters;
+
+    /**
+     * Terminal height, rows (e.g., 24)
+     */
+    public int term_height_characters;
+
+    /**
+     * Terminal width, pixels (e.g., 640)
+     */
+    public int term_width_pixels;
+
+    /**
+     * Terminal height, pixels (e.g., 480)
+     */
+    public int term_height_pixels;
+
+    /**
+     * Encoded terminal modes
+     */
+    public byte[] terminal_modes;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/src/main/java/ch/ethz/ssh2/RequestMismatchException.java	Thu Dec 03 11:23:55 2015 -0800
@@ -0,0 +1,17 @@
+package ch.ethz.ssh2;
+
+import java.io.IOException;
+
+/**
+ * @version $Id: RequestMismatchException.java 151 2014-04-28 10:03:39Z dkocher@sudo.ch $
+ */
+public class RequestMismatchException extends IOException {
+
+    public RequestMismatchException() {
+        super("The server sent an invalid id field.");
+    }
+
+    public RequestMismatchException(final String message) {
+        super(message);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/src/main/java/ch/ethz/ssh2/SCPClient.java	Thu Dec 03 11:23:55 2015 -0800
@@ -0,0 +1,742 @@
+package ch.ethz.ssh2;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.charset.Charset;
+import java.nio.charset.UnsupportedCharsetException;
+
+/**
+ * A very basic <code>SCPClient</code> that can be used to copy files from/to
+ * the SSH-2 server. On the server side, the "scp" program must be in the PATH.
+ * <p/>
+ * This scp client is thread safe - you can download (and upload) different sets
+ * of files concurrently without any troubles. The <code>SCPClient</code> is
+ * actually mapping every request to a distinct {@link ch.ethz.ssh2.Session}.
+ *
+ * @author Christian Plattner, plattner@inf.ethz.ch
+ * @version $Id: SCPClient.java 85 2014-04-07 14:05:09Z dkocher@sudo.ch $
+ */
+
+public class SCPClient {
+    Connection conn;
+
+    String charsetName = null;
+
+    /**
+     * Set the charset used to convert between Java Unicode Strings and byte encodings
+     * used by the server for paths and file names.
+     *
+     * @param charset the name of the charset to be used or <code>null</code> to use the platform's
+     * default encoding.
+     * @throws IOException
+     * @see #getCharset()
+     */
+    public void setCharset(String charset) throws IOException {
+        if (charset == null) {
+            charsetName = charset;
+            return;
+        }
+
+        try {
+            Charset.forName(charset);
+        }
+        catch (UnsupportedCharsetException e) {
+            throw new IOException("This charset is not supported", e);
+        }
+
+        charsetName = charset;
+    }
+
+    /**
+     * The currently used charset for filename encoding/decoding.
+     *
+     * @return The name of the charset (<code>null</code> if the platform's default charset is being used)
+     * @see #setCharset(String)
+     */
+    public String getCharset() {
+        return charsetName;
+    }
+
+    public class LenNamePair {
+        public long length;
+        String filename;
+    }
+
+    public SCPClient(Connection conn) {
+        if (conn == null)
+            throw new IllegalArgumentException("Cannot accept null argument!");
+
+        this.conn = conn;
+    }
+
+    protected void readResponse(InputStream is) throws IOException {
+        int c = is.read();
+
+        if (c == 0)
+            return;
+
+        if (c == -1)
+            throw new IOException("Remote scp terminated unexpectedly.");
+
+        if ((c != 1) && (c != 2))
+            throw new IOException("Remote scp sent illegal error code.");
+
+        if (c == 2)
+            throw new IOException("Remote scp terminated with error.");
+
+        String err = receiveLine(is);
+        throw new IOException("Remote scp terminated with error (" + err + ").");
+    }
+
+    protected String receiveLine(InputStream is) throws IOException {
+        StringBuilder sb = new StringBuilder(30);
+
+        while (true) {
+            /* This is a random limit - if your path names are longer, then adjust it */
+            if (sb.length() > 8192)
+                throw new IOException("Remote scp sent a too long line");
+
+            int c = is.read();
+
+            if (c < 0)
+                throw new IOException("Remote scp terminated unexpectedly.");
+
+            if (c == '\n')
+                break;
+
+            sb.append((char) c);
+        }
+
+        return sb.toString();
+    }
+
+    protected LenNamePair parseCLine(String line) throws IOException {
+        /* Minimum line: "xxxx y z" ---> 8 chars */
+        if (line.length() < 8)
+            throw new IOException("Malformed C line sent by remote SCP binary, line too short.");
+
+        if ((line.charAt(4) != ' ') || (line.charAt(5) == ' '))
+            throw new IOException("Malformed C line sent by remote SCP binary.");
+
+        int length_name_sep = line.indexOf(' ', 5);
+
+        if (length_name_sep == -1)
+            throw new IOException("Malformed C line sent by remote SCP binary.");
+
+        String length_substring = line.substring(5, length_name_sep);
+        String name_substring = line.substring(length_name_sep + 1);
+
+        if ((length_substring.length() <= 0) || (name_substring.length() <= 0))
+            throw new IOException("Malformed C line sent by remote SCP binary.");
+
+        if ((6 + length_substring.length() + name_substring.length()) != line.length())
+            throw new IOException("Malformed C line sent by remote SCP binary.");
+
+        final long len;
+
+        try {
+            len = Long.parseLong(length_substring);
+        }
+        catch (NumberFormatException e) {
+            throw new IOException("Malformed C line sent by remote SCP binary, cannot parse file length.");
+        }
+
+        if (len < 0)
+            throw new IOException("Malformed C line sent by remote SCP binary, illegal file length.");
+
+        LenNamePair lnp = new LenNamePair();
+        lnp.length = len;
+        lnp.filename = name_substring;
+        return lnp;
+    }
+
+    /**
+     * The session for opened for this SCP transfer must be closed using
+     * SCPOutputStream#close
+     *
+     * @param remoteFile
+     * @param length The size of the file to send
+     * @param remoteTargetDirectory
+     * @param mode
+     * @return
+     * @throws IOException
+     */
+    public SCPOutputStream put(final String remoteFile, long length, String remoteTargetDirectory, String mode)
+    throws IOException {
+        Session sess = null;
+
+        if (null == remoteFile)
+            throw new IllegalArgumentException("Null argument.");
+
+        if (null == remoteTargetDirectory)
+            remoteTargetDirectory = "";
+
+        if (null == mode)
+            mode = "0600";
+
+        if (mode.length() != 4)
+            throw new IllegalArgumentException("Invalid mode.");
+
+        for (int i = 0; i < mode.length(); i++)
+            if (Character.isDigit(mode.charAt(i)) == false)
+                throw new IllegalArgumentException("Invalid mode.");
+
+        remoteTargetDirectory = (remoteTargetDirectory.length() > 0) ? remoteTargetDirectory : ".";
+        String cmd = "scp -t -d \"" + remoteTargetDirectory + "\"";
+        sess = conn.openSession();
+        sess.execCommand(cmd, charsetName);
+        return new SCPOutputStream(this, sess, remoteFile, length, mode);
+    }
+
+    /**
+     * The session for opened for this SCP transfer must be closed using
+     * SCPInputStream#close
+     *
+     * @param remoteFile
+     * @return
+     * @throws IOException
+     */
+    public SCPInputStream get(final String remoteFile) throws IOException {
+        Session sess = null;
+
+        if (null == remoteFile)
+            throw new IllegalArgumentException("Null argument.");
+
+        if (remoteFile.length() == 0)
+            throw new IllegalArgumentException("Cannot accept empty filename.");
+
+        String cmd = "scp -f";
+        cmd += (" \"" + remoteFile + "\"");
+        sess = conn.openSession();
+        sess.execCommand(cmd, charsetName);
+        return new SCPInputStream(this, sess);
+    }
+    private void sendBytes(Session sess, byte[] data, String fileName, String mode) throws IOException {
+        OutputStream os = sess.getStdin();
+        InputStream is = new BufferedInputStream(sess.getStdout(), 512);
+        readResponse(is);
+        String cline = "C" + mode + " " + data.length + " " + fileName + "\n";
+        os.write(cline.getBytes("ISO-8859-1"));
+        os.flush();
+        readResponse(is);
+        os.write(data, 0, data.length);
+        os.write(0);
+        os.flush();
+        readResponse(is);
+        os.write("E\n".getBytes("ISO-8859-1"));
+        os.flush();
+    }
+
+    private void sendFiles(Session sess, String[] files, String[] remoteFiles, String mode) throws IOException {
+        byte[] buffer = new byte[8192];
+        OutputStream os = new BufferedOutputStream(sess.getStdin(), 40000);
+        InputStream is = new BufferedInputStream(sess.getStdout(), 512);
+        readResponse(is);
+
+        for (int i = 0; i < files.length; i++) {
+            File f = new File(files[i]);
+            long remain = f.length();
+            String remoteName;
+
+            if ((remoteFiles != null) && (remoteFiles.length > i) && (remoteFiles[i] != null))
+                remoteName = remoteFiles[i];
+            else
+                remoteName = f.getName();
+
+            String cline = "C" + mode + " " + remain + " " + remoteName + "\n";
+            os.write(cline.getBytes("ISO-8859-1"));
+            os.flush();
+            readResponse(is);
+            FileInputStream fis = null;
+
+            try {
+                fis = new FileInputStream(f);
+
+                while (remain > 0) {
+                    int trans;
+
+                    if (remain > buffer.length)
+                        trans = buffer.length;
+                    else
+                        trans = (int) remain;
+
+                    if (fis.read(buffer, 0, trans) != trans)
+                        throw new IOException("Cannot read enough from local file " + files[i]);
+
+                    os.write(buffer, 0, trans);
+                    remain -= trans;
+                }
+            }
+            finally {
+                if (fis != null)
+                    fis.close();
+            }
+
+            os.write(0);
+            os.flush();
+            readResponse(is);
+        }
+
+        os.write("E\n".getBytes("ISO-8859-1"));
+        os.flush();
+    }
+
+    private void receiveFiles(Session sess, OutputStream[] targets) throws IOException {
+        byte[] buffer = new byte[8192];
+        OutputStream os = new BufferedOutputStream(sess.getStdin(), 512);
+        InputStream is = new BufferedInputStream(sess.getStdout(), 40000);
+        os.write(0x0);
+        os.flush();
+
+        for (int i = 0; i < targets.length; i++) {
+            LenNamePair lnp = null;
+
+            while (true) {
+                int c = is.read();
+
+                if (c < 0)
+                    throw new IOException("Remote scp terminated unexpectedly.");
+
+                String line = receiveLine(is);
+
+                if (c == 'T') {
+                    /* Ignore modification times */
+                    continue;
+                }
+
+                if ((c == 1) || (c == 2))
+                    throw new IOException("Remote SCP error: " + line);
+
+                if (c == 'C') {
+                    lnp = parseCLine(line);
+                    break;
+                }
+
+                throw new IOException("Remote SCP error: " + ((char) c) + line);
+            }
+
+            os.write(0x0);
+            os.flush();
+            long remain = lnp.length;
+
+            while (remain > 0) {
+                int trans;
+
+                if (remain > buffer.length)
+                    trans = buffer.length;
+                else
+                    trans = (int) remain;
+
+                int this_time_received = is.read(buffer, 0, trans);
+
+                if (this_time_received < 0) {
+                    throw new IOException("Remote scp terminated connection unexpectedly");
+                }
+
+                targets[i].write(buffer, 0, this_time_received);
+                remain -= this_time_received;
+            }
+
+            readResponse(is);
+            os.write(0x0);
+            os.flush();
+        }
+    }
+
+    private void receiveFiles(Session sess, String[] files, String target) throws IOException {
+        byte[] buffer = new byte[8192];
+        OutputStream os = new BufferedOutputStream(sess.getStdin(), 512);
+        InputStream is = new BufferedInputStream(sess.getStdout(), 40000);
+        os.write(0x0);
+        os.flush();
+
+        for (int i = 0; i < files.length; i++) {
+            LenNamePair lnp = null;
+
+            while (true) {
+                int c = is.read();
+
+                if (c < 0)
+                    throw new IOException("Remote scp terminated unexpectedly.");
+
+                String line = receiveLine(is);
+
+                if (c == 'T') {
+                    /* Ignore modification times */
+                    continue;
+                }
+
+                if ((c == 1) || (c == 2))
+                    throw new IOException("Remote SCP error: " + line);
+
+                if (c == 'C') {
+                    lnp = parseCLine(line);
+                    break;
+                }
+
+                throw new IOException("Remote SCP error: " + ((char) c) + line);
+            }
+
+            os.write(0x0);
+            os.flush();
+            File f = new File(target + File.separatorChar + lnp.filename);
+            FileOutputStream fop = null;
+
+            try {
+                fop = new FileOutputStream(f);
+                long remain = lnp.length;
+
+                while (remain > 0) {
+                    int trans;
+
+                    if (remain > buffer.length)
+                        trans = buffer.length;
+                    else
+                        trans = (int) remain;
+
+                    int this_time_received = is.read(buffer, 0, trans);
+
+                    if (this_time_received < 0) {
+                        throw new IOException("Remote scp terminated connection unexpectedly");
+                    }
+
+                    fop.write(buffer, 0, this_time_received);
+                    remain -= this_time_received;
+                }
+            }
+            finally {
+                if (fop != null)
+                    fop.close();
+            }
+
+            readResponse(is);
+            os.write(0x0);
+            os.flush();
+        }
+    }
+
+    /**
+     * Copy a local file to a remote directory, uses mode 0600 when creating the
+     * file on the remote side.
+     *
+     * @param localFile
+     *            Path and name of local file.
+     * @param remoteTargetDirectory
+     *            Remote target directory. Use an empty string to specify the
+     *            default directory.
+     *
+     * @throws IOException
+     */
+    public void put(String localFile, String remoteTargetDirectory) throws IOException {
+        put(new String[] { localFile }, remoteTargetDirectory, "0600");
+    }
+
+    /**
+     * Copy a set of local files to a remote directory, uses mode 0600 when
+     * creating files on the remote side.
+     *
+     * @param localFiles
+     *            Paths and names of local file names.
+     * @param remoteTargetDirectory
+     *            Remote target directory. Use an empty string to specify the
+     *            default directory.
+     *
+     * @throws IOException
+     */
+
+    public void put(String[] localFiles, String remoteTargetDirectory) throws IOException {
+        put(localFiles, remoteTargetDirectory, "0600");
+    }
+
+    /**
+     * Copy a local file to a remote directory, uses the specified mode when
+     * creating the file on the remote side.
+     *
+     * @param localFile
+     *            Path and name of local file.
+     * @param remoteTargetDirectory
+     *            Remote target directory. Use an empty string to specify the
+     *            default directory.
+     * @param mode
+     *            a four digit string (e.g., 0644, see "man chmod", "man open")
+     * @throws IOException
+     */
+    public void put(String localFile, String remoteTargetDirectory, String mode) throws IOException {
+        put(new String[] { localFile }, remoteTargetDirectory, mode);
+    }
+
+    /**
+     * Copy a local file to a remote directory, uses the specified mode and
+     * remote filename when creating the file on the remote side.
+     *
+     * @param localFile
+     *            Path and name of local file.
+     * @param remoteFileName
+     *            The name of the file which will be created in the remote
+     *            target directory.
+     * @param remoteTargetDirectory
+     *            Remote target directory. Use an empty string to specify the
+     *            default directory.
+     * @param mode
+     *            a four digit string (e.g., 0644, see "man chmod", "man open")
+     * @throws IOException
+     */
+    public void put(String localFile, String remoteFileName, String remoteTargetDirectory, String mode)
+    throws IOException {
+        put(new String[] { localFile }, new String[] { remoteFileName }, remoteTargetDirectory, mode);
+    }
+
+    /**
+     * Create a remote file and copy the contents of the passed byte array into
+     * it. Uses mode 0600 for creating the remote file.
+     *
+     * @param data
+     *            the data to be copied into the remote file.
+     * @param remoteFileName
+     *            The name of the file which will be created in the remote
+     *            target directory.
+     * @param remoteTargetDirectory
+     *            Remote target directory. Use an empty string to specify the
+     *            default directory.
+     * @throws IOException
+     */
+
+    public void put(byte[] data, String remoteFileName, String remoteTargetDirectory) throws IOException {
+        put(data, remoteFileName, remoteTargetDirectory, "0600");
+    }
+
+    /**
+     * Create a remote file and copy the contents of the passed byte array into
+     * it. The method use the specified mode when creating the file on the
+     * remote side.
+     *
+     * @param data
+     *            the data to be copied into the remote file.
+     * @param remoteFileName
+     *            The name of the file which will be created in the remote
+     *            target directory.
+     * @param remoteTargetDirectory
+     *            Remote target directory. Use an empty string to specify the
+     *            default directory.
+     * @param mode
+     *            a four digit string (e.g., 0644, see "man chmod", "man open")
+     * @throws IOException
+     */
+    public void put(byte[] data, String remoteFileName, String remoteTargetDirectory, String mode) throws IOException {
+        Session sess = null;
+
+        if ((remoteFileName == null) || (remoteTargetDirectory == null) || (mode == null))
+            throw new IllegalArgumentException("Null argument.");
+
+        if (mode.length() != 4)
+            throw new IllegalArgumentException("Invalid mode.");
+
+        for (int i = 0; i < mode.length(); i++)
+            if (Character.isDigit(mode.charAt(i)) == false)
+                throw new IllegalArgumentException("Invalid mode.");
+
+        remoteTargetDirectory = remoteTargetDirectory.trim();
+        remoteTargetDirectory = (remoteTargetDirectory.length() > 0) ? remoteTargetDirectory : ".";
+        String cmd = "scp -t -d " + remoteTargetDirectory;
+
+        try {
+            sess = conn.openSession();
+            sess.execCommand(cmd);
+            sendBytes(sess, data, remoteFileName, mode);
+        }
+        catch (IOException e) {
+            throw(IOException) new IOException("Error during SCP transfer.").initCause(e);
+        }
+        finally {
+            if (sess != null)
+                sess.close();
+        }
+    }
+
+    /**
+     * Copy a set of local files to a remote directory, uses the specified mode
+     * when creating the files on the remote side.
+     *
+     * @param localFiles
+     *            Paths and names of the local files.
+     * @param remoteTargetDirectory
+     *            Remote target directory. Use an empty string to specify the
+     *            default directory.
+     * @param mode
+     *            a four digit string (e.g., 0644, see "man chmod", "man open")
+     * @throws IOException
+     */
+    public void put(String[] localFiles, String remoteTargetDirectory, String mode) throws IOException {
+        put(localFiles, null, remoteTargetDirectory, mode);
+    }
+
+    public void put(String[] localFiles, String[] remoteFiles, String remoteTargetDirectory, String mode)
+    throws IOException {
+        Session sess = null;
+
+        /*
+         * remoteFiles may be null, indicating that the local filenames shall be
+         * used
+         */
+
+        if ((localFiles == null) || (remoteTargetDirectory == null) || (mode == null))
+            throw new IllegalArgumentException("Null argument.");
+
+        if (mode.length() != 4)
+            throw new IllegalArgumentException("Invalid mode.");
+
+        for (int i = 0; i < mode.length(); i++)
+            if (Character.isDigit(mode.charAt(i)) == false)
+                throw new IllegalArgumentException("Invalid mode.");
+
+        if (localFiles.length == 0)
+            return;
+
+        remoteTargetDirectory = remoteTargetDirectory.trim();
+        remoteTargetDirectory = (remoteTargetDirectory.length() > 0) ? remoteTargetDirectory : ".";
+        String cmd = "scp -t -d " + remoteTargetDirectory;
+
+        for (int i = 0; i < localFiles.length; i++) {
+            if (localFiles[i] == null)
+                throw new IllegalArgumentException("Cannot accept null filename.");
+        }
+
+        try {
+            sess = conn.openSession();
+            sess.execCommand(cmd);
+            sendFiles(sess, localFiles, remoteFiles, mode);
+        }
+        catch (IOException e) {
+            throw(IOException) new IOException("Error during SCP transfer.").initCause(e);
+        }
+        finally {
+            if (sess != null)
+                sess.close();
+        }
+    }
+
+    /**
+     * Download a file from the remote server to a local directory.
+     *
+     * @param remoteFile
+     *            Path and name of the remote file.
+     * @param localTargetDirectory
+     *            Local directory to put the downloaded file.
+     *
+     * @throws IOException
+     */
+    public void get(String remoteFile, String localTargetDirectory) throws IOException {
+        get(new String[] { remoteFile }, localTargetDirectory);
+    }
+
+    /**
+     * Download a file from the remote server and pipe its contents into an
+     * <code>OutputStream</code>. Please note that, to enable flexible usage
+     * of this method, the <code>OutputStream</code> will not be closed nor
+     * flushed.
+     *
+     * @param remoteFile
+     *            Path and name of the remote file.
+     * @param target
+     *            OutputStream where the contents of the file will be sent to.
+     * @throws IOException
+     */
+    public void get(String remoteFile, OutputStream target) throws IOException {
+        get(new String[] { remoteFile }, new OutputStream[] { target });
+    }
+
+    private void get(String remoteFiles[], OutputStream[] targets) throws IOException {
+        Session sess = null;
+
+        if ((remoteFiles == null) || (targets == null))
+            throw new IllegalArgumentException("Null argument.");
+
+        if (remoteFiles.length != targets.length)
+            throw new IllegalArgumentException("Length of arguments does not match.");
+
+        if (remoteFiles.length == 0)
+            return;
+
+        String cmd = "scp -f";
+
+        for (int i = 0; i < remoteFiles.length; i++) {
+            if (remoteFiles[i] == null)
+                throw new IllegalArgumentException("Cannot accept null filename.");
+
+            String tmp = remoteFiles[i].trim();
+
+            if (tmp.length() == 0)
+                throw new IllegalArgumentException("Cannot accept empty filename.");
+
+            cmd += (" " + tmp);
+        }