diff --git a/java/CMakeLists.txt b/java/CMakeLists.txt
index eb391e3..d00bedb 100644
--- a/java/CMakeLists.txt
+++ b/java/CMakeLists.txt
@@ -5,7 +5,7 @@
 
 find_package(Java)
 
-set(DEFAULT_JAVACFLAGS "-source 1.5 -target 1.5 -Xlint:all,-serial,-cast")
+set(DEFAULT_JAVACFLAGS "-source 1.5 -target 1.5 -Xlint:all,-serial,-cast,-unchecked,-fallthrough,-dep-ann")
 set(JAVACFLAGS ${DEFAULT_JAVACFLAGS} CACHE STRING
   "Java compiler flags (Default: ${DEFAULT_JAVACFLAGS})")
 message(STATUS "Java compiler flags = ${JAVACFLAGS}")
@@ -27,7 +27,7 @@
   F8Menu
   OptionsDialogCallback
   PasswdDialog
-  PixelBufferImage
+  PlatformPixelBuffer
   OptionsDialog
   ServerDialog
   UserPrefs
@@ -41,17 +41,69 @@
     ${CMAKE_CURRENT_BINARY_DIR}/${CLASSPATH}/${class}.class)
 endforeach()
 
+set(JSCH_CLASSNAMES
+  DH
+  DHG1
+  DHG14
+  DHGEX
+  JSch
+  Session
+  UserAuth
+  UserAuthKeyboardInteractive
+  UserAuthPassword
+  UserAuthPublicKey
+  UserAuthNone
+  jce/AES128CBC
+  jce/AES192CTR
+  jce/ARCFOUR128
+  jce/BlowfishCBC
+  jce/HMACMD5
+  jce/KeyPairGenDSA
+  jce/Random
+  jce/SignatureRSA
+  jce/AES128CTR
+  jce/AES256CBC
+  jce/ARCFOUR256
+  jce/DH
+  jce/HMACSHA196
+  jce/KeyPairGenRSA
+  jce/SHA1
+  jce/TripleDESCBC
+  jce/AES192CBC
+  jce/AES256CTR
+  jce/ARCFOUR
+  jce/HMACMD596
+  jce/HMACSHA1
+  jce/MD5
+  jce/SignatureDSA
+  jce/TripleDESCTR
+  jcraft/Compression
+  jcraft/HMAC
+  jcraft/HMACMD596
+  jcraft/HMACMD5
+  jcraft/HMACSHA196
+  jcraft/HMACSHA1)
+set(JSCH_SRCDIR ${CMAKE_CURRENT_SOURCE_DIR}/com/jcraft/jsch)
+foreach(class ${JSCH_CLASSNAMES})
+  set(JAVA_SOURCES ${JAVA_SOURCES} ${JSCH_SRCDIR}/${class}.java)
+  set(JAVA_CLASSES_FULL ${JAVA_CLASSES_FULL}
+    ${CMAKE_CURRENT_BINARY_DIR}/com/jcraft/jsch/${class}.class)
+endforeach()
+
 file(GLOB DEPEND_SOURCES
   ${CMAKE_CURRENT_SOURCE_DIR}/com/tigervnc/rfb/*.java
   ${CMAKE_CURRENT_SOURCE_DIR}/com/tigervnc/rdr/*.java
   ${CMAKE_CURRENT_SOURCE_DIR}/com/tigervnc/network/*.java
+  ${CMAKE_CURRENT_SOURCE_DIR}/com/jcraft/jsch/*.java
+  ${CMAKE_CURRENT_SOURCE_DIR}/com/jcraft/jsch/jcraft/*.java
+  ${CMAKE_CURRENT_SOURCE_DIR}/com/jcraft/jsch/jgss/*.java
   ${CMAKE_CURRENT_SOURCE_DIR}/com/jcraft/jzlib/*.java)
 
 string(REGEX REPLACE " " ";" JAVACFLAGS "${JAVACFLAGS}")
 add_custom_command(OUTPUT ${JAVA_CLASSES_FULL}
   DEPENDS ${JAVA_SOURCES} ${DEPEND_SOURCES}
   COMMAND ${JAVA_COMPILE}
-  ARGS ${JAVACFLAGS} -cp ${CMAKE_CURRENT_SOURCE_DIR}
+  ARGS ${JAVACFLAGS} -sourcepath ${CMAKE_CURRENT_SOURCE_DIR}
     -d ${CMAKE_CURRENT_BINARY_DIR} ${JAVA_SOURCES})
 
 configure_file(${CLASSPATH}/timestamp.in ${CLASSPATH}/timestamp)
@@ -84,6 +136,9 @@
     com/tigervnc/rdr/*.class
     com/tigervnc/network/*.class
     com/jcraft/jzlib/*.class
+    com/jcraft/jsch/jcraft/*.class
+    com/jcraft/jsch/jce/*.class
+    com/jcraft/jsch/*.class
     com/tigervnc/vncviewer/tigervnc.png
     com/tigervnc/vncviewer/tigervnc.ico
   COMMAND ${CMAKE_COMMAND}
diff --git a/java/com/jcraft/jsch/Buffer.java b/java/com/jcraft/jsch/Buffer.java
new file mode 100644
index 0000000..a3135a1
--- /dev/null
+++ b/java/com/jcraft/jsch/Buffer.java
@@ -0,0 +1,254 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+public class Buffer{
+  final byte[] tmp=new byte[4];
+  byte[] buffer;
+  int index;
+  int s;
+  public Buffer(int size){
+    buffer=new byte[size];
+    index=0;
+    s=0;
+  }
+  public Buffer(byte[] buffer){
+    this.buffer=buffer;
+    index=0;
+    s=0;
+  }
+  public Buffer(){ this(1024*10*2); }
+  public void putByte(byte foo){
+    buffer[index++]=foo;
+  }
+  public void putByte(byte[] foo) {
+    putByte(foo, 0, foo.length);
+  }
+  public void putByte(byte[] foo, int begin, int length) {
+    System.arraycopy(foo, begin, buffer, index, length);
+    index+=length;
+  }
+  public void putString(byte[] foo){
+    putString(foo, 0, foo.length);
+  }
+  public void putString(byte[] foo, int begin, int length) {
+    putInt(length);
+    putByte(foo, begin, length);
+  }
+  public void putInt(int val) {
+    tmp[0]=(byte)(val >>> 24);
+    tmp[1]=(byte)(val >>> 16);
+    tmp[2]=(byte)(val >>> 8);
+    tmp[3]=(byte)(val);
+    System.arraycopy(tmp, 0, buffer, index, 4);
+    index+=4;
+  }
+  public void putLong(long val) {
+    tmp[0]=(byte)(val >>> 56);
+    tmp[1]=(byte)(val >>> 48);
+    tmp[2]=(byte)(val >>> 40);
+    tmp[3]=(byte)(val >>> 32);
+    System.arraycopy(tmp, 0, buffer, index, 4);
+    tmp[0]=(byte)(val >>> 24);
+    tmp[1]=(byte)(val >>> 16);
+    tmp[2]=(byte)(val >>> 8);
+    tmp[3]=(byte)(val);
+    System.arraycopy(tmp, 0, buffer, index+4, 4);
+    index+=8;
+  }
+  void skip(int n) {
+    index+=n;
+  }
+  void putPad(int n) {
+    while(n>0){
+      buffer[index++]=(byte)0;
+      n--;
+    }
+  }
+  public void putMPInt(byte[] foo){
+    int i=foo.length;
+    if((foo[0]&0x80)!=0){
+      i++;
+      putInt(i);
+      putByte((byte)0);
+    }
+    else{
+      putInt(i);
+    }
+    putByte(foo);
+  }
+  public int getLength(){
+    return index-s;
+  }
+  public int getOffSet(){
+    return s;
+  }
+  public void setOffSet(int s){
+    this.s=s;
+  }
+  public long getLong(){
+    long foo = getInt()&0xffffffffL;
+    foo = ((foo<<32)) | (getInt()&0xffffffffL);
+    return foo;
+  }
+  public int getInt(){
+    int foo = getShort();
+    foo = ((foo<<16)&0xffff0000) | (getShort()&0xffff);
+    return foo;
+  }
+  public long getUInt(){
+    long foo = 0L;
+    long bar = 0L;
+    foo = getByte();
+    foo = ((foo<<8)&0xff00)|(getByte()&0xff);
+    bar = getByte();
+    bar = ((bar<<8)&0xff00)|(getByte()&0xff);
+    foo = ((foo<<16)&0xffff0000) | (bar&0xffff);
+    return foo;
+  }
+  int getShort() {
+    int foo = getByte();
+    foo = ((foo<<8)&0xff00)|(getByte()&0xff);
+    return foo;
+  }
+  public int getByte() {
+    return (buffer[s++]&0xff);
+  }
+  public void getByte(byte[] foo) {
+    getByte(foo, 0, foo.length);
+  }
+  void getByte(byte[] foo, int start, int len) {
+    System.arraycopy(buffer, s, foo, start, len); 
+    s+=len;
+  }
+  public int getByte(int len) {
+    int foo=s;
+    s+=len;
+    return foo;
+  }
+  public byte[] getMPInt() {
+    int i=getInt();  // uint32
+    if(i<0 ||  // bigger than 0x7fffffff
+       i>8*1024){
+      // TODO: an exception should be thrown.
+      i = 8*1024; // the session will be broken, but working around OOME.
+    }
+    byte[] foo=new byte[i];
+    getByte(foo, 0, i);
+    return foo;
+  }
+  public byte[] getMPIntBits() {
+    int bits=getInt();
+    int bytes=(bits+7)/8;
+    byte[] foo=new byte[bytes];
+    getByte(foo, 0, bytes);
+    if((foo[0]&0x80)!=0){
+      byte[] bar=new byte[foo.length+1];
+      bar[0]=0; // ??
+      System.arraycopy(foo, 0, bar, 1, foo.length);
+      foo=bar;
+    }
+    return foo;
+  }
+  public byte[] getString() {
+    int i = getInt();  // uint32
+    if(i<0 ||  // bigger than 0x7fffffff
+       i>256*1024){
+      // TODO: an exception should be thrown.
+      i = 256*1024; // the session will be broken, but working around OOME.
+    }
+    byte[] foo=new byte[i];
+    getByte(foo, 0, i);
+    return foo;
+  }
+  byte[] getString(int[]start, int[]len) {
+    int i=getInt();
+    start[0]=getByte(i);
+    len[0]=i;
+    return buffer;
+  }
+  public void reset(){
+    index=0;
+    s=0;
+  }
+  public void shift(){
+    if(s==0)return;
+    System.arraycopy(buffer, s, buffer, 0, index-s);
+    index=index-s;
+    s=0;
+  }
+  void rewind(){
+    s=0;
+  }
+
+  byte getCommand(){
+    return buffer[5];
+  }
+
+  void checkFreeSize(int n){
+    if(buffer.length<index+n){
+      byte[] tmp = new byte[buffer.length*2];
+      System.arraycopy(buffer, 0, tmp, 0, index);
+      buffer = tmp;
+    }
+  }
+
+/*
+  static String[] chars={
+    "0","1","2","3","4","5","6","7","8","9", "a","b","c","d","e","f"
+  };
+  static void dump_buffer(){
+    int foo;
+    for(int i=0; i<tmp_buffer_index; i++){
+        foo=tmp_buffer[i]&0xff;
+	System.err.print(chars[(foo>>>4)&0xf]);
+	System.err.print(chars[foo&0xf]);
+        if(i%16==15){
+          System.err.println("");
+	  continue;
+	}
+        if(i>0 && i%2==1){
+          System.err.print(" ");
+	}
+    }
+    System.err.println("");
+  }
+  static void dump(byte[] b){
+    dump(b, 0, b.length);
+  }
+  static void dump(byte[] b, int s, int l){
+    for(int i=s; i<s+l; i++){
+      System.err.print(Integer.toHexString(b[i]&0xff)+":");
+    }
+    System.err.println("");
+  }
+*/
+
+}
diff --git a/java/com/jcraft/jsch/ChangeLog b/java/com/jcraft/jsch/ChangeLog
new file mode 100644
index 0000000..7642c28
--- /dev/null
+++ b/java/com/jcraft/jsch/ChangeLog
@@ -0,0 +1,794 @@
+ChangeLog of JSch
+====================================================================
+Last modified: Thu Feb  2 09:04:04 UTC 2012
+
+	
+Changes since version 0.1.45:
+- bugfix: in the agent forwarding mode, "ssh-add -l" on the remote
+          will freeze.                                                 FIXED
+- bugfix: requests should not be sent to the closed channel.           FIXED
+- bugfix: ChannelShell#setAgentForwarding(true) will cause
+          resource leaks.                                              FIXED
+- change: for the efficiency, channel opening will be delayed
+          in local port forwarding.
+- change: added examples/Sudo.java to demonstrate sudo on exec channel.
+- change: authentication trials will be failed at 6 failures by the default.
+- change: updating copyright messages; 2011 -> 2012
+- feature: added JSch#setIdentityRepository(IdentityRepository irepo) to
+	   integrate with jsch-agent-proxy.
+
+	
+Changes since version 0.1.44:
+- bugfix: fields referred by multiple threads simultaneously should be
+	  volatile.                                                    FIXED 
+- bugfix: use local window size offered by the remote in sftp put.
+                                                                       FIXED 
+- bugfix: SftpProgressMonitor#init was not invoked in sftp-put
+	  for input-stream.                                            FIXED 
+- bugfix: sftp protocol version 3, 4 and 5 should allow only 
+	  UTF-8 encoding.                                              FIXED 
+- bugfix: Channel Subsystem had failed to set X forwarding flag.
+                                                                       FIXED 
+- bugfix: Channel X11 had leaked some resources.
+                                                                       FIXED 
+- bugfix: packet compression may break sessions
+	  in some case(transferring deflated data).                    FIXED 
+- bugfix: failed to set dev-null for logger
+                                                                       FIXED 
+- bugfix: even in sftp protocol version 3 session, some sftpd sends data
+	  packets defined in sftp protocol 6 ;-( working around it.    FIXED 
+- bugfix: ChannelSftp file globbing logic had missed 
+	  the string "foo\\\*bar" as a pattern.                        FIXED 
+- bugfix: sequential accesses to ChannelSftp by multiple threads may
+	  break its I/O channel.
+	  https://bugs.eclipse.org/bugs/show_bug.cgi?id=359184         FIXED 
+- bugfix: KeyPair.load can not handle private keys cyphered with AES.  FIXED
+- change: to improve sftp-put performance, send multiple packet at one time.
+- change: wait/notify will be used instead of sleep loop 
+          in establishing channel connections.
+- change: increasing local window size for sftp get.
+- change: updating copyright messages; 2010 -> 2011
+- change: src/com -> src/main/java/com
+- feature: key-exchange method "diffie-hellman-group14-sha1"
+	  (RFC4253#section-8.2)
+- feature: KeyPair#getPlulicKeyCommment() is added.
+
+	
+Changes since version 0.1.43:
+- bugfix: hmac-md5-96 and hmac-sha1-96 are broken. FIXED.
+- bugfix: working around OOME in parsing broken data from the remote. FIXED.
+- bugfix: failed to send very long command for exec channels. FIXED.
+- bugfix: in some case, failed to get the response 
+	  for remote port-forwarding request.  FIXED.
+- feature: support for private keys ciphered with aes192-cbc and aes128-cbc.
+
+	
+Changes since version 0.1.42:
+- bugfix: the remote window size must be in unsigned int.  FIXED.
+- bugfix: support for EBCDIC environment.  FIXED.
+- bugfix: data may be written to the closed channel.  FIXED.
+- bugfix: NPE in closing channels.  FIXED.
+- bugfix: the private key file may include garbage data before its header.  FIXED.
+- bugfix: the session down may not be detected during the re-keying process.  FIXED.
+- change: try keyboard-interactive auth with the given password if UserInfo is not given.
+- change: working around the wrong auth method list sent by some SSHD 
+          in the partial auth success.
+- change: working around the CPNI-957037 Plain-text Recovery Attack.
+- change: in searching for [host]:non-default port in known_hosts, 
+          host:22 should be also checked.
+- change: updating copyright messages; 2009 -> 2010
+
+	
+Changes since version 0.1.41:
+- bugfix: making exec request during re-keying process will cause 
+	  the dead lock for the session.                        FIXED.
+          Many thanks for PanLi at Prominic dot NET and www.prominic.net, 
+	  US based hosting company.  Without their testing JSch with
+  	  hundreds of hosts and their bug reports, this problem 
+	  was not fixed.
+- change: updating copyright messages; 2008 -> 2009	
+
+	
+Changes since version 0.1.40:
+- bugfix: canceling the remote port-forwarding with the incorrect 
+	  bind-address.                                         FIXED.
+- bugfix: sftp had missed to close the file in some case.       FIXED.
+- bugfix: ls(sftp) will throw an exception for the empty directory
+	  in connecting to some sftpd server.                   FIXED.
+- change: dropping the session gently in accepting incorrect packets.
+- change: by the default, aes128-ctr will be chosen if it is available
+	  on the local and the remote.
+- feature: adding the support for the private key ciphered in AES256.
+- feature: new ciphers: aes128-ctr,aes192-ctr,aes256-ctr,
+	   3des-ctr,arcfour,arcfour128 ,arcfour256
+
+	
+Changes since version 0.1.39:
+- bugfix: ProxySOCKS4 had not been functional.                  FIXED.
+- bugfix: NPE at closing the session when it is not opened.     FIXED.
+- change: JSch#getConfing has become public.
+
+	
+Changes since version 0.1.38:
+- bugfix: session will be dropped at rekeying.                  FIXED.
+- bugfix: NPE should not be thrown at unexpected session drop.  FIXED.
+- change: Channel#getSession() may throw JSchExecption.
+
+		
+Changes since version 0.1.37:
+- bugfix: NPE should not be thrown at unexpected session drop.  FIXED.
+- bugfix: AIOOBE at Session#connect().                         FIXED.
+- bugfix: Even if 'true' is given for
+	    Channel#setOutputStream(OutputStream out, boolean dontclose)
+	  as the second paramter, 'out' will be closed.        FIXED.
+- change: 'examples/Sftp.java' has been modified to demonstrate
+          ChannelSftp#reaplpath(String path)
+- change: setEnv(Hashtable env) for exec and shell channels have been
+	  marked as @deprecated
+- feature: setEnv(String name, String value) has been added to exec
+	   and shell channels.
+- feature: setEnv(byte[] name, byte[] value) has been added to exec
+	   and shell channels.
+- feature: ChannelSftp#realpath(String path) has been added.
+- feature: ChannelExec#setCommand(byte[] command) has been added.
+- feature: com.jcraft.jsch.ChannelSftp.LsEntry has implemented
+	   java.lang.Comparable
+- feature: Session#getServerAliveInterval(), Session#getServerAliveCountMaX()
+	   have been added.
+
+
+Changes since version 0.1.36:
+- bugfix: some sftpd will send invalid data in sftp protocol 
+          point of view, and we need to work around such data. FIXED.
+- bugfix: the stream forwarding had been broken since 0.1.30.  FIXED.
+- bugfix: failed to detect 'SSH_MSG_CHANNEL_OPEN_FAILURE'.     FIXED.
+- bugfix: ChannelSftp will generate the unfavorable absolute pathname
+	  in some case.                                        FIXED.
+- bugfix: failed to ignore the invalid public-key file.        FIXED.
+- change: ignoring empty data sent by 'SSH_MSG_CHANNEL_DATA' and
+           'SSH_MSG_CHANNEL_EXTENDED_DATA'.
+- change: updating copyright messages; 2007 -> 2008
+- change: build.xml will enable 'javac.debug' option by the default.
+- change: added logging messages to IndentityFile and Session class.
+- change: followings are deprecated methods,
+	   InputStream ChannelSftp#get(String src, 
+	                               int mode)
+	   InputStream ChannelSftp#get(String src, 
+	                               SftpProgressMonitor, 
+	                               int mode)
+- feature: following method is added,
+	   InputStream ChannelSftp#get(String src, 
+	                               SftpProgressMonitor monitor, 
+	                               long skip)
+
+	
+Changes since version 0.1.35:			
+- bugfix: ChannelSftp can not handle the local filenames correctly on Windows. FIXED.
+- bugfix: '/' must be handled as the file separator on JVM for Windows.  FIXED.
+- change: the system property
+	    "javax.security.auth.useSubjectCredsOnly"
+	  will be set to "false" for "gssapi-with-mic"
+	  if that property is not given explicitly.
+- change: added changes about ChannelSftp#{pwd(), home()} to
+	  ChangeLog; 'Changes since version 0.1.34:' section.
+	
+	
+Changes since version 0.1.34:			
+- bugfix: the OutputStream from the channel may make the JVM
+	  lockup in some case.                                 FIXED.
+	  There was a possibility that Channel#connect() may be failed 
+	  to initialize its internal without throwing the JSchException.
+	  On such case, the write operation for OutputStream from 
+	  that channel will cause the system(JVM) to lock up.
+- bugfix: ChannelSftp had problems filename globbing.              FIXED.
+- bugfix: the message included in SSH_FXP_STATUS must be UTF-8.    FIXED.
+- change: ChannelSftp supports the filename globbing for 
+	  the filename in multi-byte characters.
+- change: ChannelSftp will internally handle filenames in UTF-8 encoding. 
+- change: ChannelSftp#pwd() may throw an SftpException.
+- change: ChannelSftp#home() may throw an SftpException.
+- feature: following methods have been added in ChannelSftp
+	   String getServerVersion()
+	   String getClientVersion()
+	   void setFilenameEncoding(String encoding)
+	   String getExtension(String key)
+	
+Changes since version 0.1.33:			
+- bugfix: there had a possibility that the session may be broken 
+	  if ciphers for upward/downward streams are different.    FIXED.
+- bugfix: the authentication method "keyboard-interactive" had 
+	  not been tried without UserInfo.                         FIXED.
+- bugfix: ChannelShell#setTerminalMode(byte[] terminal_mode) had 
+	  not been functional.                                     FIXED.
+- bugfix: the remote port-forwarding to the daemon had been broken 
+	  since 0.1.30.                                            FIXED. 
+- change: the cipher "aes128-cbc" will be used if AES is available.
+- change: the interface 'com.jcraft.jsch.ForwardedTCPIPDaemon' has been changed.
+- change: the data transfer rate will be improved on some environment.
+- feature: ChannelExec can control the size of pty;
+	   ChannelExec#setPtySize(int col, int row, int wp, int hp) is
+           added.
+- feature: the property "CheckCiphers" has been added.
+	   Refer to 'examples/AES.java'.
+- feature: Session#setConfig(String key, String value),
+	   JSch#setConfig(String key, String value) have been added.
+
+	
+Changes since version 0.1.32:			
+- bugfix: freeze in 'diffie-hellman-group-exchange-sha1'.          FIXED.
+          By the default, 'diffie-hellman-group1-sha1' will be used
+	  and if you have not chosen 'diffie-hellman-group-exchange-sha1'
+	  explicitly, you don't have to worry about it.
+- bugfix: there should be timeout mechanism in opening a socket
+	  for remote port forwarding.                              FIXED.
+	  At the failure or timeout, 'SSH_MSG_CHANNEL_OPEN_FAILURE'
+	  will be sent to sshd.
+- bugfix: there should be timeout mechanism in opening a socket
+	  for X11 forwarding.                                      FIXED.
+	  At the failure or timeout, 'SSH_MSG_CHANNEL_OPEN_FAILURE'
+          will be sent to sshd.
+
+	
+Changes since version 0.1.31:			
+- bugfix: remote port forwarding will be hanged at its closing.    FIXED.
+- bugfix: X forwarding channels will be hanged and some resources 
+	  will be leaked whenever they are closed.                 FIXED.
+- bugfix: failed to detect "Connection refused".                   FIXED.
+- bugfix: at the failure for keyboard-interactive auth method, 
+	a session will be terminated.                              FIXED.
+- bugfix: due to the cancel for keyboard-interactive auth method, 
+	a session will be terminated.                              FIXED.
+- change: com.jcraft.jsch.jcraft.Compression#uncompress will respect
+	the argument "start".
+- change: "gssapi-with-mic" will choose the default credential.
+- feature: Session#setPortForwardingL will return the assigned local
+	TCP port number; TCP port will be assigned dynamically if lport==0.
+- feature: support for SSH_MSG_UNIMPLEMENTED.
+- feature: support for PASSWD_CHANGEREQ. 
+
+	
+Changes since version 0.1.30:		
+- bugfix: a problem in padding for ciphered private key.  
+	PKCS#5 padding should be used.                             FIXED.
+- bugfix: crash in parsing invalid public key file.                FIXED.
+- bugfix: a public key may not have a comment.                     FIXED.
+- bugfix: output stream from ChannelSftp#put will hang if it is closed
+	  twice.                                                   FIXED.
+- feature: agent forwarding. To enable this functionality,
+	Channel{Exec,Shell,Sftp}#setAgentForwarding(boolean enable) are added.
+- feature: ChannelShell#setTerminalMode(byte[] terminal_mode) is added.
+- feature: Session#setDaemonThread(boolean true) to run internal threads as
+	   daemon threads.
+- feature: an option "PreferredAuthentications" is added.
+	   The default value is "gssapi-with-mic,publickey,keyboard-interactive,password".
+- change: if alias-name is given, non-standard TCP port number will not be
+	  saved in 'known_hosts' file.
+
+Changes since version 0.1.29:		
+- bugfix: ChannelSftp#cd() will not throw an exception even if
+	  a file is given.                                           FIXED.
+- bugfix: ChannelSftp#put() has a bug which will appear in using
+	  on the slow network.                                       FIXED.
+- bugfix: ChannelSftp#ls() has a bug which will appear in using
+	  on the slow network.                                       FIXED.
+- bugfix: a bug had sneaked in the remote port forwarding.           FIXED.
+- bugfix: some APIs from JCE have the memory leak on Mac OS X,
+	  so we have re-written the code(com.jcraft.jsch.jcraft.HMAC*
+	  classes) without them.  On Mac OS X, such new classes will
+	  be used automatically.                                     FIXED.
+- bugfix: the session will be crashed by the long banner message.    FIXED.
+- change: '/dev/random' will not be referred on Gnu/Linux.
+- change: if non-standard TCP port number is used, that number will 
+	  be saved in known_hosts file as recent OpenSSH's ssh client does.
+- change: Channel#getOutputStream will not use Piped{Output,Input}Stream.
+- change: com.jcraft.jsch.HostKeyRepository interface has been
+	  slightly modified.
+- feature: Session#setPortForwardingR(String bind_address, ...) has been added.
+- feature: the packet compression method 'zlib@openssh.com' has been supported.
+- feature: the hashed known_hosts file has been supported.
+	   Refer to 'examples/KnownHosts.java'.
+- feature: the authentication method 'gssapi-with-mic' has been
+ 	   experimentally supported.
+- feature: com.jcraft.jsch.Logger interface and 
+	   JSch#setLogger(Logger logger) have been added.
+	   Refer to 'examples/Logger.java' for the usage.
+
+
+Changes since version 0.1.28:	
+- bugfix: ChannelSftp#put will stack in some situations              FIXED.
+- bugfix: ChannelSftp invoked 'glob_remote' redundantly.             FIXED.
+- bugfix: ChannelSftp failed to make globbing for some file names.    FIXED.
+- bugfix: ChannelSftp did not carefully read its input-stream.       FIXED.
+- bugfix: ChannelSftp#lstat did not try globbing for given path.      FIXED.
+- bugfix: at closing channel, eof_lcoal and eof_remote did not
+          become true.                                               FIXED.
+- bugfix: IdentityFile did not carefully read file input-streams.    FIXED.
+- bugfix: KeyPair did not carefully read file input-streams.         FIXED.
+- bugfix: ProxySOCKS4 did not carefully read file input-streams.     FIXED.
+- bugfix: ProxySOCKS5 did not carefully read file input-streams.     FIXED.
+- bugfix: ForwardedTCPIPDaemom may fail in some situation.           FIXED.
+- bugfix: X forwarding failed to handle the magic-cookie 
+	  in some case                                               FIXED.
+          Thanks to Walter Pfannenmller.
+- bugfix: setKnownHosts in KnownHosts.java doesn't read the last
+	  line if linefeed is missing                                FIXED.
+          Thanks to Henrik Langos.
+- bugfix: With StrictHostKeyChecking set to yes connect()
+          shouldn't ask.                                             FIXED.
+          Thanks to Henrik Langos.
+- change: Identity#setPassphrase(String passphrase) is replaced with
+          Identity#setPassphrase(byte[] passphrase).
+- change: IdentityFile will clear its internal secrets at finalizing.
+- change: KeyPair will clear its internal secrets at finalizing.
+- change: KeyPair will clear its internal secrets at finalizing.
+- change: MAC#doFinal() is replaced with
+          MAC#doFile(byte[] buf, int offset)
+- change: at TCP socket reading timeout, keep-alive message will be sent
+          to the remote sshd.  To disable this functionality, invoke
+          explicitly Session.setServerAliveCountMax(0)
+- change: PortWatcher stops to use InetAddress.getByAddress().
+- change: in the user authentication, username, password and passphrase
+	  will be encoded in UTF-8.
+- change: JSch#addIdentity will check duplicate keys.
+- change: SftpException#message has been deleted.
+- change: SftpException#getMessage() will return the detailed message.
+- feature: IdentityFile#setPassphrase(byte[] passphrase) is added.
+- feature: IdentityFile#clear() is added to clear its internal secrets.
+- feature: KeyPair#decrypt(byte[] passphrase) is added.
+- feature: JSch#addIdentity(String path, byte[] passphrase) is added.
+- feature: JSch#getIdentityNames() is added.
+- feature: JSch#removeIdentity(String name) is added.
+- feature: JSch#removeAllIdentity() is added.
+- feature: ChannelSftp#readlink(String path) is added.
+- feature: ChannelSftp#getHome() is added.
+- feature: Channel#connect(int connectTimeout) is added.
+- feature: ChannelShell#setPtyType(String ttype) is added.
+- feature: Session#setPassword(byte[] password) is added.
+- feature: Session#setHostKeyAlias(String alias) is added.
+- feature: KeepAlive is implemented and 
+	   Session#setServerAliveInterval(int interval) and
+	   Session#setServerAliveCountMax(int count) are added.
+- feature: Session#sendKeepAliveMsg() is added.
+- feature: JSchException#getCause() may return a reason.
+- feature: SftpException#getCause() may return a reason.	
+- feature: ChannelExec#setErrStream(OutputStream out, boolean dontclose)
+           is added.
+	
+
+Changes since version 0.1.27:	
+- bugfix: ChannelSftp#localAbsolutePath did not work correctly.      FIXED.
+- bugfix: ChannelSftp#chmod did not work for directory.              FIXED.
+- bugfix: ProxyHTTP had a bug in processing HTTP headers.            FIXED.
+- bugfix: messages before server's version string should be ignored. FIXED.
+- feature: Environment Variable Passing.
+
+	
+Changes since version 0.1.26:
+- bugfix: there was a session crash bug. That occurrence is rare, but 
+          depends on the thread scheduling.  FIXED.
+- bugfix: problems in generating remote/local absolute paths on sftp.  FIXED.
+- bugfix: problems in handling cancel operations for sftp.  FIXED.
+- bugfix: ChannelX11s were not terminated for a wrong cookie.  FIXED.
+- bugfix: NoSuchAlgorithmException should be thrown if JCE is not 
+	  accessible.  FIXED.
+- bugfix: ProxyHTTP should check the return code from proxy.  FIXED.
+- bugfix: server's version string should be checked carefully.  FIXED.
+- feature: some more improvements on sftp uploading.
+- feature: 'getUserName' method is added to Session class.
+
+	
+Changes since version 0.1.25:		
+- bugfix: infinite loop/hang on connection at unexpected error during
+          key-exchanging operation.  FIXED
+- bugfix: delays on sftp uploading.  FIXED
+- bugfix: failed to purge a host-key from its repository in some case. FIXED.
+- feature: SOCKS4 proxy
+
+	
+Changes since version 0.1.24:		
+- bugfix: remote port forwarding is not established. FIXED. 
+- bugfix: failed to parse known_hosts file if it has a long public key blob.
+ 	  FIXED.
+- bugfix: sftp put/get operations keep failing.  FIXED.
+- bugfix: ChannelShell.setXForwarding always set xforwarding to be true. FIXED.
+- change: ChannelShell.setPty is added.
+- change: Proxy interface is free from session object.
+- change: added examples/ScpToNoneCipher.java to demonstrate NONE Cipher switching.
+- feature: added NONE Cipher switching support.
+- feature: timeout check will be enabled for proxy connections.
+
+	
+Changes since version 0.1.23:		
+- bugfix: there was resource leak problems in closing local port forwardings.
+  	  FIXED. 
+- bugfix: there was a session crash problems in using aes-cbc cipher.  FIXED. 
+- change: ChannelSession.setPtySize was redefined.
+- feature: added SocketFactory for remote port forwarding.
+	   Session.setPortForwardingR(int rport, String host, int lport, 
+	                              SocketFactory sf)
+- feature: added ServerSocketFactory for local port forwarding.	
+	   Session.setPortForwardingL(String boundaddress,
+	                              int lport, String host, int rport,
+	                              ServerSocketFactory ssf)
+
+Changes since version 0.1.22:		
+- bugfix: there was a freeze problem at fails on key-exchanging. FIXED.
+- bugfix: race-condition forcefully disconnects session in closing channels.
+	  FIXED. 
+
+	
+Changes since version 0.1.21:		
+- bugfix: there is a bug in read() method implementation for the
+          input-stream returned from ChannelSftp.get().  FIXED. 
+- bugfix: at fail on requesting for the remote port forwarding,
+	  an exception should be thrown. FIXED. 
+- bugfix: SSH_MSG_CHANNEL_OPEN request for the X11 forwarding should not
+	  be accepted if clients don not expect it. FIXED.
+- bugfix: there is a problem in transferring large data(mote than 1GB)
+	  to sshd from recent OpenSSH(3.6.1 or later). FIXED.
+	  For security concerns, those sshd will re-key periodically and 
+	  jsch had failed to handle it.
+- bugfix: 'exec', 'shell' and 'sftp' channels will fail if the acceptable
+	  packet size by remote sshd is not so large. FIXED.
+- bugfix: there are problems in 'InputStream ChannelSftp.get(String)' 
+   	  and 'OutputStream put(String)'.  FIXED.
+- feature: added boolean flag 'dontclose' to 
+	   * setInputStream(),
+	   * setOutputStream() and
+	   * setExtOutputStream() 
+           methods of Channel class.
+- feature: added 'com.jcraft.jsch.ChannelSubsystem'
+- feature: allowed to control the compression level in the packet compression.
+ 	   Refer to 'examples/Compression.java'.
+- change: modified 'com/jcraft/jsch/jce/KeyPairGenRSA.java' to be complied
+	  on JDK 1.2.
+- change: 'examples/ScpTo.java' and 'examples/ScpFrom.java' will use
+	  'long' type for the file size instead of 'int'.
+- change: 'Identity.getSignature' method will not expect 'session'.
+- change: while waiting for socket connection establishment, Thread.join
+	  will be used instead of Thread.sleep.
+
+
+Changes since version 0.1.20:		
+- known issue: there are problems in 'InputStream ChannelSftp.get(String)' 
+   	       and 'OutputStream put(String)'.  They will be re-implemented
+  	       in the next release.
+- bugfix: EOF packets should not be sent twice. This bug had crashed 
+	  the session on every channel close. FIXED.
+- bugfix: at the fail on opening connection to remote sshd,
+          a misleading exception "invalid server's version string"
+          had been thrown. FIXED.
+- bugfix: fixed a bug in hadling the size of remote channel window.
+- bugfix: channels should not be closed even if EOF is received. FIXED.
+- bugfix: fixed bugs in file name globbing on sftp.
+- change: to transfer packets efficiently, the size of internal buffer
+          for each channel has been increased.
+- change: ChannelSftp.ls will return a vector of 
+	  com.jcraft.jsch.ChannelSftp.LsEntry.  Sorry for inconveniences.
+- feature: added ForwardedTCPIPDaemon.  Refer to 'examples/Daemon.java', 
+           which demonstrates to provide network services like inetd.
+- feature: ChannelExec.setPty() method to request for assigning pseudo tty.
+- feature: added ciphers "aes128-cbc", "aes192-cbc" and "aes256-cbc".
+	   Refer to 'examples/AES.java'.
+- feature: local port-forwarding settings can be dynamically deleted 
+           by the bound address.
+- feature: added 'Channel.isClosed()'. Channel.getExitStatus() should be
+	   invoked after Channel.isClosed()==true.
+
+	
+Changes since version 0.1.19:		
+- ClassCastException while calling ChannelExec.finalize() method. FIXED.
+  Thanks to wswiatek at ais dot pl.
+
+	
+Changes since version 0.1.18:		
+- fixed problems related to thread-safety.
+  Thanks to Eric Meek at cs dot utk dot edu.
+- At the lost of the network connectivity to the remote SSHD,  clients 
+  connected to the local port were never made aware of the
+  disconnection.  FIXED.
+- fixed confusions in handling EOFs from local input stream and 
+  the input stream for remote process.
+- 'com.jcraft.jsch.jce.AES128CBC' is added, but it is not be functional in
+  this release.  It will work in the next release.
+- Some sshd(Foxit-WAC-Serve) waits for SSH_MSG_NEWKEYS request before
+  sending it. FIXED.	
+- fixed a problem in connecting to Cisco Devices.	
+  Thanks to Jason Jeffords at comcast dot net.
+- changed the method 'add' of 'HostKeyRepository' interface.
+- 'UIKeyborarInteracetive' will ignore empty prompt by sshd.
+- added 'sendIgnore()' method to 'Session' class.
+- added '-p' for scp command in 'examples/ScpTo.java' to preserve
+  modification times, access times, and modes from the original file.
+
+	
+Changes since version 0.1.17:		
+- added 'com.jcraft.jsch.HostKeyRepository' interface.
+  It will allow you to handle host keys in your own repository
+  (for example, RDB) instead of using 'known_hosts' file.
+- added methods to get the finger-print of host keys.
+  refer to 'examples/KnownHosts.java'.	
+- improved 'known_hosts' file handling.
+  - comment lines will be kept.
+  - SSH1 host keys will be kept.
+  - each hostname can have multiple host keys.	
+- fixed a crash bug in processing private keys which have too long key-bits.
+
+	
+Changes since version 0.1.16:		
+- 'com.jcraft.jsch.jce.DHG1' and 'com.jcraft.jsch.jce.DHGEX' are moved to
+  'com.jcraft.jsch' package.	 
+- added APIs to handle hostkeys included in 'known_hosts',
+     JSch.getHostKeys(),
+     JSch.removeHostKey()
+- allowing to set timeout value in opening sockets,
+     Session.connect(int timeout)
+
+	
+Changes since version 0.1.15:		
+- adding support of setting mtime for remote files on sftp channel.
+- setKnownHosts method of JSch class will accept InputStream.
+- implementation of Basic password authentication for HTTP proxy.
+- fixed a bug in checking which ssh protocol version remote sshd supports
+- SSH_MSG_CHANNEL_OPEN_FAILURE will be handled correctly.
+- methods in SftpATTRS class has been public.
+- working around SIGBLOB bug hidden in older sshd.
+
+	
+Changes since version 0.1.14:		
+- fixed a crash bug in accepting keep-alive messages.
+- the parent directory of 'known_hosts' file will be created 
+  if it does not exist.
+- the Subsystem channel support was removed.
+
+	
+Changes since version 0.1.13:		
+- added 'setClientVersion' method to Session class.
+- fixed hung-up problem on SftpChannel in connecting to
+  the sshd, which does not support sftp.
+- fixed OutOfMemory exception problem in decrypting a private key
+  with bad passphrase.
+- fixed hung-up problem in communicating with the sshd,
+  whose window size is small.
+- RuntimeExceptions will be thrown from jsch APIs.
+- SSH_MSG_CHANNEL_SUCCESS and SSH_MSG_CHANNEL_FAILURE requests
+  have been supported.
+  	
+	
+Changes since version 0.1.12:	
+- added the partial authentication support.
+- allowing to change the passphrase of a private key file
+  instead of creating a new private key.
+- added 'examples/ChangePassphrase.java' 	
+- the interface 'UIKeyboardInteractive' has been modified.
+
+	
+Changes since version 0.1.11:	
+- RSA keypair generation.
+- added the method 'getFingerPrint' to KeyPair class,
+  which will return the finger print of the public key.
+- fixed a bug in generating non-ciphered private key.
+
+	
+Changes since version 0.1.10:	
+- fixed a bug in the password authentication, sneaked in
+  0.1.9. By this bug, the password authentication had failed every time.
+
+	
+Changes since version 0.1.9:	
+- username and password can be in UTF-8 encoding.
+- DSA keypair generation.
+- added 'examples/KeyGen.java', which demonstrates
+  the DSA keypair generation.
+
+	
+Changes since version 0.1.8:	
+- fixed crash problems on the local port forwarding.
+- fixed crash problems on the remote port forwarding.
+- added setErrStream() and getErrStream() to ChannelExec.
+- added keyboard-interactive authentication support.
+- modified TripleDESCBC to support IBM's JDK 1.4.1.
+- added 'examples/UserAuthKI.java', which demonstrates keyboard-interactive
+  authentication.
+
+	
+Changes since version 0.1.7:	
+- added APIs for sftp resume downloads and uploads.
+  The author greatly appreciates 
+	elpernotador(webmaster at unlix dot com dot ar),
+  who motivated him to hack this functionality.
+- 'examples/Sftp.java' demonstrates sftp resume functionality.
+  Please refer to "put-resume", "put-append", "get-resume" and
+  "get-append" command.
+- added the support of 'window-change' request.
+- fixed a freeze bug in 'Inputstream get(String src)' method of 'ChannelSftp'
+  class.
+
+	
+Changes since version 0.1.6:	
+- added 'int getExitStatus()' method to 'Channel' class.
+- fixed crash bugs in closing channels for port forwarding.
+- fixed glitches in managing forwarded ports.
+
+	
+Changes since version 0.1.5:	
+- fixed crash bugs in port forwarding.
+- modified to use "ssh-rsa" for key-exchanging by the default.
+- the port forwarding setting can be canceled dynamically.
+- fixed a freeze bug in getting an empty file on sftp channel.
+
+	
+Changes since version 0.1.4:	
+- fixed a bug in managing local window size.
+  The local window should be consumed by CHANNEL_EXTENDED_DATA packet.
+- checking the availability of the ssh session in opening channels.
+  In some case, ssh session had been freezed.	
+- java.io.File.separator will be refereed in generating local pathname
+  on sftp channel.
+- absolute local pathname will be handled correctly on sftp channel.
+
+	
+Changes since version 0.1.3:	
+- fixed a serious bug, which had leaked resources related to
+  ChannelExec.	
+- added the older SFTP protocol(version 0, 1, 2) support.
+- fixed a problem in the authentication step for FSecure's sshd.
+- fixed a bug, which had broken Diffie-Hellman key exchange in some case.
+- implemented the file name globbing for local files on sftp session. 
+- fixed a bug in the file name globbing.
+- added an interface 'SftpProgressMonitor'.
+- modified 'examples/Sftp.java' to demonstrate displaying progress-bar
+  in transferring files. 	 
+	
+	
+Changes since version 0.1.2:	
+- modified 'build.xml' to allow Ant users to compile jsch with debug
+  support (i.e. line-number tables) by overriding the property
+  javac.debug on the command line.
+- added a property 'StrictHostKeyChecking'.
+- added 'UserAuthNone' class to request a list of authentication methods on
+  remote sshd.	 
+- channels will be managed in each sessions.
+- added 'ChannelSubsystem', which allows users to use their own
+  implementations for subsystems.
+- added 'isEOF()' method to 'Channel' class.
+- supported key pair files in DOS file format.
+
+	
+Changes since version 0.1.1:	
+- added the file name globbing support on sftp session.
+- fixed a bug in the public key authentication.
+  When there was not a public key in ~/.ssh/, that problem occurred.
+- improved the 'setTimeout' method.
+- fixed a typo in 'LICENSE.txt'
+
+	
+Changes since version 0.1.0:	
+- added 'rekey' method to 'Session' class for key re-exchanging.
+- added 'rekey' and 'compression' command to 'examples/Sftp.java'.
+- added new 'get' and 'put' methods to 'ChannelSftp'.
+  Those methods will operate I/O streams.
+- methods in 'ChannelSftp' will throw 'SftpException'	
+- 'ChannelSftp.Ssh_exp_name' is added for the output of 'ls'.
+  Thanks to Graeme Vetterlein.
+- added 'setTimeout' and 'getTimeout' methods to 'Session' class.
+- guess will be done in the algorithm negotiation step.
+- FSecure's DSA private key has been supported partially.
+- hostkeys will be saved into 'known_hosts' file.
+- fixed a bug in 'Util.toBase64' method.	
+- 'Identity' will reject unrecognized keys.
+- 'build.xml' will check if jzlib is available or not. 
+  Thanks to Stefan Bodewig.	
+- added javadoc target in 'build.xml'.
+  Thanks to Robert Anderson.
+	
+	
+Changes since version 0.0.13:	
+- fixed a bug in connecting to Fsecure's sshd on Windows.
+- the license is changed to BSD style.	
+
+
+Changes since version 0.0.12:	
+- fixed a bug in verifying DAS signatures.
+- added 'SftpATTR' class, which allow you to get attributes of remote files on 
+  sftp channel, and 'stat', 'lstat' method are added to 'ChannelSftp' class.
+- added 'getInputStream' and 'getOutputStream' methods Channel class, which 
+  return passive I/O streams.	 
+- 'setIdentity' method is deleted from 'Session' class and
+  'addIdentity' method is added to 'JSch' class
+- 'setUserName' method is deleted from 'Session' class and
+  'getSession' method of 'JSch' class is changed.
+- 'isConnected' method is added to 'Session' class.
+- 'UserInfo' interface is changed.
+
+	
+Changes since version 0.0.11:	
+- taking care of remote window size.
+- adding 'disconnect' method to 'Channel' and 'Session' classes.
+- signal sending support.
+- 'mkdir' command for sftp.
+- 'fromBase64' method has been moved to Util class and 'toBase64' method has
+   also been added to that class.
+- 'KnownHosts' class for checking host-key in 'known_host' file.
+- 'examples/KnownHosts.java' has been added.
+- 'setUserName' and 'setPassword' methods have been added to Session class.
+- 'UserInfo' interface has been changed.
+- The implementation of compression has moved to 'com.jcraft.jsch.jcraft'
+  package.
+- fixed a bug in handling 'SSH_MSG_CHANNEL_REQUET' request.
+- fixed a bug in sending multiple requests on a single session.
+	
+	
+Changes since version 0.0.10:	
+- Diffie-Hellman key exchange 'diffie-hellman-group1-sha1' is supported.
+  Refer to 'src/com/jcraft/jsch/jce/DHG1.java'.
+  Thanks to Mitsugu Kitano, whose feedback was very helpful.
+- By the default, 'diffie-hellman-group1-sha1' will be used in the
+  key exchange step.
+- The file attribute on 'SSH File Transfer Protocol' is supported.
+  Now, we can say JSch supports 'SSH File Transfer Protocol'.
+- 'examples/Sftp.java' is updated.
+  'chgrp','chown','chmod' commands are supported.
+
+	
+Changes since version 0.0.9:	
+- SSH File Transfer Protocol is supported partially.
+- 'examples/Sftp.java' is added.
+  This example is a tiny sftp command and supports 'cd','put','get','rm',etc.
+- 'close' method is added to Channel interface.	
+- build.xml for examples is added.
+  Thanks to Ronald Broberg.
+
+	
+Changes since version 0.0.8:	
+- the tunneling through a SOCKS5 proxy is supported.
+- 'examples/ScpFrom.java' is added.
+- 'com.jcraft.jsch.UserInfo' interface is modified.
+
+	
+Changes since version 0.0.7:	
+- Packet comression is supported.
+- 'examples/Compression.java' is added.
+- JZlib is included.
+
+	
+Changes since version 0.0.6:	
+- RSA host key is supported.
+- RSA public key authentication is supported.
+
+
+Changes since version 0.0.5:	
+- DSA public key authentication is supported.
+- examples/UserAuthPubKey.java is added.
+- examples/ScpTo.java is added.
+	
+
+Changes since version 0.0.4:	
+- 3des-cbc is supported.
+- hmac-sha1 is supported.
+- hmac-md5-96 is supported.
+- hmac-sha1-96 is supported.	
+	
+
+Changes since version 0.0.3:	
+- port forwarding, similar to the -L option of SSH.
+- examples/PortForwardingL.java is added.
+- examples/StreamForwarding.java is added.
+- examples/Exec.java is renamed as examples/Shell.java
+- stream forwarding is added.
+- ChannelSftp class is added for implementing filexfer.
+- interfaces for jsch users are changed.
+	
+
+Changes since version 0.0.2:	
+- remote exec is supported.	
+- examples/Exec.java is added.
+- build.xml and some scripts for Ant are added. (lbruand)
+- Const class is added. (lbruand)
+
+	
+Changes since version 0.0.1:
+- the tunneling via HTTP proxy is supported.
+- port forwarding like option -R of ssh command.
+  the given port on the remote host will be forwarded to the given host
+  and port on the local side.	
diff --git a/java/com/jcraft/jsch/Channel.java b/java/com/jcraft/jsch/Channel.java
new file mode 100644
index 0000000..669b575
--- /dev/null
+++ b/java/com/jcraft/jsch/Channel.java
@@ -0,0 +1,677 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.IOException;
+
+
+public abstract class Channel implements Runnable{
+
+  static final int SSH_MSG_CHANNEL_OPEN_CONFIRMATION=      91;
+  static final int SSH_MSG_CHANNEL_OPEN_FAILURE=           92;
+  static final int SSH_MSG_CHANNEL_WINDOW_ADJUST=          93;
+
+  static final int SSH_OPEN_ADMINISTRATIVELY_PROHIBITED=    1;
+  static final int SSH_OPEN_CONNECT_FAILED=                 2;
+  static final int SSH_OPEN_UNKNOWN_CHANNEL_TYPE=           3;
+  static final int SSH_OPEN_RESOURCE_SHORTAGE=              4;
+
+  static int index=0; 
+  private static java.util.Vector pool=new java.util.Vector();
+  static Channel getChannel(String type){
+    if(type.equals("session")){
+      return new ChannelSession();
+    }
+    if(type.equals("shell")){
+      return new ChannelShell();
+    }
+    if(type.equals("exec")){
+      return new ChannelExec();
+    }
+    if(type.equals("x11")){
+      return new ChannelX11();
+    }
+    if(type.equals("auth-agent@openssh.com")){
+      return new ChannelAgentForwarding();
+    }
+    if(type.equals("direct-tcpip")){
+      return new ChannelDirectTCPIP();
+    }
+    if(type.equals("forwarded-tcpip")){
+      return new ChannelForwardedTCPIP();
+    }
+    if(type.equals("sftp")){
+      return new ChannelSftp();
+    }
+    if(type.equals("subsystem")){
+      return new ChannelSubsystem();
+    }
+    return null;
+  }
+  static Channel getChannel(int id, Session session){
+    synchronized(pool){
+      for(int i=0; i<pool.size(); i++){
+        Channel c=(Channel)(pool.elementAt(i));
+        if(c.id==id && c.session==session) return c;
+      }
+    }
+    return null;
+  }
+  static void del(Channel c){
+    synchronized(pool){
+      pool.removeElement(c);
+    }
+  }
+
+  int id;
+  volatile int recipient=-1;
+  protected byte[] type=Util.str2byte("foo");
+  volatile int lwsize_max=0x100000;
+  volatile int lwsize=lwsize_max;     // local initial window size
+  volatile int lmpsize=0x4000;     // local maximum packet size
+
+  volatile long rwsize=0;         // remote initial window size
+  volatile int rmpsize=0;        // remote maximum packet size
+
+  IO io=null;    
+  Thread thread=null;
+
+  volatile boolean eof_local=false;
+  volatile boolean eof_remote=false;
+
+  volatile boolean close=false;
+  volatile boolean connected=false;
+  volatile boolean open_confirmation=false;
+
+  volatile int exitstatus=-1;
+
+  volatile int reply=0; 
+  volatile int connectTimeout=0;
+
+  private Session session;
+
+  int notifyme=0; 
+
+  Channel(){
+    synchronized(pool){
+      id=index++;
+      pool.addElement(this);
+    }
+  }
+  synchronized void setRecipient(int foo){
+    this.recipient=foo;
+    if(notifyme>0)
+      notifyAll();
+  }
+  int getRecipient(){
+    return recipient;
+  }
+
+  void init() throws JSchException {
+  }
+
+  public void connect() throws JSchException{
+    connect(0);
+  }
+
+  public void connect(int connectTimeout) throws JSchException{
+    this.connectTimeout=connectTimeout;
+    try{
+      sendChannelOpen();
+      start();
+    }
+    catch(Exception e){
+      connected=false;
+      disconnect();
+      if(e instanceof JSchException) 
+        throw (JSchException)e;
+      throw new JSchException(e.toString(), e);
+    }
+  }
+
+  public void setXForwarding(boolean foo){
+  }
+
+  public void start() throws JSchException{}
+
+  public boolean isEOF() {return eof_remote;}
+
+  void getData(Buffer buf){
+    setRecipient(buf.getInt());
+    setRemoteWindowSize(buf.getUInt());
+    setRemotePacketSize(buf.getInt());
+  }
+
+  public void setInputStream(InputStream in){
+    io.setInputStream(in, false);
+  }
+  public void setInputStream(InputStream in, boolean dontclose){
+    io.setInputStream(in, dontclose);
+  }
+  public void setOutputStream(OutputStream out){
+    io.setOutputStream(out, false);
+  }
+  public void setOutputStream(OutputStream out, boolean dontclose){
+    io.setOutputStream(out, dontclose);
+  }
+  public void setExtOutputStream(OutputStream out){
+    io.setExtOutputStream(out, false);
+  }
+  public void setExtOutputStream(OutputStream out, boolean dontclose){
+    io.setExtOutputStream(out, dontclose);
+  }
+  public InputStream getInputStream() throws IOException {
+    PipedInputStream in=
+      new MyPipedInputStream(
+                             32*1024  // this value should be customizable.
+                             );
+    io.setOutputStream(new PassiveOutputStream(in), false);
+    return in;
+  }
+  public InputStream getExtInputStream() throws IOException {
+    PipedInputStream in=
+      new MyPipedInputStream(
+                             32*1024  // this value should be customizable.
+                             );
+    io.setExtOutputStream(new PassiveOutputStream(in), false);
+    return in;
+  }
+  public OutputStream getOutputStream() throws IOException {
+    /*
+    PipedOutputStream out=new PipedOutputStream();
+    io.setInputStream(new PassiveInputStream(out
+                                             , 32*1024
+                                             ), false);
+    return out;
+    */
+
+    final Channel channel=this;
+    OutputStream out=new OutputStream(){
+        private int dataLen=0;
+        private Buffer buffer=null;
+        private Packet packet=null;
+        private boolean closed=false;
+        private synchronized void init() throws java.io.IOException{
+          buffer=new Buffer(rmpsize);
+          packet=new Packet(buffer);
+
+          byte[] _buf=buffer.buffer;
+          if(_buf.length-(14+0)-Session.buffer_margin<=0){
+            buffer=null;
+            packet=null;
+            throw new IOException("failed to initialize the channel.");
+          }
+
+        }
+        byte[] b=new byte[1];
+        public void write(int w) throws java.io.IOException{
+          b[0]=(byte)w;
+          write(b, 0, 1);
+        }
+        public void write(byte[] buf, int s, int l) throws java.io.IOException{
+          if(packet==null){
+            init();
+          }
+
+          if(closed){
+            throw new java.io.IOException("Already closed");
+          }
+
+          byte[] _buf=buffer.buffer;
+          int _bufl=_buf.length;
+          while(l>0){
+            int _l=l;
+            if(l>_bufl-(14+dataLen)-Session.buffer_margin){
+              _l=_bufl-(14+dataLen)-Session.buffer_margin;
+            }
+
+            if(_l<=0){
+              flush();
+              continue;
+            }
+
+            System.arraycopy(buf, s, _buf, 14+dataLen, _l);
+            dataLen+=_l;
+            s+=_l;
+            l-=_l;
+          }
+        }
+
+        public void flush() throws java.io.IOException{
+          if(closed){
+            throw new java.io.IOException("Already closed");
+          }
+          if(dataLen==0)
+            return;
+          packet.reset();
+          buffer.putByte((byte)Session.SSH_MSG_CHANNEL_DATA);
+          buffer.putInt(recipient);
+          buffer.putInt(dataLen);
+          buffer.skip(dataLen);
+          try{
+            int foo=dataLen;
+            dataLen=0;
+            synchronized(channel){
+              if(!channel.close)
+                getSession().write(packet, channel, foo);
+            }
+          }
+          catch(Exception e){
+            close();
+            throw new java.io.IOException(e.toString());
+          }
+
+        }
+        public void close() throws java.io.IOException{
+          if(packet==null){
+            try{
+              init();
+            }
+            catch(java.io.IOException e){
+              // close should be finished silently.
+              return;
+            }
+          }
+          if(closed){
+            return;
+          }
+          if(dataLen>0){
+            flush();
+          }
+          channel.eof();
+          closed=true;
+        }
+      };
+    return out;
+  }
+
+  class MyPipedInputStream extends PipedInputStream{
+    MyPipedInputStream() throws IOException{ super(); }
+    MyPipedInputStream(int size) throws IOException{
+      super();
+      buffer=new byte[size];
+    }
+    MyPipedInputStream(PipedOutputStream out) throws IOException{ super(out); }
+    MyPipedInputStream(PipedOutputStream out, int size) throws IOException{
+      super(out);
+      buffer=new byte[size];
+    }
+
+    /*
+     * TODO: We should have our own Piped[I/O]Stream implementation.
+     * Before accepting data, JDK's PipedInputStream will check the existence of
+     * reader thread, and if it is not alive, the stream will be closed.
+     * That behavior may cause the problem if multiple threads make access to it.
+     */
+    public synchronized void updateReadSide() throws IOException {
+      if(available() != 0){ // not empty
+        return;
+      }
+      in = 0;
+      out = 0;
+      buffer[in++] = 0;
+      read();
+    }
+  }
+  void setLocalWindowSizeMax(int foo){ this.lwsize_max=foo; }
+  void setLocalWindowSize(int foo){ this.lwsize=foo; }
+  void setLocalPacketSize(int foo){ this.lmpsize=foo; }
+  synchronized void setRemoteWindowSize(long foo){ this.rwsize=foo; }
+  synchronized void addRemoteWindowSize(int foo){ 
+    this.rwsize+=foo; 
+    if(notifyme>0)
+      notifyAll();
+  }
+  void setRemotePacketSize(int foo){ this.rmpsize=foo; }
+
+  public void run(){
+  }
+
+  void write(byte[] foo) throws IOException {
+    write(foo, 0, foo.length);
+  }
+  void write(byte[] foo, int s, int l) throws IOException {
+    try{
+      io.put(foo, s, l);
+    }catch(NullPointerException e){}
+  }
+  void write_ext(byte[] foo, int s, int l) throws IOException {
+    try{
+      io.put_ext(foo, s, l);
+    }catch(NullPointerException e){}
+  }
+
+  void eof_remote(){
+    eof_remote=true;
+    try{
+      io.out_close();
+    }
+    catch(NullPointerException e){}
+  }
+
+  void eof(){
+    if(eof_local)return;
+    eof_local=true;
+
+    try{
+      Buffer buf=new Buffer(100);
+      Packet packet=new Packet(buf);
+      packet.reset();
+      buf.putByte((byte)Session.SSH_MSG_CHANNEL_EOF);
+      buf.putInt(getRecipient());
+      synchronized(this){
+        if(!close)
+          getSession().write(packet);
+      }
+    }
+    catch(Exception e){
+      //System.err.println("Channel.eof");
+      //e.printStackTrace();
+    }
+    /*
+    if(!isConnected()){ disconnect(); }
+    */
+  }
+
+  /*
+  http://www1.ietf.org/internet-drafts/draft-ietf-secsh-connect-24.txt
+
+5.3  Closing a Channel
+  When a party will no longer send more data to a channel, it SHOULD
+   send SSH_MSG_CHANNEL_EOF.
+
+            byte      SSH_MSG_CHANNEL_EOF
+            uint32    recipient_channel
+
+  No explicit response is sent to this message.  However, the
+   application may send EOF to whatever is at the other end of the
+  channel.  Note that the channel remains open after this message, and
+   more data may still be sent in the other direction.  This message
+   does not consume window space and can be sent even if no window space
+   is available.
+
+     When either party wishes to terminate the channel, it sends
+     SSH_MSG_CHANNEL_CLOSE.  Upon receiving this message, a party MUST
+   send back a SSH_MSG_CHANNEL_CLOSE unless it has already sent this
+   message for the channel.  The channel is considered closed for a
+     party when it has both sent and received SSH_MSG_CHANNEL_CLOSE, and
+   the party may then reuse the channel number.  A party MAY send
+   SSH_MSG_CHANNEL_CLOSE without having sent or received
+   SSH_MSG_CHANNEL_EOF.
+
+            byte      SSH_MSG_CHANNEL_CLOSE
+            uint32    recipient_channel
+
+   This message does not consume window space and can be sent even if no
+   window space is available.
+
+   It is recommended that any data sent before this message is delivered
+     to the actual destination, if possible.
+  */
+
+  void close(){
+    if(close)return;
+    close=true;
+    eof_local=eof_remote=true;
+
+    try{
+      Buffer buf=new Buffer(100);
+      Packet packet=new Packet(buf);
+      packet.reset();
+      buf.putByte((byte)Session.SSH_MSG_CHANNEL_CLOSE);
+      buf.putInt(getRecipient());
+      synchronized(this){
+        getSession().write(packet);
+      }
+    }
+    catch(Exception e){
+      //e.printStackTrace();
+    }
+  }
+  public boolean isClosed(){
+    return close;
+  }
+  static void disconnect(Session session){
+    Channel[] channels=null;
+    int count=0;
+    synchronized(pool){
+      channels=new Channel[pool.size()];
+      for(int i=0; i<pool.size(); i++){
+	try{
+	  Channel c=((Channel)(pool.elementAt(i)));
+	  if(c.session==session){
+	    channels[count++]=c;
+	  }
+	}
+	catch(Exception e){
+	}
+      } 
+    }
+    for(int i=0; i<count; i++){
+      channels[i].disconnect();
+    }
+  }
+
+  public void disconnect(){
+    //System.err.println(this+":disconnect "+io+" "+connected);
+    //Thread.dumpStack();
+
+    try{
+
+      synchronized(this){
+        if(!connected){
+          return;
+        }
+        connected=false;
+      }
+
+      close();
+
+      eof_remote=eof_local=true;
+
+      thread=null;
+
+      try{
+        if(io!=null){
+          io.close();
+        }
+      }
+      catch(Exception e){
+        //e.printStackTrace();
+      }
+      // io=null;
+    }
+    finally{
+      Channel.del(this);
+    }
+  }
+
+  public boolean isConnected(){
+    Session _session=this.session;
+    if(_session!=null){
+      return _session.isConnected() && connected;
+    }
+    return false;
+  }
+
+  public void sendSignal(String signal) throws Exception {
+    RequestSignal request=new RequestSignal();
+    request.setSignal(signal);
+    request.request(getSession(), this);
+  }
+
+//  public String toString(){
+//      return "Channel: type="+new String(type)+",id="+id+",recipient="+recipient+",window_size="+window_size+",packet_size="+packet_size;
+//  }
+
+/*
+  class OutputThread extends Thread{
+    Channel c;
+    OutputThread(Channel c){ this.c=c;}
+    public void run(){c.output_thread();}
+  }
+*/
+
+  class PassiveInputStream extends MyPipedInputStream{
+    PipedOutputStream out;
+    PassiveInputStream(PipedOutputStream out, int size) throws IOException{
+      super(out, size);
+      this.out=out;
+    }
+    PassiveInputStream(PipedOutputStream out) throws IOException{
+      super(out);
+      this.out=out;
+    }
+    public void close() throws IOException{
+      if(out!=null){
+        this.out.close();
+      }
+      out=null;
+    }
+  }
+  class PassiveOutputStream extends PipedOutputStream{
+    PassiveOutputStream(PipedInputStream in) throws IOException{
+      super(in);
+    }
+  }
+
+  void setExitStatus(int status){ exitstatus=status; }
+  public int getExitStatus(){ return exitstatus; }
+
+  void setSession(Session session){
+    this.session=session;
+  }
+
+  public Session getSession() throws JSchException{ 
+    Session _session=session;
+    if(_session==null){
+      throw new JSchException("session is not available");
+    }
+    return _session;
+  }
+  public int getId(){ return id; }
+
+  protected void sendOpenConfirmation() throws Exception{
+    Buffer buf=new Buffer(100);
+    Packet packet=new Packet(buf);
+    packet.reset();
+    buf.putByte((byte)SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
+    buf.putInt(getRecipient());
+    buf.putInt(id);
+    buf.putInt(lwsize);
+    buf.putInt(lmpsize);
+    getSession().write(packet);
+  }
+
+  protected void sendOpenFailure(int reasoncode){
+    try{
+      Buffer buf=new Buffer(100);
+      Packet packet=new Packet(buf);
+      packet.reset();
+      buf.putByte((byte)SSH_MSG_CHANNEL_OPEN_FAILURE);
+      buf.putInt(getRecipient());
+      buf.putInt(reasoncode);
+      buf.putString(Util.str2byte("open failed"));
+      buf.putString(Util.empty);
+      getSession().write(packet);
+    }
+    catch(Exception e){
+    }
+  }
+
+  protected Packet genChannelOpenPacket(){
+    Buffer buf=new Buffer(100);
+    Packet packet=new Packet(buf);
+    // byte   SSH_MSG_CHANNEL_OPEN(90)
+    // string channel type         //
+    // uint32 sender channel       // 0
+    // uint32 initial window size  // 0x100000(65536)
+    // uint32 maxmum packet size   // 0x4000(16384)
+    packet.reset();
+    buf.putByte((byte)90);
+    buf.putString(this.type);
+    buf.putInt(this.id);
+    buf.putInt(this.lwsize);
+    buf.putInt(this.lmpsize);
+    return packet;
+  }
+
+  protected void sendChannelOpen() throws Exception {
+    Session _session=getSession();
+    if(!_session.isConnected()){
+      throw new JSchException("session is down");
+    }
+
+    Packet packet = genChannelOpenPacket();
+    _session.write(packet);
+
+    int retry=10;
+    long start=System.currentTimeMillis();
+    long timeout=connectTimeout;
+    if(timeout!=0L) retry = 1;
+    synchronized(this){
+      while(this.getRecipient()==-1 &&
+            _session.isConnected() &&
+             retry>0){
+        if(timeout>0L){
+          if((System.currentTimeMillis()-start)>timeout){
+            retry=0;
+            continue;
+          }
+        }
+        try{
+          long t = timeout==0L ? 5000L : timeout;
+          this.notifyme=1;
+          wait(t);
+        }
+        catch(java.lang.InterruptedException e){
+        }
+        finally{
+          this.notifyme=0;
+        }
+        retry--;
+      }
+    }
+    if(!_session.isConnected()){
+      throw new JSchException("session is down");
+    }
+    if(this.getRecipient()==-1){  // timeout
+      throw new JSchException("channel is not opened.");
+    }
+    if(this.open_confirmation==false){  // SSH_MSG_CHANNEL_OPEN_FAILURE
+      throw new JSchException("channel is not opened.");
+    }
+    connected=true;
+  }
+}
diff --git a/java/com/jcraft/jsch/ChannelAgentForwarding.java b/java/com/jcraft/jsch/ChannelAgentForwarding.java
new file mode 100644
index 0000000..9788d90
--- /dev/null
+++ b/java/com/jcraft/jsch/ChannelAgentForwarding.java
@@ -0,0 +1,266 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2006-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+import java.net.*;
+import java.util.Vector;
+
+class ChannelAgentForwarding extends Channel{
+
+  static private final int LOCAL_WINDOW_SIZE_MAX=0x20000;
+  static private final int LOCAL_MAXIMUM_PACKET_SIZE=0x4000;
+
+  private final byte SSH_AGENTC_REQUEST_RSA_IDENTITIES = 1;
+  private final byte SSH_AGENT_RSA_IDENTITIES_ANSWER = 2;
+  private final byte SSH_AGENTC_RSA_CHALLENGE = 3;
+  private final byte SSH_AGENT_RSA_RESPONSE = 4;
+  private final byte SSH_AGENT_FAILURE = 5;
+  private final byte SSH_AGENT_SUCCESS = 6;
+  private final byte SSH_AGENTC_ADD_RSA_IDENTITY	= 7;
+  private final byte SSH_AGENTC_REMOVE_RSA_IDENTITY = 8;
+  private final byte SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES = 9;
+
+  private final byte SSH2_AGENTC_REQUEST_IDENTITIES=11;
+  private final byte SSH2_AGENT_IDENTITIES_ANSWER=12;
+  private final byte SSH2_AGENTC_SIGN_REQUEST=13;
+  private final byte SSH2_AGENT_SIGN_RESPONSE=14;
+  private final byte SSH2_AGENTC_ADD_IDENTITY=17;
+  private final byte SSH2_AGENTC_REMOVE_IDENTITY=18;
+  private final byte SSH2_AGENTC_REMOVE_ALL_IDENTITIES=19;
+  private final byte SSH2_AGENT_FAILURE=30;
+
+  boolean init=true;
+
+  private Buffer rbuf=null;
+  private Buffer wbuf=null;
+  private Packet packet=null;
+  private Buffer mbuf=null;
+
+  ChannelAgentForwarding(){
+    super();
+
+    setLocalWindowSizeMax(LOCAL_WINDOW_SIZE_MAX);
+    setLocalWindowSize(LOCAL_WINDOW_SIZE_MAX);
+    setLocalPacketSize(LOCAL_MAXIMUM_PACKET_SIZE);
+
+    type=Util.str2byte("auth-agent@openssh.com");
+    rbuf=new Buffer();
+    rbuf.reset();
+    //wbuf=new Buffer(rmpsize);
+    //packet=new Packet(wbuf);
+    mbuf=new Buffer();
+    connected=true;
+  }
+
+  public void run(){
+    try{
+      sendOpenConfirmation();
+    }
+    catch(Exception e){
+      close=true;
+      disconnect();
+    }
+  }
+
+  void write(byte[] foo, int s, int l) throws java.io.IOException {
+
+    if(packet==null){
+      wbuf=new Buffer(rmpsize);
+      packet=new Packet(wbuf);
+    }
+
+    rbuf.shift();
+    if(rbuf.buffer.length<rbuf.index+l){
+      byte[] newbuf=new byte[rbuf.s+l];
+      System.arraycopy(rbuf.buffer, 0, newbuf, 0, rbuf.buffer.length);
+      rbuf.buffer=newbuf;
+    }
+
+    rbuf.putByte(foo, s, l);
+
+    int mlen=rbuf.getInt();
+    if(mlen>rbuf.getLength()){
+      rbuf.s-=4;
+      return;
+    }
+
+    int typ=rbuf.getByte();
+
+    Session _session=null;
+    try{
+      _session=getSession();
+    }
+    catch(JSchException e){
+      throw new java.io.IOException(e.toString());
+    }
+
+    IdentityRepository irepo = _session.jsch.getIdentityRepository();
+    UserInfo userinfo=_session.getUserInfo();
+
+    mbuf.reset();
+
+    if(typ==SSH2_AGENTC_REQUEST_IDENTITIES){ 
+      mbuf.putByte(SSH2_AGENT_IDENTITIES_ANSWER);
+      Vector identities = irepo.getIdentities();
+      synchronized(identities){
+        int count=0;
+        for(int i=0; i<identities.size(); i++){
+          Identity identity=(Identity)(identities.elementAt(i));
+          if(identity.getPublicKeyBlob()!=null)
+            count++;
+        }
+        mbuf.putInt(count);
+        for(int i=0; i<identities.size(); i++){
+          Identity identity=(Identity)(identities.elementAt(i));
+          byte[] pubkeyblob=identity.getPublicKeyBlob();
+          if(pubkeyblob==null)
+            continue;
+          mbuf.putString(pubkeyblob);
+          mbuf.putString(Util.empty);
+        }
+      }
+    }
+    else if(typ==SSH_AGENTC_REQUEST_RSA_IDENTITIES) {
+      mbuf.putByte(SSH_AGENT_RSA_IDENTITIES_ANSWER);
+      mbuf.putInt(0);
+    }
+    else if(typ==SSH2_AGENTC_SIGN_REQUEST){
+      byte[] blob=rbuf.getString();
+      byte[] data=rbuf.getString();
+      int flags=rbuf.getInt();
+
+//      if((flags & 1)!=0){ //SSH_AGENT_OLD_SIGNATURE // old OpenSSH 2.0, 2.1
+//        datafellows = SSH_BUG_SIGBLOB;
+//      }
+
+      Vector identities = irepo.getIdentities();
+      Identity identity = null;
+      synchronized(identities){
+        for(int i=0; i<identities.size(); i++){
+          Identity _identity=(Identity)(identities.elementAt(i));
+          if(_identity.getPublicKeyBlob()==null)
+            continue;
+          if(!Util.array_equals(blob, _identity.getPublicKeyBlob())){
+            continue;
+          }
+          if(_identity.isEncrypted()){
+            if(userinfo==null)
+              continue;
+            while(_identity.isEncrypted()){
+              if(!userinfo.promptPassphrase("Passphrase for "+_identity.getName())){
+                break;
+              }
+
+              String _passphrase=userinfo.getPassphrase();
+              if(_passphrase==null){
+                break;
+              }
+
+              byte[] passphrase=Util.str2byte(_passphrase);
+              try{
+                if(_identity.setPassphrase(passphrase)){
+                  break;
+                }
+              }
+              catch(JSchException e){
+                break;
+              }
+            }
+          }
+
+          if(!_identity.isEncrypted()){
+            identity=_identity;
+            break;
+          }
+        }
+      }
+
+      byte[] signature=null;
+
+      if(identity!=null){
+        signature=identity.getSignature(data);
+      }
+
+      if(signature==null){
+        mbuf.putByte(SSH2_AGENT_FAILURE);
+      }
+      else{
+        mbuf.putByte(SSH2_AGENT_SIGN_RESPONSE);
+        mbuf.putString(signature);
+      }
+    }
+    else if(typ==SSH2_AGENTC_REMOVE_IDENTITY){
+      byte[] blob=rbuf.getString();
+      irepo.remove(blob);
+      mbuf.putByte(SSH_AGENT_SUCCESS);
+    }
+    else if(typ==SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES){
+      mbuf.putByte(SSH_AGENT_SUCCESS);
+    }
+    else if(typ==SSH2_AGENTC_REMOVE_ALL_IDENTITIES){
+      irepo.removeAll();
+      mbuf.putByte(SSH_AGENT_SUCCESS);
+    }
+    else if(typ==SSH2_AGENTC_ADD_IDENTITY){
+      int fooo = rbuf.getLength();
+      byte[] tmp = new byte[fooo];
+      rbuf.getByte(tmp);
+      boolean result = irepo.add(tmp);
+      mbuf.putByte(result ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
+    }
+    else {
+      rbuf.skip(rbuf.getLength()-1);
+      mbuf.putByte(SSH_AGENT_FAILURE);
+    }
+
+    byte[] response = new byte[mbuf.getLength()];
+    mbuf.getByte(response);
+    send(response);
+  }
+
+  private void send(byte[] message){
+    packet.reset();
+    wbuf.putByte((byte)Session.SSH_MSG_CHANNEL_DATA);
+    wbuf.putInt(recipient);
+    wbuf.putInt(4+message.length);
+    wbuf.putString(message);
+
+    try{
+      getSession().write(packet, this, 4+message.length);
+    }
+    catch(Exception e){
+    }
+  }
+
+  void eof_remote(){
+    super.eof_remote();
+    eof();
+  }
+}
diff --git a/java/com/jcraft/jsch/ChannelDirectTCPIP.java b/java/com/jcraft/jsch/ChannelDirectTCPIP.java
new file mode 100644
index 0000000..c8af6a2
--- /dev/null
+++ b/java/com/jcraft/jsch/ChannelDirectTCPIP.java
@@ -0,0 +1,155 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+import java.io.*;
+
+public class ChannelDirectTCPIP extends Channel{
+
+  static private final int LOCAL_WINDOW_SIZE_MAX=0x20000;
+  static private final int LOCAL_MAXIMUM_PACKET_SIZE=0x4000;
+  static private final byte[] _type = Util.str2byte("direct-tcpip");
+  String host;
+  int port;
+
+  String originator_IP_address="127.0.0.1";
+  int originator_port=0;
+
+  ChannelDirectTCPIP(){
+    super();
+    type = _type;
+    setLocalWindowSizeMax(LOCAL_WINDOW_SIZE_MAX);
+    setLocalWindowSize(LOCAL_WINDOW_SIZE_MAX);
+    setLocalPacketSize(LOCAL_MAXIMUM_PACKET_SIZE);
+  }
+
+  void init (){
+    io=new IO();
+  }
+
+  public void connect() throws JSchException{
+    try{
+      Session _session=getSession();
+      if(!_session.isConnected()){
+        throw new JSchException("session is down");
+      }
+
+      if(io.in!=null){
+        thread=new Thread(this);
+        thread.setName("DirectTCPIP thread "+_session.getHost());
+        if(_session.daemon_thread){
+          thread.setDaemon(_session.daemon_thread);
+        }
+        thread.start();
+      }
+    }
+    catch(Exception e){
+      io.close();
+      io=null;
+      Channel.del(this);
+      if (e instanceof JSchException) {
+        throw (JSchException) e;
+      }
+    }
+  }
+
+  public void run(){
+
+    try{
+      sendChannelOpen();
+
+      Buffer buf=new Buffer(rmpsize);
+      Packet packet=new Packet(buf);
+      Session _session=getSession();
+      int i=0;
+
+      while(isConnected() &&
+            thread!=null && 
+            io!=null && 
+            io.in!=null){
+        i=io.in.read(buf.buffer, 
+                     14, 
+                     buf.buffer.length-14
+                     -Session.buffer_margin
+                     );
+        if(i<=0){
+          eof();
+          break;
+        }
+        packet.reset();
+        buf.putByte((byte)Session.SSH_MSG_CHANNEL_DATA);
+        buf.putInt(recipient);
+        buf.putInt(i);
+        buf.skip(i);
+        synchronized(this){
+          if(close)
+            break;
+          _session.write(packet, this, i);
+        }
+      }
+    }
+    catch(Exception e){
+    }
+    disconnect();
+  }
+
+  public void setInputStream(InputStream in){
+    io.setInputStream(in);
+  }
+  public void setOutputStream(OutputStream out){
+    io.setOutputStream(out);
+  }
+
+  public void setHost(String host){this.host=host;}
+  public void setPort(int port){this.port=port;}
+  public void setOrgIPAddress(String foo){this.originator_IP_address=foo;}
+  public void setOrgPort(int foo){this.originator_port=foo;}
+
+  protected Packet genChannelOpenPacket(){
+    Buffer buf = new Buffer(150);
+    Packet packet = new Packet(buf);
+    // byte   SSH_MSG_CHANNEL_OPEN(90)
+    // string channel type         //
+    // uint32 sender channel       // 0
+    // uint32 initial window size  // 0x100000(65536)
+    // uint32 maxmum packet size   // 0x4000(16384)
+    packet.reset();
+    buf.putByte((byte)90);
+    buf.putString(this.type);
+    buf.putInt(id);
+    buf.putInt(lwsize);
+    buf.putInt(lmpsize);
+    buf.putString(Util.str2byte(host));
+    buf.putInt(port);
+    buf.putString(Util.str2byte(originator_IP_address));
+    buf.putInt(originator_port);
+    return packet;
+  }
+}
diff --git a/java/com/jcraft/jsch/ChannelExec.java b/java/com/jcraft/jsch/ChannelExec.java
new file mode 100644
index 0000000..45322b6
--- /dev/null
+++ b/java/com/jcraft/jsch/ChannelExec.java
@@ -0,0 +1,83 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+import java.util.*;
+
+public class ChannelExec extends ChannelSession{
+
+  byte[] command=new byte[0];
+
+  public void start() throws JSchException{
+    Session _session=getSession();
+    try{
+      sendRequests();
+      Request request=new RequestExec(command);
+      request.request(_session, this);
+    }
+    catch(Exception e){
+      if(e instanceof JSchException) throw (JSchException)e;
+      if(e instanceof Throwable)
+        throw new JSchException("ChannelExec", (Throwable)e);
+      throw new JSchException("ChannelExec");
+    }
+
+    if(io.in!=null){
+      thread=new Thread(this);
+      thread.setName("Exec thread "+_session.getHost());
+      if(_session.daemon_thread){
+        thread.setDaemon(_session.daemon_thread);
+      }
+      thread.start();
+    }
+  }
+
+  public void setCommand(String command){ 
+    this.command=Util.str2byte(command);
+  }
+  public void setCommand(byte[] command){ 
+    this.command=command;
+  }
+
+  void init() throws JSchException {
+    io.setInputStream(getSession().in);
+    io.setOutputStream(getSession().out);
+  }
+
+  public void setErrStream(java.io.OutputStream out){
+    setExtOutputStream(out);
+  }
+  public void setErrStream(java.io.OutputStream out, boolean dontclose){
+    setExtOutputStream(out, dontclose);
+  }
+  public java.io.InputStream getErrStream() throws java.io.IOException {
+    return getExtInputStream();
+  }
+}
diff --git a/java/com/jcraft/jsch/ChannelForwardedTCPIP.java b/java/com/jcraft/jsch/ChannelForwardedTCPIP.java
new file mode 100644
index 0000000..912f1d8
--- /dev/null
+++ b/java/com/jcraft/jsch/ChannelForwardedTCPIP.java
@@ -0,0 +1,315 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+import java.net.*;
+import java.io.*;
+
+public class ChannelForwardedTCPIP extends Channel{
+
+  static java.util.Vector pool=new java.util.Vector();
+
+  static private final int LOCAL_WINDOW_SIZE_MAX=0x20000;
+//static private final int LOCAL_WINDOW_SIZE_MAX=0x100000;
+  static private final int LOCAL_MAXIMUM_PACKET_SIZE=0x4000;
+
+  static private final int TIMEOUT=10*1000;
+
+  SocketFactory factory=null;
+  private Socket socket=null;
+  private ForwardedTCPIPDaemon daemon=null;
+  String target;
+  int lport;
+  int rport;
+
+  ChannelForwardedTCPIP(){
+    super();
+    setLocalWindowSizeMax(LOCAL_WINDOW_SIZE_MAX);
+    setLocalWindowSize(LOCAL_WINDOW_SIZE_MAX);
+    setLocalPacketSize(LOCAL_MAXIMUM_PACKET_SIZE);
+    io=new IO();
+    connected=true;
+  }
+
+  public void run(){
+    try{ 
+      if(lport==-1){
+        Class c=Class.forName(target);
+        daemon=(ForwardedTCPIPDaemon)c.newInstance();
+
+        PipedOutputStream out=new PipedOutputStream();
+        io.setInputStream(new PassiveInputStream(out
+                                                 , 32*1024
+                                                 ), false);
+
+        daemon.setChannel(this, getInputStream(), out);
+        Object[] foo=getPort(getSession(), rport);
+        daemon.setArg((Object[])foo[3]);
+
+        new Thread(daemon).start();
+      }
+      else{
+        socket=(factory==null) ? 
+           Util.createSocket(target, lport, TIMEOUT) : 
+          factory.createSocket(target, lport);
+        socket.setTcpNoDelay(true);
+        io.setInputStream(socket.getInputStream());
+        io.setOutputStream(socket.getOutputStream());
+      }
+      sendOpenConfirmation();
+    }
+    catch(Exception e){
+      sendOpenFailure(SSH_OPEN_ADMINISTRATIVELY_PROHIBITED);
+      close=true;
+      disconnect();
+      return; 
+    }
+
+    thread=Thread.currentThread();
+    Buffer buf=new Buffer(rmpsize);
+    Packet packet=new Packet(buf);
+    int i=0;
+    try{
+      Session _session = getSession();
+      while(thread!=null && 
+            io!=null && 
+            io.in!=null){
+        i=io.in.read(buf.buffer, 
+                     14, 
+                     buf.buffer.length-14
+                     -Session.buffer_margin
+                     );
+        if(i<=0){
+          eof();
+          break;
+        }
+        packet.reset();
+        buf.putByte((byte)Session.SSH_MSG_CHANNEL_DATA);
+        buf.putInt(recipient);
+        buf.putInt(i);
+        buf.skip(i);
+        synchronized(this){
+          if(close)
+            break;
+          _session.write(packet, this, i);
+        }
+      }
+    }
+    catch(Exception e){
+      //System.err.println(e);
+    }
+    //thread=null;
+    //eof();
+    disconnect();
+  }
+
+  void getData(Buffer buf){
+    setRecipient(buf.getInt());
+    setRemoteWindowSize(buf.getUInt());
+    setRemotePacketSize(buf.getInt());
+    byte[] addr=buf.getString();
+    int port=buf.getInt();
+    byte[] orgaddr=buf.getString();
+    int orgport=buf.getInt();
+
+    /*
+    System.err.println("addr: "+Util.byte2str(addr));
+    System.err.println("port: "+port);
+    System.err.println("orgaddr: "+Util.byte2str(orgaddr));
+    System.err.println("orgport: "+orgport);
+    */
+
+    Session _session=null;
+    try{
+      _session=getSession();
+    }
+    catch(JSchException e){
+      // session has been already down.
+    }
+
+    synchronized(pool){
+      for(int i=0; i<pool.size(); i++){
+        Object[] foo=(Object[])(pool.elementAt(i));
+        if(foo[0]!=_session) continue;
+        if(((Integer)foo[1]).intValue()!=port) continue;
+        this.rport=port;
+        this.target=(String)foo[2];
+        if(foo[3]==null || (foo[3] instanceof Object[])){ this.lport=-1; }
+        else{ this.lport=((Integer)foo[3]).intValue(); }
+        if(foo.length>=6){
+          this.factory=((SocketFactory)foo[5]);
+        }
+        break;
+      }
+      if(target==null){
+        //System.err.println("??");
+      }
+    }
+  }
+
+  static Object[] getPort(Session session, int rport){
+    synchronized(pool){
+      for(int i=0; i<pool.size(); i++){
+        Object[] bar=(Object[])(pool.elementAt(i));
+        if(bar[0]!=session) continue;
+        if(((Integer)bar[1]).intValue()!=rport) continue;
+        return bar;
+      }
+      return null;
+    }
+  }
+
+  static String[] getPortForwarding(Session session){
+    java.util.Vector foo=new java.util.Vector();
+    synchronized(pool){
+      for(int i=0; i<pool.size(); i++){
+        Object[] bar=(Object[])(pool.elementAt(i));
+        if(bar[0]!=session) continue;
+        if(bar[3]==null){ foo.addElement(bar[1]+":"+bar[2]+":"); }
+        else{ foo.addElement(bar[1]+":"+bar[2]+":"+bar[3]); }
+      }
+    }
+    String[] bar=new String[foo.size()];
+    for(int i=0; i<foo.size(); i++){
+      bar[i]=(String)(foo.elementAt(i));
+    }
+    return bar;
+  }
+
+  static String normalize(String address){
+    if(address==null){ return "localhost"; }
+    else if(address.length()==0 || address.equals("*")){ return ""; }
+    else{ return address; }
+  }
+
+  static void addPort(Session session, String _address_to_bind, int port, String target, int lport, SocketFactory factory) throws JSchException{
+    String address_to_bind=normalize(_address_to_bind);
+    synchronized(pool){
+      if(getPort(session, port)!=null){
+        throw new JSchException("PortForwardingR: remote port "+port+" is already registered.");
+      }
+      Object[] foo=new Object[6];
+      foo[0]=session; foo[1]=new Integer(port);
+      foo[2]=target; foo[3]=new Integer(lport);
+      foo[4]=address_to_bind;
+      foo[5]=factory;
+      pool.addElement(foo);
+    }
+  }
+  static void addPort(Session session, String _address_to_bind, int port, String daemon, Object[] arg) throws JSchException{
+    String address_to_bind=normalize(_address_to_bind);
+    synchronized(pool){
+      if(getPort(session, port)!=null){
+        throw new JSchException("PortForwardingR: remote port "+port+" is already registered.");
+      }
+      Object[] foo=new Object[5];
+      foo[0]=session; foo[1]=new Integer(port);
+      foo[2]=daemon; foo[3]=arg;
+      foo[4]=address_to_bind; 
+      pool.addElement(foo);
+    }
+  }
+  static void delPort(ChannelForwardedTCPIP c){
+    Session _session=null;
+    try{
+      _session=c.getSession();
+    }
+    catch(JSchException e){
+      // session has been already down.
+    }
+    if(_session!=null)
+      delPort(_session, c.rport);
+  }
+  static void delPort(Session session, int rport){
+    delPort(session, null, rport);
+  }
+  static void delPort(Session session, String address_to_bind, int rport){
+    synchronized(pool){
+      Object[] foo=null;
+      for(int i=0; i<pool.size(); i++){
+        Object[] bar=(Object[])(pool.elementAt(i));
+        if(bar[0]!=session) continue;
+        if(((Integer)bar[1]).intValue()!=rport) continue;
+        foo=bar;
+        break;
+      }
+      if(foo==null)return;
+      pool.removeElement(foo);
+      if(address_to_bind==null){
+        address_to_bind=(String)foo[4];
+      }	
+      if(address_to_bind==null){
+        address_to_bind="0.0.0.0";
+      }
+    }
+
+    Buffer buf=new Buffer(100); // ??
+    Packet packet=new Packet(buf);
+
+    try{
+      // byte SSH_MSG_GLOBAL_REQUEST 80
+      // string "cancel-tcpip-forward"
+      // boolean want_reply
+      // string  address_to_bind (e.g. "127.0.0.1")
+      // uint32  port number to bind
+      packet.reset();
+      buf.putByte((byte) 80/*SSH_MSG_GLOBAL_REQUEST*/);
+      buf.putString(Util.str2byte("cancel-tcpip-forward"));
+      buf.putByte((byte)0);
+      buf.putString(Util.str2byte(address_to_bind));
+      buf.putInt(rport);
+      session.write(packet);
+    }
+    catch(Exception e){
+//    throw new JSchException(e.toString());
+    }
+  }
+  static void delPort(Session session){
+    int[] rport=null;
+    int count=0;
+    synchronized(pool){
+      rport=new int[pool.size()];
+      for(int i=0; i<pool.size(); i++){
+        Object[] bar=(Object[])(pool.elementAt(i));
+        if(bar[0]==session) {
+          rport[count++]=((Integer)bar[1]).intValue();
+        }
+      }
+    }
+    for(int i=0; i<count; i++){
+      delPort(session, rport[i]);
+    }
+  }
+
+  public int getRemotePort(){return rport;}
+  void setSocketFactory(SocketFactory factory){
+    this.factory=factory;
+  }
+}
diff --git a/java/com/jcraft/jsch/ChannelSession.java b/java/com/jcraft/jsch/ChannelSession.java
new file mode 100644
index 0000000..ffe217a
--- /dev/null
+++ b/java/com/jcraft/jsch/ChannelSession.java
@@ -0,0 +1,276 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+import java.util.*;
+
+class ChannelSession extends Channel{
+  private static byte[] _session=Util.str2byte("session");
+
+  protected boolean agent_forwarding=false;
+  protected boolean xforwading=false;
+  protected Hashtable env=null;
+
+  protected boolean pty=false;
+
+  protected String ttype="vt100";
+  protected int tcol=80;
+  protected int trow=24;
+  protected int twp=640;
+  protected int thp=480;
+  protected byte[] terminal_mode=null;
+
+  ChannelSession(){
+    super();
+    type=_session;
+    io=new IO();
+  }
+
+  /**
+   * Enable the agent forwarding.
+   *
+   * @param enable
+   */
+  public void setAgentForwarding(boolean enable){ 
+    agent_forwarding=enable;
+  }
+
+  /**
+   * Enable the X11 forwarding.
+   *
+   * @param enable
+   * @see RFC4254 6.3.1. Requesting X11 Forwarding
+   */
+  public void setXForwarding(boolean enable){
+    xforwading=enable; 
+  }
+
+  /**
+   * @deprecated Use {@link #setEnv(String, String)} or {@link #setEnv(byte[], byte[])} instead.
+   * @see #setEnv(String, String)
+   * @see #setEnv(byte[], byte[])
+   */
+  public void setEnv(Hashtable env){ 
+    synchronized(this){
+      this.env=env; 
+    }
+  }
+
+  /**
+   * Set the environment variable. 
+   * If <code>name</code> and <code>value</code> are needed to be passed 
+   * to the remote in your faivorite encoding,use 
+   * {@link #setEnv(byte[], byte[])}.
+   *
+   * @param name A name for environment variable.
+   * @param value A value for environment variable.
+   * @see RFC4254 6.4 Environment Variable Passing
+   */
+  public void setEnv(String name, String value){
+    setEnv(Util.str2byte(name), Util.str2byte(value));
+  }
+
+  /**
+   * Set the environment variable.
+   *
+   * @param name A name of environment variable.
+   * @param value A value of environment variable.
+   * @see #setEnv(String, String)
+   * @see RFC4254 6.4 Environment Variable Passing
+   */
+  public void setEnv(byte[] name, byte[] value){
+    synchronized(this){
+      getEnv().put(name, value);
+    }
+  }
+
+  private Hashtable getEnv(){
+    if(env==null)
+      env=new Hashtable();
+    return env;
+  }
+
+  /**
+   * Allocate a Pseudo-Terminal.
+   *
+   * @param enable
+   * @see RFC4254 6.2. Requesting a Pseudo-Terminal
+   */
+  public void setPty(boolean enable){ 
+    pty=enable; 
+  }
+
+  /**
+   * Set the terminal mode.
+   * 
+   * @param terminal_mode
+   */
+  public void setTerminalMode(byte[] terminal_mode){
+    this.terminal_mode=terminal_mode;
+  }
+
+  /**
+   * Change the window dimension interactively.
+   * 
+   * @param col terminal width, columns
+   * @param row terminal height, rows
+   * @param wp terminal width, pixels
+   * @param hp terminal height, pixels
+   * @see RFC4254 6.7. Window Dimension Change Message
+   */
+  public void setPtySize(int col, int row, int wp, int hp){
+    setPtyType(this.ttype, col, row, wp, hp);
+    if(!pty || !isConnected()){
+      return;
+    }
+    try{
+      RequestWindowChange request=new RequestWindowChange();
+      request.setSize(col, row, wp, hp);
+      request.request(getSession(), this);
+    }
+    catch(Exception e){
+      //System.err.println("ChannelSessio.setPtySize: "+e);
+    }
+  }
+
+  /**
+   * Set the terminal type.
+   * This method is not effective after Channel#connect().
+   *
+   * @param ttype terminal type(for example, "vt100")
+   * @see #setPtyType(String, int, int, int, int)
+   */
+  public void setPtyType(String ttype){
+    setPtyType(ttype, 80, 24, 640, 480);
+  }
+
+  /**
+   * Set the terminal type.
+   * This method is not effective after Channel#connect().
+   *
+   * @param ttype terminal type(for example, "vt100")
+   * @param col terminal width, columns
+   * @param row terminal height, rows
+   * @param wp terminal width, pixels
+   * @param hp terminal height, pixels
+   */
+  public void setPtyType(String ttype, int col, int row, int wp, int hp){
+    this.ttype=ttype;
+    this.tcol=col;
+    this.trow=row;
+    this.twp=wp;
+    this.thp=hp;
+  }
+
+  protected void sendRequests() throws Exception{
+    Session _session=getSession();
+    Request request;
+    if(agent_forwarding){
+      request=new RequestAgentForwarding();
+      request.request(_session, this);
+    }
+
+    if(xforwading){
+      request=new RequestX11();
+      request.request(_session, this);
+    }
+
+    if(pty){
+      request=new RequestPtyReq();
+      ((RequestPtyReq)request).setTType(ttype);
+      ((RequestPtyReq)request).setTSize(tcol, trow, twp, thp);
+      if(terminal_mode!=null){
+        ((RequestPtyReq)request).setTerminalMode(terminal_mode);
+      }
+      request.request(_session, this);
+    }
+
+    if(env!=null){
+      for(Enumeration _env=env.keys(); _env.hasMoreElements();){
+        Object name=_env.nextElement();
+        Object value=env.get(name);
+        request=new RequestEnv();
+        ((RequestEnv)request).setEnv(toByteArray(name), 
+                                     toByteArray(value));
+        request.request(_session, this);
+      }
+    }
+  }
+
+  private byte[] toByteArray(Object o){
+    if(o instanceof String){
+      return Util.str2byte((String)o);
+    }
+    return (byte[])o;
+  }
+
+  public void run(){
+    //System.err.println(this+":run >");
+
+    Buffer buf=new Buffer(rmpsize);
+    Packet packet=new Packet(buf);
+    int i=-1;
+    try{
+      while(isConnected() &&
+	    thread!=null && 
+            io!=null && 
+            io.in!=null){
+        i=io.in.read(buf.buffer, 
+                     14,    
+                     buf.buffer.length-14
+                     -Session.buffer_margin
+		     );
+	if(i==0)continue;
+	if(i==-1){
+	  eof();
+	  break;
+	}
+	if(close)break;
+        //System.out.println("write: "+i);
+        packet.reset();
+        buf.putByte((byte)Session.SSH_MSG_CHANNEL_DATA);
+        buf.putInt(recipient);
+        buf.putInt(i);
+        buf.skip(i);
+	getSession().write(packet, this, i);
+      }
+    }
+    catch(Exception e){
+      //System.err.println("# ChannelExec.run");
+      //e.printStackTrace();
+    }
+    Thread _thread=thread; 
+    if(_thread!=null){
+      synchronized(_thread){ _thread.notifyAll(); }
+    }
+    thread=null;
+    //System.err.println(this+":run <");
+  }
+}
diff --git a/java/com/jcraft/jsch/ChannelSftp.java b/java/com/jcraft/jsch/ChannelSftp.java
new file mode 100644
index 0000000..66aec55
--- /dev/null
+++ b/java/com/jcraft/jsch/ChannelSftp.java
@@ -0,0 +1,2651 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+import java.io.*;
+
+import java.util.Vector;
+
+public class ChannelSftp extends ChannelSession{
+
+  static private final int LOCAL_MAXIMUM_PACKET_SIZE=32*1024;
+  static private final int LOCAL_WINDOW_SIZE_MAX=(64*LOCAL_MAXIMUM_PACKET_SIZE);
+
+  private static final byte SSH_FXP_INIT=               1;
+  private static final byte SSH_FXP_VERSION=            2;
+  private static final byte SSH_FXP_OPEN=               3;
+  private static final byte SSH_FXP_CLOSE=              4;
+  private static final byte SSH_FXP_READ=               5;
+  private static final byte SSH_FXP_WRITE=              6;
+  private static final byte SSH_FXP_LSTAT=              7;
+  private static final byte SSH_FXP_FSTAT=              8;
+  private static final byte SSH_FXP_SETSTAT=            9;
+  private static final byte SSH_FXP_FSETSTAT=          10;
+  private static final byte SSH_FXP_OPENDIR=           11;
+  private static final byte SSH_FXP_READDIR=           12;
+  private static final byte SSH_FXP_REMOVE=            13;
+  private static final byte SSH_FXP_MKDIR=             14;
+  private static final byte SSH_FXP_RMDIR=             15;
+  private static final byte SSH_FXP_REALPATH=          16;
+  private static final byte SSH_FXP_STAT=              17;
+  private static final byte SSH_FXP_RENAME=            18;
+  private static final byte SSH_FXP_READLINK=          19;
+  private static final byte SSH_FXP_SYMLINK=           20;
+  private static final byte SSH_FXP_STATUS=           101;
+  private static final byte SSH_FXP_HANDLE=           102;
+  private static final byte SSH_FXP_DATA=             103;
+  private static final byte SSH_FXP_NAME=             104;
+  private static final byte SSH_FXP_ATTRS=            105;
+  private static final byte SSH_FXP_EXTENDED=         (byte)200;
+  private static final byte SSH_FXP_EXTENDED_REPLY=   (byte)201;
+
+  // pflags
+  private static final int SSH_FXF_READ=           0x00000001;
+  private static final int SSH_FXF_WRITE=          0x00000002;
+  private static final int SSH_FXF_APPEND=         0x00000004;
+  private static final int SSH_FXF_CREAT=          0x00000008;
+  private static final int SSH_FXF_TRUNC=          0x00000010;
+  private static final int SSH_FXF_EXCL=           0x00000020;
+
+  private static final int SSH_FILEXFER_ATTR_SIZE=         0x00000001;
+  private static final int SSH_FILEXFER_ATTR_UIDGID=       0x00000002;
+  private static final int SSH_FILEXFER_ATTR_PERMISSIONS=  0x00000004;
+  private static final int SSH_FILEXFER_ATTR_ACMODTIME=    0x00000008;
+  private static final int SSH_FILEXFER_ATTR_EXTENDED=     0x80000000;
+
+  public static final int SSH_FX_OK=                            0;
+  public static final int SSH_FX_EOF=                           1;
+  public static final int SSH_FX_NO_SUCH_FILE=                  2;
+  public static final int SSH_FX_PERMISSION_DENIED=             3;
+  public static final int SSH_FX_FAILURE=                       4;
+  public static final int SSH_FX_BAD_MESSAGE=                   5;
+  public static final int SSH_FX_NO_CONNECTION=                 6;
+  public static final int SSH_FX_CONNECTION_LOST=               7;
+  public static final int SSH_FX_OP_UNSUPPORTED=                8;
+/*
+   SSH_FX_OK
+      Indicates successful completion of the operation.
+   SSH_FX_EOF
+     indicates end-of-file condition; for SSH_FX_READ it means that no
+       more data is available in the file, and for SSH_FX_READDIR it
+      indicates that no more files are contained in the directory.
+   SSH_FX_NO_SUCH_FILE
+      is returned when a reference is made to a file which should exist
+      but doesn't.
+   SSH_FX_PERMISSION_DENIED
+      is returned when the authenticated user does not have sufficient
+      permissions to perform the operation.
+   SSH_FX_FAILURE
+      is a generic catch-all error message; it should be returned if an
+      error occurs for which there is no more specific error code
+      defined.
+   SSH_FX_BAD_MESSAGE
+      may be returned if a badly formatted packet or protocol
+      incompatibility is detected.
+   SSH_FX_NO_CONNECTION
+      is a pseudo-error which indicates that the client has no
+      connection to the server (it can only be generated locally by the
+      client, and MUST NOT be returned by servers).
+   SSH_FX_CONNECTION_LOST
+      is a pseudo-error which indicates that the connection to the
+      server has been lost (it can only be generated locally by the
+      client, and MUST NOT be returned by servers).
+   SSH_FX_OP_UNSUPPORTED
+      indicates that an attempt was made to perform an operation which
+      is not supported for the server (it may be generated locally by
+      the client if e.g.  the version number exchange indicates that a
+      required feature is not supported by the server, or it may be
+      returned by the server if the server does not implement an
+      operation).
+*/
+  private static final int MAX_MSG_LENGTH = 256* 1024;
+
+  public static final int OVERWRITE=0;
+  public static final int RESUME=1;
+  public static final int APPEND=2;
+
+  private boolean interactive=false;
+  private int seq=1;
+  private int[] ackid=new int[1];
+
+  private Buffer buf;
+  private Packet packet;
+
+  // The followings will be used in file uploading.
+  private Buffer obuf;
+  private Packet opacket;
+
+  private int client_version=3;
+  private int server_version=3;
+  private String version=String.valueOf(client_version);
+
+  private java.util.Hashtable extensions=null;
+  private InputStream io_in=null;
+
+/*
+10. Changes from previous protocol versions
+  The SSH File Transfer Protocol has changed over time, before it's
+   standardization.  The following is a description of the incompatible
+   changes between different versions.
+10.1 Changes between versions 3 and 2
+   o  The SSH_FXP_READLINK and SSH_FXP_SYMLINK messages were added.
+   o  The SSH_FXP_EXTENDED and SSH_FXP_EXTENDED_REPLY messages were added.
+   o  The SSH_FXP_STATUS message was changed to include fields `error
+      message' and `language tag'.
+10.2 Changes between versions 2 and 1
+   o  The SSH_FXP_RENAME message was added.
+10.3 Changes between versions 1 and 0
+   o  Implementation changes, no actual protocol changes.
+*/
+
+  private static final String file_separator=java.io.File.separator;
+  private static final char file_separatorc=java.io.File.separatorChar;
+  private static boolean fs_is_bs=(byte)java.io.File.separatorChar == '\\';
+
+  private String cwd;
+  private String home;
+  private String lcwd;
+
+  private static final String UTF8="UTF-8";
+  private String fEncoding=UTF8;
+  private boolean fEncoding_is_utf8=true;
+
+  private RequestQueue rq = new RequestQueue(10);
+  public void setBulkRequests(int bulk_requests) throws JSchException {
+    if(bulk_requests>0) 
+      rq = new RequestQueue(bulk_requests);
+    else 
+      throw new JSchException("setBulkRequests: "+ 
+                              bulk_requests+" must be greater than 0.");
+  }
+  public int getBulkRequests(){
+    return rq.size();
+  }
+
+  ChannelSftp(){
+    super();
+    setLocalWindowSizeMax(LOCAL_WINDOW_SIZE_MAX);
+    setLocalWindowSize(LOCAL_WINDOW_SIZE_MAX);
+    setLocalPacketSize(LOCAL_MAXIMUM_PACKET_SIZE);
+  }
+
+  void init(){
+  }
+
+  public void start() throws JSchException{
+    try{
+
+      PipedOutputStream pos=new PipedOutputStream();
+      io.setOutputStream(pos);
+      PipedInputStream pis=new MyPipedInputStream(pos, rmpsize);
+      io.setInputStream(pis);
+
+      io_in=io.in;
+
+      if(io_in==null){
+        throw new JSchException("channel is down");
+      }
+
+      Request request=new RequestSftp();
+      request.request(getSession(), this);
+
+      /*
+      System.err.println("lmpsize: "+lmpsize);
+      System.err.println("lwsize: "+lwsize);
+      System.err.println("rmpsize: "+rmpsize);
+      System.err.println("rwsize: "+rwsize);
+      */
+
+      buf=new Buffer(lmpsize);
+      packet=new Packet(buf);
+
+      obuf=new Buffer(rmpsize);
+      opacket=new Packet(obuf);
+
+      int i=0;
+      int length;
+      int type;
+      byte[] str;
+
+      // send SSH_FXP_INIT
+      sendINIT();
+
+      // receive SSH_FXP_VERSION
+      Header header=new Header();
+      header=header(buf, header);
+      length=header.length;
+      if(length > MAX_MSG_LENGTH){
+        throw new SftpException(SSH_FX_FAILURE, 
+                                "Received message is too long: " + length);
+      }
+      type=header.type;             // 2 -> SSH_FXP_VERSION
+      server_version=header.rid;
+      //System.err.println("SFTP protocol server-version="+server_version);
+      if(length>0){
+        extensions=new java.util.Hashtable();
+        // extension data
+        fill(buf, length);
+        byte[] extension_name=null;
+        byte[] extension_data=null;
+        while(length>0){
+          extension_name=buf.getString();
+          length-=(4+extension_name.length);
+          extension_data=buf.getString();
+          length-=(4+extension_data.length);
+          extensions.put(Util.byte2str(extension_name),
+                         Util.byte2str(extension_data));
+        }
+      }
+
+      lcwd=new File(".").getCanonicalPath();
+    }
+    catch(Exception e){
+      //System.err.println(e);
+      if(e instanceof JSchException) throw (JSchException)e;
+      if(e instanceof Throwable)
+        throw new JSchException(e.toString(), (Throwable)e);
+      throw new JSchException(e.toString());
+    }
+  }
+
+  public void quit(){ disconnect();}
+  public void exit(){ disconnect();}
+  public void lcd(String path) throws SftpException{
+    path=localAbsolutePath(path);
+    if((new File(path)).isDirectory()){
+      try{
+	path=(new File(path)).getCanonicalPath();
+      }
+      catch(Exception e){}
+      lcwd=path;
+      return;
+    }
+    throw new SftpException(SSH_FX_NO_SUCH_FILE, "No such directory");
+  }
+
+  public void cd(String path) throws SftpException{
+    try{
+      ((MyPipedInputStream)io_in).updateReadSide();
+
+      path=remoteAbsolutePath(path);
+      path=isUnique(path);
+
+      byte[] str=_realpath(path);
+      SftpATTRS attr=_stat(str);
+
+      if((attr.getFlags()&SftpATTRS.SSH_FILEXFER_ATTR_PERMISSIONS)==0){
+        throw new SftpException(SSH_FX_FAILURE, 
+                                "Can't change directory: "+path);
+      }
+      if(!attr.isDir()){
+        throw new SftpException(SSH_FX_FAILURE, 
+                                "Can't change directory: "+path);
+      }
+
+      setCwd(Util.byte2str(str, fEncoding));
+    }
+    catch(Exception e){
+      if(e instanceof SftpException) throw (SftpException)e;
+      if(e instanceof Throwable)
+        throw new SftpException(SSH_FX_FAILURE, "", (Throwable)e);
+      throw new SftpException(SSH_FX_FAILURE, "");
+    }
+  }
+
+  public void put(String src, String dst) throws SftpException{
+    put(src, dst, null, OVERWRITE);
+  }
+  public void put(String src, String dst, int mode) throws SftpException{
+    put(src, dst, null, mode);
+  }
+  public void put(String src, String dst, 
+		  SftpProgressMonitor monitor) throws SftpException{
+    put(src, dst, monitor, OVERWRITE);
+  }
+  public void put(String src, String dst, 
+		  SftpProgressMonitor monitor, int mode) throws SftpException{
+
+    try{
+      ((MyPipedInputStream)io_in).updateReadSide();
+
+      src=localAbsolutePath(src);
+      dst=remoteAbsolutePath(dst);
+
+      Vector v=glob_remote(dst);
+      int vsize=v.size();
+      if(vsize!=1){
+        if(vsize==0){
+          if(isPattern(dst))
+            throw new SftpException(SSH_FX_FAILURE, dst);
+          else
+            dst=Util.unquote(dst);
+        }
+        throw new SftpException(SSH_FX_FAILURE, v.toString());
+      }
+      else{
+        dst=(String)(v.elementAt(0));
+      }
+
+      boolean isRemoteDir=isRemoteDir(dst);
+
+      v=glob_local(src);
+      vsize=v.size();
+
+      StringBuffer dstsb=null;
+      if(isRemoteDir){
+        if(!dst.endsWith("/")){
+	    dst+="/";
+        }
+        dstsb=new StringBuffer(dst);
+      }
+      else if(vsize>1){
+        throw new SftpException(SSH_FX_FAILURE, 
+                                "Copying multiple files, but the destination is missing or a file.");
+      }
+
+      for(int j=0; j<vsize; j++){
+	String _src=(String)(v.elementAt(j));
+	String _dst=null;
+	if(isRemoteDir){
+	  int i=_src.lastIndexOf(file_separatorc);
+          if(fs_is_bs){
+            int ii=_src.lastIndexOf('/');
+            if(ii!=-1 && ii>i)
+              i=ii; 
+          }
+	  if(i==-1) dstsb.append(_src);
+	  else dstsb.append(_src.substring(i + 1));
+          _dst=dstsb.toString();
+          dstsb.delete(dst.length(), _dst.length());
+	}
+        else{
+          _dst=dst;
+        }
+        //System.err.println("_dst "+_dst);
+
+	long size_of_dst=0;
+	if(mode==RESUME){
+	  try{
+	    SftpATTRS attr=_stat(_dst);
+	    size_of_dst=attr.getSize();
+	  }
+	  catch(Exception eee){
+	    //System.err.println(eee);
+	  }
+	  long size_of_src=new File(_src).length();
+	  if(size_of_src<size_of_dst){
+	    throw new SftpException(SSH_FX_FAILURE, 
+                                    "failed to resume for "+_dst);
+	  }
+	  if(size_of_src==size_of_dst){
+	    return;
+	  }
+	}
+
+        if(monitor!=null){
+ 	  monitor.init(SftpProgressMonitor.PUT, _src, _dst,
+		       (new File(_src)).length());
+	  if(mode==RESUME){
+	    monitor.count(size_of_dst);
+	  }
+        }
+	FileInputStream fis=null;
+	try{
+	  fis=new FileInputStream(_src);
+	  _put(fis, _dst, monitor, mode);
+	}
+	finally{
+	  if(fis!=null) {
+	    fis.close();
+	  }
+	}
+      }
+    }
+    catch(Exception e){
+      if(e instanceof SftpException) throw (SftpException)e;
+      if(e instanceof Throwable)
+        throw new SftpException(SSH_FX_FAILURE, e.toString(), (Throwable)e);
+      throw new SftpException(SSH_FX_FAILURE, e.toString());
+    }
+  }
+  public void put(InputStream src, String dst) throws SftpException{
+    put(src, dst, null, OVERWRITE);
+  }
+  public void put(InputStream src, String dst, int mode) throws SftpException{
+    put(src, dst, null, mode);
+  }
+  public void put(InputStream src, String dst, 
+		  SftpProgressMonitor monitor) throws SftpException{
+    put(src, dst, monitor, OVERWRITE);
+  }
+  public void put(InputStream src, String dst, 
+		  SftpProgressMonitor monitor, int mode) throws SftpException{
+    try{
+      ((MyPipedInputStream)io_in).updateReadSide();
+
+      dst=remoteAbsolutePath(dst);
+
+      Vector v=glob_remote(dst);
+      int vsize=v.size();
+      if(vsize!=1){
+        if(vsize==0){
+          if(isPattern(dst))
+            throw new SftpException(SSH_FX_FAILURE, dst);
+          else
+            dst=Util.unquote(dst);
+        }
+        throw new SftpException(SSH_FX_FAILURE, v.toString());
+      }
+      else{
+        dst=(String)(v.elementAt(0));
+      }
+
+      if(isRemoteDir(dst)){
+        throw new SftpException(SSH_FX_FAILURE, dst+" is a directory");
+      }
+
+      if(monitor!=null){
+        monitor.init(SftpProgressMonitor.PUT, 
+                     "-", dst,
+                     SftpProgressMonitor.UNKNOWN_SIZE);
+      }
+
+      _put(src, dst, monitor, mode);
+    }
+    catch(Exception e){
+      if(e instanceof SftpException) throw (SftpException)e;
+      if(e instanceof Throwable)
+        throw new SftpException(SSH_FX_FAILURE, e.toString(), (Throwable)e);
+      throw new SftpException(SSH_FX_FAILURE, e.toString());
+    }
+  }
+
+  public void _put(InputStream src, String dst, 
+                   SftpProgressMonitor monitor, int mode) throws SftpException{
+    try{
+      ((MyPipedInputStream)io_in).updateReadSide();
+
+      byte[] dstb=Util.str2byte(dst, fEncoding);
+      long skip=0;
+      if(mode==RESUME || mode==APPEND){
+	try{
+	  SftpATTRS attr=_stat(dstb);
+	  skip=attr.getSize();
+	}
+	catch(Exception eee){
+	  //System.err.println(eee);
+	}
+      }
+      if(mode==RESUME && skip>0){
+	long skipped=src.skip(skip);
+	if(skipped<skip){
+	  throw new SftpException(SSH_FX_FAILURE, "failed to resume for "+dst);
+	}
+      }
+
+      if(mode==OVERWRITE){ sendOPENW(dstb); }
+      else{ sendOPENA(dstb); }
+
+      Header header=new Header();
+      header=header(buf, header);
+      int length=header.length;
+      int type=header.type;
+
+      fill(buf, length);
+
+      if(type!=SSH_FXP_STATUS && type!=SSH_FXP_HANDLE){
+	throw new SftpException(SSH_FX_FAILURE, "invalid type="+type);
+      }
+      if(type==SSH_FXP_STATUS){
+        int i=buf.getInt();
+        throwStatusError(buf, i);
+      }
+      byte[] handle=buf.getString();         // handle
+      byte[] data=null;
+
+      boolean dontcopy=true;
+
+      if(!dontcopy){  // This case will not work anymore.
+        data=new byte[obuf.buffer.length
+                      -(5+13+21+handle.length+Session.buffer_margin
+                        )
+        ];
+      }
+
+      long offset=0;
+      if(mode==RESUME || mode==APPEND){
+	offset+=skip;
+      }
+
+      int startid=seq;
+      int ackcount=0;
+      int _s=0;
+      int _datalen=0;
+
+      if(!dontcopy){  // This case will not work anymore.
+        _datalen=data.length;
+      }
+      else{
+        data=obuf.buffer;
+        _s=5+13+21+handle.length;
+        _datalen=obuf.buffer.length-_s-Session.buffer_margin;
+      }
+
+      int bulk_requests = rq.size();
+
+      while(true){
+        int nread=0;
+        int count=0;
+        int s=_s;
+        int datalen=_datalen;
+
+        do{
+          nread=src.read(data, s, datalen);
+          if(nread>0){
+            s+=nread;
+            datalen-=nread;
+            count+=nread;
+          }
+        }
+        while(datalen>0 && nread>0); 
+        if(count<=0)break;
+
+        int foo=count;
+        while(foo>0){
+          if((seq-1)==startid ||
+             ((seq-startid)-ackcount)>=bulk_requests){
+            while(((seq-startid)-ackcount)>=bulk_requests){
+              if(this.rwsize>=foo) break;
+              if(checkStatus(ackid, header)){
+                int _ackid = ackid[0];
+                if(startid>_ackid || _ackid>seq-1){
+                  if(_ackid==seq){
+                    System.err.println("ack error: startid="+startid+" seq="+seq+" _ackid="+_ackid);
+                  } 
+                  else{
+                    throw new SftpException(SSH_FX_FAILURE, "ack error: startid="+startid+" seq="+seq+" _ackid="+_ackid);
+                  }
+                }
+                ackcount++;
+              }
+              else{
+                break;
+              }
+            }
+          }
+          foo-=sendWRITE(handle, offset, data, 0, foo);
+        }
+        offset+=count;
+	if(monitor!=null && !monitor.count(count)){
+          break;
+	}
+      }
+      int _ackcount=seq-startid;
+      while(_ackcount>ackcount){
+        if(!checkStatus(null, header)){
+          break;
+        }
+        ackcount++;
+      }
+      if(monitor!=null)monitor.end();
+      _sendCLOSE(handle, header);
+    }
+    catch(Exception e){
+      if(e instanceof SftpException) throw (SftpException)e;
+      if(e instanceof Throwable)
+        throw new SftpException(SSH_FX_FAILURE, e.toString(), (Throwable)e);
+      throw new SftpException(SSH_FX_FAILURE, e.toString());
+    }
+  }
+
+  public OutputStream put(String dst) throws SftpException{
+    return put(dst, (SftpProgressMonitor)null, OVERWRITE);
+  }
+  public OutputStream put(String dst, final int mode) throws SftpException{
+    return put(dst, (SftpProgressMonitor)null, mode);
+  }
+  public OutputStream put(String dst, final SftpProgressMonitor monitor, final int mode) throws SftpException{
+    return put(dst, monitor, mode, 0);
+  }
+  public OutputStream put(String dst, final SftpProgressMonitor monitor, final int mode, long offset) throws SftpException{
+    try{
+      ((MyPipedInputStream)io_in).updateReadSide();
+
+      dst=remoteAbsolutePath(dst);
+      dst=isUnique(dst);
+
+      if(isRemoteDir(dst)){
+	throw new SftpException(SSH_FX_FAILURE, dst+" is a directory");
+      }
+
+      byte[] dstb=Util.str2byte(dst, fEncoding);
+
+      long skip=0;
+      if(mode==RESUME || mode==APPEND){
+	try{
+	  SftpATTRS attr=_stat(dstb);
+	  skip=attr.getSize();
+	}
+	catch(Exception eee){
+	  //System.err.println(eee);
+	}
+      }
+
+      if(mode==OVERWRITE){ sendOPENW(dstb); }
+      else{ sendOPENA(dstb); }
+
+      Header header=new Header();
+      header=header(buf, header);
+      int length=header.length;
+      int type=header.type;
+
+      fill(buf, length);
+
+      if(type!=SSH_FXP_STATUS && type!=SSH_FXP_HANDLE){
+	throw new SftpException(SSH_FX_FAILURE, "");
+      }
+      if(type==SSH_FXP_STATUS){
+        int i=buf.getInt();
+        throwStatusError(buf, i);
+      }
+      final byte[] handle=buf.getString();         // handle
+
+      if(mode==RESUME || mode==APPEND){
+	offset+=skip;
+      }
+
+      final long[] _offset=new long[1];
+      _offset[0]=offset;
+      OutputStream out = new OutputStream(){
+        private boolean init=true;
+        private boolean isClosed=false;
+        private int[] ackid=new int[1];
+        private int startid=0;
+        private int _ackid=0;
+        private int ackcount=0;
+        private int writecount=0;
+        private Header header=new Header();          
+
+        public void write(byte[] d) throws java.io.IOException{
+          write(d, 0, d.length);
+        }
+
+        public void write(byte[] d, int s, int len) throws java.io.IOException{
+          if(init){
+            startid=seq;
+            _ackid=seq;
+            init=false;
+          }
+
+          if(isClosed){
+            throw new IOException("stream already closed");
+          }
+
+          try{
+            int _len=len;
+            while(_len>0){
+              int sent=sendWRITE(handle, _offset[0], d, s, _len);
+              writecount++;
+              _offset[0]+=sent;
+              s+=sent;
+              _len-=sent;
+              if((seq-1)==startid ||
+                 io_in.available()>=1024){
+                while(io_in.available()>0){
+                  if(checkStatus(ackid, header)){
+                    _ackid=ackid[0];
+                    if(startid>_ackid || _ackid>seq-1){
+                      throw new SftpException(SSH_FX_FAILURE, "");
+                    }
+                    ackcount++;
+                  }
+                  else{
+                    break;
+                  }
+                }
+              }
+            }
+    	    if(monitor!=null && !monitor.count(len)){
+              close();
+              throw new IOException("canceled");
+	    }
+          }
+          catch(IOException e){ throw e; }
+          catch(Exception e){ throw new IOException(e.toString());  }
+        }
+
+        byte[] _data=new byte[1];
+        public void write(int foo) throws java.io.IOException{
+          _data[0]=(byte)foo;
+          write(_data, 0, 1);
+        }
+
+        public void flush() throws java.io.IOException{
+
+          if(isClosed){
+            throw new IOException("stream already closed");
+          }
+
+          if(!init){
+            try{
+              while(writecount>ackcount){
+                if(!checkStatus(null, header)){
+                  break;
+                }
+                ackcount++;
+              }
+            }
+            catch(SftpException e){
+              throw new IOException(e.toString());
+            }
+          }
+        }
+
+        public void close() throws java.io.IOException{
+          if(isClosed){
+            return;
+          }
+          flush();
+          if(monitor!=null)monitor.end();
+          try{ _sendCLOSE(handle, header); }
+          catch(IOException e){ throw e; }
+          catch(Exception e){
+            throw new IOException(e.toString());
+          }
+          isClosed=true;
+        }
+      };
+      return out;
+    }
+    catch(Exception e){
+      if(e instanceof SftpException) throw (SftpException)e;
+      if(e instanceof Throwable)
+        throw new SftpException(SSH_FX_FAILURE, "", (Throwable)e);
+      throw new SftpException(SSH_FX_FAILURE, "");
+    }
+  }
+
+  public void get(String src, String dst) throws SftpException{
+    get(src, dst, null, OVERWRITE);
+  }
+  public void get(String src, String dst,
+		  SftpProgressMonitor monitor) throws SftpException{
+    get(src, dst, monitor, OVERWRITE);
+  }
+  public void get(String src, String dst,
+		  SftpProgressMonitor monitor, int mode) throws SftpException{
+    // System.out.println("get: "+src+" "+dst);
+
+    boolean _dstExist = false;
+    String _dst=null;
+    try{
+      ((MyPipedInputStream)io_in).updateReadSide();
+
+      src=remoteAbsolutePath(src);
+      dst=localAbsolutePath(dst);
+
+      Vector v=glob_remote(src);
+      int vsize=v.size();
+      if(vsize==0){
+        throw new SftpException(SSH_FX_NO_SUCH_FILE, "No such file");
+      }
+
+      File dstFile=new File(dst);
+      boolean isDstDir=dstFile.isDirectory();
+      StringBuffer dstsb=null;
+      if(isDstDir){
+        if(!dst.endsWith(file_separator)){
+          dst+=file_separator;
+        }
+        dstsb=new StringBuffer(dst);
+      }
+      else if(vsize>1){
+        throw new SftpException(SSH_FX_FAILURE, 
+                                "Copying multiple files, but destination is missing or a file.");
+      }
+
+      for(int j=0; j<vsize; j++){
+	String _src=(String)(v.elementAt(j));
+	SftpATTRS attr=_stat(_src);
+        if(attr.isDir()){
+          throw new SftpException(SSH_FX_FAILURE, 
+                                  "not supported to get directory "+_src);
+        } 
+
+	_dst=null;
+	if(isDstDir){
+	  int i=_src.lastIndexOf('/');
+	  if(i==-1) dstsb.append(_src);
+	  else dstsb.append(_src.substring(i + 1));
+          _dst=dstsb.toString();
+          dstsb.delete(dst.length(), _dst.length());
+	}
+        else{
+          _dst=dst;
+        }
+
+        File _dstFile=new File(_dst);
+	if(mode==RESUME){
+	  long size_of_src=attr.getSize();
+	  long size_of_dst=_dstFile.length();
+	  if(size_of_dst>size_of_src){
+	    throw new SftpException(SSH_FX_FAILURE, 
+                                    "failed to resume for "+_dst);
+	  }
+	  if(size_of_dst==size_of_src){
+	    return;
+	  }
+	}
+
+	if(monitor!=null){
+	  monitor.init(SftpProgressMonitor.GET, _src, _dst, attr.getSize());
+	  if(mode==RESUME){
+	    monitor.count(_dstFile.length());
+	  }
+	}
+
+        FileOutputStream fos=null;
+        _dstExist = _dstFile.exists();
+        try{
+          if(mode==OVERWRITE){
+            fos=new FileOutputStream(_dst);
+          }
+          else{
+            fos=new FileOutputStream(_dst, true); // append
+          }
+          // System.err.println("_get: "+_src+", "+_dst);
+          _get(_src, fos, monitor, mode, new File(_dst).length());
+        }
+        finally{
+          if(fos!=null){
+            fos.close();
+          }
+        }
+      }
+    }
+    catch(Exception e){
+      if(!_dstExist && _dst!=null){
+        File _dstFile = new File(_dst);
+        if(_dstFile.exists() && _dstFile.length()==0){
+          _dstFile.delete();
+        }
+      }
+      if(e instanceof SftpException) throw (SftpException)e;
+      if(e instanceof Throwable)
+        throw new SftpException(SSH_FX_FAILURE, "", (Throwable)e);
+      throw new SftpException(SSH_FX_FAILURE, "");
+    }
+  }
+  public void get(String src, OutputStream dst) throws SftpException{
+    get(src, dst, null, OVERWRITE, 0);
+  }
+  public void get(String src, OutputStream dst,
+		  SftpProgressMonitor monitor) throws SftpException{
+    get(src, dst, monitor, OVERWRITE, 0);
+  }
+  public void get(String src, OutputStream dst,
+		   SftpProgressMonitor monitor, int mode, long skip) throws SftpException{
+//System.err.println("get: "+src+", "+dst);
+    try{
+      ((MyPipedInputStream)io_in).updateReadSide();
+
+      src=remoteAbsolutePath(src);
+      src=isUnique(src);
+
+      if(monitor!=null){
+	SftpATTRS attr=_stat(src);
+        monitor.init(SftpProgressMonitor.GET, src, "??", attr.getSize());
+        if(mode==RESUME){
+          monitor.count(skip);
+        }
+      }
+      _get(src, dst, monitor, mode, skip);
+    }
+    catch(Exception e){
+      if(e instanceof SftpException) throw (SftpException)e;
+      if(e instanceof Throwable)
+        throw new SftpException(SSH_FX_FAILURE, "", (Throwable)e);
+      throw new SftpException(SSH_FX_FAILURE, "");
+    }
+  }
+
+  private void _get(String src, OutputStream dst,
+                    SftpProgressMonitor monitor, int mode, long skip) throws SftpException{
+    //System.err.println("_get: "+src+", "+dst);
+
+    byte[] srcb=Util.str2byte(src, fEncoding);
+    try{
+      sendOPENR(srcb);
+
+      Header header=new Header();
+      header=header(buf, header);
+      int length=header.length;
+      int type=header.type;
+
+      fill(buf, length);
+
+      if(type!=SSH_FXP_STATUS && type!=SSH_FXP_HANDLE){
+	throw new SftpException(SSH_FX_FAILURE, "");
+      }
+
+      if(type==SSH_FXP_STATUS){
+        int i=buf.getInt();
+        throwStatusError(buf, i);
+      }
+
+      byte[] handle=buf.getString();         // filename
+
+      long offset=0;
+      if(mode==RESUME){
+	offset+=skip;
+      }
+
+      int request_max=1;
+      rq.init();
+      long request_offset=offset;
+
+      int request_len = buf.buffer.length-13;
+      if(server_version==0){ request_len=1024; }
+
+      loop:
+      while(true){
+
+        while(rq.count() < request_max){
+          sendREAD(handle, request_offset, request_len, rq);
+          request_offset += request_len;
+        }
+
+        header=header(buf, header);
+        length=header.length;
+        type=header.type;
+
+        RequestQueue.Request rr = rq.get(header.rid);
+
+        if(type==SSH_FXP_STATUS){
+          fill(buf, length);
+          int i=buf.getInt();    
+          if(i==SSH_FX_EOF){
+            break loop;
+          }
+          throwStatusError(buf, i);
+        }
+
+        if(type!=SSH_FXP_DATA){ 
+	  break loop;
+        }
+
+        buf.rewind();
+        fill(buf.buffer, 0, 4); length-=4;
+        int length_of_data = buf.getInt();   // length of data 
+
+        /**
+         Since sftp protocol version 6, "end-of-file" has been defined,
+
+           byte   SSH_FXP_DATA
+           uint32 request-id
+           string data
+           bool   end-of-file [optional]
+
+         but some sftpd server will send such a field in the sftp protocol 3 ;-(
+         */
+        int optional_data = length - length_of_data;
+
+        int foo = length_of_data;
+        while(foo>0){
+          int bar=foo;
+          if(bar>buf.buffer.length){
+            bar=buf.buffer.length;
+          }
+          int data_len = io_in.read(buf.buffer, 0, bar);
+          if(data_len<0){
+            break loop;
+	  }
+          
+          dst.write(buf.buffer, 0, data_len);
+
+          offset+=data_len;
+          foo-=data_len;
+
+          if(monitor!=null){
+            if(!monitor.count(data_len)){
+              skip(foo); 
+              if(optional_data>0){
+                skip(optional_data);
+              }
+              break loop;
+            }
+          }
+
+        }
+	//System.err.println("length: "+length);  // length should be 0
+
+        if(optional_data>0){
+          skip(optional_data);
+        }
+
+        if(length_of_data<rr.length){  //
+          rq.cancel(header, buf);
+          sendREAD(handle, rr.offset+length_of_data, (int)(rr.length-length_of_data), rq);
+          request_offset=rr.offset+rr.length;
+        }
+
+        if(request_max < rq.size()){
+          request_max++;
+        }
+      }
+      dst.flush();
+
+      if(monitor!=null)monitor.end();
+
+      rq.cancel(header, buf);
+
+      _sendCLOSE(handle, header);
+    }
+    catch(Exception e){
+      if(e instanceof SftpException) throw (SftpException)e;
+      if(e instanceof Throwable)
+        throw new SftpException(SSH_FX_FAILURE, "", (Throwable)e);
+      throw new SftpException(SSH_FX_FAILURE, "");
+    }
+  }
+
+
+  private class RequestQueue {
+    class Request {
+      int id;
+      long offset;
+      long length;
+    }
+
+    Request[] rrq=null;
+    int head, count;
+    RequestQueue(int size){
+      rrq = new Request[size];
+      for(int i=0; i<rrq.length; i++){
+        rrq[i]=new Request();
+      }
+      init();
+    }
+
+    void init(){
+      head=count=0;
+    }
+
+    void add(int id, long offset, int length){
+      if(count == 0) head = 0;
+      int tail = head + count;
+      if(tail>=rrq.length) tail -= rrq.length;
+      rrq[tail].id=id;
+      rrq[tail].offset=offset;
+      rrq[tail].length=length;
+      count++;
+    }
+
+    Request get(int id){
+      count -= 1;
+      int i=head;
+      head++; 
+      if(head==rrq.length) head=0;
+      if(rrq[i].id!=id){
+        System.err.println("The request is not in order.");
+      }
+      rrq[i].id=0;
+      return rrq[i];
+    }
+
+    int count() {
+      return count;
+    }
+
+    int size() {
+      return rrq.length;
+    } 
+
+    void cancel(Header header, Buffer buf) throws IOException {
+      int _count = count;
+      for(int i=0; i<_count; i++){
+        header=header(buf, header);
+        int length=header.length;
+        get(header.rid);
+        skip(length); 
+      }
+    }
+  }
+
+  public InputStream get(String src) throws SftpException{
+    return get(src, null, 0L);
+  }
+  public InputStream get(String src, SftpProgressMonitor monitor) throws SftpException{
+    return get(src, monitor, 0L);
+  }
+
+  /**
+   * @deprecated  This method will be deleted in the future.
+   */
+  public InputStream get(String src, int mode) throws SftpException{
+    return get(src, null, 0L);
+  }
+  /**
+   * @deprecated  This method will be deleted in the future.
+   */
+  public InputStream get(String src, final SftpProgressMonitor monitor, final int mode) throws SftpException{
+    return get(src, monitor, 0L);
+  }
+  public InputStream get(String src, final SftpProgressMonitor monitor, final long skip) throws SftpException{
+
+    try{
+      ((MyPipedInputStream)io_in).updateReadSide();
+
+      src=remoteAbsolutePath(src);
+      src=isUnique(src);
+
+      byte[] srcb=Util.str2byte(src, fEncoding);
+
+      SftpATTRS attr=_stat(srcb);
+      if(monitor!=null){
+        monitor.init(SftpProgressMonitor.GET, src, "??", attr.getSize());
+      }
+
+      sendOPENR(srcb);
+
+      Header header=new Header();
+      header=header(buf, header);
+      int length=header.length;
+      int type=header.type;
+
+      fill(buf, length);
+
+      if(type!=SSH_FXP_STATUS && type!=SSH_FXP_HANDLE){
+	throw new SftpException(SSH_FX_FAILURE, "");
+      }
+      if(type==SSH_FXP_STATUS){
+        int i=buf.getInt();
+        throwStatusError(buf, i);
+      }
+
+      final byte[] handle=buf.getString();         // handle
+
+      java.io.InputStream in=new java.io.InputStream(){
+           long offset=skip;
+           boolean closed=false;
+           int rest_length=0;
+           byte[] _data=new byte[1];
+           byte[] rest_byte=new byte[1024];
+           Header header=new Header();
+
+           public int read() throws java.io.IOException{
+             if(closed)return -1;
+             int i=read(_data, 0, 1);
+             if (i==-1) { return -1; }
+             else {
+               return _data[0]&0xff;
+             }
+           }
+           public int read(byte[] d) throws java.io.IOException{
+             if(closed)return -1;
+             return read(d, 0, d.length);
+           }
+           public int read(byte[] d, int s, int len) throws java.io.IOException{
+             if(closed)return -1;
+             if(d==null){throw new NullPointerException();}
+             if(s<0 || len <0 || s+len>d.length){
+               throw new IndexOutOfBoundsException();
+             } 
+             if(len==0){ return 0; }
+
+             if(rest_length>0){
+               int foo=rest_length;
+               if(foo>len) foo=len;
+               System.arraycopy(rest_byte, 0, d, s, foo);
+               if(foo!=rest_length){
+                 System.arraycopy(rest_byte, foo, 
+                                  rest_byte, 0, rest_length-foo);
+               }
+
+               if(monitor!=null){
+                 if(!monitor.count(foo)){
+                   close();
+                   return -1;
+                 }
+               }
+
+               rest_length-=foo;
+               return foo;
+             }
+
+             if(buf.buffer.length-13<len){
+               len=buf.buffer.length-13;
+             }
+             if(server_version==0 && len>1024){
+               len=1024; 
+             }
+
+             try{sendREAD(handle, offset, len);}
+             catch(Exception e){ throw new IOException("error"); }
+
+             header=header(buf, header);
+             rest_length=header.length;
+             int type=header.type;
+             int id=header.rid;
+
+             if(type!=SSH_FXP_STATUS && type!=SSH_FXP_DATA){ 
+               throw new IOException("error");
+             }
+             if(type==SSH_FXP_STATUS){
+               fill(buf, rest_length);
+               int i=buf.getInt();    
+               rest_length=0;
+               if(i==SSH_FX_EOF){
+                 close();
+                 return -1;
+               }
+               //throwStatusError(buf, i);
+               throw new IOException("error");
+             }
+             buf.rewind();
+             fill(buf.buffer, 0, 4);
+             int length_of_data = buf.getInt(); rest_length-=4;
+
+             /**
+              Since sftp protocol version 6, "end-of-file" has been defined,
+     
+                byte   SSH_FXP_DATA
+                uint32 request-id
+                string data
+                bool   end-of-file [optional]
+     
+              but some sftpd server will send such a field in the sftp protocol 3 ;-(
+              */
+             int optional_data = rest_length - length_of_data;
+
+             offset += length_of_data;
+             int foo = length_of_data;
+             if(foo>0){
+               int bar=foo;
+               if(bar>len){
+                 bar=len;
+               }
+               int i=io_in.read(d, s, bar);
+               if(i<0){
+                 return -1;
+               }
+               foo-=i;
+               rest_length=foo;
+
+               if(foo>0){
+                 if(rest_byte.length<foo){
+                   rest_byte=new byte[foo];
+                 }
+                 int _s=0;
+                 int _len=foo;
+                 int j;
+                 while(_len>0){
+                   j=io_in.read(rest_byte, _s, _len);
+                   if(j<=0)break;
+                   _s+=j;
+                   _len-=j;
+                 }
+               }
+
+               if(optional_data>0){
+                 io_in.skip(optional_data);
+               }
+
+               if(monitor!=null){
+                 if(!monitor.count(i)){
+                   close();
+                   return -1;
+                 }
+               }
+
+               return i;
+             }
+             return 0; // ??
+           }
+           public void close() throws IOException{
+             if(closed)return;
+             closed=true;
+             if(monitor!=null)monitor.end();
+             try{_sendCLOSE(handle, header);}
+             catch(Exception e){throw new IOException("error");}
+           }
+         };
+       return in;
+     }
+     catch(Exception e){
+       if(e instanceof SftpException) throw (SftpException)e;
+       if(e instanceof Throwable)
+         throw new SftpException(SSH_FX_FAILURE, "", (Throwable)e);
+       throw new SftpException(SSH_FX_FAILURE, "");
+     }
+   }
+
+   public java.util.Vector ls(String path) throws SftpException{
+     //System.out.println("ls: "+path);
+     try{
+       ((MyPipedInputStream)io_in).updateReadSide();
+
+       path=remoteAbsolutePath(path);
+       byte[] pattern=null;
+       java.util.Vector v=new java.util.Vector();
+
+       int foo=path.lastIndexOf('/');
+       String dir=path.substring(0, ((foo==0)?1:foo));
+       String _pattern=path.substring(foo+1);
+       dir=Util.unquote(dir);
+
+       // If pattern has included '*' or '?', we need to convert
+       // to UTF-8 string before globbing.
+       byte[][] _pattern_utf8=new byte[1][];
+       boolean pattern_has_wildcard=isPattern(_pattern, _pattern_utf8);
+
+       if(pattern_has_wildcard){
+         pattern=_pattern_utf8[0];
+       }
+       else{
+         String upath=Util.unquote(path);
+         //SftpATTRS attr=_lstat(upath);
+         SftpATTRS attr=_stat(upath);
+         if(attr.isDir()){
+           pattern=null;
+           dir=upath;
+         }
+         else{
+           /*
+             // If we can generage longname by ourself,
+             // we don't have to use openDIR.
+           String filename=Util.unquote(_pattern);
+           String longname=...
+           v.addElement(new LsEntry(filename, longname, attr));
+           return v;
+           */
+
+           if(fEncoding_is_utf8){
+             pattern=_pattern_utf8[0];
+             pattern=Util.unquote(pattern);
+           }
+           else{
+             _pattern=Util.unquote(_pattern);
+             pattern=Util.str2byte(_pattern, fEncoding);
+           }
+
+         }
+       }
+
+       sendOPENDIR(Util.str2byte(dir, fEncoding));
+
+       Header header=new Header();
+       header=header(buf, header);
+       int length=header.length;
+       int type=header.type;
+
+       fill(buf, length);
+
+       if(type!=SSH_FXP_STATUS && type!=SSH_FXP_HANDLE){
+         throw new SftpException(SSH_FX_FAILURE, "");
+       }
+       if(type==SSH_FXP_STATUS){
+         int i=buf.getInt();
+         throwStatusError(buf, i);
+       }
+
+       byte[] handle=buf.getString();         // handle
+
+       while(true){
+         sendREADDIR(handle);
+
+         header=header(buf, header);
+         length=header.length;
+         type=header.type;
+         if(type!=SSH_FXP_STATUS && type!=SSH_FXP_NAME){
+           throw new SftpException(SSH_FX_FAILURE, "");
+         }
+         if(type==SSH_FXP_STATUS){ 
+           fill(buf, length);
+           int i=buf.getInt();
+           if(i==SSH_FX_EOF)
+             break;
+           throwStatusError(buf, i);
+         }
+
+         buf.rewind();
+         fill(buf.buffer, 0, 4); length-=4;
+         int count=buf.getInt();
+
+         byte[] str;
+         int flags;
+
+         buf.reset();
+         while(count>0){
+           if(length>0){
+             buf.shift();
+             int j=(buf.buffer.length>(buf.index+length)) ? 
+               length : 
+               (buf.buffer.length-buf.index);
+             int i=fill(buf.buffer, buf.index, j);
+             buf.index+=i;
+             length-=i;
+           }
+           byte[] filename=buf.getString();
+           byte[] longname=null;
+           if(server_version<=3){
+             longname=buf.getString();
+           }
+           SftpATTRS attrs=SftpATTRS.getATTR(buf);
+
+           boolean find=false;
+           String f=null;
+           if(pattern==null){
+             find=true;
+           }
+           else if(!pattern_has_wildcard){
+             find=Util.array_equals(pattern, filename);
+           }
+           else{
+             byte[] _filename=filename;
+             if(!fEncoding_is_utf8){
+               f=Util.byte2str(_filename, fEncoding);
+               _filename=Util.str2byte(f, UTF8);
+             }
+             find=Util.glob(pattern, _filename);
+           }
+
+           if(find){
+             if(f==null){
+               f=Util.byte2str(filename, fEncoding);
+             }
+             String l=null;
+             if(longname==null){
+               // TODO: we need to generate long name from attrs
+               //       for the sftp protocol 4(and later).
+               l=attrs.toString()+" "+f;
+             }
+             else{
+               l=Util.byte2str(longname, fEncoding);
+             }
+             v.addElement(new LsEntry(f, l, attrs));
+           }
+
+           count--; 
+         }
+       }
+       _sendCLOSE(handle, header);
+
+       /*
+       if(v.size()==1 && pattern_has_wildcard){
+         LsEntry le=(LsEntry)v.elementAt(0);
+         if(le.getAttrs().isDir()){
+           String f=le.getFilename();
+           if(isPattern(f)){
+             f=Util.quote(f);
+           }
+           if(!dir.endsWith("/")){
+             dir+="/";
+           }
+           v=null;
+           return ls(dir+f);
+         }
+       }
+       */
+
+       return v;
+     }
+     catch(Exception e){
+       if(e instanceof SftpException) throw (SftpException)e;
+       if(e instanceof Throwable)
+         throw new SftpException(SSH_FX_FAILURE, "", (Throwable)e);
+       throw new SftpException(SSH_FX_FAILURE, "");
+     }
+   }
+   public String readlink(String path) throws SftpException{
+     try{
+       if(server_version<3){
+         throw new SftpException(SSH_FX_OP_UNSUPPORTED, 
+                                 "The remote sshd is too old to support symlink operation.");
+       }
+
+       ((MyPipedInputStream)io_in).updateReadSide();
+
+       path=remoteAbsolutePath(path);
+
+       path=isUnique(path);
+
+       sendREADLINK(Util.str2byte(path, fEncoding));
+
+       Header header=new Header();
+       header=header(buf, header);
+       int length=header.length;
+       int type=header.type;
+
+       fill(buf, length);
+
+       if(type!=SSH_FXP_STATUS && type!=SSH_FXP_NAME){
+         throw new SftpException(SSH_FX_FAILURE, "");
+       }
+       if(type==SSH_FXP_NAME){
+         int count=buf.getInt();       // count
+         byte[] filename=null;
+         for(int i=0; i<count; i++){
+           filename=buf.getString();
+           if(server_version<=3){
+             byte[] longname=buf.getString();
+           }
+           SftpATTRS.getATTR(buf);
+         }
+         return Util.byte2str(filename, fEncoding);
+       }
+
+       int i=buf.getInt();
+       throwStatusError(buf, i);
+     }
+     catch(Exception e){
+       if(e instanceof SftpException) throw (SftpException)e;
+       if(e instanceof Throwable)
+         throw new SftpException(SSH_FX_FAILURE, "", (Throwable)e);
+       throw new SftpException(SSH_FX_FAILURE, "");
+     }
+     return null;
+   }
+   public void symlink(String oldpath, String newpath) throws SftpException{
+     if(server_version<3){
+       throw new SftpException(SSH_FX_OP_UNSUPPORTED, 
+                               "The remote sshd is too old to support symlink operation.");
+     }
+
+     try{
+       ((MyPipedInputStream)io_in).updateReadSide();
+
+       oldpath=remoteAbsolutePath(oldpath);
+       newpath=remoteAbsolutePath(newpath);
+
+       oldpath=isUnique(oldpath);
+
+       if(isPattern(newpath)){
+         throw new SftpException(SSH_FX_FAILURE, newpath);
+       }
+       newpath=Util.unquote(newpath);
+
+       sendSYMLINK(Util.str2byte(oldpath, fEncoding),
+                   Util.str2byte(newpath, fEncoding));
+
+       Header header=new Header();
+       header=header(buf, header);
+       int length=header.length;
+       int type=header.type;
+
+       fill(buf, length);
+
+       if(type!=SSH_FXP_STATUS){
+         throw new SftpException(SSH_FX_FAILURE, "");
+       }
+
+       int i=buf.getInt();
+       if(i==SSH_FX_OK) return;
+       throwStatusError(buf, i);
+     }
+     catch(Exception e){
+       if(e instanceof SftpException) throw (SftpException)e;
+       if(e instanceof Throwable)
+         throw new SftpException(SSH_FX_FAILURE, "", (Throwable)e);
+       throw new SftpException(SSH_FX_FAILURE, "");
+     }
+   }
+
+   public void rename(String oldpath, String newpath) throws SftpException{
+     if(server_version<2){
+       throw new SftpException(SSH_FX_OP_UNSUPPORTED, 
+                               "The remote sshd is too old to support rename operation.");
+     }
+
+     try{
+       ((MyPipedInputStream)io_in).updateReadSide();
+
+       oldpath=remoteAbsolutePath(oldpath);
+       newpath=remoteAbsolutePath(newpath);
+
+       oldpath=isUnique(oldpath);
+
+       Vector v=glob_remote(newpath);
+       int vsize=v.size();
+       if(vsize>=2){
+         throw new SftpException(SSH_FX_FAILURE, v.toString());
+       }
+       if(vsize==1){
+         newpath=(String)(v.elementAt(0));
+       }
+       else{  // vsize==0
+         if(isPattern(newpath))
+           throw new SftpException(SSH_FX_FAILURE, newpath);
+         newpath=Util.unquote(newpath);
+       }
+
+       sendRENAME(Util.str2byte(oldpath, fEncoding),
+                  Util.str2byte(newpath, fEncoding));
+
+       Header header=new Header();
+       header=header(buf, header);
+       int length=header.length;
+       int type=header.type;
+
+       fill(buf, length);
+
+       if(type!=SSH_FXP_STATUS){
+         throw new SftpException(SSH_FX_FAILURE, "");
+       }
+
+       int i=buf.getInt();
+       if(i==SSH_FX_OK) return;
+       throwStatusError(buf, i);
+    }
+    catch(Exception e){
+      if(e instanceof SftpException) throw (SftpException)e;
+      if(e instanceof Throwable)
+        throw new SftpException(SSH_FX_FAILURE, "", (Throwable)e);
+      throw new SftpException(SSH_FX_FAILURE, "");
+    }
+  }
+  public void rm(String path) throws SftpException{
+    try{
+      ((MyPipedInputStream)io_in).updateReadSide();
+
+      path=remoteAbsolutePath(path);
+
+      Vector v=glob_remote(path);
+      int vsize=v.size();
+
+      Header header=new Header();
+
+      for(int j=0; j<vsize; j++){
+	path=(String)(v.elementAt(j));
+        sendREMOVE(Util.str2byte(path, fEncoding));
+
+        header=header(buf, header);
+        int length=header.length;
+        int type=header.type;
+
+        fill(buf, length);
+
+        if(type!=SSH_FXP_STATUS){
+	  throw new SftpException(SSH_FX_FAILURE, "");
+        }
+        int i=buf.getInt();
+	if(i!=SSH_FX_OK){
+	  throwStatusError(buf, i);
+	}
+      }
+    }
+    catch(Exception e){
+      if(e instanceof SftpException) throw (SftpException)e;
+      if(e instanceof Throwable)
+        throw new SftpException(SSH_FX_FAILURE, "", (Throwable)e);
+      throw new SftpException(SSH_FX_FAILURE, "");
+    }
+  }
+
+  private boolean isRemoteDir(String path){
+    try{
+      sendSTAT(Util.str2byte(path, fEncoding));
+
+      Header header=new Header();
+      header=header(buf, header);
+      int length=header.length;
+      int type=header.type;
+
+      fill(buf, length);
+
+      if(type!=SSH_FXP_ATTRS){
+        return false; 
+      }
+      SftpATTRS attr=SftpATTRS.getATTR(buf);
+      return attr.isDir();
+    }
+    catch(Exception e){}
+    return false;
+  }
+
+  public void chgrp(int gid, String path) throws SftpException{
+    try{
+      ((MyPipedInputStream)io_in).updateReadSide();
+
+      path=remoteAbsolutePath(path);
+
+      Vector v=glob_remote(path);
+      int vsize=v.size();
+      for(int j=0; j<vsize; j++){
+	path=(String)(v.elementAt(j));
+
+        SftpATTRS attr=_stat(path);
+
+	attr.setFLAGS(0);
+	attr.setUIDGID(attr.uid, gid); 
+	_setStat(path, attr);
+      }
+    }
+    catch(Exception e){
+      if(e instanceof SftpException) throw (SftpException)e;
+      if(e instanceof Throwable)
+        throw new SftpException(SSH_FX_FAILURE, "", (Throwable)e);
+      throw new SftpException(SSH_FX_FAILURE, "");
+    }
+  }
+
+  public void chown(int uid, String path) throws SftpException{
+    try{
+      ((MyPipedInputStream)io_in).updateReadSide();
+
+      path=remoteAbsolutePath(path);
+
+      Vector v=glob_remote(path);
+      int vsize=v.size();
+      for(int j=0; j<vsize; j++){
+	path=(String)(v.elementAt(j));
+
+        SftpATTRS attr=_stat(path);
+
+	attr.setFLAGS(0);
+	attr.setUIDGID(uid, attr.gid); 
+	_setStat(path, attr);
+      }
+    }
+    catch(Exception e){
+      if(e instanceof SftpException) throw (SftpException)e;
+      if(e instanceof Throwable)
+        throw new SftpException(SSH_FX_FAILURE, "", (Throwable)e);
+      throw new SftpException(SSH_FX_FAILURE, "");
+    }
+  }
+
+  public void chmod(int permissions, String path) throws SftpException{
+    try{
+      ((MyPipedInputStream)io_in).updateReadSide();
+
+      path=remoteAbsolutePath(path);
+
+      Vector v=glob_remote(path);
+      int vsize=v.size();
+      for(int j=0; j<vsize; j++){
+	path=(String)(v.elementAt(j));
+
+	SftpATTRS attr=_stat(path);
+
+	attr.setFLAGS(0);
+	attr.setPERMISSIONS(permissions); 
+	_setStat(path, attr);
+      }
+    }
+    catch(Exception e){
+      if(e instanceof SftpException) throw (SftpException)e;
+      if(e instanceof Throwable)
+        throw new SftpException(SSH_FX_FAILURE, "", (Throwable)e);
+      throw new SftpException(SSH_FX_FAILURE, "");
+    }
+  }
+
+  public void setMtime(String path, int mtime) throws SftpException{
+    try{
+      ((MyPipedInputStream)io_in).updateReadSide();
+
+      path=remoteAbsolutePath(path);
+
+      Vector v=glob_remote(path);
+      int vsize=v.size();
+      for(int j=0; j<vsize; j++){
+	path=(String)(v.elementAt(j));
+
+        SftpATTRS attr=_stat(path);
+
+	attr.setFLAGS(0);
+	attr.setACMODTIME(attr.getATime(), mtime);
+	_setStat(path, attr);
+      }
+    }
+    catch(Exception e){
+      if(e instanceof SftpException) throw (SftpException)e;
+      if(e instanceof Throwable)
+        throw new SftpException(SSH_FX_FAILURE, "", (Throwable)e);
+      throw new SftpException(SSH_FX_FAILURE, "");
+    }
+  }
+
+  public void rmdir(String path) throws SftpException{
+    try{
+      ((MyPipedInputStream)io_in).updateReadSide();
+
+      path=remoteAbsolutePath(path);
+
+      Vector v=glob_remote(path);
+      int vsize=v.size();
+
+      Header header=new Header();
+
+      for(int j=0; j<vsize; j++){
+	path=(String)(v.elementAt(j));
+	sendRMDIR(Util.str2byte(path, fEncoding));
+
+        header=header(buf, header);
+        int length=header.length;
+        int type=header.type;
+
+        fill(buf, length);
+
+	if(type!=SSH_FXP_STATUS){
+	  throw new SftpException(SSH_FX_FAILURE, "");
+	}
+
+	int i=buf.getInt();
+	if(i!=SSH_FX_OK){
+	  throwStatusError(buf, i);
+	}
+      }
+    }
+    catch(Exception e){
+      if(e instanceof SftpException) throw (SftpException)e;
+      if(e instanceof Throwable)
+        throw new SftpException(SSH_FX_FAILURE, "", (Throwable)e);
+      throw new SftpException(SSH_FX_FAILURE, "");
+    }
+  }
+
+  public void mkdir(String path) throws SftpException{
+    try{
+      ((MyPipedInputStream)io_in).updateReadSide();
+
+      path=remoteAbsolutePath(path);
+
+      sendMKDIR(Util.str2byte(path, fEncoding), null);
+
+      Header header=new Header();      
+      header=header(buf, header);
+      int length=header.length;
+      int type=header.type;
+
+      fill(buf, length);
+
+      if(type!=SSH_FXP_STATUS){
+	throw new SftpException(SSH_FX_FAILURE, "");
+      }
+
+      int i=buf.getInt();
+      if(i==SSH_FX_OK) return;
+      throwStatusError(buf, i);
+    }
+    catch(Exception e){
+      if(e instanceof SftpException) throw (SftpException)e;
+      if(e instanceof Throwable)
+        throw new SftpException(SSH_FX_FAILURE, "", (Throwable)e);
+      throw new SftpException(SSH_FX_FAILURE, "");
+    }
+  }
+
+  public SftpATTRS stat(String path) throws SftpException{
+    try{
+      ((MyPipedInputStream)io_in).updateReadSide();
+
+      path=remoteAbsolutePath(path);
+      path=isUnique(path);
+
+      return _stat(path);
+    }
+    catch(Exception e){
+      if(e instanceof SftpException) throw (SftpException)e;
+      if(e instanceof Throwable)
+        throw new SftpException(SSH_FX_FAILURE, "", (Throwable)e);
+      throw new SftpException(SSH_FX_FAILURE, "");
+    }
+    //return null;
+  }
+
+  private SftpATTRS _stat(byte[] path) throws SftpException{
+    try{
+
+      sendSTAT(path);
+
+      Header header=new Header();
+      header=header(buf, header);
+      int length=header.length;
+      int type=header.type;
+
+      fill(buf, length);
+
+      if(type!=SSH_FXP_ATTRS){
+	if(type==SSH_FXP_STATUS){
+	  int i=buf.getInt();
+	  throwStatusError(buf, i);
+	}
+	throw new SftpException(SSH_FX_FAILURE, "");
+      }
+      SftpATTRS attr=SftpATTRS.getATTR(buf);
+      return attr;
+    }
+    catch(Exception e){
+      if(e instanceof SftpException) throw (SftpException)e;
+      if(e instanceof Throwable)
+        throw new SftpException(SSH_FX_FAILURE, "", (Throwable)e);
+      throw new SftpException(SSH_FX_FAILURE, "");
+    }
+    //return null;
+  }
+
+  private SftpATTRS _stat(String path) throws SftpException{
+    return _stat(Util.str2byte(path, fEncoding));
+  }
+
+  public SftpATTRS lstat(String path) throws SftpException{
+    try{
+      ((MyPipedInputStream)io_in).updateReadSide();
+
+      path=remoteAbsolutePath(path);
+      path=isUnique(path);
+
+      return _lstat(path);
+    }
+    catch(Exception e){
+      if(e instanceof SftpException) throw (SftpException)e;
+      if(e instanceof Throwable)
+        throw new SftpException(SSH_FX_FAILURE, "", (Throwable)e);
+      throw new SftpException(SSH_FX_FAILURE, "");
+    }
+  }
+
+  private SftpATTRS _lstat(String path) throws SftpException{
+    try{
+      sendLSTAT(Util.str2byte(path, fEncoding));
+
+      Header header=new Header();
+      header=header(buf, header);
+      int length=header.length;
+      int type=header.type;
+
+      fill(buf, length);
+
+      if(type!=SSH_FXP_ATTRS){
+	if(type==SSH_FXP_STATUS){
+	  int i=buf.getInt();
+	  throwStatusError(buf, i);
+	}
+	throw new SftpException(SSH_FX_FAILURE, "");
+      }
+      SftpATTRS attr=SftpATTRS.getATTR(buf);
+      return attr;
+    }
+    catch(Exception e){
+      if(e instanceof SftpException) throw (SftpException)e;
+      if(e instanceof Throwable)
+        throw new SftpException(SSH_FX_FAILURE, "", (Throwable)e);
+      throw new SftpException(SSH_FX_FAILURE, "");
+    }
+  }
+
+  private byte[] _realpath(String path) throws SftpException, IOException, Exception{
+    sendREALPATH(Util.str2byte(path, fEncoding));
+
+    Header header=new Header();
+    header=header(buf, header);
+    int length=header.length;
+    int type=header.type;
+
+    fill(buf, length);
+
+    if(type!=SSH_FXP_STATUS && type!=SSH_FXP_NAME){
+      throw new SftpException(SSH_FX_FAILURE, "");
+    }
+    int i;
+    if(type==SSH_FXP_STATUS){
+      i=buf.getInt();
+      throwStatusError(buf, i);
+    }
+    i=buf.getInt();   // count
+
+    byte[] str=null;
+    while(i-->0){
+      str=buf.getString();  // absolute path;
+      if(server_version<=3){
+        byte[] lname=buf.getString();  // long filename
+      }
+      SftpATTRS attr=SftpATTRS.getATTR(buf);  // dummy attribute
+    }
+    return str;
+  }
+
+  public void setStat(String path, SftpATTRS attr) throws SftpException{
+    try{
+      ((MyPipedInputStream)io_in).updateReadSide();
+
+      path=remoteAbsolutePath(path);
+
+      Vector v=glob_remote(path);
+      int vsize=v.size();
+      for(int j=0; j<vsize; j++){
+	path=(String)(v.elementAt(j));
+	_setStat(path, attr);
+      }
+    }
+    catch(Exception e){
+      if(e instanceof SftpException) throw (SftpException)e;
+      if(e instanceof Throwable)
+        throw new SftpException(SSH_FX_FAILURE, "", (Throwable)e);
+      throw new SftpException(SSH_FX_FAILURE, "");
+    }
+  }
+  private void _setStat(String path, SftpATTRS attr) throws SftpException{
+    try{
+      sendSETSTAT(Util.str2byte(path, fEncoding), attr);
+
+      Header header=new Header();
+      header=header(buf, header);
+      int length=header.length;
+      int type=header.type;
+
+      fill(buf, length);
+
+      if(type!=SSH_FXP_STATUS){
+	throw new SftpException(SSH_FX_FAILURE, "");
+      }
+      int i=buf.getInt();
+      if(i!=SSH_FX_OK){
+	throwStatusError(buf, i);
+      }
+    }
+    catch(Exception e){
+      if(e instanceof SftpException) throw (SftpException)e;
+      if(e instanceof Throwable)
+        throw new SftpException(SSH_FX_FAILURE, "", (Throwable)e);
+      throw new SftpException(SSH_FX_FAILURE, "");
+    }
+  }
+
+  public String pwd() throws SftpException{ return getCwd(); }
+  public String lpwd(){ return lcwd; }
+  public String version(){ return version; }
+  public String getHome() throws SftpException {
+    if(home==null){
+      try{
+        ((MyPipedInputStream)io_in).updateReadSide();
+
+        byte[] _home=_realpath("");
+        home=Util.byte2str(_home, fEncoding);
+      }
+      catch(Exception e){
+        if(e instanceof SftpException) throw (SftpException)e;
+        if(e instanceof Throwable)
+          throw new SftpException(SSH_FX_FAILURE, "", (Throwable)e);
+        throw new SftpException(SSH_FX_FAILURE, "");
+      }
+    }
+    return home; 
+  }
+
+  private String getCwd() throws SftpException{
+    if(cwd==null)
+      cwd=getHome();
+    return cwd;
+  }
+
+  private void setCwd(String cwd){
+    this.cwd=cwd;
+  }
+
+  private void read(byte[] buf, int s, int l) throws IOException, SftpException{
+    int i=0;
+    while(l>0){
+      i=io_in.read(buf, s, l);
+      if(i<=0){
+        throw new SftpException(SSH_FX_FAILURE, "");
+      }
+      s+=i;
+      l-=i;
+    }
+  }
+
+  private boolean checkStatus(int[] ackid, Header header) throws IOException, SftpException{
+    header=header(buf, header);
+    int length=header.length;
+    int type=header.type;
+    if(ackid!=null)
+      ackid[0]=header.rid;
+
+    fill(buf, length);
+
+    if(type!=SSH_FXP_STATUS){ 
+      throw new SftpException(SSH_FX_FAILURE, "");
+    }
+    int i=buf.getInt();
+    if(i!=SSH_FX_OK){
+      throwStatusError(buf, i);
+    }
+    return true;
+  }
+  private boolean _sendCLOSE(byte[] handle, Header header) throws Exception{
+    sendCLOSE(handle);
+    return checkStatus(null, header);
+  }
+
+  private void sendINIT() throws Exception{
+    packet.reset();
+    putHEAD(SSH_FXP_INIT, 5);
+    buf.putInt(3);                // version 3
+    getSession().write(packet, this, 5+4);
+  }
+
+  private void sendREALPATH(byte[] path) throws Exception{
+    sendPacketPath(SSH_FXP_REALPATH, path);
+  }
+  private void sendSTAT(byte[] path) throws Exception{
+    sendPacketPath(SSH_FXP_STAT, path);
+  }
+  private void sendLSTAT(byte[] path) throws Exception{
+    sendPacketPath(SSH_FXP_LSTAT, path);
+  }
+  private void sendFSTAT(byte[] handle) throws Exception{
+    sendPacketPath(SSH_FXP_FSTAT, handle);
+  }
+  private void sendSETSTAT(byte[] path, SftpATTRS attr) throws Exception{
+    packet.reset();
+    putHEAD(SSH_FXP_SETSTAT, 9+path.length+attr.length());
+    buf.putInt(seq++);
+    buf.putString(path);             // path
+    attr.dump(buf);
+    getSession().write(packet, this, 9+path.length+attr.length()+4);
+  }
+  private void sendREMOVE(byte[] path) throws Exception{
+    sendPacketPath(SSH_FXP_REMOVE, path);
+  }
+  private void sendMKDIR(byte[] path, SftpATTRS attr) throws Exception{
+    packet.reset();
+    putHEAD(SSH_FXP_MKDIR, 9+path.length+(attr!=null?attr.length():4));
+    buf.putInt(seq++);
+    buf.putString(path);             // path
+    if(attr!=null) attr.dump(buf);
+    else buf.putInt(0);
+    getSession().write(packet, this, 9+path.length+(attr!=null?attr.length():4)+4);
+  }
+  private void sendRMDIR(byte[] path) throws Exception{
+    sendPacketPath(SSH_FXP_RMDIR, path);
+  }
+  private void sendSYMLINK(byte[] p1, byte[] p2) throws Exception{
+    sendPacketPath(SSH_FXP_SYMLINK, p1, p2);
+  }
+  private void sendREADLINK(byte[] path) throws Exception{
+    sendPacketPath(SSH_FXP_READLINK, path);
+  }
+  private void sendOPENDIR(byte[] path) throws Exception{
+    sendPacketPath(SSH_FXP_OPENDIR, path);
+  }
+  private void sendREADDIR(byte[] path) throws Exception{
+    sendPacketPath(SSH_FXP_READDIR, path);
+  }
+  private void sendRENAME(byte[] p1, byte[] p2) throws Exception{
+    sendPacketPath(SSH_FXP_RENAME, p1, p2);
+  }
+  private void sendCLOSE(byte[] path) throws Exception{
+    sendPacketPath(SSH_FXP_CLOSE, path);
+  }
+  private void sendOPENR(byte[] path) throws Exception{
+    sendOPEN(path, SSH_FXF_READ);
+  }
+  private void sendOPENW(byte[] path) throws Exception{
+    sendOPEN(path, SSH_FXF_WRITE|SSH_FXF_CREAT|SSH_FXF_TRUNC);
+  }
+  private void sendOPENA(byte[] path) throws Exception{
+    sendOPEN(path, SSH_FXF_WRITE|/*SSH_FXF_APPEND|*/SSH_FXF_CREAT);
+  }
+  private void sendOPEN(byte[] path, int mode) throws Exception{
+    packet.reset();
+    putHEAD(SSH_FXP_OPEN, 17+path.length);
+    buf.putInt(seq++);
+    buf.putString(path);
+    buf.putInt(mode);
+    buf.putInt(0);           // attrs
+    getSession().write(packet, this, 17+path.length+4);
+  }
+  private void sendPacketPath(byte fxp, byte[] path) throws Exception{
+    packet.reset();
+    putHEAD(fxp, 9+path.length);
+    buf.putInt(seq++);
+    buf.putString(path);             // path
+    getSession().write(packet, this, 9+path.length+4);
+  }
+  private void sendPacketPath(byte fxp, byte[] p1, byte[] p2) throws Exception{
+    packet.reset();
+    putHEAD(fxp, 13+p1.length+p2.length);
+    buf.putInt(seq++);
+    buf.putString(p1);
+    buf.putString(p2);
+    getSession().write(packet, this, 13+p1.length+p2.length+4);
+  }
+
+  private int sendWRITE(byte[] handle, long offset, 
+                        byte[] data, int start, int length) throws Exception{
+    int _length=length;
+    opacket.reset();
+    if(obuf.buffer.length<obuf.index+13+21+handle.length+length+Session.buffer_margin){
+      _length=obuf.buffer.length-(obuf.index+13+21+handle.length+Session.buffer_margin);
+      // System.err.println("_length="+_length+" length="+length);
+    }
+
+    putHEAD(obuf, SSH_FXP_WRITE, 21+handle.length+_length);       // 14
+    obuf.putInt(seq++);                                      //  4
+    obuf.putString(handle);                                  //  4+handle.length
+    obuf.putLong(offset);                                    //  8
+    if(obuf.buffer!=data){
+      obuf.putString(data, start, _length);                    //  4+_length
+    }
+    else{
+      obuf.putInt(_length);
+      obuf.skip(_length);
+    }
+    getSession().write(opacket, this, 21+handle.length+_length+4);
+    return _length;
+  }
+  private void sendREAD(byte[] handle, long offset, int length) throws Exception{
+    sendREAD(handle, offset, length, null);
+  }
+  private void sendREAD(byte[] handle, long offset, int length,
+                        RequestQueue rrq) throws Exception{
+    packet.reset();
+    putHEAD(SSH_FXP_READ, 21+handle.length);
+    buf.putInt(seq++);
+    buf.putString(handle);
+    buf.putLong(offset);
+    buf.putInt(length);
+    getSession().write(packet, this, 21+handle.length+4);
+    if(rrq!=null){
+      rrq.add(seq-1, offset, length);
+    }
+  }
+
+  private void putHEAD(Buffer buf, byte type, int length) throws Exception{
+    buf.putByte((byte)Session.SSH_MSG_CHANNEL_DATA);
+    buf.putInt(recipient);
+    buf.putInt(length+4);
+    buf.putInt(length);
+    buf.putByte(type);
+  }
+
+  private void putHEAD(byte type, int length) throws Exception{
+    putHEAD(buf, type, length);
+  }
+
+  private Vector glob_remote(String _path) throws Exception{
+    Vector v=new Vector();
+    int i=0;
+
+    int foo=_path.lastIndexOf('/');
+    if(foo<0){  // it is not absolute path.
+      v.addElement(Util.unquote(_path)); 
+      return v;
+    }
+
+    String dir=_path.substring(0, ((foo==0)?1:foo));
+    String _pattern=_path.substring(foo+1);
+
+    dir=Util.unquote(dir);
+
+    byte[] pattern=null;
+    byte[][] _pattern_utf8=new byte[1][];
+    boolean pattern_has_wildcard=isPattern(_pattern, _pattern_utf8);
+
+    if(!pattern_has_wildcard){
+      if(!dir.equals("/"))
+        dir+="/";
+      v.addElement(dir+Util.unquote(_pattern));
+      return v;
+    }
+
+    pattern=_pattern_utf8[0];
+
+    sendOPENDIR(Util.str2byte(dir, fEncoding));
+
+    Header header=new Header();
+    header=header(buf, header);
+    int length=header.length;
+    int type=header.type;
+
+    fill(buf, length);
+
+    if(type!=SSH_FXP_STATUS && type!=SSH_FXP_HANDLE){
+      throw new SftpException(SSH_FX_FAILURE, "");
+    }
+    if(type==SSH_FXP_STATUS){
+      i=buf.getInt();
+      throwStatusError(buf, i);
+    }
+
+    byte[] handle=buf.getString();         // filename
+    String pdir=null;                      // parent directory
+
+    while(true){
+      sendREADDIR(handle);
+      header=header(buf, header);
+      length=header.length;
+      type=header.type;
+
+      if(type!=SSH_FXP_STATUS && type!=SSH_FXP_NAME){
+	throw new SftpException(SSH_FX_FAILURE, "");
+      }
+      if(type==SSH_FXP_STATUS){ 
+        fill(buf, length);
+	break;
+      }
+
+      buf.rewind();
+      fill(buf.buffer, 0, 4); length-=4;
+      int count=buf.getInt();
+
+      byte[] str;
+      int flags;
+
+      buf.reset();
+      while(count>0){
+	if(length>0){
+	  buf.shift();
+          int j=(buf.buffer.length>(buf.index+length)) ? length : (buf.buffer.length-buf.index);
+	  i=io_in.read(buf.buffer, buf.index, j);
+	  if(i<=0)break;
+	  buf.index+=i;
+	  length-=i;
+	}
+
+	byte[] filename=buf.getString();
+	//System.err.println("filename: "+new String(filename));
+        if(server_version<=3){
+          str=buf.getString();  // longname
+        }
+	SftpATTRS attrs=SftpATTRS.getATTR(buf);
+
+        byte[] _filename=filename;
+        String f=null;
+        boolean found=false;
+
+        if(!fEncoding_is_utf8){
+          f=Util.byte2str(filename, fEncoding);
+          _filename=Util.str2byte(f, UTF8);
+        }
+        found=Util.glob(pattern, _filename);
+
+	if(found){
+          if(f==null){
+            f=Util.byte2str(filename, fEncoding);
+          }
+          if(pdir==null){
+            pdir=dir;
+            if(!pdir.endsWith("/")){
+              pdir+="/";
+            }
+          }
+	  v.addElement(pdir+f);
+	}
+	count--; 
+      }
+    }
+    if(_sendCLOSE(handle, header)) 
+      return v;
+    return null;
+  }
+
+  private boolean isPattern(byte[] path){
+    int length=path.length;
+    int i=0;
+    while(i<length){
+      if(path[i]=='*' || path[i]=='?')
+        return true;
+      if(path[i]=='\\' && (i+1)<length)
+        i++;
+      i++;
+    }
+    return false;
+  }
+
+  private Vector glob_local(String _path) throws Exception{
+//System.err.println("glob_local: "+_path);
+    Vector v=new Vector();
+    byte[] path=Util.str2byte(_path, UTF8);
+    int i=path.length-1;
+    while(i>=0){
+      if(path[i]!='*' && path[i]!='?'){
+        i--;
+        continue;
+      }
+      if(!fs_is_bs &&
+         i>0 && path[i-1]=='\\'){
+        i--;
+        if(i>0 && path[i-1]=='\\'){
+          i--;
+          i--;
+          continue;
+        }
+      }
+      break;
+    }
+
+    if(i<0){ v.addElement(fs_is_bs ? _path : Util.unquote(_path)); return v;}
+
+    while(i>=0){
+      if(path[i]==file_separatorc ||
+         (fs_is_bs && path[i]=='/')){ // On Windows, '/' is also the separator.
+        break;
+      }
+      i--;
+    }
+
+    if(i<0){ v.addElement(fs_is_bs ? _path : Util.unquote(_path)); return v;}
+
+    byte[] dir;
+    if(i==0){dir=new byte[]{(byte)file_separatorc};}
+    else{ 
+      dir=new byte[i];
+      System.arraycopy(path, 0, dir, 0, i);
+    }
+
+    byte[] pattern=new byte[path.length-i-1];
+    System.arraycopy(path, i+1, pattern, 0, pattern.length);
+
+//System.err.println("dir: "+new String(dir)+" pattern: "+new String(pattern));
+    try{
+      String[] children=(new File(Util.byte2str(dir, UTF8))).list();
+      String pdir=Util.byte2str(dir)+file_separator;
+      for(int j=0; j<children.length; j++){
+//System.err.println("children: "+children[j]);
+	if(Util.glob(pattern, Util.str2byte(children[j], UTF8))){
+	  v.addElement(pdir+children[j]);
+	}
+      }
+    }
+    catch(Exception e){
+    }
+    return v;
+  }
+
+  private void throwStatusError(Buffer buf, int i) throws SftpException{
+    if(server_version>=3 &&   // WindRiver's sftp will send invalid 
+       buf.getLength()>=4){   // SSH_FXP_STATUS packet.
+      byte[] str=buf.getString();
+      //byte[] tag=buf.getString();
+      throw new SftpException(i, Util.byte2str(str, UTF8));
+    }
+    else{
+      throw new SftpException(i, "Failure");
+    }
+  }
+
+  private static boolean isLocalAbsolutePath(String path){
+    return (new File(path)).isAbsolute();
+  }
+
+  public void disconnect(){
+    super.disconnect();
+  }
+
+  private boolean isPattern(String path, byte[][] utf8){
+    byte[] _path=Util.str2byte(path, UTF8);
+    if(utf8!=null)
+      utf8[0]=_path;
+    return isPattern(_path);
+  }
+
+  private boolean isPattern(String path){
+    return isPattern(path, null);
+  }
+
+  private void fill(Buffer buf, int len)  throws IOException{
+    buf.reset();
+    fill(buf.buffer, 0, len);
+    buf.skip(len);
+  }
+
+  private int fill(byte[] buf, int s, int len) throws IOException{
+    int i=0;
+    int foo=s;
+    while(len>0){
+      i=io_in.read(buf, s, len);
+      if(i<=0){
+        throw new IOException("inputstream is closed");
+        //return (s-foo)==0 ? i : s-foo;
+      }
+      s+=i;
+      len-=i;
+    }
+    return s-foo;
+  }
+  private void skip(long foo) throws IOException{
+    while(foo>0){
+      long bar=io_in.skip(foo);
+      if(bar<=0) 
+        break;
+      foo-=bar;
+    }
+  }
+
+  class Header{
+    int length;
+    int type;
+    int rid;
+  }
+  private Header header(Buffer buf, Header header) throws IOException{
+    buf.rewind();
+    int i=fill(buf.buffer, 0, 9);
+    header.length=buf.getInt()-5;
+    header.type=buf.getByte()&0xff;
+    header.rid=buf.getInt();  
+    return header;
+  }
+
+  private String remoteAbsolutePath(String path) throws SftpException{
+    if(path.charAt(0)=='/') return path;
+    String cwd=getCwd();
+//    if(cwd.equals(getHome())) return path;
+    if(cwd.endsWith("/")) return cwd+path;
+    return cwd+"/"+path;
+  }
+
+  private String localAbsolutePath(String path){
+    if(isLocalAbsolutePath(path)) return path;
+    if(lcwd.endsWith(file_separator)) return lcwd+path;
+    return lcwd+file_separator+path;
+  }
+
+  /**
+   * This method will check if the given string can be expanded to the
+   * unique string.  If it can be expanded to mutiple files, SftpException
+   * will be thrown.
+   * @return the returned string is unquoted.
+   */
+  private String isUnique(String path) throws SftpException, Exception{
+    Vector v=glob_remote(path);
+    if(v.size()!=1){
+      throw new SftpException(SSH_FX_FAILURE, path+" is not unique: "+v.toString());
+    }
+    return (String)(v.elementAt(0));
+  }
+
+  public int getServerVersion() throws SftpException{
+    if(!isConnected()){
+      throw new SftpException(SSH_FX_FAILURE, "The channel is not connected.");
+    }
+    return server_version;
+  }
+
+  public void setFilenameEncoding(String encoding) throws SftpException{
+    int sversion=getServerVersion();
+    if(3 <= sversion && sversion <= 5 &&
+       !encoding.equals(UTF8)){
+      throw new SftpException(SSH_FX_FAILURE,
+                              "The encoding can not be changed for this sftp server.");
+    }
+    if(encoding.equals(UTF8)){
+      encoding=UTF8;
+    }
+    fEncoding=encoding;
+    fEncoding_is_utf8=fEncoding.equals(UTF8);
+  }
+
+  public String getExtension(String key){
+    if(extensions==null)
+      return null;
+    return (String)extensions.get(key);
+  }
+
+  public String realpath(String path) throws SftpException{
+    try{
+      byte[] _path=_realpath(remoteAbsolutePath(path));
+      return Util.byte2str(_path, fEncoding);
+    }
+    catch(Exception e){
+      if(e instanceof SftpException) throw (SftpException)e;
+      if(e instanceof Throwable)
+        throw new SftpException(SSH_FX_FAILURE, "", (Throwable)e);
+      throw new SftpException(SSH_FX_FAILURE, "");
+    }
+  }
+
+  public class LsEntry implements Comparable{
+    private  String filename;
+    private  String longname;
+    private  SftpATTRS attrs;
+    LsEntry(String filename, String longname, SftpATTRS attrs){
+      setFilename(filename);
+      setLongname(longname);
+      setAttrs(attrs);
+    }
+    public String getFilename(){return filename;};
+    void setFilename(String filename){this.filename = filename;};
+    public String getLongname(){return longname;};
+    void setLongname(String longname){this.longname = longname;};
+    public SftpATTRS getAttrs(){return attrs;};
+    void setAttrs(SftpATTRS attrs) {this.attrs = attrs;};
+    public String toString(){ return longname; }
+    public int compareTo(Object o) throws ClassCastException{
+      if(o instanceof LsEntry){
+        return filename.compareTo(((LsEntry)o).getFilename());
+      }
+      throw new ClassCastException("a decendent of LsEntry must be given.");
+    }
+  }
+}
diff --git a/java/com/jcraft/jsch/ChannelShell.java b/java/com/jcraft/jsch/ChannelShell.java
new file mode 100644
index 0000000..eeb24a3
--- /dev/null
+++ b/java/com/jcraft/jsch/ChannelShell.java
@@ -0,0 +1,70 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+import java.util.*;
+
+public class ChannelShell extends ChannelSession{
+
+  ChannelShell(){
+    super();
+    pty=true;
+  }
+
+  public void start() throws JSchException{
+    Session _session=getSession();
+    try{
+      sendRequests();
+
+      Request request=new RequestShell();
+      request.request(_session, this);
+    }
+    catch(Exception e){
+      if(e instanceof JSchException) throw (JSchException)e;
+      if(e instanceof Throwable)
+        throw new JSchException("ChannelShell", (Throwable)e);
+      throw new JSchException("ChannelShell");
+    }
+
+    if(io.in!=null){
+      thread=new Thread(this);
+      thread.setName("Shell for "+_session.host);
+      if(_session.daemon_thread){
+        thread.setDaemon(_session.daemon_thread);
+      }
+      thread.start();
+    }
+  }
+
+  void init() throws JSchException {
+    io.setInputStream(getSession().in);
+    io.setOutputStream(getSession().out);
+  }
+}
diff --git a/java/com/jcraft/jsch/ChannelSubsystem.java b/java/com/jcraft/jsch/ChannelSubsystem.java
new file mode 100644
index 0000000..3f33bf3
--- /dev/null
+++ b/java/com/jcraft/jsch/ChannelSubsystem.java
@@ -0,0 +1,83 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2005-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+public class ChannelSubsystem extends ChannelSession{
+  boolean xforwading=false;
+  boolean pty=false;
+  boolean want_reply=true;
+  String subsystem="";
+  public void setXForwarding(boolean foo){ xforwading=foo; }
+  public void setPty(boolean foo){ pty=foo; }
+  public void setWantReply(boolean foo){ want_reply=foo; }
+  public void setSubsystem(String foo){ subsystem=foo; }
+  public void start() throws JSchException{
+    Session _session=getSession();
+    try{
+      Request request;
+      if(xforwading){
+        request=new RequestX11();
+        request.request(_session, this);
+      }
+      if(pty){
+	request=new RequestPtyReq();
+	request.request(_session, this);
+      }
+      request=new RequestSubsystem();
+      ((RequestSubsystem)request).request(_session, this, subsystem, want_reply);
+    }
+    catch(Exception e){
+      if(e instanceof JSchException){ throw (JSchException)e; }
+      if(e instanceof Throwable)
+        throw new JSchException("ChannelSubsystem", (Throwable)e);
+      throw new JSchException("ChannelSubsystem");
+    }
+    if(io.in!=null){
+      thread=new Thread(this);
+      thread.setName("Subsystem for "+_session.host);
+      if(_session.daemon_thread){
+        thread.setDaemon(_session.daemon_thread);
+      }
+      thread.start();
+    }
+  }
+
+  void init() throws JSchException {
+    io.setInputStream(getSession().in);
+    io.setOutputStream(getSession().out);
+  }
+
+  public void setErrStream(java.io.OutputStream out){
+    setExtOutputStream(out);
+  }
+  public java.io.InputStream getErrStream() throws java.io.IOException {
+    return getExtInputStream();
+  }
+}
diff --git a/java/com/jcraft/jsch/ChannelX11.java b/java/com/jcraft/jsch/ChannelX11.java
new file mode 100644
index 0000000..393728c
--- /dev/null
+++ b/java/com/jcraft/jsch/ChannelX11.java
@@ -0,0 +1,273 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+import java.net.*;
+
+class ChannelX11 extends Channel{
+
+  static private final int LOCAL_WINDOW_SIZE_MAX=0x20000;
+  static private final int LOCAL_MAXIMUM_PACKET_SIZE=0x4000;
+
+  static private final int TIMEOUT=10*1000;
+
+  private static String host="127.0.0.1";
+  private static int port=6000;
+
+  private boolean init=true;
+
+  static byte[] cookie=null;
+  private static byte[] cookie_hex=null;
+
+  private static java.util.Hashtable faked_cookie_pool=new java.util.Hashtable();
+  private static java.util.Hashtable faked_cookie_hex_pool=new java.util.Hashtable();
+
+  private static byte[] table={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,
+                               0x61,0x62,0x63,0x64,0x65,0x66};
+
+  private Socket socket = null;
+
+  static int revtable(byte foo){
+    for(int i=0; i<table.length; i++){
+      if(table[i]==foo)return i;
+    }
+    return 0;
+  }
+  static void setCookie(String foo){
+    cookie_hex=Util.str2byte(foo); 
+    cookie=new byte[16];
+    for(int i=0; i<16; i++){
+	cookie[i]=(byte)(((revtable(cookie_hex[i*2])<<4)&0xf0) |
+			 ((revtable(cookie_hex[i*2+1]))&0xf));
+    }
+  }
+  static void setHost(String foo){ host=foo; }
+  static void setPort(int foo){ port=foo; }
+  static byte[] getFakedCookie(Session session){
+    synchronized(faked_cookie_hex_pool){
+      byte[] foo=(byte[])faked_cookie_hex_pool.get(session);
+      if(foo==null){
+	Random random=Session.random;
+	foo=new byte[16];
+	synchronized(random){
+	  random.fill(foo, 0, 16);
+	}
+/*
+System.err.print("faked_cookie: ");
+for(int i=0; i<foo.length; i++){
+    System.err.print(Integer.toHexString(foo[i]&0xff)+":");
+}
+System.err.println("");
+*/
+	faked_cookie_pool.put(session, foo);
+	byte[] bar=new byte[32];
+	for(int i=0; i<16; i++){
+	  bar[2*i]=table[(foo[i]>>>4)&0xf];
+	  bar[2*i+1]=table[(foo[i])&0xf];
+	}
+	faked_cookie_hex_pool.put(session, bar);
+	foo=bar;
+      }
+      return foo;
+    }
+  }
+
+  static void removeFakedCookie(Session session){
+    synchronized(faked_cookie_hex_pool){
+      faked_cookie_hex_pool.remove(session);
+      faked_cookie_pool.remove(session);
+    }
+  }
+
+  ChannelX11(){
+    super();
+
+    setLocalWindowSizeMax(LOCAL_WINDOW_SIZE_MAX);
+    setLocalWindowSize(LOCAL_WINDOW_SIZE_MAX);
+    setLocalPacketSize(LOCAL_MAXIMUM_PACKET_SIZE);
+
+    type=Util.str2byte("x11");
+
+    connected=true;
+    /*
+    try{ 
+      socket=Util.createSocket(host, port, TIMEOUT);
+      socket.setTcpNoDelay(true);
+      io=new IO();
+      io.setInputStream(socket.getInputStream());
+      io.setOutputStream(socket.getOutputStream());
+    }
+    catch(Exception e){
+      //System.err.println(e);
+    }
+    */
+  }
+
+  public void run(){
+
+    try{ 
+      socket=Util.createSocket(host, port, TIMEOUT);
+      socket.setTcpNoDelay(true);
+      io=new IO();
+      io.setInputStream(socket.getInputStream());
+      io.setOutputStream(socket.getOutputStream());
+      sendOpenConfirmation();
+    }
+    catch(Exception e){
+      sendOpenFailure(SSH_OPEN_ADMINISTRATIVELY_PROHIBITED);
+      close=true;
+      disconnect();
+      return;
+    }
+
+    thread=Thread.currentThread();
+    Buffer buf=new Buffer(rmpsize);
+    Packet packet=new Packet(buf);
+    int i=0;
+    try{
+      while(thread!=null &&
+            io!=null &&
+            io.in!=null){
+        i=io.in.read(buf.buffer, 
+		     14, 
+		     buf.buffer.length-14-Session.buffer_margin);
+	if(i<=0){
+	  eof();
+          break;
+	}
+	if(close)break;
+        packet.reset();
+        buf.putByte((byte)Session.SSH_MSG_CHANNEL_DATA);
+        buf.putInt(recipient);
+        buf.putInt(i);
+        buf.skip(i);
+	getSession().write(packet, this, i);
+      }
+    }
+    catch(Exception e){
+      //System.err.println(e);
+    }
+    disconnect();
+  }
+
+  private byte[] cache=new byte[0];
+  private byte[] addCache(byte[] foo, int s, int l){
+    byte[] bar=new byte[cache.length+l];
+    System.arraycopy(foo, s, bar, cache.length, l);
+    if(cache.length>0)
+      System.arraycopy(cache, 0, bar, 0, cache.length);
+    cache=bar;
+    return cache;
+  }
+
+  void write(byte[] foo, int s, int l) throws java.io.IOException {
+    //if(eof_local)return;
+
+    if(init){
+
+      Session _session=null;
+      try{
+        _session=getSession();
+      }
+      catch(JSchException e){
+        throw new java.io.IOException(e.toString());
+      }
+
+      foo=addCache(foo, s, l);
+      s=0; 
+      l=foo.length;
+
+      if(l<9)
+        return;
+
+      int plen=(foo[s+6]&0xff)*256+(foo[s+7]&0xff);
+      int dlen=(foo[s+8]&0xff)*256+(foo[s+9]&0xff);
+
+      if((foo[s]&0xff)==0x42){
+      }
+      else if((foo[s]&0xff)==0x6c){
+         plen=((plen>>>8)&0xff)|((plen<<8)&0xff00);
+         dlen=((dlen>>>8)&0xff)|((dlen<<8)&0xff00);
+      }
+      else{
+	  // ??
+      }
+
+      if(l<12+plen+((-plen)&3)+dlen)
+        return;
+
+      byte[] bar=new byte[dlen];
+      System.arraycopy(foo, s+12+plen+((-plen)&3), bar, 0, dlen);
+      byte[] faked_cookie=null;
+
+      synchronized(faked_cookie_pool){
+	faked_cookie=(byte[])faked_cookie_pool.get(_session);
+      }
+
+      /*
+System.err.print("faked_cookie: ");
+for(int i=0; i<faked_cookie.length; i++){
+    System.err.print(Integer.toHexString(faked_cookie[i]&0xff)+":");
+}
+System.err.println("");
+System.err.print("bar: ");
+for(int i=0; i<bar.length; i++){
+    System.err.print(Integer.toHexString(bar[i]&0xff)+":");
+}
+System.err.println("");
+      */
+
+      if(equals(bar, faked_cookie)){
+        if(cookie!=null)
+          System.arraycopy(cookie, 0, foo, s+12+plen+((-plen)&3), dlen);
+      }
+      else{
+	  //System.err.println("wrong cookie");
+          thread=null;
+          eof();
+          io.close();
+          disconnect();
+      }
+      init=false;
+      io.put(foo, s, l);
+      cache=null;
+      return;
+    }
+    io.put(foo, s, l);
+  }
+
+  private static boolean equals(byte[] foo, byte[] bar){
+    if(foo.length!=bar.length)return false;
+    for(int i=0; i<foo.length; i++){
+      if(foo[i]!=bar[i])return false;
+    }
+    return true;
+  }
+}
diff --git a/java/com/jcraft/jsch/Cipher.java b/java/com/jcraft/jsch/Cipher.java
new file mode 100644
index 0000000..cc7084e
--- /dev/null
+++ b/java/com/jcraft/jsch/Cipher.java
@@ -0,0 +1,40 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+public interface Cipher{
+  static int ENCRYPT_MODE=0;
+  static int DECRYPT_MODE=1;
+  int getIVSize(); 
+  int getBlockSize(); 
+  void init(int mode, byte[] key, byte[] iv) throws Exception; 
+  void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception;
+  boolean isCBC();
+}
diff --git a/java/com/jcraft/jsch/CipherNone.java b/java/com/jcraft/jsch/CipherNone.java
new file mode 100644
index 0000000..61f836a
--- /dev/null
+++ b/java/com/jcraft/jsch/CipherNone.java
@@ -0,0 +1,42 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+public class CipherNone implements Cipher{
+  private static final int ivsize=8;
+  private static final int bsize=16;
+  public int getIVSize(){return ivsize;} 
+  public int getBlockSize(){return bsize;}
+  public void init(int mode, byte[] key, byte[] iv) throws Exception{
+  }
+  public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception{
+  }
+  public boolean isCBC(){return false; }
+}
diff --git a/java/com/jcraft/jsch/Compression.java b/java/com/jcraft/jsch/Compression.java
new file mode 100644
index 0000000..7ae7922
--- /dev/null
+++ b/java/com/jcraft/jsch/Compression.java
@@ -0,0 +1,38 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+public interface Compression{
+  static public final int INFLATER=0;
+  static public final int DEFLATER=1;
+  void init(int type, int level);
+  byte[] compress(byte[] buf, int start, int[] len);
+  byte[] uncompress(byte[] buf, int start, int[] len);
+}
diff --git a/java/com/jcraft/jsch/DH.java b/java/com/jcraft/jsch/DH.java
new file mode 100644
index 0000000..963f13c
--- /dev/null
+++ b/java/com/jcraft/jsch/DH.java
@@ -0,0 +1,39 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+public interface DH{
+  void init() throws Exception;
+  void setP(byte[] p);
+  void setG(byte[] g);
+  byte[] getE() throws Exception;
+  void setF(byte[] f);
+  byte[] getK() throws Exception;
+}
diff --git a/java/com/jcraft/jsch/DHG1.java b/java/com/jcraft/jsch/DHG1.java
new file mode 100644
index 0000000..9b9a860
--- /dev/null
+++ b/java/com/jcraft/jsch/DHG1.java
@@ -0,0 +1,310 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+public class DHG1 extends KeyExchange{
+
+  static final byte[] g={ 2 };
+  static final byte[] p={
+(byte)0x00,
+(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF, 
+(byte)0xC9,(byte)0x0F,(byte)0xDA,(byte)0xA2,(byte)0x21,(byte)0x68,(byte)0xC2,(byte)0x34,
+(byte)0xC4,(byte)0xC6,(byte)0x62,(byte)0x8B,(byte)0x80,(byte)0xDC,(byte)0x1C,(byte)0xD1,
+(byte)0x29,(byte)0x02,(byte)0x4E,(byte)0x08,(byte)0x8A,(byte)0x67,(byte)0xCC,(byte)0x74,
+(byte)0x02,(byte)0x0B,(byte)0xBE,(byte)0xA6,(byte)0x3B,(byte)0x13,(byte)0x9B,(byte)0x22,
+(byte)0x51,(byte)0x4A,(byte)0x08,(byte)0x79,(byte)0x8E,(byte)0x34,(byte)0x04,(byte)0xDD,
+(byte)0xEF,(byte)0x95,(byte)0x19,(byte)0xB3,(byte)0xCD,(byte)0x3A,(byte)0x43,(byte)0x1B,
+(byte)0x30,(byte)0x2B,(byte)0x0A,(byte)0x6D,(byte)0xF2,(byte)0x5F,(byte)0x14,(byte)0x37,
+(byte)0x4F,(byte)0xE1,(byte)0x35,(byte)0x6D,(byte)0x6D,(byte)0x51,(byte)0xC2,(byte)0x45,
+(byte)0xE4,(byte)0x85,(byte)0xB5,(byte)0x76,(byte)0x62,(byte)0x5E,(byte)0x7E,(byte)0xC6,
+(byte)0xF4,(byte)0x4C,(byte)0x42,(byte)0xE9,(byte)0xA6,(byte)0x37,(byte)0xED,(byte)0x6B,
+(byte)0x0B,(byte)0xFF,(byte)0x5C,(byte)0xB6,(byte)0xF4,(byte)0x06,(byte)0xB7,(byte)0xED,
+(byte)0xEE,(byte)0x38,(byte)0x6B,(byte)0xFB,(byte)0x5A,(byte)0x89,(byte)0x9F,(byte)0xA5,
+(byte)0xAE,(byte)0x9F,(byte)0x24,(byte)0x11,(byte)0x7C,(byte)0x4B,(byte)0x1F,(byte)0xE6,
+(byte)0x49,(byte)0x28,(byte)0x66,(byte)0x51,(byte)0xEC,(byte)0xE6,(byte)0x53,(byte)0x81,
+(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF
+};
+
+  private static final int SSH_MSG_KEXDH_INIT=                     30;
+  private static final int SSH_MSG_KEXDH_REPLY=                    31;
+
+  static final int RSA=0;
+  static final int DSS=1;
+  private int type=0;
+
+  private int state;
+
+  DH dh;
+//  HASH sha;
+
+//  byte[] K;
+//  byte[] H;
+
+  byte[] V_S;
+  byte[] V_C;
+  byte[] I_S;
+  byte[] I_C;
+
+//  byte[] K_S;
+
+  byte[] e;
+
+  private Buffer buf;
+  private Packet packet;
+
+  public void init(Session session,
+		   byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception{
+    this.session=session;
+    this.V_S=V_S;      
+    this.V_C=V_C;      
+    this.I_S=I_S;      
+    this.I_C=I_C;      
+
+//    sha=new SHA1();
+//    sha.init();
+    try{
+      Class c=Class.forName(session.getConfig("sha-1"));
+      sha=(HASH)(c.newInstance());
+      sha.init();
+    }
+    catch(Exception e){
+      System.err.println(e);
+    }
+
+    buf=new Buffer();
+    packet=new Packet(buf);
+
+    try{
+      Class c=Class.forName(session.getConfig("dh"));
+      dh=(DH)(c.newInstance());
+      dh.init();
+    }
+    catch(Exception e){
+      //System.err.println(e);
+      throw e;
+    }
+
+    dh.setP(p);
+    dh.setG(g);
+
+    // The client responds with:
+    // byte  SSH_MSG_KEXDH_INIT(30)
+    // mpint e <- g^x mod p
+    //         x is a random number (1 < x < (p-1)/2)
+
+    e=dh.getE();
+
+    packet.reset();
+    buf.putByte((byte)SSH_MSG_KEXDH_INIT);
+    buf.putMPInt(e);
+    session.write(packet);
+
+    if(JSch.getLogger().isEnabled(Logger.INFO)){
+      JSch.getLogger().log(Logger.INFO, 
+                           "SSH_MSG_KEXDH_INIT sent");
+      JSch.getLogger().log(Logger.INFO, 
+                           "expecting SSH_MSG_KEXDH_REPLY");
+    }
+
+    state=SSH_MSG_KEXDH_REPLY;
+  }
+
+  public boolean next(Buffer _buf) throws Exception{
+    int i,j;
+
+    switch(state){
+    case SSH_MSG_KEXDH_REPLY:
+      // The server responds with:
+      // byte      SSH_MSG_KEXDH_REPLY(31)
+      // string    server public host key and certificates (K_S)
+      // mpint     f
+      // string    signature of H
+      j=_buf.getInt();
+      j=_buf.getByte();
+      j=_buf.getByte();
+      if(j!=31){
+	System.err.println("type: must be 31 "+j);
+	return false;
+      }
+
+      K_S=_buf.getString();
+      // K_S is server_key_blob, which includes ....
+      // string ssh-dss
+      // impint p of dsa
+      // impint q of dsa
+      // impint g of dsa
+      // impint pub_key of dsa
+      //System.err.print("K_S: "); //dump(K_S, 0, K_S.length);
+      byte[] f=_buf.getMPInt();
+      byte[] sig_of_H=_buf.getString();
+      /*
+for(int ii=0; ii<sig_of_H.length;ii++){
+  System.err.print(Integer.toHexString(sig_of_H[ii]&0xff));
+  System.err.print(": ");
+}
+System.err.println("");
+      */
+
+      dh.setF(f);
+      K=dh.getK();
+
+      //The hash H is computed as the HASH hash of the concatenation of the
+      //following:
+      // string    V_C, the client's version string (CR and NL excluded)
+      // string    V_S, the server's version string (CR and NL excluded)
+      // string    I_C, the payload of the client's SSH_MSG_KEXINIT
+      // string    I_S, the payload of the server's SSH_MSG_KEXINIT
+      // string    K_S, the host key
+      // mpint     e, exchange value sent by the client
+      // mpint     f, exchange value sent by the server
+      // mpint     K, the shared secret
+      // This value is called the exchange hash, and it is used to authenti-
+      // cate the key exchange.
+      buf.reset();
+      buf.putString(V_C); buf.putString(V_S);
+      buf.putString(I_C); buf.putString(I_S);
+      buf.putString(K_S);
+      buf.putMPInt(e); buf.putMPInt(f);
+      buf.putMPInt(K);
+      byte[] foo=new byte[buf.getLength()];
+      buf.getByte(foo);
+      sha.update(foo, 0, foo.length);
+      H=sha.digest();
+      //System.err.print("H -> "); //dump(H, 0, H.length);
+
+      i=0;
+      j=0;
+      j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
+	((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
+      String alg=Util.byte2str(K_S, i, j);
+      i+=j;
+
+      boolean result=false;
+
+      if(alg.equals("ssh-rsa")){
+	byte[] tmp;
+	byte[] ee;
+	byte[] n;
+
+	type=RSA;
+
+	j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
+	  ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
+	tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
+	ee=tmp;
+	j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
+	  ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
+	tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
+	n=tmp;
+	
+//	SignatureRSA sig=new SignatureRSA();
+//	sig.init();
+
+	SignatureRSA sig=null;
+	try{
+	  Class c=Class.forName(session.getConfig("signature.rsa"));
+	  sig=(SignatureRSA)(c.newInstance());
+	  sig.init();
+	}
+	catch(Exception e){
+	  System.err.println(e);
+	}
+
+	sig.setPubKey(ee, n);   
+	sig.update(H);
+	result=sig.verify(sig_of_H);
+
+        if(JSch.getLogger().isEnabled(Logger.INFO)){
+          JSch.getLogger().log(Logger.INFO, 
+                               "ssh_rsa_verify: signature "+result);
+        }
+
+      }
+      else if(alg.equals("ssh-dss")){
+	byte[] q=null;
+	byte[] tmp;
+	byte[] p;
+	byte[] g;
+      
+	type=DSS;
+
+	j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
+	  ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
+	tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
+	p=tmp;
+	j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
+	  ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
+	tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
+	q=tmp;
+	j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
+	  ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
+	tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
+	g=tmp;
+	j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
+	  ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
+	tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
+	f=tmp;
+//	SignatureDSA sig=new SignatureDSA();
+//	sig.init();
+	SignatureDSA sig=null;
+	try{
+	  Class c=Class.forName(session.getConfig("signature.dss"));
+	  sig=(SignatureDSA)(c.newInstance());
+	  sig.init();
+	}
+	catch(Exception e){
+	  System.err.println(e);
+	}
+	sig.setPubKey(f, p, q, g);   
+	sig.update(H);
+	result=sig.verify(sig_of_H);
+
+        if(JSch.getLogger().isEnabled(Logger.INFO)){
+          JSch.getLogger().log(Logger.INFO, 
+                               "ssh_dss_verify: signature "+result);
+        }
+
+      }
+      else{
+	System.err.println("unknown alg");
+      }	    
+      state=STATE_END;
+      return result;
+    }
+    return false;
+  }
+
+  public String getKeyType(){
+    if(type==DSS) return "DSA";
+    return "RSA";
+  }
+
+  public int getState(){return state; }
+}
diff --git a/java/com/jcraft/jsch/DHG14.java b/java/com/jcraft/jsch/DHG14.java
new file mode 100644
index 0000000..8ef5fb7
--- /dev/null
+++ b/java/com/jcraft/jsch/DHG14.java
@@ -0,0 +1,310 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+public class DHG14 extends KeyExchange{
+
+  static final byte[] g={ 2 };
+  static final byte[] p={
+(byte)0x00,
+(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,
+(byte)0xC9,(byte)0x0F,(byte)0xDA,(byte)0xA2,(byte)0x21,(byte)0x68,(byte)0xC2,(byte)0x34,
+(byte)0xC4,(byte)0xC6,(byte)0x62,(byte)0x8B,(byte)0x80,(byte)0xDC,(byte)0x1C,(byte)0xD1,
+(byte)0x29,(byte)0x02,(byte)0x4E,(byte)0x08,(byte)0x8A,(byte)0x67,(byte)0xCC,(byte)0x74,
+(byte)0x02,(byte)0x0B,(byte)0xBE,(byte)0xA6,(byte)0x3B,(byte)0x13,(byte)0x9B,(byte)0x22,
+(byte)0x51,(byte)0x4A,(byte)0x08,(byte)0x79,(byte)0x8E,(byte)0x34,(byte)0x04,(byte)0xDD,
+(byte)0xEF,(byte)0x95,(byte)0x19,(byte)0xB3,(byte)0xCD,(byte)0x3A,(byte)0x43,(byte)0x1B,
+(byte)0x30,(byte)0x2B,(byte)0x0A,(byte)0x6D,(byte)0xF2,(byte)0x5F,(byte)0x14,(byte)0x37,
+(byte)0x4F,(byte)0xE1,(byte)0x35,(byte)0x6D,(byte)0x6D,(byte)0x51,(byte)0xC2,(byte)0x45,
+(byte)0xE4,(byte)0x85,(byte)0xB5,(byte)0x76,(byte)0x62,(byte)0x5E,(byte)0x7E,(byte)0xC6,
+(byte)0xF4,(byte)0x4C,(byte)0x42,(byte)0xE9,(byte)0xA6,(byte)0x37,(byte)0xED,(byte)0x6B,
+(byte)0x0B,(byte)0xFF,(byte)0x5C,(byte)0xB6,(byte)0xF4,(byte)0x06,(byte)0xB7,(byte)0xED,
+(byte)0xEE,(byte)0x38,(byte)0x6B,(byte)0xFB,(byte)0x5A,(byte)0x89,(byte)0x9F,(byte)0xA5,
+(byte)0xAE,(byte)0x9F,(byte)0x24,(byte)0x11,(byte)0x7C,(byte)0x4B,(byte)0x1F,(byte)0xE6,
+(byte)0x49,(byte)0x28,(byte)0x66,(byte)0x51,(byte)0xEC,(byte)0xE4,(byte)0x5B,(byte)0x3D,
+(byte)0xC2,(byte)0x00,(byte)0x7C,(byte)0xB8,(byte)0xA1,(byte)0x63,(byte)0xBF,(byte)0x05,
+(byte)0x98,(byte)0xDA,(byte)0x48,(byte)0x36,(byte)0x1C,(byte)0x55,(byte)0xD3,(byte)0x9A,
+(byte)0x69,(byte)0x16,(byte)0x3F,(byte)0xA8,(byte)0xFD,(byte)0x24,(byte)0xCF,(byte)0x5F,
+(byte)0x83,(byte)0x65,(byte)0x5D,(byte)0x23,(byte)0xDC,(byte)0xA3,(byte)0xAD,(byte)0x96,
+(byte)0x1C,(byte)0x62,(byte)0xF3,(byte)0x56,(byte)0x20,(byte)0x85,(byte)0x52,(byte)0xBB,
+(byte)0x9E,(byte)0xD5,(byte)0x29,(byte)0x07,(byte)0x70,(byte)0x96,(byte)0x96,(byte)0x6D,
+(byte)0x67,(byte)0x0C,(byte)0x35,(byte)0x4E,(byte)0x4A,(byte)0xBC,(byte)0x98,(byte)0x04,
+(byte)0xF1,(byte)0x74,(byte)0x6C,(byte)0x08,(byte)0xCA,(byte)0x18,(byte)0x21,(byte)0x7C,
+(byte)0x32,(byte)0x90,(byte)0x5E,(byte)0x46,(byte)0x2E,(byte)0x36,(byte)0xCE,(byte)0x3B,
+(byte)0xE3,(byte)0x9E,(byte)0x77,(byte)0x2C,(byte)0x18,(byte)0x0E,(byte)0x86,(byte)0x03,
+(byte)0x9B,(byte)0x27,(byte)0x83,(byte)0xA2,(byte)0xEC,(byte)0x07,(byte)0xA2,(byte)0x8F,
+(byte)0xB5,(byte)0xC5,(byte)0x5D,(byte)0xF0,(byte)0x6F,(byte)0x4C,(byte)0x52,(byte)0xC9,
+(byte)0xDE,(byte)0x2B,(byte)0xCB,(byte)0xF6,(byte)0x95,(byte)0x58,(byte)0x17,(byte)0x18,
+(byte)0x39,(byte)0x95,(byte)0x49,(byte)0x7C,(byte)0xEA,(byte)0x95,(byte)0x6A,(byte)0xE5,
+(byte)0x15,(byte)0xD2,(byte)0x26,(byte)0x18,(byte)0x98,(byte)0xFA,(byte)0x05,(byte)0x10,
+(byte)0x15,(byte)0x72,(byte)0x8E,(byte)0x5A,(byte)0x8A,(byte)0xAC,(byte)0xAA,(byte)0x68,
+(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF
+};
+
+  private static final int SSH_MSG_KEXDH_INIT=                     30;
+  private static final int SSH_MSG_KEXDH_REPLY=                    31;
+
+  static final int RSA=0;
+  static final int DSS=1;
+  private int type=0;
+
+  private int state;
+
+  DH dh;
+
+  byte[] V_S;
+  byte[] V_C;
+  byte[] I_S;
+  byte[] I_C;
+
+  byte[] e;
+
+  private Buffer buf;
+  private Packet packet;
+
+  public void init(Session session,
+		   byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception{
+    this.session=session;
+    this.V_S=V_S;      
+    this.V_C=V_C;      
+    this.I_S=I_S;      
+    this.I_C=I_C;      
+
+    try{
+      Class c=Class.forName(session.getConfig("sha-1"));
+      sha=(HASH)(c.newInstance());
+      sha.init();
+    }
+    catch(Exception e){
+      System.err.println(e);
+    }
+
+    buf=new Buffer();
+    packet=new Packet(buf);
+
+    try{
+      Class c=Class.forName(session.getConfig("dh"));
+      dh=(DH)(c.newInstance());
+      dh.init();
+    }
+    catch(Exception e){
+      //System.err.println(e);
+      throw e;
+    }
+
+    dh.setP(p);
+    dh.setG(g);
+    // The client responds with:
+    // byte  SSH_MSG_KEXDH_INIT(30)
+    // mpint e <- g^x mod p
+    //         x is a random number (1 < x < (p-1)/2)
+
+    e=dh.getE();
+    packet.reset();
+    buf.putByte((byte)SSH_MSG_KEXDH_INIT);
+    buf.putMPInt(e);
+
+    if(V_S==null){  // This is a really ugly hack for Session.checkKexes ;-(
+      return;
+    }
+
+    session.write(packet);
+
+    if(JSch.getLogger().isEnabled(Logger.INFO)){
+      JSch.getLogger().log(Logger.INFO, 
+                           "SSH_MSG_KEXDH_INIT sent");
+      JSch.getLogger().log(Logger.INFO, 
+                           "expecting SSH_MSG_KEXDH_REPLY");
+    }
+
+    state=SSH_MSG_KEXDH_REPLY;
+  }
+
+  public boolean next(Buffer _buf) throws Exception{
+    int i,j;
+
+    switch(state){
+    case SSH_MSG_KEXDH_REPLY:
+      // The server responds with:
+      // byte      SSH_MSG_KEXDH_REPLY(31)
+      // string    server public host key and certificates (K_S)
+      // mpint     f
+      // string    signature of H
+      j=_buf.getInt();
+      j=_buf.getByte();
+      j=_buf.getByte();
+      if(j!=31){
+	System.err.println("type: must be 31 "+j);
+	return false;
+      }
+
+      K_S=_buf.getString();
+      // K_S is server_key_blob, which includes ....
+      // string ssh-dss
+      // impint p of dsa
+      // impint q of dsa
+      // impint g of dsa
+      // impint pub_key of dsa
+      //System.err.print("K_S: "); //dump(K_S, 0, K_S.length);
+      byte[] f=_buf.getMPInt();
+      byte[] sig_of_H=_buf.getString();
+
+      dh.setF(f);
+      K=dh.getK();
+
+      //The hash H is computed as the HASH hash of the concatenation of the
+      //following:
+      // string    V_C, the client's version string (CR and NL excluded)
+      // string    V_S, the server's version string (CR and NL excluded)
+      // string    I_C, the payload of the client's SSH_MSG_KEXINIT
+      // string    I_S, the payload of the server's SSH_MSG_KEXINIT
+      // string    K_S, the host key
+      // mpint     e, exchange value sent by the client
+      // mpint     f, exchange value sent by the server
+      // mpint     K, the shared secret
+      // This value is called the exchange hash, and it is used to authenti-
+      // cate the key exchange.
+      buf.reset();
+      buf.putString(V_C); buf.putString(V_S);
+      buf.putString(I_C); buf.putString(I_S);
+      buf.putString(K_S);
+      buf.putMPInt(e); buf.putMPInt(f);
+      buf.putMPInt(K);
+      byte[] foo=new byte[buf.getLength()];
+      buf.getByte(foo);
+      sha.update(foo, 0, foo.length);
+      H=sha.digest();
+      //System.err.print("H -> "); //dump(H, 0, H.length);
+
+      i=0;
+      j=0;
+      j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
+	((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
+      String alg=Util.byte2str(K_S, i, j);
+      i+=j;
+
+      boolean result=false;
+
+      if(alg.equals("ssh-rsa")){
+	byte[] tmp;
+	byte[] ee;
+	byte[] n;
+
+	type=RSA;
+
+	j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
+	  ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
+	tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
+	ee=tmp;
+	j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
+	  ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
+	tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
+	n=tmp;
+	
+	SignatureRSA sig=null;
+	try{
+	  Class c=Class.forName(session.getConfig("signature.rsa"));
+	  sig=(SignatureRSA)(c.newInstance());
+	  sig.init();
+	}
+	catch(Exception e){
+	  System.err.println(e);
+	}
+
+	sig.setPubKey(ee, n);   
+	sig.update(H);
+	result=sig.verify(sig_of_H);
+
+        if(JSch.getLogger().isEnabled(Logger.INFO)){
+          JSch.getLogger().log(Logger.INFO, 
+                               "ssh_rsa_verify: signature "+result);
+        }
+
+      }
+      else if(alg.equals("ssh-dss")){
+	byte[] q=null;
+	byte[] tmp;
+	byte[] p;
+	byte[] g;
+      
+	type=DSS;
+
+	j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
+	  ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
+	tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
+	p=tmp;
+	j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
+	  ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
+	tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
+	q=tmp;
+	j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
+	  ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
+	tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
+	g=tmp;
+	j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
+	  ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
+	tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
+	f=tmp;
+
+	SignatureDSA sig=null;
+	try{
+	  Class c=Class.forName(session.getConfig("signature.dss"));
+	  sig=(SignatureDSA)(c.newInstance());
+	  sig.init();
+	}
+	catch(Exception e){
+	  System.err.println(e);
+	}
+	sig.setPubKey(f, p, q, g);   
+	sig.update(H);
+	result=sig.verify(sig_of_H);
+
+        if(JSch.getLogger().isEnabled(Logger.INFO)){
+          JSch.getLogger().log(Logger.INFO, 
+                               "ssh_dss_verify: signature "+result);
+        }
+
+      }
+      else{
+	System.err.println("unknown alg");
+      }	    
+      state=STATE_END;
+      return result;
+    }
+    return false;
+  }
+
+  public String getKeyType(){
+    if(type==DSS) return "DSA";
+    return "RSA";
+  }
+
+  public int getState(){return state; }
+}
diff --git a/java/com/jcraft/jsch/DHGEX.java b/java/com/jcraft/jsch/DHGEX.java
new file mode 100644
index 0000000..23fa9eb
--- /dev/null
+++ b/java/com/jcraft/jsch/DHGEX.java
@@ -0,0 +1,340 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+public class DHGEX extends KeyExchange{
+
+  private static final int SSH_MSG_KEX_DH_GEX_GROUP=               31;
+  private static final int SSH_MSG_KEX_DH_GEX_INIT=                32;
+  private static final int SSH_MSG_KEX_DH_GEX_REPLY=               33;
+  private static final int SSH_MSG_KEX_DH_GEX_REQUEST=             34;
+
+  static int min=1024;
+
+//  static int min=512;
+  static int preferred=1024;
+  static int max=1024;
+
+//  static int preferred=1024;
+//  static int max=2000;
+
+  static final int RSA=0;
+  static final int DSS=1;
+  private int type=0;
+
+  private int state;
+
+//  com.jcraft.jsch.DH dh;
+  DH dh;
+
+  byte[] V_S;
+  byte[] V_C;
+  byte[] I_S;
+  byte[] I_C;
+
+  private Buffer buf;
+  private Packet packet;
+
+  private byte[] p;
+  private byte[] g;
+  private byte[] e;
+  //private byte[] f;
+
+  public void init(Session session,
+		   byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception{
+    this.session=session;
+    this.V_S=V_S;      
+    this.V_C=V_C;      
+    this.I_S=I_S;      
+    this.I_C=I_C;      
+
+    try{
+      Class c=Class.forName(session.getConfig("sha-1"));
+      sha=(HASH)(c.newInstance());
+      sha.init();
+    }
+    catch(Exception e){
+      System.err.println(e);
+    }
+
+    buf=new Buffer();
+    packet=new Packet(buf);
+
+    try{
+      Class c=Class.forName(session.getConfig("dh"));
+      dh=(com.jcraft.jsch.DH)(c.newInstance());
+      dh.init();
+    }
+    catch(Exception e){
+//      System.err.println(e);
+      throw e;
+    }
+
+    packet.reset();
+    buf.putByte((byte)SSH_MSG_KEX_DH_GEX_REQUEST);
+    buf.putInt(min);
+    buf.putInt(preferred);
+    buf.putInt(max);
+    session.write(packet); 
+
+    if(JSch.getLogger().isEnabled(Logger.INFO)){
+      JSch.getLogger().log(Logger.INFO, 
+                           "SSH_MSG_KEX_DH_GEX_REQUEST("+min+"<"+preferred+"<"+max+") sent");
+      JSch.getLogger().log(Logger.INFO, 
+                           "expecting SSH_MSG_KEX_DH_GEX_GROUP");
+    }
+
+    state=SSH_MSG_KEX_DH_GEX_GROUP;
+  }
+
+  public boolean next(Buffer _buf) throws Exception{
+    int i,j;
+    switch(state){
+    case SSH_MSG_KEX_DH_GEX_GROUP:
+      // byte  SSH_MSG_KEX_DH_GEX_GROUP(31)
+      // mpint p, safe prime
+      // mpint g, generator for subgroup in GF (p)
+      _buf.getInt();
+      _buf.getByte();
+      j=_buf.getByte();
+      if(j!=SSH_MSG_KEX_DH_GEX_GROUP){
+	System.err.println("type: must be SSH_MSG_KEX_DH_GEX_GROUP "+j);
+	return false;
+      }
+
+      p=_buf.getMPInt();
+      g=_buf.getMPInt();
+      /*
+for(int iii=0; iii<p.length; iii++){
+System.err.println("0x"+Integer.toHexString(p[iii]&0xff)+",");
+}
+System.err.println("");
+for(int iii=0; iii<g.length; iii++){
+System.err.println("0x"+Integer.toHexString(g[iii]&0xff)+",");
+}
+      */
+      dh.setP(p);
+      dh.setG(g);
+
+      // The client responds with:
+      // byte  SSH_MSG_KEX_DH_GEX_INIT(32)
+      // mpint e <- g^x mod p
+      //         x is a random number (1 < x < (p-1)/2)
+
+      e=dh.getE();
+
+      packet.reset();
+      buf.putByte((byte)SSH_MSG_KEX_DH_GEX_INIT);
+      buf.putMPInt(e);
+      session.write(packet);
+
+      if(JSch.getLogger().isEnabled(Logger.INFO)){
+        JSch.getLogger().log(Logger.INFO, 
+                             "SSH_MSG_KEX_DH_GEX_INIT sent");
+        JSch.getLogger().log(Logger.INFO, 
+                             "expecting SSH_MSG_KEX_DH_GEX_REPLY");
+      }
+
+      state=SSH_MSG_KEX_DH_GEX_REPLY;
+      return true;
+      //break;
+
+    case SSH_MSG_KEX_DH_GEX_REPLY:
+      // The server responds with:
+      // byte      SSH_MSG_KEX_DH_GEX_REPLY(33)
+      // string    server public host key and certificates (K_S)
+      // mpint     f
+      // string    signature of H
+      j=_buf.getInt();
+      j=_buf.getByte();
+      j=_buf.getByte();
+      if(j!=SSH_MSG_KEX_DH_GEX_REPLY){
+	System.err.println("type: must be SSH_MSG_KEX_DH_GEX_REPLY "+j);
+	return false;
+      }
+
+      K_S=_buf.getString();
+      // K_S is server_key_blob, which includes ....
+      // string ssh-dss
+      // impint p of dsa
+      // impint q of dsa
+      // impint g of dsa
+      // impint pub_key of dsa
+      //System.err.print("K_S: "); dump(K_S, 0, K_S.length);
+
+      byte[] f=_buf.getMPInt();
+      byte[] sig_of_H=_buf.getString();
+
+      dh.setF(f);
+      K=dh.getK();
+
+      //The hash H is computed as the HASH hash of the concatenation of the
+      //following:
+      // string    V_C, the client's version string (CR and NL excluded)
+      // string    V_S, the server's version string (CR and NL excluded)
+      // string    I_C, the payload of the client's SSH_MSG_KEXINIT
+      // string    I_S, the payload of the server's SSH_MSG_KEXINIT
+      // string    K_S, the host key
+      // uint32    min, minimal size in bits of an acceptable group
+      // uint32   n, preferred size in bits of the group the server should send
+      // uint32    max, maximal size in bits of an acceptable group
+      // mpint     p, safe prime
+      // mpint     g, generator for subgroup
+      // mpint     e, exchange value sent by the client
+      // mpint     f, exchange value sent by the server
+      // mpint     K, the shared secret
+      // This value is called the exchange hash, and it is used to authenti-
+      // cate the key exchange.
+
+      buf.reset();
+      buf.putString(V_C); buf.putString(V_S);
+      buf.putString(I_C); buf.putString(I_S);
+      buf.putString(K_S);
+      buf.putInt(min); buf.putInt(preferred); buf.putInt(max);
+      buf.putMPInt(p); buf.putMPInt(g); buf.putMPInt(e); buf.putMPInt(f);
+      buf.putMPInt(K);
+
+      byte[] foo=new byte[buf.getLength()];
+      buf.getByte(foo);
+      sha.update(foo, 0, foo.length);
+
+      H=sha.digest();
+
+      // System.err.print("H -> "); dump(H, 0, H.length);
+
+      i=0;
+      j=0;
+      j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
+	((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
+      String alg=Util.byte2str(K_S, i, j);
+      i+=j;
+
+      boolean result=false;
+      if(alg.equals("ssh-rsa")){
+	byte[] tmp;
+	byte[] ee;
+	byte[] n;
+	
+	type=RSA;
+
+	j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
+	  ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
+	tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
+	ee=tmp;
+	j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
+	  ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
+	tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
+	n=tmp;
+
+//	SignatureRSA sig=new SignatureRSA();
+//	sig.init();
+
+	SignatureRSA sig=null;
+	try{
+	  Class c=Class.forName(session.getConfig("signature.rsa"));
+	  sig=(SignatureRSA)(c.newInstance());
+	  sig.init();
+	}
+	catch(Exception e){
+	  System.err.println(e);
+	}
+
+	sig.setPubKey(ee, n);   
+	sig.update(H);
+	result=sig.verify(sig_of_H);
+
+        if(JSch.getLogger().isEnabled(Logger.INFO)){
+          JSch.getLogger().log(Logger.INFO, 
+                               "ssh_rsa_verify: signature "+result);
+        }
+
+      }
+      else if(alg.equals("ssh-dss")){
+	byte[] q=null;
+	byte[] tmp;
+
+	type=DSS;
+
+	j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
+	  ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
+	tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
+	p=tmp;
+	j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
+	  ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
+	tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
+	q=tmp;
+	j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
+	  ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
+	tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
+	g=tmp;
+	j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
+	  ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
+	tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
+	f=tmp;
+	
+//	SignatureDSA sig=new SignatureDSA();
+//	sig.init();
+
+	SignatureDSA sig=null;
+	try{
+	  Class c=Class.forName(session.getConfig("signature.dss"));
+	  sig=(SignatureDSA)(c.newInstance());
+	  sig.init();
+	}
+	catch(Exception e){
+	  System.err.println(e);
+	}
+
+	sig.setPubKey(f, p, q, g);   
+	sig.update(H);
+	result=sig.verify(sig_of_H);
+
+        if(JSch.getLogger().isEnabled(Logger.INFO)){
+          JSch.getLogger().log(Logger.INFO, 
+                               "ssh_dss_verify: signature "+result);
+        }
+
+      }
+      else{
+	System.err.println("unknown alg");
+      }	    
+      state=STATE_END;
+      return result;
+    }
+    return false;
+  }
+
+  public String getKeyType(){
+    if(type==DSS) return "DSA";
+    return "RSA";
+  }
+
+  public int getState(){return state; }
+}
diff --git a/java/com/jcraft/jsch/ForwardedTCPIPDaemon.java b/java/com/jcraft/jsch/ForwardedTCPIPDaemon.java
new file mode 100644
index 0000000..4176aef
--- /dev/null
+++ b/java/com/jcraft/jsch/ForwardedTCPIPDaemon.java
@@ -0,0 +1,36 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+import java.io.*;
+
+public interface ForwardedTCPIPDaemon extends Runnable{
+  void setChannel(ChannelForwardedTCPIP channel, InputStream in, OutputStream out);
+  void setArg(Object[] arg);
+}
diff --git a/java/com/jcraft/jsch/GSSContext.java b/java/com/jcraft/jsch/GSSContext.java
new file mode 100644
index 0000000..23c58ee
--- /dev/null
+++ b/java/com/jcraft/jsch/GSSContext.java
@@ -0,0 +1,38 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2004-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+public interface GSSContext{
+  public void create(String user, String host) throws JSchException;
+  public boolean isEstablished();
+  public byte[] init(byte[] token, int s, int l) throws JSchException;
+  public byte[] getMIC(byte[] message, int s, int l);
+  public void dispose();
+}
diff --git a/java/com/jcraft/jsch/HASH.java b/java/com/jcraft/jsch/HASH.java
new file mode 100644
index 0000000..6bfff88
--- /dev/null
+++ b/java/com/jcraft/jsch/HASH.java
@@ -0,0 +1,37 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+public interface HASH{
+  void init() throws Exception;
+  int getBlockSize();
+  void update(byte[] foo, int start, int len) throws Exception;
+  byte[] digest() throws Exception;
+}
diff --git a/java/com/jcraft/jsch/HostKey.java b/java/com/jcraft/jsch/HostKey.java
new file mode 100644
index 0000000..6401ad2
--- /dev/null
+++ b/java/com/jcraft/jsch/HostKey.java
@@ -0,0 +1,104 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+public class HostKey{
+  private static final byte[] sshdss=Util.str2byte("ssh-dss");
+  private static final byte[] sshrsa=Util.str2byte("ssh-rsa");
+
+  protected static final int GUESS=0;
+  public static final int SSHDSS=1;
+  public static final int SSHRSA=2;
+  static final int UNKNOWN=3;
+
+  protected String host;
+  protected int type;
+  protected byte[] key;
+
+  public HostKey(String host, byte[] key) throws JSchException {
+    this(host, GUESS, key);
+  }
+
+  public HostKey(String host, int type, byte[] key) throws JSchException {
+    this.host=host; 
+    if(type==GUESS){
+      if(key[8]=='d'){ this.type=SSHDSS; }
+      else if(key[8]=='r'){ this.type=SSHRSA; }
+      else { throw new JSchException("invalid key type");}
+    }
+    else{
+      this.type=type; 
+    }
+    this.key=key;
+  }
+
+  public String getHost(){ return host; }
+  public String getType(){
+    if(type==SSHDSS){ return Util.byte2str(sshdss); }
+    if(type==SSHRSA){ return Util.byte2str(sshrsa);}
+    return "UNKNOWN";
+  }
+  public String getKey(){
+    return Util.byte2str(Util.toBase64(key, 0, key.length));
+  }
+  public String getFingerPrint(JSch jsch){
+    HASH hash=null;
+    try{
+      Class c=Class.forName(jsch.getConfig("md5"));
+      hash=(HASH)(c.newInstance());
+    }
+    catch(Exception e){ System.err.println("getFingerPrint: "+e); }
+    return Util.getFingerPrint(hash, key);
+  }
+
+  boolean isMatched(String _host){
+    return isIncluded(_host);
+  }
+
+  private boolean isIncluded(String _host){
+    int i=0;
+    String hosts=this.host; 
+    int hostslen=hosts.length();
+    int hostlen=_host.length();
+    int j;
+    while(i<hostslen){
+      j=hosts.indexOf(',', i);
+      if(j==-1){
+       if(hostlen!=hostslen-i) return false;
+       return hosts.regionMatches(true, i, _host, 0, hostlen);
+      }
+      if(hostlen==(j-i)){
+	if(hosts.regionMatches(true, i, _host, 0, hostlen)) return true;
+      }
+      i=j+1;
+    }
+    return false;
+  }
+}
diff --git a/java/com/jcraft/jsch/HostKeyRepository.java b/java/com/jcraft/jsch/HostKeyRepository.java
new file mode 100644
index 0000000..adfe633
--- /dev/null
+++ b/java/com/jcraft/jsch/HostKeyRepository.java
@@ -0,0 +1,44 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2004-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+public interface HostKeyRepository{
+  final int OK=0;
+  final int NOT_INCLUDED=1;
+  final int CHANGED=2;
+
+  int check(String host, byte[] key);
+  void add(HostKey hostkey, UserInfo ui);
+  void remove(String host, String type);
+  void remove(String host, String type, byte[] key);
+  String getKnownHostsRepositoryID();
+  HostKey[] getHostKey();
+  HostKey[] getHostKey(String host, String type);
+}
diff --git a/java/com/jcraft/jsch/IO.java b/java/com/jcraft/jsch/IO.java
new file mode 100644
index 0000000..65535ba
--- /dev/null
+++ b/java/com/jcraft/jsch/IO.java
@@ -0,0 +1,132 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+import java.io.*;
+
+public class IO{
+  InputStream in;
+  OutputStream out;
+  OutputStream out_ext;
+
+  private boolean in_dontclose=false;
+  private boolean out_dontclose=false;
+  private boolean out_ext_dontclose=false;
+
+  void setOutputStream(OutputStream out){ this.out=out; }
+  void setOutputStream(OutputStream out, boolean dontclose){
+    this.out_dontclose=dontclose;
+    setOutputStream(out);
+  }
+  void setExtOutputStream(OutputStream out){ this.out_ext=out; }
+  void setExtOutputStream(OutputStream out, boolean dontclose){
+    this.out_ext_dontclose=dontclose;
+    setExtOutputStream(out);
+  }
+  void setInputStream(InputStream in){ this.in=in; }
+  void setInputStream(InputStream in, boolean dontclose){
+    this.in_dontclose=dontclose;
+    setInputStream(in);
+  }
+
+  public void put(Packet p) throws IOException, java.net.SocketException {
+    out.write(p.buffer.buffer, 0, p.buffer.index);
+    out.flush();
+  }
+  void put(byte[] array, int begin, int length) throws IOException {
+    out.write(array, begin, length);
+    out.flush();
+  }
+  void put_ext(byte[] array, int begin, int length) throws IOException {
+    out_ext.write(array, begin, length);
+    out_ext.flush();
+  }
+
+  int getByte() throws IOException {
+    return in.read();
+  }
+
+  void getByte(byte[] array) throws IOException {
+    getByte(array, 0, array.length);
+  }
+
+  void getByte(byte[] array, int begin, int length) throws IOException {
+    do{
+      int completed = in.read(array, begin, length);
+      if(completed<0){
+	throw new IOException("End of IO Stream Read");
+      }
+      begin+=completed;
+      length-=completed;
+    }
+    while (length>0);
+  }
+
+  void out_close(){
+    try{
+      if(out!=null && !out_dontclose) out.close();
+      out=null;
+    }
+    catch(Exception ee){}
+  }
+
+  public void close(){
+    try{
+      if(in!=null && !in_dontclose) in.close();
+      in=null;
+    }
+    catch(Exception ee){}
+
+    out_close();
+
+    try{
+      if(out_ext!=null && !out_ext_dontclose) out_ext.close();
+      out_ext=null;
+    }
+    catch(Exception ee){}
+  }
+
+  /*
+  public void finalize() throws Throwable{
+    try{
+      if(in!=null) in.close();
+    }
+    catch(Exception ee){}
+    try{
+      if(out!=null) out.close();
+    }
+    catch(Exception ee){}
+    try{
+      if(out_ext!=null) out_ext.close();
+    }
+    catch(Exception ee){}
+  }
+  */
+}
diff --git a/java/com/jcraft/jsch/Identity.java b/java/com/jcraft/jsch/Identity.java
new file mode 100644
index 0000000..2f8cb80
--- /dev/null
+++ b/java/com/jcraft/jsch/Identity.java
@@ -0,0 +1,41 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+public interface Identity{
+  public boolean setPassphrase(byte[] passphrase) throws JSchException;
+  public byte[] getPublicKeyBlob();
+  public byte[] getSignature(byte[] data);
+  public boolean decrypt();
+  public String getAlgName();
+  public String getName();
+  public boolean isEncrypted();
+  public void clear();
+}
diff --git a/java/com/jcraft/jsch/IdentityFile.java b/java/com/jcraft/jsch/IdentityFile.java
new file mode 100644
index 0000000..0427dab
--- /dev/null
+++ b/java/com/jcraft/jsch/IdentityFile.java
@@ -0,0 +1,955 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+import java.io.*;
+
+class IdentityFile implements Identity{
+  String identity;
+  byte[] key;
+  byte[] iv;
+  private JSch jsch;
+  private HASH hash;
+  private byte[] encoded_data;
+
+  private Cipher cipher;
+
+  // DSA
+  private byte[] P_array;    
+  private byte[] Q_array;    
+  private byte[] G_array;    
+  private byte[] pub_array;    
+  private byte[] prv_array;    
+ 
+  // RSA
+  private  byte[] n_array;   // modulus
+  private  byte[] e_array;   // public exponent
+  private  byte[] d_array;   // private exponent
+ 
+//  private String algname="ssh-dss";
+  private String algname="ssh-rsa";
+
+  private static final int ERROR=0;
+  private static final int RSA=1;
+  private static final int DSS=2;
+  private static final int UNKNOWN=3;
+
+  private static final int OPENSSH=0;
+  private static final int FSECURE=1;
+  private static final int PUTTY=2;
+
+  private int type=ERROR;
+  private int keytype=OPENSSH;
+
+  private byte[] publickeyblob=null;
+
+  private boolean encrypted=true;
+
+  static IdentityFile newInstance(String prvfile, String pubfile, JSch jsch) throws JSchException{
+    byte[] prvkey=null;
+    byte[] pubkey=null;
+
+    File file=null;
+    FileInputStream fis=null;
+    try{
+      file=new File(prvfile);
+      fis=new FileInputStream(prvfile);
+      prvkey=new byte[(int)(file.length())];
+      int len=0;
+      while(true){
+        int i=fis.read(prvkey, len, prvkey.length-len);
+        if(i<=0)
+          break;
+        len+=i;
+      }
+      fis.close();
+    }
+    catch(Exception e){
+      try{ if(fis!=null) fis.close();}
+      catch(Exception ee){}
+      if(e instanceof Throwable)
+        throw new JSchException(e.toString(), (Throwable)e);
+      throw new JSchException(e.toString());
+    }
+
+    String _pubfile=pubfile;
+    if(pubfile==null){
+      _pubfile=prvfile+".pub";
+    }
+
+    try{
+      file=new File(_pubfile);
+      fis = new FileInputStream(_pubfile);
+      pubkey=new byte[(int)(file.length())];
+      int len=0;
+      while(true){
+        int i=fis.read(pubkey, len, pubkey.length-len);
+        if(i<=0)
+          break;
+        len+=i;
+      }
+      fis.close();
+    }
+    catch(Exception e){
+      try{ if(fis!=null) fis.close();}
+      catch(Exception ee){}
+      if(pubfile!=null){  
+        // The pubfile is explicitry given, but not accessible.
+        if(e instanceof Throwable)
+          throw new JSchException(e.toString(), (Throwable)e);
+        throw new JSchException(e.toString());
+      }
+    }
+    return newInstance(prvfile, prvkey, pubkey, jsch);
+  }
+
+  static IdentityFile newInstance(String name, byte[] prvkey, byte[] pubkey, JSch jsch) throws JSchException{
+    try{
+      return new IdentityFile(name, prvkey, pubkey, jsch);
+    }
+    finally{
+      Util.bzero(prvkey);
+    }
+  }
+
+  private IdentityFile(String name, byte[] prvkey, byte[] pubkey, JSch jsch) throws JSchException{
+    this.identity=name;
+    this.jsch=jsch;
+
+    // prvkey from "ssh-add" command on the remote.
+    if(pubkey==null &&
+       prvkey!=null && 
+       (prvkey.length>11 &&
+        prvkey[0]==0 && prvkey[1]==0 && prvkey[2]==0 && prvkey[3]==7)){
+
+      Buffer buf=new Buffer(prvkey);
+      String _type = new String(buf.getString()); // ssh-rsa
+
+      if(_type.equals("ssh-rsa")){
+        type=RSA;
+        n_array=buf.getString();
+        e_array=buf.getString();
+        d_array=buf.getString();
+        buf.getString();
+        buf.getString();
+        buf.getString();
+        this.identity += new String(buf.getString());
+      }
+      else if(_type.equals("ssh-dss")){
+        type=DSS;
+        P_array=buf.getString();
+        Q_array=buf.getString();
+        G_array=buf.getString();
+        pub_array=buf.getString();
+        prv_array=buf.getString();
+        this.identity += new String(buf.getString());
+      }
+      else{
+        throw new JSchException("privatekey: invalid key "+new String(prvkey, 4, 7));
+      }
+      encoded_data=prvkey;
+      encrypted=false;
+      keytype=OPENSSH;
+      return;
+    }
+
+    /* TODO: IdentityFile should use KeyPair.
+     * The following logic exists also in KeyPair. It is redundant.
+     */
+    try{
+      Class c;
+      c=Class.forName((String)jsch.getConfig("3des-cbc"));
+      cipher=(Cipher)(c.newInstance());
+      key=new byte[cipher.getBlockSize()];   // 24
+      iv=new byte[cipher.getIVSize()];       // 8
+      c=Class.forName((String)jsch.getConfig("md5"));
+      hash=(HASH)(c.newInstance());
+      hash.init();
+
+      byte[] buf=prvkey;
+      int len=buf.length;
+
+      int i=0;
+
+      while(i<len){
+        if(buf[i] == '-' && i+4<len && 
+           buf[i+1] == '-' && buf[i+2] == '-' && 
+           buf[i+3] == '-' && buf[i+4] == '-'){
+          break;
+        }
+        i++;
+      }
+
+      while(i<len){
+        if(buf[i]=='B'&& i+3<len && buf[i+1]=='E'&& buf[i+2]=='G'&& buf[i+3]=='I'){
+          i+=6;	    
+          if(buf[i]=='D'&& buf[i+1]=='S'&& buf[i+2]=='A'){ type=DSS; }
+	  else if(buf[i]=='R'&& buf[i+1]=='S'&& buf[i+2]=='A'){ type=RSA; }
+	  else if(buf[i]=='S'&& buf[i+1]=='S'&& buf[i+2]=='H'){ // FSecure
+	    type=UNKNOWN;
+	    keytype=FSECURE;
+	  }
+	  else{
+            //System.err.println("invalid format: "+identity);
+	    throw new JSchException("invalid privatekey: "+identity);
+	  }
+          i+=3;
+	  continue;
+	}
+        if(buf[i]=='A'&& i+7<len && buf[i+1]=='E'&& buf[i+2]=='S'&& buf[i+3]=='-' && 
+           buf[i+4]=='2'&& buf[i+5]=='5'&& buf[i+6]=='6'&& buf[i+7]=='-'){
+          i+=8;
+          if(Session.checkCipher((String)jsch.getConfig("aes256-cbc"))){
+            c=Class.forName((String)jsch.getConfig("aes256-cbc"));
+            cipher=(Cipher)(c.newInstance());
+            key=new byte[cipher.getBlockSize()];
+            iv=new byte[cipher.getIVSize()];
+          }
+          else{
+            throw new JSchException("privatekey: aes256-cbc is not available "+identity);
+          }
+          continue;
+        }
+        if(buf[i]=='A'&& i+7<len && buf[i+1]=='E'&& buf[i+2]=='S'&& buf[i+3]=='-' && 
+           buf[i+4]=='1'&& buf[i+5]=='9'&& buf[i+6]=='2'&& buf[i+7]=='-'){
+          i+=8;
+          if(Session.checkCipher((String)jsch.getConfig("aes192-cbc"))){
+            c=Class.forName((String)jsch.getConfig("aes192-cbc"));
+            cipher=(Cipher)(c.newInstance());
+            key=new byte[cipher.getBlockSize()];
+            iv=new byte[cipher.getIVSize()];
+          }
+          else{
+            throw new JSchException("privatekey: aes192-cbc is not available "+identity);
+          }
+          continue;
+        }
+        if(buf[i]=='A'&& i+7<len && buf[i+1]=='E'&& buf[i+2]=='S'&& buf[i+3]=='-' && 
+           buf[i+4]=='1'&& buf[i+5]=='2'&& buf[i+6]=='8'&& buf[i+7]=='-'){
+          i+=8;
+          if(Session.checkCipher((String)jsch.getConfig("aes128-cbc"))){
+            c=Class.forName((String)jsch.getConfig("aes128-cbc"));
+            cipher=(Cipher)(c.newInstance());
+            key=new byte[cipher.getBlockSize()];
+            iv=new byte[cipher.getIVSize()];
+          }
+          else{
+            throw new JSchException("privatekey: aes128-cbc is not available "+identity);
+          }
+          continue;
+        }
+        if(buf[i]=='C'&& i+3<len && buf[i+1]=='B'&& buf[i+2]=='C'&& buf[i+3]==','){
+          i+=4;
+	  for(int ii=0; ii<iv.length; ii++){
+            iv[ii]=(byte)(((a2b(buf[i++])<<4)&0xf0)+
+			  (a2b(buf[i++])&0xf));
+  	  }
+	  continue;
+	}
+	if(buf[i]==0x0d && i+1<len && buf[i+1]==0x0a){
+	  i++;
+	  continue;
+	}
+	if(buf[i]==0x0a && i+1<len){
+	  if(buf[i+1]==0x0a){ i+=2; break; }
+	  if(buf[i+1]==0x0d &&
+	     i+2<len && buf[i+2]==0x0a){
+	     i+=3; break;
+	  }
+	  boolean inheader=false;
+	  for(int j=i+1; j<len; j++){
+	    if(buf[j]==0x0a) break;
+	    //if(buf[j]==0x0d) break;
+	    if(buf[j]==':'){inheader=true; break;}
+	  }
+	  if(!inheader){
+	    i++; 
+	    encrypted=false;    // no passphrase
+	    break;
+	  }
+	}
+	i++;
+      }
+
+      if(type==ERROR){
+	throw new JSchException("invalid privatekey: "+identity);
+      }
+
+      int start=i;
+      while(i<len){
+        if(buf[i]==0x0a){
+	  boolean xd=(buf[i-1]==0x0d);
+          System.arraycopy(buf, i+1, 
+			   buf, 
+			   i-(xd ? 1 : 0), 
+			   len-i-1-(xd ? 1 : 0)
+			   );
+	  if(xd)len--;
+          len--;
+          continue;
+        }
+        if(buf[i]=='-'){  break; }
+        i++;
+      }
+      encoded_data=Util.fromBase64(buf, start, i-start);
+
+      if(encoded_data.length>4 &&            // FSecure
+	 encoded_data[0]==(byte)0x3f &&
+	 encoded_data[1]==(byte)0x6f &&
+	 encoded_data[2]==(byte)0xf9 &&
+	 encoded_data[3]==(byte)0xeb){
+
+	Buffer _buf=new Buffer(encoded_data);
+	_buf.getInt();  // 0x3f6ff9be
+	_buf.getInt();
+	byte[]_type=_buf.getString();
+	//System.err.println("type: "+new String(_type)); 
+	byte[] _cipher=_buf.getString();
+	String cipher=Util.byte2str(_cipher);
+	//System.err.println("cipher: "+cipher); 
+	if(cipher.equals("3des-cbc")){
+  	   _buf.getInt();
+	   byte[] foo=new byte[encoded_data.length-_buf.getOffSet()];
+	   _buf.getByte(foo);
+	   encoded_data=foo;
+	   encrypted=true;
+	   throw new JSchException("unknown privatekey format: "+identity);
+	}
+	else if(cipher.equals("none")){
+  	   _buf.getInt();
+  	   //_buf.getInt();
+
+           encrypted=false;
+
+	   byte[] foo=new byte[encoded_data.length-_buf.getOffSet()];
+	   _buf.getByte(foo);
+	   encoded_data=foo;
+	}
+
+      }
+
+      if(pubkey==null){
+        return;
+      }
+      
+      buf=pubkey;
+      len=buf.length;
+
+      if(buf.length>4 &&             // FSecure's public key
+	 buf[0]=='-' && buf[1]=='-' && buf[2]=='-' && buf[3]=='-'){
+	i=0;
+	do{i++;}while(len>i && buf[i]!=0x0a);
+	if(len<=i) return;
+	while(i<len){
+	  if(buf[i]==0x0a){
+	    boolean inheader=false;
+	    for(int j=i+1; j<len; j++){
+	      if(buf[j]==0x0a) break;
+	      if(buf[j]==':'){inheader=true; break;}
+	    }
+	    if(!inheader){
+	      i++; 
+	      break;
+	    }
+	  }
+	  i++;
+	}
+	if(len<=i) return;
+
+	start=i;
+	while(i<len){
+	  if(buf[i]==0x0a){
+	    System.arraycopy(buf, i+1, buf, i, len-i-1);
+	    len--;
+	    continue;
+	  }
+	  if(buf[i]=='-'){  break; }
+	  i++;
+	}
+	publickeyblob=Util.fromBase64(buf, start, i-start);
+
+	if(type==UNKNOWN && publickeyblob.length>8){
+	  if(publickeyblob[8]=='d'){
+	    type=DSS;
+	  }
+	  else if(publickeyblob[8]=='r'){
+	    type=RSA;
+	  }
+	}
+      }
+      else{
+	if(buf[0]!='s'|| buf[1]!='s'|| buf[2]!='h'|| buf[3]!='-') return;
+	i=0;
+	while(i<len){ if(buf[i]==' ')break; i++;} i++;
+	if(i>=len) return;
+	start=i;
+	while(i<len){ if(buf[i]==' ' || buf[i]=='\n')break; i++;}
+	publickeyblob=Util.fromBase64(buf, start, i-start);
+        if(publickeyblob.length<4+7){  // It must start with "ssh-XXX".
+          if(JSch.getLogger().isEnabled(Logger.WARN)){
+            JSch.getLogger().log(Logger.WARN, 
+                                 "failed to parse the public key");
+          }
+          publickeyblob=null;
+        }
+      }
+    }
+    catch(Exception e){
+      //System.err.println("IdentityFile: "+e);
+      if(e instanceof JSchException) throw (JSchException)e;
+      if(e instanceof Throwable)
+        throw new JSchException(e.toString(), (Throwable)e);
+      throw new JSchException(e.toString());
+    }
+  }
+
+  public String getAlgName(){
+    if(type==RSA) return "ssh-rsa";
+    return "ssh-dss"; 
+  }
+
+  public boolean setPassphrase(byte[] _passphrase) throws JSchException{
+    /*
+      hash is MD5
+      h(0) <- hash(passphrase, iv);
+      h(n) <- hash(h(n-1), passphrase, iv);
+      key <- (h(0),...,h(n))[0,..,key.length];
+    */
+    try{
+      if(encrypted){
+	if(_passphrase==null) return false;
+	byte[] passphrase=_passphrase;
+	int hsize=hash.getBlockSize();
+	byte[] hn=new byte[key.length/hsize*hsize+
+			   (key.length%hsize==0?0:hsize)];
+	byte[] tmp=null;
+	if(keytype==OPENSSH){
+	  for(int index=0; index+hsize<=hn.length;){
+	    if(tmp!=null){ hash.update(tmp, 0, tmp.length); }
+	    hash.update(passphrase, 0, passphrase.length);
+	    hash.update(iv, 0, iv.length > 8 ? 8: iv.length);
+	    tmp=hash.digest();
+	    System.arraycopy(tmp, 0, hn, index, tmp.length);
+	    index+=tmp.length;
+	  }
+	  System.arraycopy(hn, 0, key, 0, key.length); 
+	}
+	else if(keytype==FSECURE){
+	  for(int index=0; index+hsize<=hn.length;){
+	    if(tmp!=null){ hash.update(tmp, 0, tmp.length); }
+	    hash.update(passphrase, 0, passphrase.length);
+	    tmp=hash.digest();
+	    System.arraycopy(tmp, 0, hn, index, tmp.length);
+	    index+=tmp.length;
+	  }
+	  System.arraycopy(hn, 0, key, 0, key.length); 
+	}
+        Util.bzero(passphrase);
+      }
+      if(decrypt()){
+	encrypted=false;
+	return true;
+      }
+      P_array=Q_array=G_array=pub_array=prv_array=null;
+      return false;
+    }
+    catch(Exception e){
+      if(e instanceof JSchException) throw (JSchException)e;
+      if(e instanceof Throwable)
+        throw new JSchException(e.toString(), (Throwable)e);
+      throw new JSchException(e.toString());
+    }
+  }
+
+  public byte[] getPublicKeyBlob(){
+    if(publickeyblob!=null) return publickeyblob;
+    if(type==RSA) return getPublicKeyBlob_rsa();
+    return getPublicKeyBlob_dss();
+  }
+
+  byte[] getPublicKeyBlob_rsa(){
+    if(e_array==null) return null;
+    Buffer buf=new Buffer("ssh-rsa".length()+4+
+			   e_array.length+4+ 
+ 			   n_array.length+4);
+    buf.putString(Util.str2byte("ssh-rsa"));
+    buf.putString(e_array);
+    buf.putString(n_array);
+    return buf.buffer;
+  }
+
+  byte[] getPublicKeyBlob_dss(){
+    if(P_array==null) return null;
+    Buffer buf=new Buffer("ssh-dss".length()+4+
+			   P_array.length+4+ 
+			   Q_array.length+4+ 
+			   G_array.length+4+ 
+			   pub_array.length+4);
+    buf.putString(Util.str2byte("ssh-dss"));
+    buf.putString(P_array);
+    buf.putString(Q_array);
+    buf.putString(G_array);
+    buf.putString(pub_array);
+    return buf.buffer;
+  }
+
+  public byte[] getSignature(byte[] data){
+    if(type==RSA) return getSignature_rsa(data);
+    return getSignature_dss(data);
+  }
+
+  byte[] getSignature_rsa(byte[] data){
+    try{      
+      Class c=Class.forName((String)jsch.getConfig("signature.rsa"));
+      SignatureRSA rsa=(SignatureRSA)(c.newInstance());
+
+      rsa.init();
+      rsa.setPrvKey(d_array, n_array);
+
+      rsa.update(data);
+      byte[] sig = rsa.sign();
+      Buffer buf=new Buffer("ssh-rsa".length()+4+
+			    sig.length+4);
+      buf.putString(Util.str2byte("ssh-rsa"));
+      buf.putString(sig);
+      return buf.buffer;
+    }
+    catch(Exception e){
+    }
+    return null;
+  }
+
+  byte[] getSignature_dss(byte[] data){
+/*
+    byte[] foo;
+    int i;
+    System.err.print("P ");
+    foo=P_array;
+    for(i=0;  i<foo.length; i++){
+      System.err.print(Integer.toHexString(foo[i]&0xff)+":");
+    }
+    System.err.println("");
+    System.err.print("Q ");
+    foo=Q_array;
+    for(i=0;  i<foo.length; i++){
+      System.err.print(Integer.toHexString(foo[i]&0xff)+":");
+    }
+    System.err.println("");
+    System.err.print("G ");
+    foo=G_array;
+    for(i=0;  i<foo.length; i++){
+      System.err.print(Integer.toHexString(foo[i]&0xff)+":");
+    }
+    System.err.println("");
+*/
+
+    try{      
+      Class c=Class.forName((String)jsch.getConfig("signature.dss"));
+      SignatureDSA dsa=(SignatureDSA)(c.newInstance());
+      dsa.init();
+      dsa.setPrvKey(prv_array, P_array, Q_array, G_array);
+
+      dsa.update(data);
+      byte[] sig = dsa.sign();
+      Buffer buf=new Buffer("ssh-dss".length()+4+
+			    sig.length+4);
+      buf.putString(Util.str2byte("ssh-dss"));
+      buf.putString(sig);
+      return buf.buffer;
+    }
+    catch(Exception e){
+      //System.err.println("e "+e);
+    }
+    return null;
+  }
+
+  public boolean decrypt(){
+    if(type==RSA) return decrypt_rsa();
+    return decrypt_dss();
+  }
+
+  boolean decrypt_rsa(){
+    byte[] p_array;
+    byte[] q_array;
+    byte[] dmp1_array;
+    byte[] dmq1_array;
+    byte[] iqmp_array;
+
+    try{
+      byte[] plain;
+      if(encrypted){
+	if(keytype==OPENSSH){
+	  cipher.init(Cipher.DECRYPT_MODE, key, iv);
+	  plain=new byte[encoded_data.length];
+	  cipher.update(encoded_data, 0, encoded_data.length, plain, 0);
+	}
+	else if(keytype==FSECURE){
+	  for(int i=0; i<iv.length; i++)iv[i]=0;
+	  cipher.init(Cipher.DECRYPT_MODE, key, iv);
+	  plain=new byte[encoded_data.length];
+	  cipher.update(encoded_data, 0, encoded_data.length, plain, 0);
+	}
+	else{
+	  return false;
+	}
+      }
+      else{
+	if(n_array!=null) return true;
+	plain=encoded_data;
+      }
+
+      if(keytype==FSECURE){              // FSecure   
+	Buffer buf=new Buffer(plain);
+        int foo=buf.getInt();
+        if(plain.length!=foo+4){
+          return false;
+        }
+	e_array=buf.getMPIntBits();
+        d_array=buf.getMPIntBits();
+	n_array=buf.getMPIntBits();
+	byte[] u_array=buf.getMPIntBits();
+	p_array=buf.getMPIntBits();
+	q_array=buf.getMPIntBits();
+        return true;
+      }
+
+      int index=0;
+      int length=0;
+
+      if(plain[index]!=0x30)return false;
+      index++; // SEQUENCE
+      length=plain[index++]&0xff;
+      if((length&0x80)!=0){
+        int foo=length&0x7f; length=0;
+        while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
+      }
+
+      if(plain[index]!=0x02)return false;
+      index++; // INTEGER
+      length=plain[index++]&0xff;
+      if((length&0x80)!=0){
+        int foo=length&0x7f; length=0;
+        while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
+      }
+      index+=length;
+
+//System.err.println("int: len="+length);
+//System.err.print(Integer.toHexString(plain[index-1]&0xff)+":");
+//System.err.println("");
+
+      index++;
+      length=plain[index++]&0xff;
+      if((length&0x80)!=0){
+        int foo=length&0x7f; length=0;
+        while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
+      }
+      n_array=new byte[length];
+      System.arraycopy(plain, index, n_array, 0, length);
+      index+=length;
+/*
+System.err.println("int: N len="+length);
+for(int i=0; i<n_array.length; i++){
+System.err.print(Integer.toHexString(n_array[i]&0xff)+":");
+}
+System.err.println("");
+*/
+      index++;
+      length=plain[index++]&0xff;
+      if((length&0x80)!=0){
+        int foo=length&0x7f; length=0;
+        while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
+      }
+      e_array=new byte[length];
+      System.arraycopy(plain, index, e_array, 0, length);
+      index+=length;
+/*
+System.err.println("int: E len="+length);
+for(int i=0; i<e_array.length; i++){
+System.err.print(Integer.toHexString(e_array[i]&0xff)+":");
+}
+System.err.println("");
+*/
+      index++;
+      length=plain[index++]&0xff;
+      if((length&0x80)!=0){
+        int foo=length&0x7f; length=0;
+        while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
+      }
+      d_array=new byte[length];
+      System.arraycopy(plain, index, d_array, 0, length);
+      index+=length;
+/*
+System.err.println("int: D len="+length);
+for(int i=0; i<d_array.length; i++){
+System.err.print(Integer.toHexString(d_array[i]&0xff)+":");
+}
+System.err.println("");
+*/
+
+      index++;
+      length=plain[index++]&0xff;
+      if((length&0x80)!=0){
+        int foo=length&0x7f; length=0;
+        while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
+      }
+      p_array=new byte[length];
+      System.arraycopy(plain, index, p_array, 0, length);
+      index+=length;
+/*
+System.err.println("int: P len="+length);
+for(int i=0; i<p_array.length; i++){
+System.err.print(Integer.toHexString(p_array[i]&0xff)+":");
+}
+System.err.println("");
+*/
+      index++;
+      length=plain[index++]&0xff;
+      if((length&0x80)!=0){
+        int foo=length&0x7f; length=0;
+        while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
+      }
+      q_array=new byte[length];
+      System.arraycopy(plain, index, q_array, 0, length);
+      index+=length;
+/*
+System.err.println("int: q len="+length);
+for(int i=0; i<q_array.length; i++){
+System.err.print(Integer.toHexString(q_array[i]&0xff)+":");
+}
+System.err.println("");
+*/
+      index++;
+      length=plain[index++]&0xff;
+      if((length&0x80)!=0){
+        int foo=length&0x7f; length=0;
+        while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
+      }
+      dmp1_array=new byte[length];
+      System.arraycopy(plain, index, dmp1_array, 0, length);
+      index+=length;
+/*
+System.err.println("int: dmp1 len="+length);
+for(int i=0; i<dmp1_array.length; i++){
+System.err.print(Integer.toHexString(dmp1_array[i]&0xff)+":");
+}
+System.err.println("");
+*/
+      index++;
+      length=plain[index++]&0xff;
+      if((length&0x80)!=0){
+        int foo=length&0x7f; length=0;
+        while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
+      }
+      dmq1_array=new byte[length];
+      System.arraycopy(plain, index, dmq1_array, 0, length);
+      index+=length;
+/*
+System.err.println("int: dmq1 len="+length);
+for(int i=0; i<dmq1_array.length; i++){
+System.err.print(Integer.toHexString(dmq1_array[i]&0xff)+":");
+}
+System.err.println("");
+*/
+      index++;
+      length=plain[index++]&0xff;
+      if((length&0x80)!=0){
+        int foo=length&0x7f; length=0;
+        while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
+      }
+      iqmp_array=new byte[length];
+      System.arraycopy(plain, index, iqmp_array, 0, length);
+      index+=length;
+/*
+System.err.println("int: iqmp len="+length);
+for(int i=0; i<iqmp_array.length; i++){
+System.err.print(Integer.toHexString(iqmp_array[i]&0xff)+":");
+}
+System.err.println("");
+*/
+    }
+    catch(Exception e){
+      //System.err.println(e);
+      return false;
+    }
+    return true;
+  }
+
+  boolean decrypt_dss(){
+    try{
+      byte[] plain;
+      if(encrypted){
+	if(keytype==OPENSSH){
+	  cipher.init(Cipher.DECRYPT_MODE, key, iv);
+	  plain=new byte[encoded_data.length];
+	  cipher.update(encoded_data, 0, encoded_data.length, plain, 0);
+/*
+for(int i=0; i<plain.length; i++){
+System.err.print(Integer.toHexString(plain[i]&0xff)+":");
+}
+System.err.println("");
+*/
+	}
+	else if(keytype==FSECURE){
+	  for(int i=0; i<iv.length; i++)iv[i]=0;
+	  cipher.init(Cipher.DECRYPT_MODE, key, iv);
+	  plain=new byte[encoded_data.length];
+	  cipher.update(encoded_data, 0, encoded_data.length, plain, 0);
+	}
+	else{
+	  return false;
+	}
+      }
+      else{
+	if(P_array!=null) return true;
+	plain=encoded_data;
+      }
+
+      if(keytype==FSECURE){              // FSecure   
+	Buffer buf=new Buffer(plain);
+        int foo=buf.getInt();
+        if(plain.length!=foo+4){
+          return false;
+        }
+	P_array=buf.getMPIntBits();
+        G_array=buf.getMPIntBits();
+	Q_array=buf.getMPIntBits();
+	pub_array=buf.getMPIntBits();
+	prv_array=buf.getMPIntBits();
+        return true;
+      }
+
+      int index=0;
+      int length=0;
+      if(plain[index]!=0x30)return false;
+      index++; // SEQUENCE
+      length=plain[index++]&0xff;
+      if((length&0x80)!=0){
+        int foo=length&0x7f; length=0;
+        while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
+      }
+      if(plain[index]!=0x02)return false;
+      index++; // INTEGER
+      length=plain[index++]&0xff;
+      if((length&0x80)!=0){
+        int foo=length&0x7f; length=0;
+        while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
+      }
+      index+=length;
+
+      index++;
+      length=plain[index++]&0xff;
+      if((length&0x80)!=0){
+        int foo=length&0x7f; length=0;
+        while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
+      }
+      P_array=new byte[length];
+      System.arraycopy(plain, index, P_array, 0, length);
+      index+=length;
+
+      index++;
+      length=plain[index++]&0xff;
+      if((length&0x80)!=0){
+        int foo=length&0x7f; length=0;
+        while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
+      }
+      Q_array=new byte[length];
+      System.arraycopy(plain, index, Q_array, 0, length);
+      index+=length;
+
+      index++;
+      length=plain[index++]&0xff;
+      if((length&0x80)!=0){
+        int foo=length&0x7f; length=0;
+        while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
+      }
+      G_array=new byte[length];
+      System.arraycopy(plain, index, G_array, 0, length);
+      index+=length;
+
+      index++;
+      length=plain[index++]&0xff;
+      if((length&0x80)!=0){
+        int foo=length&0x7f; length=0;
+        while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
+      }
+      pub_array=new byte[length];
+      System.arraycopy(plain, index, pub_array, 0, length);
+      index+=length;
+
+      index++;
+      length=plain[index++]&0xff;
+      if((length&0x80)!=0){
+        int foo=length&0x7f; length=0;
+        while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
+      }
+      prv_array=new byte[length];
+      System.arraycopy(plain, index, prv_array, 0, length);
+      index+=length;
+    }
+    catch(Exception e){
+      //System.err.println(e);
+      //e.printStackTrace();
+      return false;
+    }
+    return true;
+  }
+
+  public boolean isEncrypted(){
+    return encrypted;
+  }
+
+  public String getName(){
+    return identity;
+  }
+
+  private byte a2b(byte c){
+    if('0'<=c&&c<='9') return (byte)(c-'0');
+    if('a'<=c&&c<='z') return (byte)(c-'a'+10);
+    return (byte)(c-'A'+10);
+  }
+
+  public boolean equals(Object o){
+    if(!(o instanceof IdentityFile)) return super.equals(o);
+    IdentityFile foo=(IdentityFile)o;
+    return getName().equals(foo.getName());
+  }
+
+  public void clear(){
+    Util.bzero(encoded_data);
+    Util.bzero(prv_array);
+    Util.bzero(d_array);
+    Util.bzero(key);
+    Util.bzero(iv);
+  }
+
+  public void finalize (){
+    clear();
+  }
+}
diff --git a/java/com/jcraft/jsch/IdentityRepository.java b/java/com/jcraft/jsch/IdentityRepository.java
new file mode 100644
index 0000000..1f75a01
--- /dev/null
+++ b/java/com/jcraft/jsch/IdentityRepository.java
@@ -0,0 +1,39 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+import java.util.Vector;
+
+public interface IdentityRepository {
+  public Vector getIdentities();
+  public boolean add(byte[] identity);
+  public boolean remove(byte[] blob);
+  public void removeAll();
+}
diff --git a/java/com/jcraft/jsch/JSch.java b/java/com/jcraft/jsch/JSch.java
new file mode 100644
index 0000000..20c39e5
--- /dev/null
+++ b/java/com/jcraft/jsch/JSch.java
@@ -0,0 +1,316 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+import java.io.InputStream;
+import java.util.Vector;
+
+public class JSch{
+  public static final String VERSION  = "0.1.46";
+
+  static java.util.Hashtable config=new java.util.Hashtable();
+  static{
+//  config.put("kex", "diffie-hellman-group-exchange-sha1");
+    config.put("kex", "diffie-hellman-group1-sha1,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1");
+    config.put("server_host_key", "ssh-rsa,ssh-dss");
+//    config.put("server_host_key", "ssh-dss,ssh-rsa");
+
+    config.put("cipher.s2c", 
+               "aes128-ctr,aes128-cbc,3des-ctr,3des-cbc,blowfish-cbc,aes192-cbc,aes256-cbc");
+    config.put("cipher.c2s",
+               "aes128-ctr,aes128-cbc,3des-ctr,3des-cbc,blowfish-cbc,aes192-cbc,aes256-cbc");
+
+    config.put("mac.s2c", "hmac-md5,hmac-sha1,hmac-sha1-96,hmac-md5-96");
+    config.put("mac.c2s", "hmac-md5,hmac-sha1,hmac-sha1-96,hmac-md5-96");
+    config.put("compression.s2c", "none");
+    // config.put("compression.s2c", "zlib@openssh.com,zlib,none");
+    config.put("compression.c2s", "none");
+    // config.put("compression.c2s", "zlib@openssh.com,zlib,none");
+
+    config.put("lang.s2c", "");
+    config.put("lang.c2s", "");
+
+    config.put("compression_level", "6");
+
+    config.put("diffie-hellman-group-exchange-sha1", 
+                                "com.jcraft.jsch.DHGEX");
+    config.put("diffie-hellman-group1-sha1", 
+	                        "com.jcraft.jsch.DHG1");
+    config.put("diffie-hellman-group14-sha1", 
+	                        "com.jcraft.jsch.DHG14");
+
+    config.put("dh",            "com.jcraft.jsch.jce.DH");
+    config.put("3des-cbc",      "com.jcraft.jsch.jce.TripleDESCBC");
+    config.put("blowfish-cbc",  "com.jcraft.jsch.jce.BlowfishCBC");
+    config.put("hmac-sha1",     "com.jcraft.jsch.jce.HMACSHA1");
+    config.put("hmac-sha1-96",  "com.jcraft.jsch.jce.HMACSHA196");
+    config.put("hmac-md5",      "com.jcraft.jsch.jce.HMACMD5");
+    config.put("hmac-md5-96",   "com.jcraft.jsch.jce.HMACMD596");
+    config.put("sha-1",         "com.jcraft.jsch.jce.SHA1");
+    config.put("md5",           "com.jcraft.jsch.jce.MD5");
+    config.put("signature.dss", "com.jcraft.jsch.jce.SignatureDSA");
+    config.put("signature.rsa", "com.jcraft.jsch.jce.SignatureRSA");
+    config.put("keypairgen.dsa",   "com.jcraft.jsch.jce.KeyPairGenDSA");
+    config.put("keypairgen.rsa",   "com.jcraft.jsch.jce.KeyPairGenRSA");
+    config.put("random",        "com.jcraft.jsch.jce.Random");
+
+    config.put("none",           "com.jcraft.jsch.CipherNone");
+
+    config.put("aes128-cbc",    "com.jcraft.jsch.jce.AES128CBC");
+    config.put("aes192-cbc",    "com.jcraft.jsch.jce.AES192CBC");
+    config.put("aes256-cbc",    "com.jcraft.jsch.jce.AES256CBC");
+
+    config.put("aes128-ctr",    "com.jcraft.jsch.jce.AES128CTR");
+    config.put("aes192-ctr",    "com.jcraft.jsch.jce.AES192CTR");
+    config.put("aes256-ctr",    "com.jcraft.jsch.jce.AES256CTR");
+    config.put("3des-ctr",      "com.jcraft.jsch.jce.TripleDESCTR");
+    config.put("arcfour",      "com.jcraft.jsch.jce.ARCFOUR");
+    config.put("arcfour128",      "com.jcraft.jsch.jce.ARCFOUR128");
+    config.put("arcfour256",      "com.jcraft.jsch.jce.ARCFOUR256");
+
+    config.put("userauth.none",    "com.jcraft.jsch.UserAuthNone");
+    config.put("userauth.password",    "com.jcraft.jsch.UserAuthPassword");
+    config.put("userauth.keyboard-interactive",    "com.jcraft.jsch.UserAuthKeyboardInteractive");
+    config.put("userauth.publickey",    "com.jcraft.jsch.UserAuthPublicKey");
+    config.put("userauth.gssapi-with-mic",    "com.jcraft.jsch.UserAuthGSSAPIWithMIC");
+    config.put("gssapi-with-mic.krb5",    "com.jcraft.jsch.jgss.GSSContextKrb5");
+
+    config.put("zlib",             "com.jcraft.jsch.jcraft.Compression");
+    config.put("zlib@openssh.com", "com.jcraft.jsch.jcraft.Compression");
+
+    config.put("StrictHostKeyChecking",  "ask");
+    config.put("HashKnownHosts",  "no");
+    //config.put("HashKnownHosts",  "yes");
+    config.put("PreferredAuthentications", "gssapi-with-mic,publickey,keyboard-interactive,password");
+
+    config.put("CheckCiphers", "aes256-ctr,aes192-ctr,aes128-ctr,aes256-cbc,aes192-cbc,aes128-cbc,3des-ctr,arcfour,arcfour128,arcfour256");
+    config.put("CheckKexes", "diffie-hellman-group14-sha1");
+
+    config.put("MaxAuthTries", "6");
+  }
+
+  private java.util.Vector sessionPool = new java.util.Vector();
+
+  private IdentityRepository identityRepository =
+    new LocalIdentityRepository(this);
+
+  public synchronized void setIdentityRepository(IdentityRepository identityRepository){
+    this.identityRepository = identityRepository;
+  }
+
+  synchronized IdentityRepository getIdentityRepository(){
+    return this.identityRepository;
+  }
+
+  private HostKeyRepository known_hosts=null;
+
+  private static final Logger DEVNULL=new Logger(){
+      public boolean isEnabled(int level){return false;}
+      public void log(int level, String message){}
+    };
+  static Logger logger=DEVNULL;
+
+  public JSch(){
+
+    try{
+      String osname=(String)(System.getProperties().get("os.name"));
+      if(osname!=null && osname.equals("Mac OS X")){
+        config.put("hmac-sha1",     "com.jcraft.jsch.jcraft.HMACSHA1"); 
+        config.put("hmac-md5",      "com.jcraft.jsch.jcraft.HMACMD5"); 
+        config.put("hmac-md5-96",   "com.jcraft.jsch.jcraft.HMACMD596"); 
+        config.put("hmac-sha1-96",  "com.jcraft.jsch.jcraft.HMACSHA196"); 
+      }
+    }
+    catch(Exception e){
+    }
+
+  }
+
+  public Session getSession(String username, String host) throws JSchException { return getSession(username, host, 22); }
+  public Session getSession(String username, String host, int port) throws JSchException {
+    if(username==null){
+      throw new JSchException("username must not be null.");
+    }
+    if(host==null){
+      throw new JSchException("host must not be null.");
+    }
+    Session s=new Session(this); 
+    s.setUserName(username);
+    s.setHost(host);
+    s.setPort(port);
+    return s;
+  }
+
+  protected void addSession(Session session){
+    synchronized(sessionPool){
+      sessionPool.addElement(session);
+    }
+  }
+
+  protected boolean removeSession(Session session){
+    synchronized(sessionPool){
+      return sessionPool.remove(session);
+    }
+  }
+  public void setHostKeyRepository(HostKeyRepository hkrepo){
+    known_hosts=hkrepo;
+  }
+
+  public void setKnownHosts(String filename) throws JSchException{
+    if(known_hosts==null) known_hosts=new KnownHosts(this);
+    if(known_hosts instanceof KnownHosts){
+      synchronized(known_hosts){
+	((KnownHosts)known_hosts).setKnownHosts(filename); 
+      }
+    }
+  }
+
+  public void setKnownHosts(InputStream stream) throws JSchException{ 
+    if(known_hosts==null) known_hosts=new KnownHosts(this);
+    if(known_hosts instanceof KnownHosts){
+      synchronized(known_hosts){
+	((KnownHosts)known_hosts).setKnownHosts(stream); 
+      }
+    }
+  }
+
+  public HostKeyRepository getHostKeyRepository(){ 
+    if(known_hosts==null) known_hosts=new KnownHosts(this);
+    return known_hosts; 
+  }
+
+  public void addIdentity(String prvkey) throws JSchException{
+    addIdentity(prvkey, (byte[])null);
+  }
+
+  public void addIdentity(String prvkey, String passphrase) throws JSchException{
+    byte[] _passphrase=null;
+    if(passphrase!=null){
+      _passphrase=Util.str2byte(passphrase);
+    }
+    addIdentity(prvkey, _passphrase);
+    if(_passphrase!=null)
+      Util.bzero(_passphrase);
+  }
+
+  public void addIdentity(String prvkey, byte[] passphrase) throws JSchException{
+    Identity identity=IdentityFile.newInstance(prvkey, null, this);
+    addIdentity(identity, passphrase);
+  }
+  public void addIdentity(String prvkey, String pubkey, byte[] passphrase) throws JSchException{
+    Identity identity=IdentityFile.newInstance(prvkey, pubkey, this);
+    addIdentity(identity, passphrase);
+  }
+
+  public void addIdentity(String name, byte[]prvkey, byte[]pubkey, byte[] passphrase) throws JSchException{
+    Identity identity=IdentityFile.newInstance(name, prvkey, pubkey, this);
+    addIdentity(identity, passphrase);
+  }
+
+  public void addIdentity(Identity identity, byte[] passphrase) throws JSchException{
+    if(passphrase!=null){
+      try{ 
+        byte[] goo=new byte[passphrase.length];
+        System.arraycopy(passphrase, 0, goo, 0, passphrase.length);
+        passphrase=goo;
+        identity.setPassphrase(passphrase); 
+      }
+      finally{
+        Util.bzero(passphrase);
+      }
+    }
+
+    if(identityRepository instanceof LocalIdentityRepository){
+      ((LocalIdentityRepository)identityRepository).add(identity);
+    }
+    else {
+      // TODO
+    }
+  }
+
+  /**
+   * @deprecated use JSch#removeIdentity(Identity identity)
+   */
+  public void removeIdentity(String name) throws JSchException{
+    Vector identities = identityRepository.getIdentities();
+    for(int i=0; i<identities.size(); i++){
+      Identity identity=(Identity)(identities.elementAt(i));
+      if(!identity.getName().equals(name))
+        continue;
+      identityRepository.remove(identity.getPublicKeyBlob());
+      break;
+    }
+  }
+
+  public void removeIdentity(Identity identity) throws JSchException{
+    identityRepository.remove(identity.getPublicKeyBlob());
+  }
+
+  public Vector getIdentityNames() throws JSchException{
+    Vector foo=new Vector();
+    Vector identities = identityRepository.getIdentities();
+    for(int i=0; i<identities.size(); i++){
+      Identity identity=(Identity)(identities.elementAt(i));
+      foo.addElement(identity.getName());
+    }
+    return foo;
+  }
+
+  public void removeAllIdentity() throws JSchException{
+    identityRepository.removeAll();
+  }
+
+  public static String getConfig(String key){ 
+    synchronized(config){
+      return (String)(config.get(key));
+    } 
+  }
+
+  public static void setConfig(java.util.Hashtable newconf){
+    synchronized(config){
+      for(java.util.Enumeration e=newconf.keys() ; e.hasMoreElements() ;) {
+	String key=(String)(e.nextElement());
+	config.put(key, (String)(newconf.get(key)));
+      }
+    }
+  }
+
+  public static void setConfig(String key, String value){
+    config.put(key, value);
+  }
+
+  public static void setLogger(Logger logger){
+    if(logger==null) logger=DEVNULL;
+    JSch.logger=logger;
+  }
+  static Logger getLogger(){
+    return logger;
+  }
+}
diff --git a/java/com/jcraft/jsch/JSchAuthCancelException.java b/java/com/jcraft/jsch/JSchAuthCancelException.java
new file mode 100644
index 0000000..65e71f1
--- /dev/null
+++ b/java/com/jcraft/jsch/JSchAuthCancelException.java
@@ -0,0 +1,45 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+class JSchAuthCancelException extends JSchException{
+  //private static final long serialVersionUID=3204965907117900987L;
+  String method;
+  JSchAuthCancelException () {
+    super();
+  }
+  JSchAuthCancelException (String s) {
+    super(s);
+    this.method=s;
+  }
+  public String getMethod(){
+    return method;
+  }
+}
diff --git a/java/com/jcraft/jsch/JSchException.java b/java/com/jcraft/jsch/JSchException.java
new file mode 100644
index 0000000..1e9056c
--- /dev/null
+++ b/java/com/jcraft/jsch/JSchException.java
@@ -0,0 +1,48 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+public class JSchException extends Exception{
+  //private static final long serialVersionUID=-1319309923966731989L;
+  private Throwable cause=null;
+  public JSchException () {
+    super();
+  }
+  public JSchException (String s) {
+    super(s);
+  }
+  public JSchException (String s, Throwable e) {
+    super(s);
+    this.cause=e;
+  }
+  public Throwable getCause(){
+    return this.cause;
+  }
+}
diff --git a/java/com/jcraft/jsch/JSchPartialAuthException.java b/java/com/jcraft/jsch/JSchPartialAuthException.java
new file mode 100644
index 0000000..aa7ac9e
--- /dev/null
+++ b/java/com/jcraft/jsch/JSchPartialAuthException.java
@@ -0,0 +1,45 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+class JSchPartialAuthException extends JSchException{
+  //private static final long serialVersionUID=-378849862323360367L;
+  String methods;
+  public JSchPartialAuthException () {
+    super();
+  }
+  public JSchPartialAuthException (String s) {
+    super(s);
+    this.methods=s;
+  }
+  public String getMethods(){
+    return methods;
+  }
+}
diff --git a/java/com/jcraft/jsch/KeyExchange.java b/java/com/jcraft/jsch/KeyExchange.java
new file mode 100644
index 0000000..ef089ba
--- /dev/null
+++ b/java/com/jcraft/jsch/KeyExchange.java
@@ -0,0 +1,159 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+public abstract class KeyExchange{
+
+  static final int PROPOSAL_KEX_ALGS=0;
+  static final int PROPOSAL_SERVER_HOST_KEY_ALGS=1;
+  static final int PROPOSAL_ENC_ALGS_CTOS=2;
+  static final int PROPOSAL_ENC_ALGS_STOC=3;
+  static final int PROPOSAL_MAC_ALGS_CTOS=4;
+  static final int PROPOSAL_MAC_ALGS_STOC=5;
+  static final int PROPOSAL_COMP_ALGS_CTOS=6;
+  static final int PROPOSAL_COMP_ALGS_STOC=7;
+  static final int PROPOSAL_LANG_CTOS=8;
+  static final int PROPOSAL_LANG_STOC=9;
+  static final int PROPOSAL_MAX=10;
+
+  //static String kex_algs="diffie-hellman-group-exchange-sha1"+
+  //                       ",diffie-hellman-group1-sha1";
+
+//static String kex="diffie-hellman-group-exchange-sha1";
+  static String kex="diffie-hellman-group1-sha1";
+  static String server_host_key="ssh-rsa,ssh-dss";
+  static String enc_c2s="blowfish-cbc";
+  static String enc_s2c="blowfish-cbc";
+  static String mac_c2s="hmac-md5";     // hmac-md5,hmac-sha1,hmac-ripemd160,
+                                        // hmac-sha1-96,hmac-md5-96
+  static String mac_s2c="hmac-md5";
+//static String comp_c2s="none";        // zlib
+//static String comp_s2c="none";
+  static String lang_c2s="";
+  static String lang_s2c="";
+
+  public static final int STATE_END=0;
+
+  protected Session session=null;
+  protected HASH sha=null;
+  protected byte[] K=null;
+  protected byte[] H=null;
+  protected byte[] K_S=null;
+
+  public abstract void init(Session session, 
+			    byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception;
+  public abstract boolean next(Buffer buf) throws Exception;
+  public abstract String getKeyType();
+  public abstract int getState();
+
+  /*
+  void dump(byte[] foo){
+    for(int i=0; i<foo.length; i++){
+      if((foo[i]&0xf0)==0)System.err.print("0");
+      System.err.print(Integer.toHexString(foo[i]&0xff));
+      if(i%16==15){System.err.println(""); continue;}
+      if(i%2==1)System.err.print(" ");
+    }
+  } 
+  */
+
+  protected static String[] guess(byte[]I_S, byte[]I_C){
+    String[] guess=new String[PROPOSAL_MAX];
+    Buffer sb=new Buffer(I_S); sb.setOffSet(17);
+    Buffer cb=new Buffer(I_C); cb.setOffSet(17);
+
+    for(int i=0; i<PROPOSAL_MAX; i++){
+      byte[] sp=sb.getString();  // server proposal
+      byte[] cp=cb.getString();  // client proposal
+      int j=0;
+      int k=0;
+
+      loop:
+      while(j<cp.length){
+	while(j<cp.length && cp[j]!=',')j++; 
+	if(k==j) return null;
+	String algorithm=Util.byte2str(cp, k, j-k);
+	int l=0;
+	int m=0;
+	while(l<sp.length){
+	  while(l<sp.length && sp[l]!=',')l++; 
+	  if(m==l) return null;
+	  if(algorithm.equals(Util.byte2str(sp, m, l-m))){
+	    guess[i]=algorithm;
+	    break loop;
+	  }
+	  l++;
+	  m=l;
+	}	
+	j++;
+	k=j;
+      }
+      if(j==0){
+	guess[i]="";
+      }
+      else if(guess[i]==null){
+	return null;
+      }
+    }
+
+    if(JSch.getLogger().isEnabled(Logger.INFO)){
+      JSch.getLogger().log(Logger.INFO, 
+                           "kex: server->client"+
+                           " "+guess[PROPOSAL_ENC_ALGS_STOC]+
+                           " "+guess[PROPOSAL_MAC_ALGS_STOC]+
+                           " "+guess[PROPOSAL_COMP_ALGS_STOC]);
+      JSch.getLogger().log(Logger.INFO, 
+                           "kex: client->server"+
+                           " "+guess[PROPOSAL_ENC_ALGS_CTOS]+
+                           " "+guess[PROPOSAL_MAC_ALGS_CTOS]+
+                           " "+guess[PROPOSAL_COMP_ALGS_CTOS]);
+    }
+
+//    for(int i=0; i<PROPOSAL_MAX; i++){
+//      System.err.println("guess: ["+guess[i]+"]");
+//    }
+
+    return guess;
+  }
+
+  public String getFingerPrint(){
+    HASH hash=null;
+    try{
+      Class c=Class.forName(session.getConfig("md5"));
+      hash=(HASH)(c.newInstance());
+    }
+    catch(Exception e){ System.err.println("getFingerPrint: "+e); }
+    return Util.getFingerPrint(hash, getHostKey());
+  }
+  byte[] getK(){ return K; }
+  byte[] getH(){ return H; }
+  HASH getHash(){ return sha; }
+  byte[] getHostKey(){ return K_S; }
+}
diff --git a/java/com/jcraft/jsch/KeyPair.java b/java/com/jcraft/jsch/KeyPair.java
new file mode 100644
index 0000000..b3f681c
--- /dev/null
+++ b/java/com/jcraft/jsch/KeyPair.java
@@ -0,0 +1,729 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+import java.io.FileOutputStream;
+import java.io.FileInputStream;
+import java.io.File;
+
+public abstract class KeyPair{
+  public static final int ERROR=0;
+  public static final int DSA=1;
+  public static final int RSA=2;
+  public static final int UNKNOWN=3;
+
+  static final int VENDOR_OPENSSH=0;
+  static final int VENDOR_FSECURE=1;
+  int vendor=VENDOR_OPENSSH;
+
+  private static final byte[] cr=Util.str2byte("\n");
+
+  public static KeyPair genKeyPair(JSch jsch, int type) throws JSchException{
+    return genKeyPair(jsch, type, 1024);
+  }
+  public static KeyPair genKeyPair(JSch jsch, int type, int key_size) throws JSchException{
+    KeyPair kpair=null;
+    if(type==DSA){ kpair=new KeyPairDSA(jsch); }
+    else if(type==RSA){ kpair=new KeyPairRSA(jsch); }
+    if(kpair!=null){
+      kpair.generate(key_size);
+    }
+    return kpair;
+  }
+
+  abstract void generate(int key_size) throws JSchException;
+
+  abstract byte[] getBegin();
+  abstract byte[] getEnd();
+  abstract int getKeySize();
+
+  public String getPublicKeyComment(){
+    return publicKeyComment;
+  }
+  private String publicKeyComment = "";
+
+  JSch jsch=null;
+  private Cipher cipher;
+  private HASH hash;
+  private Random random;
+
+  private byte[] passphrase;
+
+  public KeyPair(JSch jsch){
+    this.jsch=jsch;
+  }
+
+  static byte[][] header={Util.str2byte("Proc-Type: 4,ENCRYPTED"),
+                          Util.str2byte("DEK-Info: DES-EDE3-CBC,")};
+
+  abstract byte[] getPrivateKey();
+
+  public void writePrivateKey(java.io.OutputStream out){
+    byte[] plain=getPrivateKey();
+    byte[][] _iv=new byte[1][];
+    byte[] encoded=encrypt(plain, _iv);
+    if(encoded!=plain)
+      Util.bzero(plain);
+    byte[] iv=_iv[0];
+    byte[] prv=Util.toBase64(encoded, 0, encoded.length);
+
+    try{
+      out.write(getBegin()); out.write(cr);
+      if(passphrase!=null){
+	out.write(header[0]); out.write(cr);
+	out.write(header[1]); 
+	for(int i=0; i<iv.length; i++){
+	  out.write(b2a((byte)((iv[i]>>>4)&0x0f)));
+	  out.write(b2a((byte)(iv[i]&0x0f)));
+	}
+        out.write(cr);
+	out.write(cr);
+      }
+      int i=0;
+      while(i<prv.length){
+	if(i+64<prv.length){
+	  out.write(prv, i, 64);
+	  out.write(cr);
+	  i+=64;
+	  continue;
+	}
+	out.write(prv, i, prv.length-i);
+	out.write(cr);
+	break;
+      }
+      out.write(getEnd()); out.write(cr);
+      //out.close();
+    }
+    catch(Exception e){
+    }
+  }
+
+  private static byte[] space=Util.str2byte(" ");
+
+  abstract byte[] getKeyTypeName();
+  public abstract int getKeyType();
+
+  public byte[] getPublicKeyBlob(){ return publickeyblob; }
+
+  public void writePublicKey(java.io.OutputStream out, String comment){
+    byte[] pubblob=getPublicKeyBlob();
+    byte[] pub=Util.toBase64(pubblob, 0, pubblob.length);
+    try{
+      out.write(getKeyTypeName()); out.write(space);
+      out.write(pub, 0, pub.length); out.write(space);
+      out.write(Util.str2byte(comment));
+      out.write(cr);
+    }
+    catch(Exception e){
+    }
+  }
+
+  public void writePublicKey(String name, String comment) throws java.io.FileNotFoundException, java.io.IOException{
+    FileOutputStream fos=new FileOutputStream(name);
+    writePublicKey(fos, comment);
+    fos.close();
+  }
+
+  public void writeSECSHPublicKey(java.io.OutputStream out, String comment){
+    byte[] pubblob=getPublicKeyBlob();
+    byte[] pub=Util.toBase64(pubblob, 0, pubblob.length);
+    try{
+      out.write(Util.str2byte("---- BEGIN SSH2 PUBLIC KEY ----")); out.write(cr);
+      out.write(Util.str2byte("Comment: \""+comment+"\"")); out.write(cr);
+      int index=0;
+      while(index<pub.length){
+	int len=70;
+	if((pub.length-index)<len)len=pub.length-index;
+	out.write(pub, index, len); out.write(cr);
+	index+=len;
+      }
+      out.write(Util.str2byte("---- END SSH2 PUBLIC KEY ----")); out.write(cr);
+    }
+    catch(Exception e){
+    }
+  }
+
+  public void writeSECSHPublicKey(String name, String comment) throws java.io.FileNotFoundException, java.io.IOException{
+    FileOutputStream fos=new FileOutputStream(name);
+    writeSECSHPublicKey(fos, comment);
+    fos.close();
+  }
+
+
+  public void writePrivateKey(String name) throws java.io.FileNotFoundException, java.io.IOException{
+    FileOutputStream fos=new FileOutputStream(name);
+    writePrivateKey(fos);
+    fos.close();
+  }
+
+  public String getFingerPrint(){
+    if(hash==null) hash=genHash();
+    byte[] kblob=getPublicKeyBlob();
+    if(kblob==null) return null;
+    return getKeySize()+" "+Util.getFingerPrint(hash, kblob);
+  }
+
+  private byte[] encrypt(byte[] plain, byte[][] _iv){
+    if(passphrase==null) return plain;
+
+    if(cipher==null) cipher=genCipher();
+    byte[] iv=_iv[0]=new byte[cipher.getIVSize()];
+
+    if(random==null) random=genRandom();
+    random.fill(iv, 0, iv.length);
+
+    byte[] key=genKey(passphrase, iv);
+    byte[] encoded=plain;
+
+    // PKCS#5Padding
+    {
+      //int bsize=cipher.getBlockSize();
+      int bsize=cipher.getIVSize();
+      byte[] foo=new byte[(encoded.length/bsize+1)*bsize];
+      System.arraycopy(encoded, 0, foo, 0, encoded.length);
+      int padding=bsize-encoded.length%bsize;
+      for(int i=foo.length-1; (foo.length-padding)<=i; i--){
+        foo[i]=(byte)padding;
+      }
+      encoded=foo;
+    }
+
+    try{
+      cipher.init(Cipher.ENCRYPT_MODE, key, iv);
+      cipher.update(encoded, 0, encoded.length, encoded, 0);
+    }
+    catch(Exception e){
+      //System.err.println(e);
+    }
+    Util.bzero(key);
+    return encoded;
+  }
+
+  abstract boolean parse(byte[] data);
+
+  private byte[] decrypt(byte[] data, byte[] passphrase, byte[] iv){
+    /*
+    if(iv==null){  // FSecure
+      iv=new byte[8];
+      for(int i=0; i<iv.length; i++)iv[i]=0;
+    }
+    */
+    try{
+      byte[] key=genKey(passphrase, iv);
+      cipher.init(Cipher.DECRYPT_MODE, key, iv);
+      Util.bzero(key);
+      byte[] plain=new byte[data.length];
+      cipher.update(data, 0, data.length, plain, 0);
+      return plain;
+    }
+    catch(Exception e){
+      //System.err.println(e);
+    }
+    return null;
+  }
+
+  int writeSEQUENCE(byte[] buf, int index, int len){
+    buf[index++]=0x30;
+    index=writeLength(buf, index, len);
+    return index;
+  }
+  int writeINTEGER(byte[] buf, int index, byte[] data){
+    buf[index++]=0x02;
+    index=writeLength(buf, index, data.length);
+    System.arraycopy(data, 0, buf, index, data.length);
+    index+=data.length;
+    return index;
+  }
+
+  int countLength(int len){
+    int i=1;
+    if(len<=0x7f) return i;
+    while(len>0){
+      len>>>=8;
+      i++;
+    }
+    return i;
+  }
+
+  int writeLength(byte[] data, int index, int len){
+    int i=countLength(len)-1;
+    if(i==0){
+      data[index++]=(byte)len;
+      return index;
+    }
+    data[index++]=(byte)(0x80|i);
+    int j=index+i;
+    while(i>0){
+      data[index+i-1]=(byte)(len&0xff);
+      len>>>=8;
+      i--;
+    }
+    return j;
+  }
+
+  private Random genRandom(){
+    if(random==null){
+      try{
+	Class c=Class.forName(jsch.getConfig("random"));
+        random=(Random)(c.newInstance());
+      }
+      catch(Exception e){ System.err.println("connect: random "+e); }
+    }
+    return random;
+  }
+
+  private HASH genHash(){
+    try{
+      Class c=Class.forName(jsch.getConfig("md5"));
+      hash=(HASH)(c.newInstance());
+      hash.init();
+    }
+    catch(Exception e){
+    }
+    return hash;
+  }
+  private Cipher genCipher(){
+    try{
+      Class c;
+      c=Class.forName(jsch.getConfig("3des-cbc"));
+      cipher=(Cipher)(c.newInstance());
+    }
+    catch(Exception e){
+    }
+    return cipher;
+  }
+
+  /*
+    hash is MD5
+    h(0) <- hash(passphrase, iv);
+    h(n) <- hash(h(n-1), passphrase, iv);
+    key <- (h(0),...,h(n))[0,..,key.length];
+  */
+  synchronized byte[] genKey(byte[] passphrase, byte[] iv){
+    if(cipher==null) cipher=genCipher();
+    if(hash==null) hash=genHash();
+
+    byte[] key=new byte[cipher.getBlockSize()];
+    int hsize=hash.getBlockSize();
+    byte[] hn=new byte[key.length/hsize*hsize+
+		       (key.length%hsize==0?0:hsize)];
+    try{
+      byte[] tmp=null;
+      if(vendor==VENDOR_OPENSSH){
+	for(int index=0; index+hsize<=hn.length;){
+	  if(tmp!=null){ hash.update(tmp, 0, tmp.length); }
+	  hash.update(passphrase, 0, passphrase.length);
+          hash.update(iv, 0, iv.length > 8 ? 8: iv.length);
+	  tmp=hash.digest();
+	  System.arraycopy(tmp, 0, hn, index, tmp.length);
+	  index+=tmp.length;
+	}
+	System.arraycopy(hn, 0, key, 0, key.length); 
+      }
+      else if(vendor==VENDOR_FSECURE){
+	for(int index=0; index+hsize<=hn.length;){
+	  if(tmp!=null){ hash.update(tmp, 0, tmp.length); }
+	  hash.update(passphrase, 0, passphrase.length);
+	  tmp=hash.digest();
+	  System.arraycopy(tmp, 0, hn, index, tmp.length);
+	  index+=tmp.length;
+	}
+	System.arraycopy(hn, 0, key, 0, key.length); 
+      }
+    }
+    catch(Exception e){
+      System.err.println(e);
+    }
+    return key;
+  } 
+
+  public void setPassphrase(String passphrase){
+    if(passphrase==null || passphrase.length()==0){
+      setPassphrase((byte[])null);
+    }
+    else{
+      setPassphrase(Util.str2byte(passphrase));
+    }
+  }
+  public void setPassphrase(byte[] passphrase){
+    if(passphrase!=null && passphrase.length==0) 
+      passphrase=null;
+    this.passphrase=passphrase;
+  }
+
+  private boolean encrypted=false;
+  private byte[] data=null;
+  private byte[] iv=null;
+  private byte[] publickeyblob=null;
+
+  public boolean isEncrypted(){ return encrypted; }
+  public boolean decrypt(String _passphrase){
+    if(_passphrase==null || _passphrase.length()==0){
+      return !encrypted;
+    }
+    return decrypt(Util.str2byte(_passphrase));
+  }
+  public boolean decrypt(byte[] _passphrase){
+    if(!encrypted){
+      return true;
+    }
+    if(_passphrase==null){
+      return !encrypted;
+    }
+    byte[] bar=new byte[_passphrase.length];
+    System.arraycopy(_passphrase, 0, bar, 0, bar.length);
+    _passphrase=bar;
+    byte[] foo=decrypt(data, _passphrase, iv);
+    Util.bzero(_passphrase);
+    if(parse(foo)){
+      encrypted=false;
+    }
+    return !encrypted;
+  }
+
+  public static KeyPair load(JSch jsch, String prvkey) throws JSchException{
+    String pubkey=prvkey+".pub";
+    if(!new File(pubkey).exists()){
+      pubkey=null;
+    }
+    return load(jsch, prvkey, pubkey);
+  }
+  public static KeyPair load(JSch jsch, String prvkey, String pubkey) throws JSchException{
+
+    byte[] iv=new byte[8];       // 8
+    boolean encrypted=true;
+    byte[] data=null;
+
+    byte[] publickeyblob=null;
+
+    int type=ERROR;
+    int vendor=VENDOR_OPENSSH;
+    String publicKeyComment = "";
+    Cipher cipher=null;
+
+    try{
+      File file=new File(prvkey);
+      FileInputStream fis=new FileInputStream(prvkey);
+      byte[] buf=new byte[(int)(file.length())];
+      int len=0;
+      while(true){
+        int i=fis.read(buf, len, buf.length-len);
+        if(i<=0)
+          break;
+        len+=i;
+      }
+      fis.close();
+
+      int i=0;
+
+      while(i<len){
+        if(buf[i] == '-' && i+4<len && 
+           buf[i+1] == '-' && buf[i+2] == '-' && 
+           buf[i+3] == '-' && buf[i+4] == '-'){
+          break;
+        }
+        i++;
+      }
+
+      while(i<len){
+        if(buf[i]=='B'&& i+3<len && buf[i+1]=='E'&& buf[i+2]=='G'&& buf[i+3]=='I'){
+          i+=6;	    
+          if(buf[i]=='D'&& buf[i+1]=='S'&& buf[i+2]=='A'){ type=DSA; }
+	  else if(buf[i]=='R'&& buf[i+1]=='S'&& buf[i+2]=='A'){ type=RSA; }
+	  else if(buf[i]=='S'&& buf[i+1]=='S'&& buf[i+2]=='H'){ // FSecure
+	    type=UNKNOWN;
+	    vendor=VENDOR_FSECURE;
+	  }
+	  else{
+	    throw new JSchException("invalid privatekey: "+prvkey);
+	  }
+          i+=3;
+	  continue;
+	}
+        if(buf[i]=='A'&& i+7<len && buf[i+1]=='E'&& buf[i+2]=='S'&& buf[i+3]=='-' && 
+           buf[i+4]=='2'&& buf[i+5]=='5'&& buf[i+6]=='6'&& buf[i+7]=='-'){
+          i+=8;
+          if(Session.checkCipher((String)jsch.getConfig("aes256-cbc"))){
+            Class c=Class.forName((String)jsch.getConfig("aes256-cbc"));
+            cipher=(Cipher)(c.newInstance());
+            // key=new byte[cipher.getBlockSize()];
+            iv=new byte[cipher.getIVSize()];
+          }
+          else{
+            throw new JSchException("privatekey: aes256-cbc is not available "+prvkey);
+          }
+          continue;
+        }
+        if(buf[i]=='A'&& i+7<len && buf[i+1]=='E'&& buf[i+2]=='S'&& buf[i+3]=='-' && 
+           buf[i+4]=='1'&& buf[i+5]=='9'&& buf[i+6]=='2'&& buf[i+7]=='-'){
+          i+=8;
+          if(Session.checkCipher((String)jsch.getConfig("aes192-cbc"))){
+            Class c=Class.forName((String)jsch.getConfig("aes192-cbc"));
+            cipher=(Cipher)(c.newInstance());
+            // key=new byte[cipher.getBlockSize()];
+            iv=new byte[cipher.getIVSize()];
+          }
+          else{
+            throw new JSchException("privatekey: aes192-cbc is not available "+prvkey);
+          }
+          continue;
+        }
+        if(buf[i]=='A'&& i+7<len && buf[i+1]=='E'&& buf[i+2]=='S'&& buf[i+3]=='-' && 
+           buf[i+4]=='1'&& buf[i+5]=='2'&& buf[i+6]=='8'&& buf[i+7]=='-'){
+          i+=8;
+          if(Session.checkCipher((String)jsch.getConfig("aes128-cbc"))){
+            Class c=Class.forName((String)jsch.getConfig("aes128-cbc"));
+            cipher=(Cipher)(c.newInstance());
+            // key=new byte[cipher.getBlockSize()];
+            iv=new byte[cipher.getIVSize()];
+          }
+          else{
+            throw new JSchException("privatekey: aes128-cbc is not available "+prvkey);
+          }
+          continue;
+        }
+        if(buf[i]=='C'&& i+3<len && buf[i+1]=='B'&& buf[i+2]=='C'&& buf[i+3]==','){
+          i+=4;
+	  for(int ii=0; ii<iv.length; ii++){
+            iv[ii]=(byte)(((a2b(buf[i++])<<4)&0xf0)+(a2b(buf[i++])&0xf));
+  	  }
+	  continue;
+	}
+	if(buf[i]==0x0d && i+1<buf.length && buf[i+1]==0x0a){
+	  i++;
+	  continue;
+	}
+	if(buf[i]==0x0a && i+1<buf.length){
+	  if(buf[i+1]==0x0a){ i+=2; break; }
+	  if(buf[i+1]==0x0d &&
+	     i+2<buf.length && buf[i+2]==0x0a){
+	     i+=3; break;
+	  }
+	  boolean inheader=false;
+	  for(int j=i+1; j<buf.length; j++){
+	    if(buf[j]==0x0a) break;
+	    //if(buf[j]==0x0d) break;
+	    if(buf[j]==':'){inheader=true; break;}
+	  }
+	  if(!inheader){
+	    i++; 
+	    encrypted=false;    // no passphrase
+	    break;
+	  }
+	}
+	i++;
+      }
+
+      if(type==ERROR){
+	throw new JSchException("invalid privatekey: "+prvkey);
+      }
+
+      int start=i;
+      while(i<len){
+        if(buf[i]==0x0a){
+	  boolean xd=(buf[i-1]==0x0d);
+          System.arraycopy(buf, i+1, 
+			   buf, 
+			   i-(xd ? 1 : 0), 
+			   len-i-1-(xd ? 1 : 0)
+			   );
+	  if(xd)len--;
+          len--;
+          continue;
+        }
+        if(buf[i]=='-'){  break; }
+        i++;
+      }
+      data=Util.fromBase64(buf, start, i-start);
+
+      if(data.length>4 &&            // FSecure
+	 data[0]==(byte)0x3f &&
+	 data[1]==(byte)0x6f &&
+	 data[2]==(byte)0xf9 &&
+	 data[3]==(byte)0xeb){
+
+	Buffer _buf=new Buffer(data);
+	_buf.getInt();  // 0x3f6ff9be
+	_buf.getInt();
+	byte[]_type=_buf.getString();
+	//System.err.println("type: "+new String(_type)); 
+	String _cipher=Util.byte2str(_buf.getString());
+	//System.err.println("cipher: "+_cipher); 
+	if(_cipher.equals("3des-cbc")){
+  	   _buf.getInt();
+	   byte[] foo=new byte[data.length-_buf.getOffSet()];
+	   _buf.getByte(foo);
+	   data=foo;
+	   encrypted=true;
+	   throw new JSchException("unknown privatekey format: "+prvkey);
+	}
+	else if(_cipher.equals("none")){
+  	   _buf.getInt();
+  	   _buf.getInt();
+
+           encrypted=false;
+
+	   byte[] foo=new byte[data.length-_buf.getOffSet()];
+	   _buf.getByte(foo);
+	   data=foo;
+	}
+      }
+
+      if(pubkey!=null){
+	try{
+	  file=new File(pubkey);
+	  fis=new FileInputStream(pubkey);
+	  buf=new byte[(int)(file.length())];
+          len=0;
+          while(true){
+            i=fis.read(buf, len, buf.length-len);
+            if(i<=0)
+              break;
+            len+=i;
+          }
+	  fis.close();
+
+	  if(buf.length>4 &&             // FSecure's public key
+	     buf[0]=='-' && buf[1]=='-' && buf[2]=='-' && buf[3]=='-'){
+
+	    boolean valid=true;
+	    i=0;
+	    do{i++;}while(buf.length>i && buf[i]!=0x0a);
+	    if(buf.length<=i) {valid=false;}
+
+	    while(valid){
+	      if(buf[i]==0x0a){
+		boolean inheader=false;
+		for(int j=i+1; j<buf.length; j++){
+		  if(buf[j]==0x0a) break;
+		  if(buf[j]==':'){inheader=true; break;}
+		}
+		if(!inheader){
+		  i++; 
+		  break;
+		}
+	      }
+	      i++;
+	    }
+	    if(buf.length<=i){valid=false;}
+
+	    start=i;
+	    while(valid && i<len){
+	      if(buf[i]==0x0a){
+		System.arraycopy(buf, i+1, buf, i, len-i-1);
+		len--;
+		continue;
+	      }
+	      if(buf[i]=='-'){  break; }
+	      i++;
+	    }
+	    if(valid){
+	      publickeyblob=Util.fromBase64(buf, start, i-start);
+	      if(type==UNKNOWN){
+		if(publickeyblob[8]=='d'){ type=DSA; }
+		else if(publickeyblob[8]=='r'){ type=RSA; }
+	      }
+	    }
+	  }
+	  else{
+	    if(buf[0]=='s'&& buf[1]=='s'&& buf[2]=='h' && buf[3]=='-'){
+	      i=0;
+	      while(i<len){ if(buf[i]==' ')break; i++;} i++;
+	      if(i<len){
+		start=i;
+		while(i<len){ if(buf[i]==' ')break; i++;}
+		publickeyblob=Util.fromBase64(buf, start, i-start);
+	      }
+              if(i++<len){
+                int s=i;
+                while(i<len){ if(buf[i]=='\n')break; i++;}
+                if(i<len){
+                  publicKeyComment = new String(buf, s, i-s);
+                }
+              } 
+	    }
+	  }
+	}
+	catch(Exception ee){
+	}
+      }
+    }
+    catch(Exception e){
+      if(e instanceof JSchException) throw (JSchException)e;
+      if(e instanceof Throwable)
+        throw new JSchException(e.toString(), (Throwable)e);
+      throw new JSchException(e.toString());
+    }
+
+    KeyPair kpair=null;
+    if(type==DSA){ kpair=new KeyPairDSA(jsch); }
+    else if(type==RSA){ kpair=new KeyPairRSA(jsch); }
+
+    if(kpair!=null){
+      kpair.encrypted=encrypted;
+      kpair.publickeyblob=publickeyblob;
+      kpair.vendor=vendor;
+      kpair.publicKeyComment=publicKeyComment;
+      kpair.cipher=cipher;
+
+      if(encrypted){
+	kpair.iv=iv;
+	kpair.data=data;
+      }
+      else{
+	if(kpair.parse(data)){
+	  return kpair;
+	}
+	else{
+	  throw new JSchException("invalid privatekey: "+prvkey);
+	}
+      }
+    }
+
+    return kpair;
+  }
+
+  static private byte a2b(byte c){
+    if('0'<=c&&c<='9') return (byte)(c-'0');
+    return (byte)(c-'a'+10);
+  }
+  static private byte b2a(byte c){
+    if(0<=c&&c<=9) return (byte)(c+'0');
+    return (byte)(c-10+'A');
+  }
+
+  public void dispose(){
+    Util.bzero(passphrase);
+  }
+
+  public void finalize (){
+    dispose();
+  }
+}
diff --git a/java/com/jcraft/jsch/KeyPairDSA.java b/java/com/jcraft/jsch/KeyPairDSA.java
new file mode 100644
index 0000000..f65d8c0
--- /dev/null
+++ b/java/com/jcraft/jsch/KeyPairDSA.java
@@ -0,0 +1,221 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+public class KeyPairDSA extends KeyPair{
+  private byte[] P_array;
+  private byte[] Q_array;
+  private byte[] G_array;
+  private byte[] pub_array;
+  private byte[] prv_array;
+
+  //private int key_size=0;
+  private int key_size=1024;
+
+  public KeyPairDSA(JSch jsch){
+    super(jsch);
+  }
+
+  void generate(int key_size) throws JSchException{
+    this.key_size=key_size;
+    try{
+      Class c=Class.forName(jsch.getConfig("keypairgen.dsa"));
+      KeyPairGenDSA keypairgen=(KeyPairGenDSA)(c.newInstance());
+      keypairgen.init(key_size);
+      P_array=keypairgen.getP();
+      Q_array=keypairgen.getQ();
+      G_array=keypairgen.getG();
+      pub_array=keypairgen.getY();
+      prv_array=keypairgen.getX();
+
+      keypairgen=null;
+    }
+    catch(Exception e){
+      //System.err.println("KeyPairDSA: "+e); 
+      if(e instanceof Throwable)
+        throw new JSchException(e.toString(), (Throwable)e);
+      throw new JSchException(e.toString());
+    }
+  }
+
+  private static final byte[] begin=Util.str2byte("-----BEGIN DSA PRIVATE KEY-----");
+  private static final byte[] end=Util.str2byte("-----END DSA PRIVATE KEY-----");
+
+  byte[] getBegin(){ return begin; }
+  byte[] getEnd(){ return end; }
+
+  byte[] getPrivateKey(){
+    int content=
+      1+countLength(1) + 1 +                           // INTEGER
+      1+countLength(P_array.length) + P_array.length + // INTEGER  P
+      1+countLength(Q_array.length) + Q_array.length + // INTEGER  Q
+      1+countLength(G_array.length) + G_array.length + // INTEGER  G
+      1+countLength(pub_array.length) + pub_array.length + // INTEGER  pub
+      1+countLength(prv_array.length) + prv_array.length;  // INTEGER  prv
+
+    int total=
+      1+countLength(content)+content;   // SEQUENCE
+
+    byte[] plain=new byte[total];
+    int index=0;
+    index=writeSEQUENCE(plain, index, content);
+    index=writeINTEGER(plain, index, new byte[1]);  // 0
+    index=writeINTEGER(plain, index, P_array);
+    index=writeINTEGER(plain, index, Q_array);
+    index=writeINTEGER(plain, index, G_array);
+    index=writeINTEGER(plain, index, pub_array);
+    index=writeINTEGER(plain, index, prv_array);
+    return plain;
+  }
+
+  boolean parse(byte[] plain){
+    try{
+
+      if(vendor==VENDOR_FSECURE){
+	if(plain[0]!=0x30){              // FSecure
+	  Buffer buf=new Buffer(plain);
+	  buf.getInt();
+	  P_array=buf.getMPIntBits();
+	  G_array=buf.getMPIntBits();
+	  Q_array=buf.getMPIntBits();
+	  pub_array=buf.getMPIntBits();
+	  prv_array=buf.getMPIntBits();
+	  return true;
+	}
+	return false;
+      }
+
+      int index=0;
+      int length=0;
+
+      if(plain[index]!=0x30)return false;
+      index++; // SEQUENCE
+      length=plain[index++]&0xff;
+      if((length&0x80)!=0){
+        int foo=length&0x7f; length=0;
+        while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
+      }
+
+      if(plain[index]!=0x02)return false;
+      index++; // INTEGER
+      length=plain[index++]&0xff;
+      if((length&0x80)!=0){
+        int foo=length&0x7f; length=0;
+        while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
+      }
+      index+=length;
+
+      index++;
+      length=plain[index++]&0xff;
+      if((length&0x80)!=0){
+        int foo=length&0x7f; length=0;
+        while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
+      }
+      P_array=new byte[length];
+      System.arraycopy(plain, index, P_array, 0, length);
+      index+=length;
+
+      index++;
+      length=plain[index++]&0xff;
+      if((length&0x80)!=0){
+        int foo=length&0x7f; length=0;
+        while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
+      }
+      Q_array=new byte[length];
+      System.arraycopy(plain, index, Q_array, 0, length);
+      index+=length;
+
+      index++;
+      length=plain[index++]&0xff;
+      if((length&0x80)!=0){
+        int foo=length&0x7f; length=0;
+        while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
+      }
+      G_array=new byte[length];
+      System.arraycopy(plain, index, G_array, 0, length);
+      index+=length;
+
+      index++;
+      length=plain[index++]&0xff;
+      if((length&0x80)!=0){
+        int foo=length&0x7f; length=0;
+        while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
+      }
+      pub_array=new byte[length];
+      System.arraycopy(plain, index, pub_array, 0, length);
+      index+=length;
+
+      index++;
+      length=plain[index++]&0xff;
+      if((length&0x80)!=0){
+        int foo=length&0x7f; length=0;
+        while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
+      }
+      prv_array=new byte[length];
+      System.arraycopy(plain, index, prv_array, 0, length);
+      index+=length;
+    }
+    catch(Exception e){
+      //System.err.println(e);
+      //e.printStackTrace();
+      return false;
+    }
+    return true;
+  }
+
+  public byte[] getPublicKeyBlob(){
+    byte[] foo=super.getPublicKeyBlob();
+    if(foo!=null) return foo;
+
+    if(P_array==null) return null;
+
+    Buffer buf=new Buffer(sshdss.length+4+
+			  P_array.length+4+ 
+			  Q_array.length+4+ 
+			  G_array.length+4+ 
+			  pub_array.length+4);
+    buf.putString(sshdss);
+    buf.putString(P_array);
+    buf.putString(Q_array);
+    buf.putString(G_array);
+    buf.putString(pub_array);
+    return buf.buffer;
+  }
+
+  private static final byte[] sshdss=Util.str2byte("ssh-dss");
+  byte[] getKeyTypeName(){return sshdss;}
+  public int getKeyType(){return DSA;}
+
+  public int getKeySize(){return key_size; }
+  public void dispose(){
+    super.dispose();
+    Util.bzero(prv_array);
+  }
+}
diff --git a/java/com/jcraft/jsch/KeyPairGenDSA.java b/java/com/jcraft/jsch/KeyPairGenDSA.java
new file mode 100644
index 0000000..f6507f2
--- /dev/null
+++ b/java/com/jcraft/jsch/KeyPairGenDSA.java
@@ -0,0 +1,39 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+public interface KeyPairGenDSA{
+  void init(int key_size) throws Exception;
+  byte[] getX();
+  byte[] getY();
+  byte[] getP();
+  byte[] getQ();
+  byte[] getG();
+}
diff --git a/java/com/jcraft/jsch/KeyPairGenRSA.java b/java/com/jcraft/jsch/KeyPairGenRSA.java
new file mode 100644
index 0000000..3a84907
--- /dev/null
+++ b/java/com/jcraft/jsch/KeyPairGenRSA.java
@@ -0,0 +1,43 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+public interface KeyPairGenRSA{
+  void init(int key_size) throws Exception;
+  byte[] getD();
+  byte[] getE();
+  byte[] getN();
+
+  byte[] getC();
+  byte[] getEP();
+  byte[] getEQ();
+  byte[] getP();
+  byte[] getQ();
+}
diff --git a/java/com/jcraft/jsch/KeyPairRSA.java b/java/com/jcraft/jsch/KeyPairRSA.java
new file mode 100644
index 0000000..dfc202f
--- /dev/null
+++ b/java/com/jcraft/jsch/KeyPairRSA.java
@@ -0,0 +1,320 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+public class KeyPairRSA extends KeyPair{
+  private byte[] prv_array;
+  private byte[] pub_array;
+  private byte[] n_array;
+
+  private byte[] p_array;  // prime p
+  private byte[] q_array;  // prime q
+  private byte[] ep_array; // prime exponent p
+  private byte[] eq_array; // prime exponent q
+  private byte[] c_array;  // coefficient
+
+  //private int key_size=0;
+  private int key_size=1024;
+
+  public KeyPairRSA(JSch jsch){
+    super(jsch);
+  }
+
+  void generate(int key_size) throws JSchException{
+    this.key_size=key_size;
+    try{
+      Class c=Class.forName(jsch.getConfig("keypairgen.rsa"));
+      KeyPairGenRSA keypairgen=(KeyPairGenRSA)(c.newInstance());
+      keypairgen.init(key_size);
+      pub_array=keypairgen.getE();
+      prv_array=keypairgen.getD();
+      n_array=keypairgen.getN();
+
+      p_array=keypairgen.getP();
+      q_array=keypairgen.getQ();
+      ep_array=keypairgen.getEP();
+      eq_array=keypairgen.getEQ();
+      c_array=keypairgen.getC();
+
+      keypairgen=null;
+    }
+    catch(Exception e){
+      //System.err.println("KeyPairRSA: "+e); 
+      if(e instanceof Throwable)
+        throw new JSchException(e.toString(), (Throwable)e);
+      throw new JSchException(e.toString());
+    }
+  }
+
+  private static final byte[] begin=Util.str2byte("-----BEGIN RSA PRIVATE KEY-----");
+  private static final byte[] end=Util.str2byte("-----END RSA PRIVATE KEY-----");
+
+  byte[] getBegin(){ return begin; }
+  byte[] getEnd(){ return end; }
+
+  byte[] getPrivateKey(){
+    int content=
+      1+countLength(1) + 1 +                           // INTEGER
+      1+countLength(n_array.length) + n_array.length + // INTEGER  N
+      1+countLength(pub_array.length) + pub_array.length + // INTEGER  pub
+      1+countLength(prv_array.length) + prv_array.length+  // INTEGER  prv
+      1+countLength(p_array.length) + p_array.length+      // INTEGER  p
+      1+countLength(q_array.length) + q_array.length+      // INTEGER  q
+      1+countLength(ep_array.length) + ep_array.length+    // INTEGER  ep
+      1+countLength(eq_array.length) + eq_array.length+    // INTEGER  eq
+      1+countLength(c_array.length) + c_array.length;      // INTEGER  c
+
+    int total=
+      1+countLength(content)+content;   // SEQUENCE
+
+    byte[] plain=new byte[total];
+    int index=0;
+    index=writeSEQUENCE(plain, index, content);
+    index=writeINTEGER(plain, index, new byte[1]);  // 0
+    index=writeINTEGER(plain, index, n_array);
+    index=writeINTEGER(plain, index, pub_array);
+    index=writeINTEGER(plain, index, prv_array);
+    index=writeINTEGER(plain, index, p_array);
+    index=writeINTEGER(plain, index, q_array);
+    index=writeINTEGER(plain, index, ep_array);
+    index=writeINTEGER(plain, index, eq_array);
+    index=writeINTEGER(plain, index, c_array);
+    return plain;
+  }
+
+  boolean parse(byte [] plain){
+    /*
+    byte[] p_array;
+    byte[] q_array;
+    byte[] dmp1_array;
+    byte[] dmq1_array;
+    byte[] iqmp_array;
+    */
+    try{
+      int index=0;
+      int length=0;
+
+      if(vendor==VENDOR_FSECURE){
+	if(plain[index]!=0x30){                  // FSecure
+	  Buffer buf=new Buffer(plain);
+	  pub_array=buf.getMPIntBits();
+	  prv_array=buf.getMPIntBits();
+	  n_array=buf.getMPIntBits();
+	  byte[] u_array=buf.getMPIntBits();
+	  p_array=buf.getMPIntBits();
+	  q_array=buf.getMPIntBits();
+	  return true;
+	}
+	return false;
+      }
+
+      index++; // SEQUENCE
+      length=plain[index++]&0xff;
+      if((length&0x80)!=0){
+        int foo=length&0x7f; length=0;
+        while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
+      }
+
+      if(plain[index]!=0x02)return false;
+      index++; // INTEGER
+      length=plain[index++]&0xff;
+      if((length&0x80)!=0){
+        int foo=length&0x7f; length=0;
+        while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
+      }
+      index+=length;
+
+//System.err.println("int: len="+length);
+//System.err.print(Integer.toHexString(plain[index-1]&0xff)+":");
+//System.err.println("");
+
+      index++;
+      length=plain[index++]&0xff;
+      if((length&0x80)!=0){
+        int foo=length&0x7f; length=0;
+        while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
+      }
+      n_array=new byte[length];
+      System.arraycopy(plain, index, n_array, 0, length);
+      index+=length;
+/*
+System.err.println("int: N len="+length);
+for(int i=0; i<n_array.length; i++){
+System.err.print(Integer.toHexString(n_array[i]&0xff)+":");
+}
+System.err.println("");
+*/
+      index++;
+      length=plain[index++]&0xff;
+      if((length&0x80)!=0){
+        int foo=length&0x7f; length=0;
+        while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
+      }
+      pub_array=new byte[length];
+      System.arraycopy(plain, index, pub_array, 0, length);
+      index+=length;
+/*
+System.err.println("int: E len="+length);
+for(int i=0; i<pub_array.length; i++){
+System.err.print(Integer.toHexString(pub_array[i]&0xff)+":");
+}
+System.err.println("");
+*/
+      index++;
+      length=plain[index++]&0xff;
+      if((length&0x80)!=0){
+        int foo=length&0x7f; length=0;
+        while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
+      }
+      prv_array=new byte[length];
+      System.arraycopy(plain, index, prv_array, 0, length);
+      index+=length;
+/*
+System.err.println("int: prv len="+length);
+for(int i=0; i<prv_array.length; i++){
+System.err.print(Integer.toHexString(prv_array[i]&0xff)+":");
+}
+System.err.println("");
+*/
+
+      index++;
+      length=plain[index++]&0xff;
+      if((length&0x80)!=0){
+        int foo=length&0x7f; length=0;
+        while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
+      }
+      p_array=new byte[length];
+      System.arraycopy(plain, index, p_array, 0, length);
+      index+=length;
+/*
+System.err.println("int: P len="+length);
+for(int i=0; i<p_array.length; i++){
+System.err.print(Integer.toHexString(p_array[i]&0xff)+":");
+}
+System.err.println("");
+*/
+      index++;
+      length=plain[index++]&0xff;
+      if((length&0x80)!=0){
+        int foo=length&0x7f; length=0;
+        while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
+      }
+      q_array=new byte[length];
+      System.arraycopy(plain, index, q_array, 0, length);
+      index+=length;
+/*
+System.err.println("int: q len="+length);
+for(int i=0; i<q_array.length; i++){
+System.err.print(Integer.toHexString(q_array[i]&0xff)+":");
+}
+System.err.println("");
+*/
+      index++;
+      length=plain[index++]&0xff;
+      if((length&0x80)!=0){
+        int foo=length&0x7f; length=0;
+        while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
+      }
+      ep_array=new byte[length];
+      System.arraycopy(plain, index, ep_array, 0, length);
+      index+=length;
+/*
+System.err.println("int: ep len="+length);
+for(int i=0; i<ep_array.length; i++){
+System.err.print(Integer.toHexString(ep_array[i]&0xff)+":");
+}
+System.err.println("");
+*/
+      index++;
+      length=plain[index++]&0xff;
+      if((length&0x80)!=0){
+        int foo=length&0x7f; length=0;
+        while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
+      }
+      eq_array=new byte[length];
+      System.arraycopy(plain, index, eq_array, 0, length);
+      index+=length;
+/*
+System.err.println("int: eq len="+length);
+for(int i=0; i<eq_array.length; i++){
+System.err.print(Integer.toHexString(eq_array[i]&0xff)+":");
+}
+System.err.println("");
+*/
+      index++;
+      length=plain[index++]&0xff;
+      if((length&0x80)!=0){
+        int foo=length&0x7f; length=0;
+        while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
+      }
+      c_array=new byte[length];
+      System.arraycopy(plain, index, c_array, 0, length);
+      index+=length;
+/*
+System.err.println("int: c len="+length);
+for(int i=0; i<c_array.length; i++){
+System.err.print(Integer.toHexString(c_array[i]&0xff)+":");
+}
+System.err.println("");
+*/
+    }
+    catch(Exception e){
+      //System.err.println(e);
+      return false;
+    }
+    return true;
+  }
+
+
+  public byte[] getPublicKeyBlob(){
+    byte[] foo=super.getPublicKeyBlob();
+    if(foo!=null) return foo;
+
+    if(pub_array==null) return null;
+
+    Buffer buf=new Buffer(sshrsa.length+4+
+			  pub_array.length+4+ 
+			  n_array.length+4);
+    buf.putString(sshrsa);
+    buf.putString(pub_array);
+    buf.putString(n_array);
+    return buf.buffer;
+  }
+
+  private static final byte[] sshrsa=Util.str2byte("ssh-rsa");
+  byte[] getKeyTypeName(){return sshrsa;}
+  public int getKeyType(){return RSA;}
+
+  public int getKeySize(){return key_size; }
+  public void dispose(){
+    super.dispose();
+    Util.bzero(prv_array);
+  }
+}
diff --git a/java/com/jcraft/jsch/KnownHosts.java b/java/com/jcraft/jsch/KnownHosts.java
new file mode 100644
index 0000000..ac76477
--- /dev/null
+++ b/java/com/jcraft/jsch/KnownHosts.java
@@ -0,0 +1,506 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+import java.io.*;
+
+public
+class KnownHosts implements HostKeyRepository{
+  private static final String _known_hosts="known_hosts";
+
+  /*
+  static final int SSHDSS=0;
+  static final int SSHRSA=1;
+  static final int UNKNOWN=2;
+  */
+
+  private JSch jsch=null;
+  private String known_hosts=null;
+  private java.util.Vector pool=null;
+
+  private MAC hmacsha1=null;
+
+  KnownHosts(JSch jsch){
+    super();
+    this.jsch=jsch;
+    pool=new java.util.Vector();
+  }
+
+  void setKnownHosts(String foo) throws JSchException{
+    try{
+      known_hosts=foo;
+      FileInputStream fis=new FileInputStream(foo);
+      setKnownHosts(fis);
+    }
+    catch(FileNotFoundException e){
+    } 
+  }
+  void setKnownHosts(InputStream foo) throws JSchException{
+    pool.removeAllElements();
+    StringBuffer sb=new StringBuffer();
+    byte i;
+    int j;
+    boolean error=false;
+    try{
+      InputStream fis=foo;
+      String host;
+      String key=null;
+      int type;
+      byte[] buf=new byte[1024];
+      int bufl=0;
+loop:
+      while(true){
+	bufl=0;
+        while(true){
+          j=fis.read();
+          if(j==-1){
+            if(bufl==0){ break loop; }
+            else{ break; }
+          }
+	  if(j==0x0d){ continue; }
+	  if(j==0x0a){ break; }
+          if(buf.length<=bufl){
+            if(bufl>1024*10) break;   // too long...
+            byte[] newbuf=new byte[buf.length*2];
+            System.arraycopy(buf, 0, newbuf, 0, buf.length);
+            buf=newbuf;
+          }
+          buf[bufl++]=(byte)j;
+	}
+
+	j=0;
+        while(j<bufl){
+          i=buf[j];
+	  if(i==' '||i=='\t'){ j++; continue; }
+	  if(i=='#'){
+	    addInvalidLine(Util.byte2str(buf, 0, bufl));
+	    continue loop;
+	  }
+	  break;
+	}
+	if(j>=bufl){ 
+	  addInvalidLine(Util.byte2str(buf, 0, bufl));
+	  continue loop; 
+	}
+
+        sb.setLength(0);
+        while(j<bufl){
+          i=buf[j++];
+          if(i==0x20 || i=='\t'){ break; }
+          sb.append((char)i);
+	}
+	host=sb.toString();
+	if(j>=bufl || host.length()==0){
+	  addInvalidLine(Util.byte2str(buf, 0, bufl));
+	  continue loop; 
+	}
+
+        sb.setLength(0);
+	type=-1;
+        while(j<bufl){
+          i=buf[j++];
+          if(i==0x20 || i=='\t'){ break; }
+          sb.append((char)i);
+	}
+	if(sb.toString().equals("ssh-dss")){ type=HostKey.SSHDSS; }
+	else if(sb.toString().equals("ssh-rsa")){ type=HostKey.SSHRSA; }
+	else { j=bufl; }
+	if(j>=bufl){
+	  addInvalidLine(Util.byte2str(buf, 0, bufl));
+	  continue loop; 
+	}
+
+        sb.setLength(0);
+        while(j<bufl){
+          i=buf[j++];
+          if(i==0x0d){ continue; }
+          if(i==0x0a){ break; }
+          sb.append((char)i);
+	}
+	key=sb.toString();
+	if(key.length()==0){
+	  addInvalidLine(Util.byte2str(buf, 0, bufl));
+	  continue loop; 
+	}
+
+	//System.err.println(host);
+	//System.err.println("|"+key+"|");
+
+	HostKey hk = null;
+        hk = new HashedHostKey(host, type, 
+                               Util.fromBase64(Util.str2byte(key), 0, 
+                                               key.length()));
+	pool.addElement(hk);
+      }
+      fis.close();
+      if(error){
+	throw new JSchException("KnownHosts: invalid format");
+      }
+    }
+    catch(Exception e){
+      if(e instanceof JSchException)
+	throw (JSchException)e;         
+      if(e instanceof Throwable)
+        throw new JSchException(e.toString(), (Throwable)e);
+      throw new JSchException(e.toString());
+    }
+  }
+  private void addInvalidLine(String line) throws JSchException {
+    HostKey hk = new HostKey(line, HostKey.UNKNOWN, null);
+    pool.addElement(hk);
+  }
+  String getKnownHostsFile(){ return known_hosts; }
+  public String getKnownHostsRepositoryID(){ return known_hosts; }
+
+  public int check(String host, byte[] key){
+    int result=NOT_INCLUDED;
+    if(host==null){
+      return result;
+    }
+
+    int type=getType(key);
+    HostKey hk;
+
+    synchronized(pool){
+      for(int i=0; i<pool.size(); i++){
+        hk=(HostKey)(pool.elementAt(i));
+        if(hk.isMatched(host) && hk.type==type){
+          if(Util.array_equals(hk.key, key)){
+            return OK;
+          }
+          else{
+            result=CHANGED;
+	  }
+        }
+      }
+    }
+
+    if(result==NOT_INCLUDED &&
+       host.startsWith("[") &&
+       host.indexOf("]:")>1
+       ){
+      return check(host.substring(1, host.indexOf("]:")), key);
+    }
+
+    return result;
+  }
+  public void add(HostKey hostkey, UserInfo userinfo){
+    int type=hostkey.type;
+    String host=hostkey.getHost();
+    byte[] key=hostkey.key;
+
+    HostKey hk=null;
+    synchronized(pool){
+      for(int i=0; i<pool.size(); i++){
+        hk=(HostKey)(pool.elementAt(i));
+        if(hk.isMatched(host) && hk.type==type){
+/*
+	  if(Util.array_equals(hk.key, key)){ return; }
+	  if(hk.host.equals(host)){
+	    hk.key=key;
+	    return;
+	  }
+	  else{
+	    hk.host=deleteSubString(hk.host, host);
+	    break;
+	  }
+*/
+        }
+      }
+    }
+
+    hk=hostkey;
+
+    pool.addElement(hk);
+
+    String bar=getKnownHostsRepositoryID();
+    if(bar!=null){
+      boolean foo=true;
+      File goo=new File(bar);
+      if(!goo.exists()){
+        foo=false;
+        if(userinfo!=null){
+          foo=userinfo.promptYesNo(bar+" does not exist.\n"+
+                                   "Are you sure you want to create it?"
+                                   );
+          goo=goo.getParentFile();
+          if(foo && goo!=null && !goo.exists()){
+            foo=userinfo.promptYesNo("The parent directory "+goo+" does not exist.\n"+
+                                     "Are you sure you want to create it?"
+                                     );
+            if(foo){
+              if(!goo.mkdirs()){
+                userinfo.showMessage(goo+" has not been created.");
+                foo=false;
+              }
+              else{
+                userinfo.showMessage(goo+" has been succesfully created.\nPlease check its access permission.");
+              }
+            }
+          }
+          if(goo==null)foo=false;
+        }
+      }
+      if(foo){
+        try{ 
+          sync(bar); 
+        }
+        catch(Exception e){ System.err.println("sync known_hosts: "+e); }
+      }
+    }
+  }
+
+  public HostKey[] getHostKey(){
+    return getHostKey(null, null);
+  }
+  public HostKey[] getHostKey(String host, String type){
+    synchronized(pool){
+      int count=0;
+      for(int i=0; i<pool.size(); i++){
+	HostKey hk=(HostKey)pool.elementAt(i);
+	if(hk.type==HostKey.UNKNOWN) continue;
+	if(host==null || 
+	   (hk.isMatched(host) && 
+	    (type==null || hk.getType().equals(type)))){
+	  count++;
+	}
+      }
+      if(count==0)return null;
+      HostKey[] foo=new HostKey[count];
+      int j=0;
+      for(int i=0; i<pool.size(); i++){
+	HostKey hk=(HostKey)pool.elementAt(i);
+	if(hk.type==HostKey.UNKNOWN) continue;
+	if(host==null || 
+	   (hk.isMatched(host) && 
+	    (type==null || hk.getType().equals(type)))){
+	  foo[j++]=hk;
+	}
+      }
+      return foo;
+    }
+  }
+  public void remove(String host, String type){
+    remove(host, type, null);
+  }
+  public void remove(String host, String type, byte[] key){
+    boolean sync=false;
+    synchronized(pool){
+    for(int i=0; i<pool.size(); i++){
+      HostKey hk=(HostKey)(pool.elementAt(i));
+      if(host==null ||
+	 (hk.isMatched(host) && 
+	  (type==null || (hk.getType().equals(type) &&
+			  (key==null || Util.array_equals(key, hk.key)))))){
+        String hosts=hk.getHost();
+        if(hosts.equals(host) || 
+           ((hk instanceof HashedHostKey) &&
+            ((HashedHostKey)hk).isHashed())){
+          pool.removeElement(hk);
+        }
+        else{
+          hk.host=deleteSubString(hosts, host);
+        }
+	sync=true;
+      }
+    }
+    }
+    if(sync){
+      try{sync();}catch(Exception e){};
+    }
+  }
+
+  protected void sync() throws IOException { 
+    if(known_hosts!=null)
+      sync(known_hosts); 
+  }
+  protected synchronized void sync(String foo) throws IOException {
+    if(foo==null) return;
+    FileOutputStream fos=new FileOutputStream(foo);
+    dump(fos);
+    fos.close();
+  }
+
+  private static final byte[] space={(byte)0x20};
+  private static final byte[] cr=Util.str2byte("\n");
+  void dump(OutputStream out) throws IOException {
+    try{
+      HostKey hk;
+      synchronized(pool){
+      for(int i=0; i<pool.size(); i++){
+        hk=(HostKey)(pool.elementAt(i));
+        //hk.dump(out);
+	String host=hk.getHost();
+	String type=hk.getType();
+	if(type.equals("UNKNOWN")){
+	  out.write(Util.str2byte(host));
+	  out.write(cr);
+	  continue;
+	}
+	out.write(Util.str2byte(host));
+	out.write(space);
+	out.write(Util.str2byte(type));
+	out.write(space);
+	out.write(Util.str2byte(hk.getKey()));
+	out.write(cr);
+      }
+      }
+    }
+    catch(Exception e){
+      System.err.println(e);
+    }
+  }
+  private int getType(byte[] key){
+    if(key[8]=='d') return HostKey.SSHDSS;
+    if(key[8]=='r') return HostKey.SSHRSA;
+    return HostKey.UNKNOWN;
+  }
+  private String deleteSubString(String hosts, String host){
+    int i=0;
+    int hostlen=host.length();
+    int hostslen=hosts.length();
+    int j;
+    while(i<hostslen){
+      j=hosts.indexOf(',', i);
+      if(j==-1) break;
+      if(!host.equals(hosts.substring(i, j))){
+        i=j+1;	  
+        continue;
+      }
+      return hosts.substring(0, i)+hosts.substring(j+1);
+    }
+    if(hosts.endsWith(host) && hostslen-i==hostlen){
+      return hosts.substring(0, (hostlen==hostslen) ? 0 :hostslen-hostlen-1);
+    }
+    return hosts;
+  }
+
+  private synchronized MAC getHMACSHA1(){
+    if(hmacsha1==null){
+      try{
+        Class c=Class.forName(jsch.getConfig("hmac-sha1"));
+        hmacsha1=(MAC)(c.newInstance());
+      }
+      catch(Exception e){ 
+        System.err.println("hmacsha1: "+e); 
+      }
+    }
+    return hmacsha1;
+  }
+
+  HostKey createHashedHostKey(String host, byte[]key) throws JSchException {
+    HashedHostKey hhk=new HashedHostKey(host, key);
+    hhk.hash();
+    return hhk;
+  } 
+  class HashedHostKey extends HostKey{
+    private static final String HASH_MAGIC="|1|";
+    private static final String HASH_DELIM="|";
+
+    private boolean hashed=false;
+    byte[] salt=null;
+    byte[] hash=null;
+
+
+    HashedHostKey(String host, byte[] key) throws JSchException {
+      this(host, GUESS, key);
+    }
+    HashedHostKey(String host, int type, byte[] key) throws JSchException {
+      super(host, type, key);
+      if(this.host.startsWith(HASH_MAGIC) &&
+         this.host.substring(HASH_MAGIC.length()).indexOf(HASH_DELIM)>0){
+        String data=this.host.substring(HASH_MAGIC.length());
+        String _salt=data.substring(0, data.indexOf(HASH_DELIM));
+        String _hash=data.substring(data.indexOf(HASH_DELIM)+1);
+        salt=Util.fromBase64(Util.str2byte(_salt), 0, _salt.length());
+        hash=Util.fromBase64(Util.str2byte(_hash), 0, _hash.length());
+        if(salt.length!=20 ||  // block size of hmac-sha1
+           hash.length!=20){
+          salt=null;
+          hash=null;
+          return;
+        }
+        hashed=true;
+      }
+    }
+
+    boolean isMatched(String _host){
+      if(!hashed){
+        return super.isMatched(_host);
+      }
+      MAC macsha1=getHMACSHA1();
+      try{
+        synchronized(macsha1){
+          macsha1.init(salt);
+          byte[] foo=Util.str2byte(_host);
+          macsha1.update(foo, 0, foo.length);
+          byte[] bar=new byte[macsha1.getBlockSize()];
+          macsha1.doFinal(bar, 0);
+          return Util.array_equals(hash, bar);
+        }
+      }
+      catch(Exception e){
+        System.out.println(e);
+      }
+      return false;
+    }
+
+    boolean isHashed(){
+      return hashed;
+    }
+
+    void hash(){
+      if(hashed)
+        return;
+      MAC macsha1=getHMACSHA1();
+      if(salt==null){
+        Random random=Session.random;
+        synchronized(random){
+          salt=new byte[macsha1.getBlockSize()];
+          random.fill(salt, 0, salt.length);
+        }
+      }
+      try{
+        synchronized(macsha1){
+          macsha1.init(salt);
+          byte[] foo=Util.str2byte(host);
+          macsha1.update(foo, 0, foo.length);
+          hash=new byte[macsha1.getBlockSize()];
+          macsha1.doFinal(hash, 0);
+        }
+      }
+      catch(Exception e){
+      }
+      host=HASH_MAGIC+Util.byte2str(Util.toBase64(salt, 0, salt.length))+
+        HASH_DELIM+Util.byte2str(Util.toBase64(hash, 0, hash.length));
+      hashed=true;
+    }
+  }
+}
diff --git a/java/com/jcraft/jsch/LICENSE.txt b/java/com/jcraft/jsch/LICENSE.txt
new file mode 100644
index 0000000..81c8eac
--- /dev/null
+++ b/java/com/jcraft/jsch/LICENSE.txt
@@ -0,0 +1,30 @@
+JSch 0.0.* was released under the GNU LGPL license.  Later, we have switched 
+over to a BSD-style license. 
+
+------------------------------------------------------------------------------
+Copyright (c) 2002-2012 Atsuhiko Yamanaka, JCraft,Inc. 
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/java/com/jcraft/jsch/LocalIdentityRepository.java b/java/com/jcraft/jsch/LocalIdentityRepository.java
new file mode 100644
index 0000000..be81415
--- /dev/null
+++ b/java/com/jcraft/jsch/LocalIdentityRepository.java
@@ -0,0 +1,90 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+import java.util.Vector;
+
+class LocalIdentityRepository implements IdentityRepository {
+
+  private Vector identities = new Vector();
+  private JSch jsch;
+
+  LocalIdentityRepository(JSch jsch){
+    this.jsch = jsch;
+  }
+
+  public synchronized Vector getIdentities() {
+    Vector v = new Vector();
+    for(int i=0; i<identities.size(); i++){
+      v.addElement(identities.elementAt(i));
+    }
+    return v;
+  }
+
+  public synchronized void add(Identity identity) {
+    if(!identities.contains(identity)) {
+      identities.addElement(identity);
+    }
+  }
+
+  public synchronized boolean add(byte[] identity) {
+    try{
+      Identity _identity =
+        IdentityFile.newInstance("from remote:", identity, null, jsch);
+      identities.addElement(_identity);
+      return true;
+    }
+    catch(JSchException e){
+      return false;
+    }
+  }
+
+  public synchronized boolean remove(byte[] blob) {
+    if(blob == null) return false;
+    for(int i=0; i<identities.size(); i++) {
+      Identity _identity = (Identity)(identities.elementAt(i));
+      byte[] _blob = _identity.getPublicKeyBlob();
+      if(_blob == null || !Util.array_equals(blob, _blob))
+        continue;
+      identities.removeElement(_identity);
+      _identity.clear();
+      return true;
+    }
+    return false;
+  }
+
+  public synchronized void removeAll() {
+    for(int i=0; i<identities.size(); i++) {
+      Identity identity=(Identity)(identities.elementAt(i));
+      identity.clear();
+    }
+    identities.removeAllElements();
+  } 
+}
diff --git a/java/com/jcraft/jsch/Logger.java b/java/com/jcraft/jsch/Logger.java
new file mode 100644
index 0000000..1263722
--- /dev/null
+++ b/java/com/jcraft/jsch/Logger.java
@@ -0,0 +1,54 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2006-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+public interface Logger{
+
+  public final int DEBUG=0;
+  public final int INFO=1;
+  public final int WARN=2;
+  public final int ERROR=3;
+  public final int FATAL=4;
+
+  public boolean isEnabled(int level);
+
+  public void log(int level, String message);
+
+  /*
+  public final Logger SIMPLE_LOGGER=new Logger(){
+      public boolean isEnabled(int level){return true;}
+      public void log(int level, String message){System.err.println(message);}
+    };
+  final Logger DEVNULL=new Logger(){
+      public boolean isEnabled(int level){return false;}
+      public void log(int level, String message){}
+    };
+  */
+}
diff --git a/java/com/jcraft/jsch/MAC.java b/java/com/jcraft/jsch/MAC.java
new file mode 100644
index 0000000..0475ce2
--- /dev/null
+++ b/java/com/jcraft/jsch/MAC.java
@@ -0,0 +1,39 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+public interface MAC{
+  String getName();
+  int getBlockSize(); 
+  void init(byte[] key) throws Exception; 
+  void update(byte[] foo, int start, int len);
+  void update(int foo);
+  void doFinal(byte[] buf, int offset);
+}
diff --git a/java/com/jcraft/jsch/Packet.java b/java/com/jcraft/jsch/Packet.java
new file mode 100644
index 0000000..9c44157
--- /dev/null
+++ b/java/com/jcraft/jsch/Packet.java
@@ -0,0 +1,115 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+public class Packet{
+
+  private static Random random=null;
+  static void setRandom(Random foo){ random=foo;}
+
+  Buffer buffer;
+  byte[] ba4=new byte[4]; 
+  public Packet(Buffer buffer){
+    this.buffer=buffer;
+  }
+  public void reset(){
+    buffer.index=5;
+  }
+  void padding(int bsize){
+    int len=buffer.index;
+    int pad=(-len)&(bsize-1);
+    if(pad<bsize){
+      pad+=bsize;
+    }
+    len=len+pad-4;
+    ba4[0]=(byte)(len>>>24);
+    ba4[1]=(byte)(len>>>16);
+    ba4[2]=(byte)(len>>>8);
+    ba4[3]=(byte)(len);
+    System.arraycopy(ba4, 0, buffer.buffer, 0, 4);
+    buffer.buffer[4]=(byte)pad;
+    synchronized(random){
+      random.fill(buffer.buffer, buffer.index, pad);
+    }
+    buffer.skip(pad);
+    //buffer.putPad(pad);
+/*
+for(int i=0; i<buffer.index; i++){
+System.err.print(Integer.toHexString(buffer.buffer[i]&0xff)+":");
+}
+System.err.println("");
+*/
+  }
+
+  int shift(int len, int bsize, int mac){
+    int s=len+5+9;
+    int pad=(-s)&(bsize-1);
+    if(pad<bsize)pad+=bsize;
+    s+=pad;
+    s+=mac;
+    s+=32; // margin for deflater; deflater may inflate data
+
+    /**/
+    if(buffer.buffer.length<s+buffer.index-5-9-len){
+      byte[] foo=new byte[s+buffer.index-5-9-len];
+      System.arraycopy(buffer.buffer, 0, foo, 0, buffer.buffer.length);
+      buffer.buffer=foo;
+    }
+    /**/
+
+//if(buffer.buffer.length<len+5+9)
+//  System.err.println("buffer.buffer.length="+buffer.buffer.length+" len+5+9="+(len+5+9));
+
+//if(buffer.buffer.length<s)
+//  System.err.println("buffer.buffer.length="+buffer.buffer.length+" s="+(s));
+
+    System.arraycopy(buffer.buffer, 
+		     len+5+9, 
+		     buffer.buffer, s, buffer.index-5-9-len);
+
+    buffer.index=10;
+    buffer.putInt(len);
+    buffer.index=len+5+9;
+    return s;
+  }
+  void unshift(byte command, int recipient, int s, int len){
+    System.arraycopy(buffer.buffer, 
+		     s, 
+		     buffer.buffer, 5+9, len);
+    buffer.buffer[5]=command;
+    buffer.index=6;
+    buffer.putInt(recipient);
+    buffer.putInt(len);
+    buffer.index=len+5+9;
+  }
+  Buffer getBuffer(){
+    return buffer;
+  }
+}
diff --git a/java/com/jcraft/jsch/PortWatcher.java b/java/com/jcraft/jsch/PortWatcher.java
new file mode 100644
index 0000000..508e16b
--- /dev/null
+++ b/java/com/jcraft/jsch/PortWatcher.java
@@ -0,0 +1,194 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+import java.net.*;
+import java.io.*;
+
+class PortWatcher implements Runnable{
+  private static java.util.Vector pool=new java.util.Vector();
+  private static InetAddress anyLocalAddress=null;
+  static{
+    // 0.0.0.0
+/*
+    try{ anyLocalAddress=InetAddress.getByAddress(new byte[4]); }
+    catch(UnknownHostException e){
+    }
+*/
+    try{ anyLocalAddress=InetAddress.getByName("0.0.0.0"); }
+    catch(UnknownHostException e){
+    }
+  }
+
+  Session session;
+  int lport;
+  int rport;
+  String host;
+  InetAddress boundaddress;
+  Runnable thread;
+  ServerSocket ss;
+
+  static String[] getPortForwarding(Session session){
+    java.util.Vector foo=new java.util.Vector();
+    synchronized(pool){
+      for(int i=0; i<pool.size(); i++){
+	PortWatcher p=(PortWatcher)(pool.elementAt(i));
+	if(p.session==session){
+	  foo.addElement(p.lport+":"+p.host+":"+p.rport);
+	}
+      }
+    }
+    String[] bar=new String[foo.size()];
+    for(int i=0; i<foo.size(); i++){
+      bar[i]=(String)(foo.elementAt(i));
+    }
+    return bar;
+  }
+  static PortWatcher getPort(Session session, String address, int lport) throws JSchException{
+    InetAddress addr;
+    try{
+      addr=InetAddress.getByName(address);
+    }
+    catch(UnknownHostException uhe){
+      throw new JSchException("PortForwardingL: invalid address "+address+" specified.", uhe);
+    }
+    synchronized(pool){
+      for(int i=0; i<pool.size(); i++){
+	PortWatcher p=(PortWatcher)(pool.elementAt(i));
+	if(p.session==session && p.lport==lport){
+	  if(/*p.boundaddress.isAnyLocalAddress() ||*/
+             (anyLocalAddress!=null &&  p.boundaddress.equals(anyLocalAddress)) ||
+	     p.boundaddress.equals(addr))
+	  return p;
+	}
+      }
+      return null;
+    }
+  }
+  static PortWatcher addPort(Session session, String address, int lport, String host, int rport, ServerSocketFactory ssf) throws JSchException{
+    if(getPort(session, address, lport)!=null){
+      throw new JSchException("PortForwardingL: local port "+ address+":"+lport+" is already registered.");
+    }
+    PortWatcher pw=new PortWatcher(session, address, lport, host, rport, ssf);
+    pool.addElement(pw);
+    return pw;
+  }
+  static void delPort(Session session, String address, int lport) throws JSchException{
+    PortWatcher pw=getPort(session, address, lport);
+    if(pw==null){
+      throw new JSchException("PortForwardingL: local port "+address+":"+lport+" is not registered.");
+    }
+    pw.delete();
+    pool.removeElement(pw);
+  }
+  static void delPort(Session session){
+    synchronized(pool){
+      PortWatcher[] foo=new PortWatcher[pool.size()];
+      int count=0;
+      for(int i=0; i<pool.size(); i++){
+	PortWatcher p=(PortWatcher)(pool.elementAt(i));
+	if(p.session==session) {
+	  p.delete();
+	  foo[count++]=p;
+	}
+      }
+      for(int i=0; i<count; i++){
+	PortWatcher p=foo[i];
+	pool.removeElement(p);
+      }
+    }
+  }
+  PortWatcher(Session session, 
+	      String address, int lport, 
+	      String host, int rport,
+              ServerSocketFactory factory) throws JSchException{
+    this.session=session;
+    this.lport=lport;
+    this.host=host;
+    this.rport=rport;
+    try{
+      boundaddress=InetAddress.getByName(address);
+      ss=(factory==null) ? 
+        new ServerSocket(lport, 0, boundaddress) :
+        factory.createServerSocket(lport, 0, boundaddress);
+    }
+    catch(Exception e){ 
+      //System.err.println(e);
+      String message="PortForwardingL: local port "+address+":"+lport+" cannot be bound.";
+      if(e instanceof Throwable)
+        throw new JSchException(message, (Throwable)e);
+      throw new JSchException(message);
+    }
+    if(lport==0){
+      int assigned=ss.getLocalPort();
+      if(assigned!=-1)
+        this.lport=assigned;
+    }
+  }
+
+  public void run(){
+    thread=this;
+    try{
+      while(thread!=null){
+        Socket socket=ss.accept();
+	socket.setTcpNoDelay(true);
+        InputStream in=socket.getInputStream();
+        OutputStream out=socket.getOutputStream();
+        ChannelDirectTCPIP channel=new ChannelDirectTCPIP();
+        channel.init();
+        channel.setInputStream(in);
+        channel.setOutputStream(out);
+	session.addChannel(channel);
+	((ChannelDirectTCPIP)channel).setHost(host);
+	((ChannelDirectTCPIP)channel).setPort(rport);
+	((ChannelDirectTCPIP)channel).setOrgIPAddress(socket.getInetAddress().getHostAddress());
+	((ChannelDirectTCPIP)channel).setOrgPort(socket.getPort());
+        channel.connect();
+	if(channel.exitstatus!=-1){
+	}
+      }
+    }
+    catch(Exception e){
+      //System.err.println("! "+e);
+    }
+
+    delete();
+  }
+
+  void delete(){
+    thread=null;
+    try{ 
+      if(ss!=null)ss.close();
+      ss=null;
+    }
+    catch(Exception e){
+    }
+  }
+}
diff --git a/java/com/jcraft/jsch/Proxy.java b/java/com/jcraft/jsch/Proxy.java
new file mode 100644
index 0000000..7d05caa
--- /dev/null
+++ b/java/com/jcraft/jsch/Proxy.java
@@ -0,0 +1,40 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+import java.io.*;
+import java.net.Socket;
+public interface Proxy{
+  void connect(SocketFactory socket_factory, String host, int port, int timeout) throws Exception;
+  InputStream getInputStream();
+  OutputStream getOutputStream();
+  Socket getSocket();
+  void close();
+}
diff --git a/java/com/jcraft/jsch/ProxyHTTP.java b/java/com/jcraft/jsch/ProxyHTTP.java
new file mode 100644
index 0000000..df23114
--- /dev/null
+++ b/java/com/jcraft/jsch/ProxyHTTP.java
@@ -0,0 +1,180 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+import java.io.*;
+import java.net.*;
+
+public class ProxyHTTP implements Proxy{
+  private static int DEFAULTPORT=80;
+  private String proxy_host;
+  private int proxy_port;
+  private InputStream in;
+  private OutputStream out;
+  private Socket socket;
+
+  private String user;
+  private String passwd;
+
+  public ProxyHTTP(String proxy_host){
+    int port=DEFAULTPORT;
+    String host=proxy_host;
+    if(proxy_host.indexOf(':')!=-1){
+      try{
+	host=proxy_host.substring(0, proxy_host.indexOf(':'));
+	port=Integer.parseInt(proxy_host.substring(proxy_host.indexOf(':')+1));
+      }
+      catch(Exception e){
+      }
+    }
+    this.proxy_host=host;
+    this.proxy_port=port;
+  }
+  public ProxyHTTP(String proxy_host, int proxy_port){
+    this.proxy_host=proxy_host;
+    this.proxy_port=proxy_port;
+  }
+  public void setUserPasswd(String user, String passwd){
+    this.user=user;
+    this.passwd=passwd;
+  }
+  public void connect(SocketFactory socket_factory, String host, int port, int timeout) throws JSchException{
+    try{
+      if(socket_factory==null){
+        socket=Util.createSocket(proxy_host, proxy_port, timeout);    
+        in=socket.getInputStream();
+        out=socket.getOutputStream();
+      }
+      else{
+        socket=socket_factory.createSocket(proxy_host, proxy_port);
+        in=socket_factory.getInputStream(socket);
+        out=socket_factory.getOutputStream(socket);
+      }
+      if(timeout>0){
+        socket.setSoTimeout(timeout);
+      }
+      socket.setTcpNoDelay(true);
+
+      out.write(Util.str2byte("CONNECT "+host+":"+port+" HTTP/1.0\r\n"));
+
+      if(user!=null && passwd!=null){
+	byte[] code=Util.str2byte(user+":"+passwd);
+	code=Util.toBase64(code, 0, code.length);
+	out.write(Util.str2byte("Proxy-Authorization: Basic "));
+	out.write(code);
+	out.write(Util.str2byte("\r\n"));
+      }
+
+      out.write(Util.str2byte("\r\n"));
+      out.flush();
+
+      int foo=0;
+
+      StringBuffer sb=new StringBuffer();
+      while(foo>=0){
+        foo=in.read(); if(foo!=13){sb.append((char)foo);  continue;}
+        foo=in.read(); if(foo!=10){continue;}
+        break;
+      }
+      if(foo<0){
+        throw new IOException();
+      }
+
+      String response=sb.toString(); 
+      String reason="Unknow reason";
+      int code=-1;
+      try{
+        foo=response.indexOf(' ');
+        int bar=response.indexOf(' ', foo+1);
+        code=Integer.parseInt(response.substring(foo+1, bar));
+        reason=response.substring(bar+1);
+      }
+      catch(Exception e){
+      }
+      if(code!=200){
+        throw new IOException("proxy error: "+reason);
+      }
+
+      /*
+      while(foo>=0){
+        foo=in.read(); if(foo!=13) continue;
+        foo=in.read(); if(foo!=10) continue;
+        foo=in.read(); if(foo!=13) continue;      
+        foo=in.read(); if(foo!=10) continue;
+        break;
+      }
+      */
+
+      int count=0;
+      while(true){
+        count=0;
+        while(foo>=0){
+          foo=in.read(); if(foo!=13){count++;  continue;}
+          foo=in.read(); if(foo!=10){continue;}
+          break;
+        }
+        if(foo<0){
+          throw new IOException();
+        }
+        if(count==0)break;
+      }
+    }
+    catch(RuntimeException e){
+      throw e;
+    }
+    catch(Exception e){
+      try{ if(socket!=null)socket.close(); }
+      catch(Exception eee){
+      }
+      String message="ProxyHTTP: "+e.toString();
+      if(e instanceof Throwable)
+        throw new JSchException(message, (Throwable)e);
+      throw new JSchException(message);
+    }
+  }
+  public InputStream getInputStream(){ return in; }
+  public OutputStream getOutputStream(){ return out; }
+  public Socket getSocket(){ return socket; }
+  public void close(){
+    try{
+      if(in!=null)in.close();
+      if(out!=null)out.close();
+      if(socket!=null)socket.close();
+    }
+    catch(Exception e){
+    }
+    in=null;
+    out=null;
+    socket=null;
+  }
+  public static int getDefaultPort(){
+    return DEFAULTPORT;
+  }
+}
diff --git a/java/com/jcraft/jsch/ProxySOCKS4.java b/java/com/jcraft/jsch/ProxySOCKS4.java
new file mode 100644
index 0000000..cb50616
--- /dev/null
+++ b/java/com/jcraft/jsch/ProxySOCKS4.java
@@ -0,0 +1,212 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2006-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*
+ This file depends on following documents,
+   - SOCKS: A protocol for TCP proxy across firewalls, Ying-Da Lee
+     http://www.socks.nec.com/protocol/socks4.protocol
+ */
+
+package com.jcraft.jsch;
+
+import java.io.*;
+import java.net.*;
+
+public class ProxySOCKS4 implements Proxy{
+  private static int DEFAULTPORT=1080;
+  private String proxy_host;
+  private int proxy_port;
+  private InputStream in;
+  private OutputStream out;
+  private Socket socket;
+  private String user;
+  private String passwd;
+
+  public ProxySOCKS4(String proxy_host){
+    int port=DEFAULTPORT;
+    String host=proxy_host;
+    if(proxy_host.indexOf(':')!=-1){
+      try{
+	host=proxy_host.substring(0, proxy_host.indexOf(':'));
+	port=Integer.parseInt(proxy_host.substring(proxy_host.indexOf(':')+1));
+      }
+      catch(Exception e){
+      }
+    }
+    this.proxy_host=host;
+    this.proxy_port=port;
+  }
+  public ProxySOCKS4(String proxy_host, int proxy_port){
+    this.proxy_host=proxy_host;
+    this.proxy_port=proxy_port;
+  }
+  public void setUserPasswd(String user, String passwd){
+    this.user=user;
+    this.passwd=passwd;
+  }
+  public void connect(SocketFactory socket_factory, String host, int port, int timeout) throws JSchException{
+    try{
+      if(socket_factory==null){
+        socket=Util.createSocket(proxy_host, proxy_port, timeout);
+        //socket=new Socket(proxy_host, proxy_port);    
+        in=socket.getInputStream();
+        out=socket.getOutputStream();
+      }
+      else{
+        socket=socket_factory.createSocket(proxy_host, proxy_port);
+        in=socket_factory.getInputStream(socket);
+        out=socket_factory.getOutputStream(socket);
+      }
+      if(timeout>0){
+        socket.setSoTimeout(timeout);
+      }
+      socket.setTcpNoDelay(true);
+
+      byte[] buf=new byte[1024];
+      int index=0;
+
+/*
+   1) CONNECT
+   
+   The client connects to the SOCKS server and sends a CONNECT request when
+   it wants to establish a connection to an application server. The client
+   includes in the request packet the IP address and the port number of the
+   destination host, and userid, in the following format.
+   
+               +----+----+----+----+----+----+----+----+----+----+....+----+
+               | VN | CD | DSTPORT |      DSTIP        | USERID       |NULL|
+               +----+----+----+----+----+----+----+----+----+----+....+----+
+   # of bytes:   1    1      2              4           variable       1
+   
+   VN is the SOCKS protocol version number and should be 4. CD is the
+   SOCKS command code and should be 1 for CONNECT request. NULL is a byte
+   of all zero bits.
+*/
+     
+      index=0;
+      buf[index++]=4;
+      buf[index++]=1;
+
+      buf[index++]=(byte)(port>>>8);
+      buf[index++]=(byte)(port&0xff);
+
+      try{
+        InetAddress addr=InetAddress.getByName(host);
+        byte[] byteAddress = addr.getAddress();
+        for (int i = 0; i < byteAddress.length; i++) {
+          buf[index++]=byteAddress[i];
+        }
+      }
+      catch(UnknownHostException uhe){
+        throw new JSchException("ProxySOCKS4: "+uhe.toString(), uhe);
+      }
+
+      if(user!=null){
+        System.arraycopy(Util.str2byte(user), 0, buf, index, user.length());
+        index+=user.length();
+      }
+      buf[index++]=0;
+      out.write(buf, 0, index);
+
+/*
+   The SOCKS server checks to see whether such a request should be granted
+   based on any combination of source IP address, destination IP address,
+   destination port number, the userid, and information it may obtain by
+   consulting IDENT, cf. RFC 1413.  If the request is granted, the SOCKS
+   server makes a connection to the specified port of the destination host.
+   A reply packet is sent to the client when this connection is established,
+   or when the request is rejected or the operation fails. 
+   
+               +----+----+----+----+----+----+----+----+
+               | VN | CD | DSTPORT |      DSTIP        |
+               +----+----+----+----+----+----+----+----+
+   # of bytes:   1    1      2              4
+   
+   VN is the version of the reply code and should be 0. CD is the result
+   code with one of the following values:
+   
+   90: request granted
+   91: request rejected or failed
+   92: request rejected becasue SOCKS server cannot connect to
+       identd on the client
+   93: request rejected because the client program and identd
+       report different user-ids
+   
+   The remaining fields are ignored.
+*/
+
+      int len=8;
+      int s=0;
+      while(s<len){
+        int i=in.read(buf, s, len-s);
+        if(i<=0){
+          throw new JSchException("ProxySOCKS4: stream is closed");
+        }
+        s+=i;
+      }
+      if(buf[0]!=0){
+        throw new JSchException("ProxySOCKS4: server returns VN "+buf[0]);
+      }
+      if(buf[1]!=90){
+        try{ socket.close(); }
+	catch(Exception eee){
+	}
+        String message="ProxySOCKS4: server returns CD "+buf[1];
+        throw new JSchException(message);
+      }
+    }
+    catch(RuntimeException e){
+      throw e;
+    }
+    catch(Exception e){
+      try{ if(socket!=null)socket.close(); }
+      catch(Exception eee){
+      }
+      throw new JSchException("ProxySOCKS4: "+e.toString());
+    }
+  }
+  public InputStream getInputStream(){ return in; }
+  public OutputStream getOutputStream(){ return out; }
+  public Socket getSocket(){ return socket; }
+  public void close(){
+    try{
+      if(in!=null)in.close();
+      if(out!=null)out.close();
+      if(socket!=null)socket.close();
+    }
+    catch(Exception e){
+    }
+    in=null;
+    out=null;
+    socket=null;
+  }
+  public static int getDefaultPort(){
+    return DEFAULTPORT;
+  }
+}
diff --git a/java/com/jcraft/jsch/ProxySOCKS5.java b/java/com/jcraft/jsch/ProxySOCKS5.java
new file mode 100644
index 0000000..7960135
--- /dev/null
+++ b/java/com/jcraft/jsch/ProxySOCKS5.java
@@ -0,0 +1,349 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*
+ This file depends on following documents,
+   - RFC 1928  SOCKS Protocol Verseion 5  
+   - RFC 1929  Username/Password Authentication for SOCKS V5. 
+ */
+
+package com.jcraft.jsch;
+
+import java.io.*;
+import java.net.*;
+
+public class ProxySOCKS5 implements Proxy{
+  private static int DEFAULTPORT=1080;
+  private String proxy_host;
+  private int proxy_port;
+  private InputStream in;
+  private OutputStream out;
+  private Socket socket;
+  private String user;
+  private String passwd;
+
+  public ProxySOCKS5(String proxy_host){
+    int port=DEFAULTPORT;
+    String host=proxy_host;
+    if(proxy_host.indexOf(':')!=-1){
+      try{
+	host=proxy_host.substring(0, proxy_host.indexOf(':'));
+	port=Integer.parseInt(proxy_host.substring(proxy_host.indexOf(':')+1));
+      }
+      catch(Exception e){
+      }
+    }
+    this.proxy_host=host;
+    this.proxy_port=port;
+  }
+  public ProxySOCKS5(String proxy_host, int proxy_port){
+    this.proxy_host=proxy_host;
+    this.proxy_port=proxy_port;
+  }
+  public void setUserPasswd(String user, String passwd){
+    this.user=user;
+    this.passwd=passwd;
+  }
+  public void connect(SocketFactory socket_factory, String host, int port, int timeout) throws JSchException{
+    try{
+      if(socket_factory==null){
+        socket=Util.createSocket(proxy_host, proxy_port, timeout);
+        //socket=new Socket(proxy_host, proxy_port);    
+        in=socket.getInputStream();
+        out=socket.getOutputStream();
+      }
+      else{
+        socket=socket_factory.createSocket(proxy_host, proxy_port);
+        in=socket_factory.getInputStream(socket);
+        out=socket_factory.getOutputStream(socket);
+      }
+      if(timeout>0){
+        socket.setSoTimeout(timeout);
+      }
+      socket.setTcpNoDelay(true);
+
+      byte[] buf=new byte[1024];
+      int index=0;
+
+/*
+                   +----+----------+----------+
+                   |VER | NMETHODS | METHODS  |
+                   +----+----------+----------+
+                   | 1  |    1     | 1 to 255 |
+                   +----+----------+----------+
+
+   The VER field is set to X'05' for this version of the protocol.  The
+   NMETHODS field contains the number of method identifier octets that
+   appear in the METHODS field.
+
+   The values currently defined for METHOD are:
+
+          o  X'00' NO AUTHENTICATION REQUIRED
+          o  X'01' GSSAPI
+          o  X'02' USERNAME/PASSWORD
+          o  X'03' to X'7F' IANA ASSIGNED
+          o  X'80' to X'FE' RESERVED FOR PRIVATE METHODS
+          o  X'FF' NO ACCEPTABLE METHODS
+*/
+
+      buf[index++]=5;
+
+      buf[index++]=2;
+      buf[index++]=0;           // NO AUTHENTICATION REQUIRED
+      buf[index++]=2;           // USERNAME/PASSWORD
+
+      out.write(buf, 0, index);
+
+/*
+    The server selects from one of the methods given in METHODS, and
+    sends a METHOD selection message:
+
+                         +----+--------+
+                         |VER | METHOD |
+                         +----+--------+
+                         | 1  |   1    |
+                         +----+--------+
+*/
+      //in.read(buf, 0, 2);
+      fill(in, buf, 2);
+ 
+      boolean check=false;
+      switch((buf[1])&0xff){
+        case 0:                // NO AUTHENTICATION REQUIRED
+          check=true;
+          break;
+        case 2:                // USERNAME/PASSWORD
+          if(user==null || passwd==null)break;
+
+/*
+   Once the SOCKS V5 server has started, and the client has selected the
+   Username/Password Authentication protocol, the Username/Password
+   subnegotiation begins.  This begins with the client producing a
+   Username/Password request:
+
+           +----+------+----------+------+----------+
+           |VER | ULEN |  UNAME   | PLEN |  PASSWD  |
+           +----+------+----------+------+----------+
+           | 1  |  1   | 1 to 255 |  1   | 1 to 255 |
+           +----+------+----------+------+----------+
+
+   The VER field contains the current version of the subnegotiation,
+   which is X'01'. The ULEN field contains the length of the UNAME field
+   that follows. The UNAME field contains the username as known to the
+   source operating system. The PLEN field contains the length of the
+   PASSWD field that follows. The PASSWD field contains the password
+   association with the given UNAME.
+*/
+          index=0;
+          buf[index++]=1;
+          buf[index++]=(byte)(user.length());
+	  System.arraycopy(Util.str2byte(user), 0, buf, index, user.length());
+	  index+=user.length();
+          buf[index++]=(byte)(passwd.length());
+	  System.arraycopy(Util.str2byte(passwd), 0, buf, index, passwd.length());
+	  index+=passwd.length();
+
+          out.write(buf, 0, index);
+
+/*
+   The server verifies the supplied UNAME and PASSWD, and sends the
+   following response:
+
+                        +----+--------+
+                        |VER | STATUS |
+                        +----+--------+
+                        | 1  |   1    |
+                        +----+--------+
+
+   A STATUS field of X'00' indicates success. If the server returns a
+   `failure' (STATUS value other than X'00') status, it MUST close the
+   connection.
+*/
+          //in.read(buf, 0, 2);
+          fill(in, buf, 2);
+          if(buf[1]==0)
+            check=true;
+          break;
+        default:
+      }
+
+      if(!check){
+        try{ socket.close(); }
+	catch(Exception eee){
+	}
+        throw new JSchException("fail in SOCKS5 proxy");
+      }
+
+/*
+      The SOCKS request is formed as follows:
+
+        +----+-----+-------+------+----------+----------+
+        |VER | CMD |  RSV  | ATYP | DST.ADDR | DST.PORT |
+        +----+-----+-------+------+----------+----------+
+        | 1  |  1  | X'00' |  1   | Variable |    2     |
+        +----+-----+-------+------+----------+----------+
+
+      Where:
+
+      o  VER    protocol version: X'05'
+      o  CMD
+         o  CONNECT X'01'
+         o  BIND X'02'
+         o  UDP ASSOCIATE X'03'
+      o  RSV    RESERVED
+         o  ATYP   address type of following address
+         o  IP V4 address: X'01'
+         o  DOMAINNAME: X'03'
+         o  IP V6 address: X'04'
+      o  DST.ADDR       desired destination address
+      o  DST.PORT desired destination port in network octet
+         order
+*/
+     
+      index=0;
+      buf[index++]=5;
+      buf[index++]=1;       // CONNECT
+      buf[index++]=0;
+
+      byte[] hostb=Util.str2byte(host);
+      int len=hostb.length;
+      buf[index++]=3;      // DOMAINNAME
+      buf[index++]=(byte)(len);
+      System.arraycopy(hostb, 0, buf, index, len);
+      index+=len;
+      buf[index++]=(byte)(port>>>8);
+      buf[index++]=(byte)(port&0xff);
+
+      out.write(buf, 0, index);
+
+/*
+   The SOCKS request information is sent by the client as soon as it has
+   established a connection to the SOCKS server, and completed the
+   authentication negotiations.  The server evaluates the request, and
+   returns a reply formed as follows:
+
+        +----+-----+-------+------+----------+----------+
+        |VER | REP |  RSV  | ATYP | BND.ADDR | BND.PORT |
+        +----+-----+-------+------+----------+----------+
+        | 1  |  1  | X'00' |  1   | Variable |    2     |
+        +----+-----+-------+------+----------+----------+
+
+   Where:
+
+   o  VER    protocol version: X'05'
+   o  REP    Reply field:
+      o  X'00' succeeded
+      o  X'01' general SOCKS server failure
+      o  X'02' connection not allowed by ruleset
+      o  X'03' Network unreachable
+      o  X'04' Host unreachable
+      o  X'05' Connection refused
+      o  X'06' TTL expired
+      o  X'07' Command not supported
+      o  X'08' Address type not supported
+      o  X'09' to X'FF' unassigned
+    o  RSV    RESERVED
+    o  ATYP   address type of following address
+      o  IP V4 address: X'01'
+      o  DOMAINNAME: X'03'
+      o  IP V6 address: X'04'
+    o  BND.ADDR       server bound address
+    o  BND.PORT       server bound port in network octet order
+*/
+
+      //in.read(buf, 0, 4);
+      fill(in, buf, 4);
+
+      if(buf[1]!=0){
+        try{ socket.close(); }
+	catch(Exception eee){
+	}
+        throw new JSchException("ProxySOCKS5: server returns "+buf[1]);
+      }
+
+      switch(buf[3]&0xff){
+        case 1:
+          //in.read(buf, 0, 6);
+          fill(in, buf, 6);
+	  break;
+        case 3:
+          //in.read(buf, 0, 1);
+          fill(in, buf, 1);
+          //in.read(buf, 0, buf[0]+2);
+          fill(in, buf, (buf[0]&0xff)+2);
+	  break;
+        case 4:
+          //in.read(buf, 0, 18);
+          fill(in, buf, 18);
+          break;
+        default:
+      }
+    }
+    catch(RuntimeException e){
+      throw e;
+    }
+    catch(Exception e){
+      try{ if(socket!=null)socket.close(); }
+      catch(Exception eee){
+      }
+      String message="ProxySOCKS5: "+e.toString();
+      if(e instanceof Throwable)
+        throw new JSchException(message, (Throwable)e);
+      throw new JSchException(message);
+    }
+  }
+  public InputStream getInputStream(){ return in; }
+  public OutputStream getOutputStream(){ return out; }
+  public Socket getSocket(){ return socket; }
+  public void close(){
+    try{
+      if(in!=null)in.close();
+      if(out!=null)out.close();
+      if(socket!=null)socket.close();
+    }
+    catch(Exception e){
+    }
+    in=null;
+    out=null;
+    socket=null;
+  }
+  public static int getDefaultPort(){
+    return DEFAULTPORT;
+  }
+  private void fill(InputStream in, byte[] buf, int len) throws JSchException, IOException{
+    int s=0;
+    while(s<len){
+      int i=in.read(buf, s, len-s);
+      if(i<=0){
+        throw new JSchException("ProxySOCKS5: stream is closed");
+      }
+      s+=i;
+    }
+  }
+}
diff --git a/java/com/jcraft/jsch/README b/java/com/jcraft/jsch/README
new file mode 100644
index 0000000..a52886e
--- /dev/null
+++ b/java/com/jcraft/jsch/README
@@ -0,0 +1,221 @@
+
+                                      JSch
+
+                                Java Secure Channel
+                         by ymnk@jcraft.com, JCraft,Inc.
+
+                            http://www.jcraft.com/jsch/
+
+Last modified: Wed Nov  1 14:43:31 UTC 2006
+
+
+Description
+===========
+JSch is a pure Java implementation of SSH2.  JSch allows you to 
+connect to an sshd server and use port forwarding, X11 forwarding, 
+file transfer, etc., and you can integrate its functionality
+into your own Java programs. JSch is licensed under BSD style license.
+
+
+Documentation
+=============
+* README files all over the source tree have info related to the stuff
+  in the directories. 
+* ChangeLog: what changed from the previous version?
+
+
+Directories & Files in the Source Tree
+======================================
+* src/com/ has source trees of JSch
+* example/ has some samples, which demonstrate the usages.
+* tools/ has scripts for Ant.
+
+
+Why JSch?
+==========
+Our intension in developing this stuff is to enable users of our pure
+java X servers, WiredX(http://wiredx.net/) and WeirdX, to enjoy secure X
+sessions.  Our efforts have mostly targeted the SSH2 protocol in relation
+to X Window System and X11 forwarding.  Of course, we are also interested in 
+adding other functionality - port forward, file transfer, terminal emulation, etc.
+
+
+Features
+========
+* JSch is in pure Java, but it depends on JavaTM Cryptography
+  Extension (JCE).  JSch is know to work with:
+  o J2SE 1.4.0 or later (no additional libraries required).
+  o J2SE 1.3 and Sun's JCE reference implementation that can be
+    obtained at http://java.sun.com/products/jce/
+  o J2SE 1.2.2 and later and Bouncycastle's JCE implementation that
+    can be obtained at http://www.bouncycastle.org/
+* SSH2 protocol support.
+* Key exchange: diffie-hellman-group-exchange-sha1, diffie-hellman-group1-sha1
+* Cipher: blowfish-cbc,3des-cbc,aes128-cbc,aes192-cbc,aes256-cbc
+          3des-ctr,aes128-ctr,aes192-ctr,aes256-ctc,
+          arcfour,arcfour128,arcfour256
+* MAC: hmac-md5,hmac-md5-96,hmac-sha1,hmac-sha1-96
+* Host key type: ssh-dss, ssh-rsa
+* Userauth: password
+* Userauth: publickey(DSA,RSA)
+* Userauth: keyboard-interactive
+* Userauth: gssapi-with-mic
+* X11 forwarding.
+* xauth spoofing.
+* connection through HTTP proxy.
+* connection through SOCKS5, SOCKS4 proxy.
+* port forwarding.
+* stream forwarding.
+* signal sending.
+  The unofficial patch for sshd of openssh will be find in the thread
+  http://marc.theaimsgroup.com/?l=openssh-unix-dev&m=104295745607575&w=2
+* envrironment variable passing.
+* remote exec.
+* generating DSA and RSA key pairs.
+* SSH File Transfer Protocol(version 0, 1, 2, 3)
+* partial authentication
+* packet compression: zlib, zlib@openssh.com
+  JZlib(http://www.jcraft.com/jzlib/) has been used.
+* hashed known_hosts file.
+* NONE Cipher switching.
+  http://www.psc.edu/networking/projects/hpn-ssh/none.php
+* JSch is licensed under BSD style license(refer to LICENSE.txt).
+
+
+How To Try
+==========
+This archive does not include java byte code, so please compile
+the source code by your self.
+  $ cd jsch-?.?.?/src
+  $ javac com/jcraft/jsch/*java com/jcraft/jsch/jce/*java com/jcraft/jzlib/*.java
+'/examples/' directory has included some samples to demonstrate what 
+JSch can do.  Please refer to '/examples/README' file.
+
+
+AES cipher
+==========
+JSch supports aes128-cbc,aes192-cbc,aes256-cbc,aes128-ctr,aes192-ctr,
+aes256-ctr but you require AES support in your J2SE to choose some of them.  
+If you are using Sun's J2SE, J2SE 1.4.2 or later is required.  
+And then, J2SE 1.4.2(or later) does not support aes256 by the default, 
+because of 'import control restrictions of some countries'.
+We have confirmed that by applying
+  "Java Cryptography Extension (JCE)
+  Unlimited Strength Jurisdiction Policy Files 1.4.2"
+on
+  http://java.sun.com/j2se/1.4.2/download.html#docs
+we can enjoy 'aes256-cbc,aes256-ctr'.
+
+
+Stream Forwarding
+=================
+JSch has a unique functionality, Stream Forwarding.
+Stream Forwarding allows you to plug Java I/O streams directly into a remote TCP
+port without assigning and opening a local TCP port.
+In port forwarding, as with the -L option of ssh command, you have to assign
+and open a local TCP port and that port is also accessible by crackers
+on localhost.  In some case, that local TCP port may be plugged to a
+secret port via SSH session.
+A sample program, /example/StreamForwarding.java , demonstrates
+this functionality.
+
+
+Generating Authentication Keys
+==============================
+JSch allows you to generate DSA and RSA key pairs, which are in OpenSSH format.
+Please refer to 'examples/KeyGen.java'.
+
+
+Packet Compression
+==================
+According to the draft from IETF sesch working group, the packet
+compression can be applied to each data stream directions; from sshd
+server to ssh client and from ssh client to sshd server.  So, jsch
+allows you to choose which data stream direction will be compressed or not.
+For example, in X11 forwarding session, the packet compression for data
+stream from sshd to ssh client will save the network traffic, but
+usually the traffic from ssh client to sshd is light, so by omitting
+the compression for this direction, you may be able to save some CPU time.
+Please refer to a sample program 'examples/Compression.java'.
+
+
+Property
+========
+By setting properties, you can control the behavior of jsch.
+Here is an example of enabling the packet compression,
+
+      Session session=jsch.getSession(user, host, 22);
+      java.util.Properties config=new java.util.Properties();
+      config.put("compression.s2c", "zlib,none");
+      config.put("compression.c2s", "zlib,none");
+      session.setConfig(config);
+      session.connect();
+
+Current release has supported following properties,
+* compression.s2c: zlib, none
+  default: none
+  Specifies whether to use compression for the data stream
+  from sshd to jsch.  If "zlib,none" is given and the remote sshd does
+  not allow the packet compression, compression will not be done.
+* compression.c2s: zlib, none
+  default: none
+  Specifies whether to use compression for the data stream
+  from jsch to sshd.
+* StrictHostKeyChecking: ask | yes | no
+  default: ask
+  If this property is set to ``yes'', jsch will never automatically add
+  host keys to the $HOME/.ssh/known_hosts file, and refuses to connect
+  to hosts whose host key has changed.  This property forces the user
+  to manually add all new hosts.  If this property is set to ``no'', 
+  jsch will automatically add new host keys to the user known hosts
+  files.  If this property is set to ``ask'', new  host keys will be
+  added to the user known host files only after the user has confirmed 
+  that is what they really want to do, and jsch will refuse to connect 
+  to hosts whose host key has changed.
+
+
+TODO
+====
+* re-implementation with java.nio.
+* replacing cipher, hash by JCE with pure Java code.
+* SSH File Transfer Protocol version 4.
+* error handling.
+
+
+Copyrights & Disclaimers
+========================
+JSch is copyrighted by ymnk, JCraft,Inc. and is licensed through BSD style license.
+Read the LICENSE.txt file for the complete license.
+
+
+Credits and Acknowledgments
+============================
+JSch has been developed by ymnk@jcraft.com and it can not be hacked
+without several help.
+* First of all, we want to thank JCE team at Sun Microsystems.
+  For long time, we had planed to implement SSH2 in pure Java,
+  but we had hesitated to do because tons of work must be done for
+  implementing ciphers, hashes, etc., from the scratch.
+  Thanks to newly added functionalities to J2SE 1.4.0, we could
+  start this project.
+* We appreciate the OpenSSH project.
+  The options '-ddd' of sshd, '---vvv' of ssh and the compile options 
+  '-DPACKET_DEBUG', '-DDEBUG_KEXDH' and  '-DDEBUG_KEX' were very
+  useful in debugging JSch.
+* We appreciate IETF sesch working group and SSH Communications Security Corp.
+  Without the standardization of the protocol, we could not get the
+  chance to implement JSch.
+* We appreciate Seigo Haruyama(http://www.unixuser.org/~haruyama/),
+  who are interpreting drafts of SSH2 protocol in Japanese.
+  His works were very useful for us to understand the technical terms
+  in our native language.
+* We also appreciate SourceForge.net's awesome service to the 
+  Open Source Community.
+
+
+If you have any comments, suggestions and questions, write us 
+at jsch@jcraft.com
+
+
+``SSH is a registered trademark and Secure Shell is a trademark of
+SSH Communications Security Corp (www.ssh.com)''.
diff --git a/java/com/jcraft/jsch/Random.java b/java/com/jcraft/jsch/Random.java
new file mode 100644
index 0000000..879b777
--- /dev/null
+++ b/java/com/jcraft/jsch/Random.java
@@ -0,0 +1,34 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+public interface Random{
+  void fill(byte[] foo, int start, int len);
+}
diff --git a/java/com/jcraft/jsch/Request.java b/java/com/jcraft/jsch/Request.java
new file mode 100644
index 0000000..94f9b01
--- /dev/null
+++ b/java/com/jcraft/jsch/Request.java
@@ -0,0 +1,69 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+abstract class Request{
+  private boolean reply=false;
+  private Session session=null;
+  private Channel channel=null;
+  void request(Session session, Channel channel) throws Exception{
+    this.session=session;
+    this.channel=channel;
+    if(channel.connectTimeout>0){
+      setReply(true);
+    }
+  }
+  boolean waitForReply(){ return reply; }
+  void setReply(boolean reply){ this.reply=reply; }
+  void write(Packet packet) throws Exception{
+    if(reply){
+      channel.reply=-1;
+    }
+    session.write(packet);
+    if(reply){
+      long start=System.currentTimeMillis();
+      long timeout=channel.connectTimeout;
+      while(channel.isConnected() && channel.reply==-1){
+	try{Thread.sleep(10);}
+	catch(Exception ee){
+	}
+        if(timeout>0L &&
+           (System.currentTimeMillis()-start)>timeout){
+          channel.reply=0;
+          throw new JSchException("channel request: timeout");
+        }
+      }
+
+      if(channel.reply==0){
+	throw new JSchException("failed to send channel request");
+      }
+    }
+  }
+}
diff --git a/java/com/jcraft/jsch/RequestAgentForwarding.java b/java/com/jcraft/jsch/RequestAgentForwarding.java
new file mode 100644
index 0000000..66d328c
--- /dev/null
+++ b/java/com/jcraft/jsch/RequestAgentForwarding.java
@@ -0,0 +1,53 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2006-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+class RequestAgentForwarding extends Request{
+  public void request(Session session, Channel channel) throws Exception{
+    super.request(session, channel);
+
+    setReply(false);
+
+    Buffer buf=new Buffer();
+    Packet packet=new Packet(buf);
+
+    // byte      SSH_MSG_CHANNEL_REQUEST(98)
+    // uint32 recipient channel
+    // string request type        // "auth-agent-req@openssh.com"
+    // boolean want reply         // 0
+    packet.reset();
+    buf.putByte((byte) Session.SSH_MSG_CHANNEL_REQUEST);
+    buf.putInt(channel.getRecipient());
+    buf.putString(Util.str2byte("auth-agent-req@openssh.com"));
+    buf.putByte((byte)(waitForReply() ? 1 : 0));
+    write(packet);
+    session.agent_forwarding=true;
+  }
+}
diff --git a/java/com/jcraft/jsch/RequestEnv.java b/java/com/jcraft/jsch/RequestEnv.java
new file mode 100644
index 0000000..cccda4d
--- /dev/null
+++ b/java/com/jcraft/jsch/RequestEnv.java
@@ -0,0 +1,54 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+class RequestEnv extends Request{
+  byte[] name=new byte[0];
+  byte[] value=new byte[0];
+  void setEnv(byte[] name, byte[] value){
+    this.name=name;
+    this.value=value;
+  }
+  public void request(Session session, Channel channel) throws Exception{
+    super.request(session, channel);
+
+    Buffer buf=new Buffer();
+    Packet packet=new Packet(buf);
+
+    packet.reset();
+    buf.putByte((byte) Session.SSH_MSG_CHANNEL_REQUEST);
+    buf.putInt(channel.getRecipient());
+    buf.putString(Util.str2byte("env"));
+    buf.putByte((byte)(waitForReply() ? 1 : 0));
+    buf.putString(name);
+    buf.putString(value);
+    write(packet);
+  }
+}
diff --git a/java/com/jcraft/jsch/RequestExec.java b/java/com/jcraft/jsch/RequestExec.java
new file mode 100644
index 0000000..318d99a
--- /dev/null
+++ b/java/com/jcraft/jsch/RequestExec.java
@@ -0,0 +1,58 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+class RequestExec extends Request{
+  private byte[] command=new byte[0];
+  RequestExec(byte[] command){
+    this.command=command;
+  }
+  public void request(Session session, Channel channel) throws Exception{
+    super.request(session, channel);
+
+    Buffer buf=new Buffer();
+    Packet packet=new Packet(buf);
+
+    // send
+    // byte     SSH_MSG_CHANNEL_REQUEST(98)
+    // uint32 recipient channel
+    // string request type       // "exec"
+    // boolean want reply        // 0
+    // string command
+    packet.reset();
+    buf.putByte((byte) Session.SSH_MSG_CHANNEL_REQUEST);
+    buf.putInt(channel.getRecipient());
+    buf.putString(Util.str2byte("exec"));
+    buf.putByte((byte)(waitForReply() ? 1 : 0));
+    buf.checkFreeSize(4+command.length);
+    buf.putString(command);
+    write(packet);
+  }
+}
diff --git a/java/com/jcraft/jsch/RequestPtyReq.java b/java/com/jcraft/jsch/RequestPtyReq.java
new file mode 100644
index 0000000..86bf4f1
--- /dev/null
+++ b/java/com/jcraft/jsch/RequestPtyReq.java
@@ -0,0 +1,78 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+class RequestPtyReq extends Request{
+  private String ttype="vt100";
+  private int tcol=80;
+  private int trow=24;
+  private int twp=640;
+  private int thp=480;
+
+  private byte[] terminal_mode=Util.empty;
+
+  void setCode(String cookie){
+  }
+
+  void setTType(String ttype){
+    this.ttype=ttype;
+  }
+  
+  void setTerminalMode(byte[] terminal_mode){
+    this.terminal_mode=terminal_mode;
+  }
+
+  void setTSize(int tcol, int trow, int twp, int thp){
+    this.tcol=tcol;
+    this.trow=trow;
+    this.twp=twp;
+    this.thp=thp;
+  }
+
+  public void request(Session session, Channel channel) throws Exception{
+    super.request(session, channel);
+
+    Buffer buf=new Buffer();
+    Packet packet=new Packet(buf);
+
+    packet.reset();
+    buf.putByte((byte) Session.SSH_MSG_CHANNEL_REQUEST);
+    buf.putInt(channel.getRecipient());
+    buf.putString(Util.str2byte("pty-req"));
+    buf.putByte((byte)(waitForReply() ? 1 : 0));
+    buf.putString(Util.str2byte(ttype));
+    buf.putInt(tcol);
+    buf.putInt(trow);
+    buf.putInt(twp);
+    buf.putInt(thp);
+    buf.putString(terminal_mode);
+    write(packet);
+  }
+}
diff --git a/java/com/jcraft/jsch/RequestSftp.java b/java/com/jcraft/jsch/RequestSftp.java
new file mode 100644
index 0000000..483c296
--- /dev/null
+++ b/java/com/jcraft/jsch/RequestSftp.java
@@ -0,0 +1,49 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+public class RequestSftp extends Request{
+  RequestSftp(){
+    setReply(true);
+  }
+  public void request(Session session, Channel channel) throws Exception{
+    super.request(session, channel);
+
+    Buffer buf=new Buffer();
+    Packet packet=new Packet(buf);
+    packet.reset();
+    buf.putByte((byte)Session.SSH_MSG_CHANNEL_REQUEST);
+    buf.putInt(channel.getRecipient());
+    buf.putString(Util.str2byte("subsystem"));
+    buf.putByte((byte)(waitForReply() ? 1 : 0));
+    buf.putString(Util.str2byte("sftp"));
+    write(packet);
+  }
+}
diff --git a/java/com/jcraft/jsch/RequestShell.java b/java/com/jcraft/jsch/RequestShell.java
new file mode 100644
index 0000000..e037ba9
--- /dev/null
+++ b/java/com/jcraft/jsch/RequestShell.java
@@ -0,0 +1,51 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+class RequestShell extends Request{
+  public void request(Session session, Channel channel) throws Exception{
+    super.request(session, channel);
+
+    Buffer buf=new Buffer();
+    Packet packet=new Packet(buf);
+
+    // send
+    // byte     SSH_MSG_CHANNEL_REQUEST(98)
+    // uint32 recipient channel
+    // string request type       // "shell"
+    // boolean want reply        // 0
+    packet.reset();
+    buf.putByte((byte) Session.SSH_MSG_CHANNEL_REQUEST);
+    buf.putInt(channel.getRecipient());
+    buf.putString(Util.str2byte("shell"));
+    buf.putByte((byte)(waitForReply() ? 1 : 0));
+    write(packet);
+  }
+}
diff --git a/java/com/jcraft/jsch/RequestSignal.java b/java/com/jcraft/jsch/RequestSignal.java
new file mode 100644
index 0000000..a692617
--- /dev/null
+++ b/java/com/jcraft/jsch/RequestSignal.java
@@ -0,0 +1,49 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+class RequestSignal extends Request{
+  private String signal="KILL";
+  public void setSignal(String foo){ signal=foo; }
+  public void request(Session session, Channel channel) throws Exception{
+    super.request(session, channel);
+
+    Buffer buf=new Buffer();
+    Packet packet=new Packet(buf);
+
+    packet.reset();
+    buf.putByte((byte) Session.SSH_MSG_CHANNEL_REQUEST);
+    buf.putInt(channel.getRecipient());
+    buf.putString(Util.str2byte("signal"));
+    buf.putByte((byte)(waitForReply() ? 1 : 0));
+    buf.putString(Util.str2byte(signal));
+    write(packet);
+  }
+}
diff --git a/java/com/jcraft/jsch/RequestSubsystem.java b/java/com/jcraft/jsch/RequestSubsystem.java
new file mode 100644
index 0000000..b6fee4f
--- /dev/null
+++ b/java/com/jcraft/jsch/RequestSubsystem.java
@@ -0,0 +1,53 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2005-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+public class RequestSubsystem extends Request{
+  private String subsystem=null;
+  public void request(Session session, Channel channel, String subsystem, boolean want_reply) throws Exception{
+    setReply(want_reply);
+    this.subsystem=subsystem;
+    this.request(session, channel);
+  }
+  public void request(Session session, Channel channel) throws Exception{
+    super.request(session, channel);
+
+    Buffer buf=new Buffer();
+    Packet packet=new Packet(buf);
+
+    packet.reset();
+    buf.putByte((byte)Session.SSH_MSG_CHANNEL_REQUEST);
+    buf.putInt(channel.getRecipient());
+    buf.putString(Util.str2byte("subsystem"));
+    buf.putByte((byte)(waitForReply() ? 1 : 0));
+    buf.putString(Util.str2byte(subsystem));
+    write(packet);
+  }
+}
diff --git a/java/com/jcraft/jsch/RequestWindowChange.java b/java/com/jcraft/jsch/RequestWindowChange.java
new file mode 100644
index 0000000..43600ac
--- /dev/null
+++ b/java/com/jcraft/jsch/RequestWindowChange.java
@@ -0,0 +1,68 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+class RequestWindowChange extends Request{
+  int width_columns=80;
+  int height_rows=24;
+  int width_pixels=640;
+  int height_pixels=480;
+  void setSize(int col, int row, int wp, int hp){
+    this.width_columns=col; 
+    this.height_rows=row; 
+    this.width_pixels=wp;
+    this.height_pixels=hp;
+  }
+  public void request(Session session, Channel channel) throws Exception{
+    super.request(session, channel);
+
+    Buffer buf=new Buffer();
+    Packet packet=new Packet(buf);
+
+    //byte      SSH_MSG_CHANNEL_REQUEST
+    //uint32    recipient_channel
+    //string    "window-change"
+    //boolean   FALSE
+    //uint32    terminal width, columns
+    //uint32    terminal height, rows
+    //uint32    terminal width, pixels
+    //uint32    terminal height, pixels
+    packet.reset();
+    buf.putByte((byte) Session.SSH_MSG_CHANNEL_REQUEST);
+    buf.putInt(channel.getRecipient());
+    buf.putString(Util.str2byte("window-change"));
+    buf.putByte((byte)(waitForReply() ? 1 : 0));
+    buf.putInt(width_columns);
+    buf.putInt(height_rows);
+    buf.putInt(width_pixels);
+    buf.putInt(height_pixels);
+    write(packet);
+  }
+}
diff --git a/java/com/jcraft/jsch/RequestX11.java b/java/com/jcraft/jsch/RequestX11.java
new file mode 100644
index 0000000..3bdaca9
--- /dev/null
+++ b/java/com/jcraft/jsch/RequestX11.java
@@ -0,0 +1,63 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+class RequestX11 extends Request{
+  public void setCookie(String cookie){
+    ChannelX11.cookie=Util.str2byte(cookie);
+  }
+  public void request(Session session, Channel channel) throws Exception{
+    super.request(session, channel);
+
+    Buffer buf=new Buffer();
+    Packet packet=new Packet(buf);
+
+    // byte      SSH_MSG_CHANNEL_REQUEST(98)
+    // uint32 recipient channel
+    // string request type        // "x11-req"
+    // boolean want reply         // 0
+    // boolean   single connection
+    // string    x11 authentication protocol // "MIT-MAGIC-COOKIE-1".
+    // string    x11 authentication cookie
+    // uint32    x11 screen number
+    packet.reset();
+    buf.putByte((byte) Session.SSH_MSG_CHANNEL_REQUEST);
+    buf.putInt(channel.getRecipient());
+    buf.putString(Util.str2byte("x11-req"));
+    buf.putByte((byte)(waitForReply() ? 1 : 0));
+    buf.putByte((byte)0);
+    buf.putString(Util.str2byte("MIT-MAGIC-COOKIE-1"));
+    buf.putString(ChannelX11.getFakedCookie(session));
+    buf.putInt(0);
+    write(packet);
+
+    session.x11_forwarding=true;
+  }
+}
diff --git a/java/com/jcraft/jsch/ServerSocketFactory.java b/java/com/jcraft/jsch/ServerSocketFactory.java
new file mode 100644
index 0000000..682b4c4
--- /dev/null
+++ b/java/com/jcraft/jsch/ServerSocketFactory.java
@@ -0,0 +1,37 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+import java.net.*;
+import java.io.*;
+
+public interface ServerSocketFactory{
+  public ServerSocket createServerSocket(int port, int backlog, InetAddress bindAddr) throws IOException;
+}
diff --git a/java/com/jcraft/jsch/Session.java b/java/com/jcraft/jsch/Session.java
new file mode 100644
index 0000000..962f52f
--- /dev/null
+++ b/java/com/jcraft/jsch/Session.java
@@ -0,0 +1,2054 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+import java.io.*;
+import java.net.*;
+
+public class Session implements Runnable{
+
+  // http://ietf.org/internet-drafts/draft-ietf-secsh-assignednumbers-01.txt
+  static final int SSH_MSG_DISCONNECT=                      1;
+  static final int SSH_MSG_IGNORE=                          2;
+  static final int SSH_MSG_UNIMPLEMENTED=                   3;
+  static final int SSH_MSG_DEBUG=                           4;
+  static final int SSH_MSG_SERVICE_REQUEST=                 5;
+  static final int SSH_MSG_SERVICE_ACCEPT=                  6;
+  static final int SSH_MSG_KEXINIT=                        20;
+  static final int SSH_MSG_NEWKEYS=                        21;
+  static final int SSH_MSG_KEXDH_INIT=                     30;
+  static final int SSH_MSG_KEXDH_REPLY=                    31;
+  static final int SSH_MSG_KEX_DH_GEX_GROUP=               31;
+  static final int SSH_MSG_KEX_DH_GEX_INIT=                32;
+  static final int SSH_MSG_KEX_DH_GEX_REPLY=               33;
+  static final int SSH_MSG_KEX_DH_GEX_REQUEST=             34;
+  static final int SSH_MSG_GLOBAL_REQUEST=                 80;
+  static final int SSH_MSG_REQUEST_SUCCESS=                81;
+  static final int SSH_MSG_REQUEST_FAILURE=                82;
+  static final int SSH_MSG_CHANNEL_OPEN=                   90;
+  static final int SSH_MSG_CHANNEL_OPEN_CONFIRMATION=      91;
+  static final int SSH_MSG_CHANNEL_OPEN_FAILURE=           92;
+  static final int SSH_MSG_CHANNEL_WINDOW_ADJUST=          93;
+  static final int SSH_MSG_CHANNEL_DATA=                   94;
+  static final int SSH_MSG_CHANNEL_EXTENDED_DATA=          95;
+  static final int SSH_MSG_CHANNEL_EOF=                    96;
+  static final int SSH_MSG_CHANNEL_CLOSE=                  97;
+  static final int SSH_MSG_CHANNEL_REQUEST=                98;
+  static final int SSH_MSG_CHANNEL_SUCCESS=                99;
+  static final int SSH_MSG_CHANNEL_FAILURE=               100;
+
+  private static final int PACKET_MAX_SIZE = 256 * 1024;
+
+  private byte[] V_S;                                 // server version
+  private byte[] V_C=Util.str2byte("SSH-2.0-JSCH-"+JSch.VERSION); // client version
+
+  private byte[] I_C; // the payload of the client's SSH_MSG_KEXINIT
+  private byte[] I_S; // the payload of the server's SSH_MSG_KEXINIT
+  private byte[] K_S; // the host key
+
+  private byte[] session_id;
+
+  private byte[] IVc2s;
+  private byte[] IVs2c;
+  private byte[] Ec2s;
+  private byte[] Es2c;
+  private byte[] MACc2s;
+  private byte[] MACs2c;
+
+  private int seqi=0;
+  private int seqo=0;
+
+  String[] guess=null;
+  private Cipher s2ccipher;
+  private Cipher c2scipher;
+  private MAC s2cmac;
+  private MAC c2smac;
+  //private byte[] mac_buf;
+  private byte[] s2cmac_result1;
+  private byte[] s2cmac_result2;
+
+  private Compression deflater;
+  private Compression inflater;
+
+  private IO io;
+  private Socket socket;
+  private int timeout=0;
+
+  private volatile boolean isConnected=false;
+
+  private boolean isAuthed=false;
+
+  private Thread connectThread=null;
+  private Object lock=new Object();
+
+  boolean x11_forwarding=false;
+  boolean agent_forwarding=false;
+
+  InputStream in=null;
+  OutputStream out=null;
+
+  static Random random;
+
+  Buffer buf;
+  Packet packet;
+
+  SocketFactory socket_factory=null;
+
+  static final int buffer_margin = 32 + // maximum padding length
+                                   20 + // maximum mac length
+                                   32;  // margin for deflater; deflater may inflate data
+
+  private java.util.Hashtable config=null;
+
+  private Proxy proxy=null;
+  private UserInfo userinfo;
+
+  private String hostKeyAlias=null;
+  private int serverAliveInterval=0;
+  private int serverAliveCountMax=1;
+
+  protected boolean daemon_thread=false;
+
+  private long kex_start_time=0L;
+
+  int max_auth_tries = 6;
+  int auth_failures = 0;
+
+  String host="127.0.0.1";
+  int port=22;
+
+  String username=null;
+  byte[] password=null;
+
+  JSch jsch;
+
+  Session(JSch jsch) throws JSchException{
+    super();
+    this.jsch=jsch;
+    buf=new Buffer();
+    packet=new Packet(buf);
+  }
+
+  public void connect() throws JSchException{
+    connect(timeout);
+  }
+
+  public void connect(int connectTimeout) throws JSchException{
+    if(isConnected){
+      throw new JSchException("session is already connected");
+    }
+
+    io=new IO();
+    if(random==null){
+      try{
+	Class c=Class.forName(getConfig("random"));
+        random=(Random)(c.newInstance());
+      }
+      catch(Exception e){ 
+        throw new JSchException(e.toString(), e);
+      }
+    }
+    Packet.setRandom(random);
+
+    if(JSch.getLogger().isEnabled(Logger.INFO)){
+      JSch.getLogger().log(Logger.INFO, 
+                           "Connecting to "+host+" port "+port);
+    }
+
+    try	{
+      int i, j;
+
+      if(proxy==null){
+        InputStream in;
+        OutputStream out;
+	if(socket_factory==null){
+          socket=Util.createSocket(host, port, connectTimeout);
+	  in=socket.getInputStream();
+	  out=socket.getOutputStream();
+	}
+	else{
+          socket=socket_factory.createSocket(host, port);
+	  in=socket_factory.getInputStream(socket);
+	  out=socket_factory.getOutputStream(socket);
+	}
+	//if(timeout>0){ socket.setSoTimeout(timeout); }
+        socket.setTcpNoDelay(true);
+        io.setInputStream(in);
+        io.setOutputStream(out);
+      }
+      else{
+	synchronized(proxy){
+          proxy.connect(socket_factory, host, port, connectTimeout);
+	  io.setInputStream(proxy.getInputStream());
+	  io.setOutputStream(proxy.getOutputStream());
+          socket=proxy.getSocket();
+	}
+      }
+
+      if(connectTimeout>0 && socket!=null){
+        socket.setSoTimeout(connectTimeout);
+      }
+
+      isConnected=true;
+
+      if(JSch.getLogger().isEnabled(Logger.INFO)){
+        JSch.getLogger().log(Logger.INFO, 
+                             "Connection established");
+      }
+
+      jsch.addSession(this);
+
+      {
+	// Some Cisco devices will miss to read '\n' if it is sent separately.
+	byte[] foo=new byte[V_C.length+1];
+	System.arraycopy(V_C, 0, foo, 0, V_C.length);
+	foo[foo.length-1]=(byte)'\n';
+	io.put(foo, 0, foo.length);
+      }
+
+      while(true){
+        i=0;
+        j=0;
+        while(i<buf.buffer.length){
+          j=io.getByte();
+          if(j<0)break;
+          buf.buffer[i]=(byte)j; i++; 
+          if(j==10)break;
+        }
+        if(j<0){
+          throw new JSchException("connection is closed by foreign host");
+        }
+
+        if(buf.buffer[i-1]==10){    // 0x0a
+          i--;
+          if(i>0 && buf.buffer[i-1]==13){  // 0x0d
+            i--;
+          }
+        }
+
+        if(i<=3 || 
+           ((i!=buf.buffer.length) &&
+            (buf.buffer[0]!='S'||buf.buffer[1]!='S'||
+             buf.buffer[2]!='H'||buf.buffer[3]!='-'))){
+          // It must not start with 'SSH-'
+          //System.err.println(new String(buf.buffer, 0, i);
+          continue;
+        }
+
+        if(i==buf.buffer.length ||
+           i<7 ||                                      // SSH-1.99 or SSH-2.0
+           (buf.buffer[4]=='1' && buf.buffer[6]!='9')  // SSH-1.5
+           ){
+          throw new JSchException("invalid server's version string");
+        }
+        break;
+      }
+
+      V_S=new byte[i]; System.arraycopy(buf.buffer, 0, V_S, 0, i);
+      //System.err.println("V_S: ("+i+") ["+new String(V_S)+"]");
+
+      if(JSch.getLogger().isEnabled(Logger.INFO)){
+        JSch.getLogger().log(Logger.INFO, 
+                             "Remote version string: "+Util.byte2str(V_S));
+        JSch.getLogger().log(Logger.INFO, 
+                             "Local version string: "+Util.byte2str(V_C));
+      }
+
+      send_kexinit();
+
+      buf=read(buf);
+      if(buf.getCommand()!=SSH_MSG_KEXINIT){
+        in_kex=false;
+	throw new JSchException("invalid protocol: "+buf.getCommand());
+      }
+
+      if(JSch.getLogger().isEnabled(Logger.INFO)){
+        JSch.getLogger().log(Logger.INFO, 
+                             "SSH_MSG_KEXINIT received");
+      }
+
+      KeyExchange kex=receive_kexinit(buf);
+
+      while(true){
+	buf=read(buf);
+	if(kex.getState()==buf.getCommand()){
+          kex_start_time=System.currentTimeMillis();
+          boolean result=kex.next(buf);
+	  if(!result){
+	    //System.err.println("verify: "+result);
+            in_kex=false;
+	    throw new JSchException("verify: "+result);
+	  }
+	}
+	else{
+          in_kex=false;
+	  throw new JSchException("invalid protocol(kex): "+buf.getCommand());
+	}
+	if(kex.getState()==KeyExchange.STATE_END){
+	  break;
+	}
+      }
+
+      try{ checkHost(host, port, kex); }
+      catch(JSchException ee){
+        in_kex=false;
+        throw ee;
+      }
+
+      send_newkeys();
+
+      // receive SSH_MSG_NEWKEYS(21)
+      buf=read(buf);
+      //System.err.println("read: 21 ? "+buf.getCommand());
+      if(buf.getCommand()==SSH_MSG_NEWKEYS){
+
+        if(JSch.getLogger().isEnabled(Logger.INFO)){
+          JSch.getLogger().log(Logger.INFO, 
+                               "SSH_MSG_NEWKEYS received");
+        }
+
+	receive_newkeys(buf, kex);
+      }
+      else{
+        in_kex=false;
+	throw new JSchException("invalid protocol(newkyes): "+buf.getCommand());
+      }
+
+      try{
+        String s = getConfig("MaxAuthTries");
+        if(s!=null){
+          max_auth_tries = Integer.parseInt(s);
+        }
+      }
+      catch(NumberFormatException e){
+        throw new JSchException("MaxAuthTries: "+getConfig("MaxAuthTries"), e);
+      }
+
+      boolean auth=false;
+      boolean auth_cancel=false;
+
+      UserAuth ua=null;
+      try{
+	Class c=Class.forName(getConfig("userauth.none"));
+        ua=(UserAuth)(c.newInstance());
+      }
+      catch(Exception e){ 
+        throw new JSchException(e.toString(), e);
+      }
+
+      auth=ua.start(this);
+
+      String cmethods=getConfig("PreferredAuthentications");
+
+      String[] cmethoda=Util.split(cmethods, ",");
+
+      String smethods=null;
+      if(!auth){
+        smethods=((UserAuthNone)ua).getMethods();
+        if(smethods!=null){
+          smethods=smethods.toLowerCase();
+        }
+        else{
+          // methods: publickey,password,keyboard-interactive
+          //smethods="publickey,password,keyboard-interactive";
+          smethods=cmethods;
+        }
+      }
+
+      String[] smethoda=Util.split(smethods, ",");
+
+      int methodi=0;
+
+      loop:
+      while(true){
+
+	while(!auth && 
+	      cmethoda!=null && methodi<cmethoda.length){
+
+          String method=cmethoda[methodi++];
+          boolean acceptable=false;
+          for(int k=0; k<smethoda.length; k++){
+            if(smethoda[k].equals(method)){
+              acceptable=true;
+              break;
+            }
+          }
+          if(!acceptable){
+            continue;
+          }
+
+          //System.err.println("  method: "+method);
+
+          if(JSch.getLogger().isEnabled(Logger.INFO)){
+            String str="Authentications that can continue: ";
+            for(int k=methodi-1; k<cmethoda.length; k++){
+              str+=cmethoda[k];
+              if(k+1<cmethoda.length)
+                str+=",";
+            }
+            JSch.getLogger().log(Logger.INFO, 
+                                 str);
+            JSch.getLogger().log(Logger.INFO, 
+                                 "Next authentication method: "+method);
+          }
+
+	  ua=null;
+          try{
+            Class c=null;
+            if(getConfig("userauth."+method)!=null){
+              c=Class.forName(getConfig("userauth."+method));
+              ua=(UserAuth)(c.newInstance());
+            }
+          }
+          catch(Exception e){
+            if(JSch.getLogger().isEnabled(Logger.WARN)){
+              JSch.getLogger().log(Logger.WARN, 
+                                   "failed to load "+method+" method");
+            }
+          }
+
+	  if(ua!=null){
+            auth_cancel=false;
+	    try{ 
+	      auth=ua.start(this); 
+              if(auth && 
+                 JSch.getLogger().isEnabled(Logger.INFO)){
+                JSch.getLogger().log(Logger.INFO, 
+                                     "Authentication succeeded ("+method+").");
+              }
+	    }
+	    catch(JSchAuthCancelException ee){
+	      auth_cancel=true;
+	    }
+	    catch(JSchPartialAuthException ee){
+              String tmp = smethods;
+              smethods=ee.getMethods();
+              smethoda=Util.split(smethods, ",");
+              if(!tmp.equals(smethods)){
+                methodi=0;
+              }
+	      //System.err.println("PartialAuth: "+methods);
+	      auth_cancel=false;
+	      continue loop;
+	    }
+	    catch(RuntimeException ee){
+	      throw ee;
+	    }
+	    catch(Exception ee){
+	      //System.err.println("ee: "+ee); // SSH_MSG_DISCONNECT: 2 Too many authentication failures
+              break loop;
+	    }
+	  }
+	}
+        break;
+      }
+
+      if(!auth){
+        if(auth_failures >= max_auth_tries){
+          if(JSch.getLogger().isEnabled(Logger.INFO)){
+            JSch.getLogger().log(Logger.INFO, 
+                                 "Login trials exceeds "+max_auth_tries);
+          }
+        }
+        if(auth_cancel)
+          throw new JSchException("Auth cancel");
+        throw new JSchException("Auth fail");
+      }
+
+      if(connectTimeout>0 || timeout>0){
+        socket.setSoTimeout(timeout);
+      }
+
+      isAuthed=true;
+
+      synchronized(lock){
+        if(isConnected){
+          connectThread=new Thread(this);
+          connectThread.setName("Connect thread "+host+" session");
+          if(daemon_thread){
+            connectThread.setDaemon(daemon_thread);
+          }
+          connectThread.start();
+        }
+        else{
+          // The session has been already down and
+          // we don't have to start new thread.
+        }
+      }
+    }
+    catch(Exception e) {
+      in_kex=false;
+      if(isConnected){
+	try{
+	  packet.reset();
+	  buf.putByte((byte)SSH_MSG_DISCONNECT);
+	  buf.putInt(3);
+	  buf.putString(Util.str2byte(e.toString()));
+	  buf.putString(Util.str2byte("en"));
+	  write(packet);
+	  disconnect();
+	}
+	catch(Exception ee){
+	}
+      }
+      isConnected=false;
+      //e.printStackTrace();
+      if(e instanceof RuntimeException) throw (RuntimeException)e;
+      if(e instanceof JSchException) throw (JSchException)e;
+      throw new JSchException("Session.connect: "+e);
+    }
+    finally{
+      Util.bzero(this.password);
+      this.password=null;
+    }
+  }
+
+  private KeyExchange receive_kexinit(Buffer buf) throws Exception {
+    int j=buf.getInt();
+    if(j!=buf.getLength()){    // packet was compressed and
+      buf.getByte();           // j is the size of deflated packet.
+      I_S=new byte[buf.index-5];
+    }
+    else{
+      I_S=new byte[j-1-buf.getByte()];
+    }
+   System.arraycopy(buf.buffer, buf.s, I_S, 0, I_S.length);
+
+   if(!in_kex){     // We are in rekeying activated by the remote!
+     send_kexinit();
+   }
+
+    guess=KeyExchange.guess(I_S, I_C);
+    if(guess==null){
+      throw new JSchException("Algorithm negotiation fail");
+    }
+
+    if(!isAuthed &&
+       (guess[KeyExchange.PROPOSAL_ENC_ALGS_CTOS].equals("none") ||
+        (guess[KeyExchange.PROPOSAL_ENC_ALGS_STOC].equals("none")))){
+      throw new JSchException("NONE Cipher should not be chosen before authentification is successed.");
+    }
+
+    KeyExchange kex=null;
+    try{
+      Class c=Class.forName(getConfig(guess[KeyExchange.PROPOSAL_KEX_ALGS]));
+      kex=(KeyExchange)(c.newInstance());
+    }
+    catch(Exception e){ 
+      throw new JSchException(e.toString(), e);
+    }
+
+    kex.init(this, V_S, V_C, I_S, I_C);
+    return kex;
+  }
+
+  private boolean in_kex=false;
+  public void rekey() throws Exception {
+    send_kexinit();
+  }
+  private void send_kexinit() throws Exception {
+    if(in_kex)
+      return;
+
+    String cipherc2s=getConfig("cipher.c2s");
+    String ciphers2c=getConfig("cipher.s2c");
+
+    String[] not_available_ciphers=checkCiphers(getConfig("CheckCiphers"));
+    if(not_available_ciphers!=null && not_available_ciphers.length>0){
+      cipherc2s=Util.diffString(cipherc2s, not_available_ciphers);
+      ciphers2c=Util.diffString(ciphers2c, not_available_ciphers);
+      if(cipherc2s==null || ciphers2c==null){
+        throw new JSchException("There are not any available ciphers.");
+      }
+    }
+
+    String kex=getConfig("kex");
+    String[] not_available_kexes=checkKexes(getConfig("CheckKexes"));
+    if(not_available_kexes!=null && not_available_kexes.length>0){
+      kex=Util.diffString(kex, not_available_kexes);
+      if(kex==null){
+        throw new JSchException("There are not any available kexes.");
+      }
+    }
+
+    in_kex=true;
+    kex_start_time=System.currentTimeMillis();
+
+    // byte      SSH_MSG_KEXINIT(20)
+    // byte[16]  cookie (random bytes)
+    // string    kex_algorithms
+    // string    server_host_key_algorithms
+    // string    encryption_algorithms_client_to_server
+    // string    encryption_algorithms_server_to_client
+    // string    mac_algorithms_client_to_server
+    // string    mac_algorithms_server_to_client
+    // string    compression_algorithms_client_to_server
+    // string    compression_algorithms_server_to_client
+    // string    languages_client_to_server
+    // string    languages_server_to_client
+    Buffer buf = new Buffer();                // send_kexinit may be invoked
+    Packet packet = new Packet(buf);          // by user thread.
+    packet.reset();
+    buf.putByte((byte) SSH_MSG_KEXINIT);
+    synchronized(random){
+      random.fill(buf.buffer, buf.index, 16); buf.skip(16);
+    }
+    buf.putString(Util.str2byte(kex));
+    buf.putString(Util.str2byte(getConfig("server_host_key")));
+    buf.putString(Util.str2byte(cipherc2s));
+    buf.putString(Util.str2byte(ciphers2c));
+    buf.putString(Util.str2byte(getConfig("mac.c2s")));
+    buf.putString(Util.str2byte(getConfig("mac.s2c")));
+    buf.putString(Util.str2byte(getConfig("compression.c2s")));
+    buf.putString(Util.str2byte(getConfig("compression.s2c")));
+    buf.putString(Util.str2byte(getConfig("lang.c2s")));
+    buf.putString(Util.str2byte(getConfig("lang.s2c")));
+    buf.putByte((byte)0);
+    buf.putInt(0);
+
+    buf.setOffSet(5);
+    I_C=new byte[buf.getLength()];
+    buf.getByte(I_C);
+
+    write(packet);
+
+    if(JSch.getLogger().isEnabled(Logger.INFO)){
+      JSch.getLogger().log(Logger.INFO, 
+                           "SSH_MSG_KEXINIT sent");
+    }
+  }
+
+  private void send_newkeys() throws Exception {
+    // send SSH_MSG_NEWKEYS(21)
+    packet.reset();
+    buf.putByte((byte)SSH_MSG_NEWKEYS);
+    write(packet);
+
+    if(JSch.getLogger().isEnabled(Logger.INFO)){
+      JSch.getLogger().log(Logger.INFO, 
+                           "SSH_MSG_NEWKEYS sent");
+    }
+  }
+
+  private void checkHost(String chost, int port, KeyExchange kex) throws JSchException {
+    String shkc=getConfig("StrictHostKeyChecking");
+
+    if(hostKeyAlias!=null){
+      chost=hostKeyAlias;
+    }
+
+    //System.err.println("shkc: "+shkc);
+
+    byte[] K_S=kex.getHostKey();
+    String key_type=kex.getKeyType();
+    String key_fprint=kex.getFingerPrint();
+
+    if(hostKeyAlias==null && port!=22){
+      chost=("["+chost+"]:"+port);
+    }
+
+//    hostkey=new HostKey(chost, K_S);
+
+    HostKeyRepository hkr=jsch.getHostKeyRepository();
+    int i=0;
+    synchronized(hkr){
+      i=hkr.check(chost, K_S);
+    }
+
+    boolean insert=false;
+
+    if((shkc.equals("ask") || shkc.equals("yes")) &&
+       i==HostKeyRepository.CHANGED){
+      String file=null;
+      synchronized(hkr){
+	file=hkr.getKnownHostsRepositoryID();
+      }
+      if(file==null){file="known_hosts";}
+
+      boolean b=false;
+
+      if(userinfo!=null){
+        String message=
+"WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!\n"+
+"IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!\n"+
+"Someone could be eavesdropping on you right now (man-in-the-middle attack)!\n"+
+"It is also possible that the "+key_type+" host key has just been changed.\n"+
+"The fingerprint for the "+key_type+" key sent by the remote host is\n"+
+key_fprint+".\n"+
+"Please contact your system administrator.\n"+
+"Add correct host key in "+file+" to get rid of this message.";
+
+        if(shkc.equals("ask")){
+          b=userinfo.promptYesNo(message+
+                                 "\nDo you want to delete the old key and insert the new key?");
+        }
+        else{  // shkc.equals("yes")
+          userinfo.showMessage(message);
+        }
+      }
+
+      if(!b){
+        throw new JSchException("HostKey has been changed: "+chost);
+      }
+
+      synchronized(hkr){
+        hkr.remove(chost, 
+                   (key_type.equals("DSA") ? "ssh-dss" : "ssh-rsa"), 
+                   null);
+        insert=true;
+      }
+    }
+
+    if((shkc.equals("ask") || shkc.equals("yes")) &&
+       (i!=HostKeyRepository.OK) && !insert){
+      if(shkc.equals("yes")){
+	throw new JSchException("reject HostKey: "+host);
+      }
+      //System.err.println("finger-print: "+key_fprint);
+      if(userinfo!=null){
+	boolean foo=userinfo.promptYesNo(
+"The authenticity of host '"+host+"' can't be established.\n"+
+key_type+" key fingerprint is "+key_fprint+".\n"+
+"Are you sure you want to continue connecting?"
+					 );
+	if(!foo){
+	  throw new JSchException("reject HostKey: "+host);
+	}
+	insert=true;
+      }
+      else{
+	if(i==HostKeyRepository.NOT_INCLUDED) 
+	  throw new JSchException("UnknownHostKey: "+host+". "+key_type+" key fingerprint is "+key_fprint);
+	else 
+          throw new JSchException("HostKey has been changed: "+host);
+      }
+    }
+
+    if(shkc.equals("no") && 
+       HostKeyRepository.NOT_INCLUDED==i){
+      insert=true;
+    }
+
+    if(i==HostKeyRepository.OK &&
+       JSch.getLogger().isEnabled(Logger.INFO)){
+      JSch.getLogger().log(Logger.INFO, 
+                           "Host '"+host+"' is known and mathces the "+key_type+" host key");
+    }
+
+    if(insert &&
+       JSch.getLogger().isEnabled(Logger.WARN)){
+      JSch.getLogger().log(Logger.WARN, 
+                           "Permanently added '"+host+"' ("+key_type+") to the list of known hosts.");
+    }
+
+    String hkh=getConfig("HashKnownHosts");
+    if(hkh.equals("yes") && (hkr instanceof KnownHosts)){
+      hostkey=((KnownHosts)hkr).createHashedHostKey(chost, K_S);
+    }
+    else{
+      hostkey=new HostKey(chost, K_S);
+    }
+
+    if(insert){
+      synchronized(hkr){
+	hkr.add(hostkey, userinfo);
+      }
+
+    }
+
+  }
+
+//public void start(){ (new Thread(this)).start();  }
+
+  public Channel openChannel(String type) throws JSchException{
+    if(!isConnected){
+      throw new JSchException("session is down");
+    }
+    try{
+      Channel channel=Channel.getChannel(type);
+      addChannel(channel);
+      channel.init();
+      return channel;
+    }
+    catch(Exception e){
+      //e.printStackTrace();
+    }
+    return null;
+  }
+
+  // encode will bin invoked in write with synchronization.
+  public void encode(Packet packet) throws Exception{
+//System.err.println("encode: "+packet.buffer.getCommand());
+//System.err.println("        "+packet.buffer.index);
+//if(packet.buffer.getCommand()==96){
+//Thread.dumpStack();
+//}
+    if(deflater!=null){
+      compress_len[0]=packet.buffer.index;
+      packet.buffer.buffer=deflater.compress(packet.buffer.buffer, 
+                                             5, compress_len);
+      packet.buffer.index=compress_len[0];
+    }
+    if(c2scipher!=null){
+      //packet.padding(c2scipher.getIVSize());
+      packet.padding(c2scipher_size);
+      int pad=packet.buffer.buffer[4];
+      synchronized(random){
+	random.fill(packet.buffer.buffer, packet.buffer.index-pad, pad);
+      }
+    }
+    else{
+      packet.padding(8);
+    }
+
+    if(c2smac!=null){
+      c2smac.update(seqo);
+      c2smac.update(packet.buffer.buffer, 0, packet.buffer.index);
+      c2smac.doFinal(packet.buffer.buffer, packet.buffer.index);
+    }
+    if(c2scipher!=null){
+      byte[] buf=packet.buffer.buffer;
+      c2scipher.update(buf, 0, packet.buffer.index, buf, 0);
+    }
+    if(c2smac!=null){
+      packet.buffer.skip(c2smac.getBlockSize());
+    }
+  }
+
+  int[] uncompress_len=new int[1];
+  int[] compress_len=new int[1];
+
+  private int s2ccipher_size=8;
+  private int c2scipher_size=8;
+  public Buffer read(Buffer buf) throws Exception{
+    int j=0;
+    while(true){
+      buf.reset();
+      io.getByte(buf.buffer, buf.index, s2ccipher_size); 
+      buf.index+=s2ccipher_size;
+      if(s2ccipher!=null){
+        s2ccipher.update(buf.buffer, 0, s2ccipher_size, buf.buffer, 0);
+      }
+      j=((buf.buffer[0]<<24)&0xff000000)|
+        ((buf.buffer[1]<<16)&0x00ff0000)|
+        ((buf.buffer[2]<< 8)&0x0000ff00)|
+        ((buf.buffer[3]    )&0x000000ff);
+      // RFC 4253 6.1. Maximum Packet Length
+      if(j<5 || j>PACKET_MAX_SIZE){
+        start_discard(buf, s2ccipher, s2cmac, j, PACKET_MAX_SIZE);
+      }
+      int need = j+4-s2ccipher_size;
+      //if(need<0){
+      //  throw new IOException("invalid data");
+      //}
+      if((buf.index+need)>buf.buffer.length){
+        byte[] foo=new byte[buf.index+need];
+        System.arraycopy(buf.buffer, 0, foo, 0, buf.index);
+        buf.buffer=foo;
+      }
+
+      if((need%s2ccipher_size)!=0){
+        String message="Bad packet length "+need;
+        if(JSch.getLogger().isEnabled(Logger.FATAL)){
+          JSch.getLogger().log(Logger.FATAL, message); 
+        }
+        start_discard(buf, s2ccipher, s2cmac, j, PACKET_MAX_SIZE-s2ccipher_size);
+      }
+
+      if(need>0){
+	io.getByte(buf.buffer, buf.index, need); buf.index+=(need);
+	if(s2ccipher!=null){
+	  s2ccipher.update(buf.buffer, s2ccipher_size, need, buf.buffer, s2ccipher_size);
+	}
+      }
+
+      if(s2cmac!=null){
+	s2cmac.update(seqi);
+	s2cmac.update(buf.buffer, 0, buf.index);
+
+        s2cmac.doFinal(s2cmac_result1, 0);
+	io.getByte(s2cmac_result2, 0, s2cmac_result2.length);
+        if(!java.util.Arrays.equals(s2cmac_result1, s2cmac_result2)){
+          if(need > PACKET_MAX_SIZE){
+            throw new IOException("MAC Error");
+          }
+          start_discard(buf, s2ccipher, s2cmac, j, PACKET_MAX_SIZE-need);
+          continue;
+	}
+      }
+
+      seqi++;
+
+      if(inflater!=null){
+        //inflater.uncompress(buf);
+	int pad=buf.buffer[4];
+	uncompress_len[0]=buf.index-5-pad;
+	byte[] foo=inflater.uncompress(buf.buffer, 5, uncompress_len);
+	if(foo!=null){
+	  buf.buffer=foo;
+	  buf.index=5+uncompress_len[0];
+	}
+	else{
+	  System.err.println("fail in inflater");
+	  break;
+	}
+      }
+
+      int type=buf.getCommand()&0xff;
+      //System.err.println("read: "+type);
+      if(type==SSH_MSG_DISCONNECT){
+        buf.rewind();
+        buf.getInt();buf.getShort();
+	int reason_code=buf.getInt();
+	byte[] description=buf.getString();
+	byte[] language_tag=buf.getString();
+	throw new JSchException("SSH_MSG_DISCONNECT: "+
+				    reason_code+
+				" "+Util.byte2str(description)+
+				" "+Util.byte2str(language_tag));
+	//break;
+      }
+      else if(type==SSH_MSG_IGNORE){
+      }
+      else if(type==SSH_MSG_UNIMPLEMENTED){
+        buf.rewind();
+        buf.getInt();buf.getShort();
+	int reason_id=buf.getInt();
+        if(JSch.getLogger().isEnabled(Logger.INFO)){
+          JSch.getLogger().log(Logger.INFO, 
+                               "Received SSH_MSG_UNIMPLEMENTED for "+reason_id);
+        }
+      }
+      else if(type==SSH_MSG_DEBUG){
+        buf.rewind();
+        buf.getInt();buf.getShort();
+/*
+	byte always_display=(byte)buf.getByte();
+	byte[] message=buf.getString();
+	byte[] language_tag=buf.getString();
+	System.err.println("SSH_MSG_DEBUG:"+
+			   " "+Util.byte2str(message)+
+			   " "+Util.byte2str(language_tag));
+*/
+      }
+      else if(type==SSH_MSG_CHANNEL_WINDOW_ADJUST){
+          buf.rewind();
+          buf.getInt();buf.getShort();
+	  Channel c=Channel.getChannel(buf.getInt(), this);
+	  if(c==null){
+	  }
+	  else{
+	    c.addRemoteWindowSize(buf.getInt()); 
+	  }
+      }
+      else if(type==UserAuth.SSH_MSG_USERAUTH_SUCCESS){
+        isAuthed=true;
+        if(inflater==null && deflater==null){
+          String method;
+          method=guess[KeyExchange.PROPOSAL_COMP_ALGS_CTOS];
+          initDeflater(method);
+          method=guess[KeyExchange.PROPOSAL_COMP_ALGS_STOC];
+          initInflater(method);
+        }
+        break;
+      }
+      else{
+        break;
+      }
+    }
+    buf.rewind();
+    return buf;
+  }
+
+  private void start_discard(Buffer buf, Cipher cipher, MAC mac, 
+                             int packet_length, int discard) throws JSchException, IOException{
+    MAC discard_mac = null;
+
+    if(!cipher.isCBC()){
+      throw new JSchException("Packet corrupt");
+    }
+
+    if(packet_length!=PACKET_MAX_SIZE && mac != null){
+      discard_mac = mac;
+    }
+
+    discard -= buf.index;
+
+    while(discard>0){
+      buf.reset();
+      int len = discard>buf.buffer.length ? buf.buffer.length : discard;
+      io.getByte(buf.buffer, 0, len);
+      if(discard_mac!=null){
+        discard_mac.update(buf.buffer, 0, len);
+      }
+      discard -= len;
+    }
+
+    if(discard_mac!=null){
+      discard_mac.doFinal(buf.buffer, 0);
+    }
+
+    throw new JSchException("Packet corrupt");
+  }
+
+  byte[] getSessionId(){
+    return session_id;
+  }
+
+  private void receive_newkeys(Buffer buf, KeyExchange kex) throws Exception {
+    updateKeys(kex);
+    in_kex=false;
+  }
+  private void updateKeys(KeyExchange kex) throws Exception{
+    byte[] K=kex.getK();
+    byte[] H=kex.getH();
+    HASH hash=kex.getHash();
+
+//    String[] guess=kex.guess;
+
+    if(session_id==null){
+      session_id=new byte[H.length];
+      System.arraycopy(H, 0, session_id, 0, H.length);
+    }
+
+    /*
+      Initial IV client to server:     HASH (K || H || "A" || session_id)
+      Initial IV server to client:     HASH (K || H || "B" || session_id)
+      Encryption key client to server: HASH (K || H || "C" || session_id)
+      Encryption key server to client: HASH (K || H || "D" || session_id)
+      Integrity key client to server:  HASH (K || H || "E" || session_id)
+      Integrity key server to client:  HASH (K || H || "F" || session_id)
+    */
+
+    buf.reset();
+    buf.putMPInt(K);
+    buf.putByte(H);
+    buf.putByte((byte)0x41);
+    buf.putByte(session_id);
+    hash.update(buf.buffer, 0, buf.index);
+    IVc2s=hash.digest();
+
+    int j=buf.index-session_id.length-1;
+
+    buf.buffer[j]++;
+    hash.update(buf.buffer, 0, buf.index);
+    IVs2c=hash.digest();
+
+    buf.buffer[j]++;
+    hash.update(buf.buffer, 0, buf.index);
+    Ec2s=hash.digest();
+
+    buf.buffer[j]++;
+    hash.update(buf.buffer, 0, buf.index);
+    Es2c=hash.digest();
+
+    buf.buffer[j]++;
+    hash.update(buf.buffer, 0, buf.index);
+    MACc2s=hash.digest();
+
+    buf.buffer[j]++;
+    hash.update(buf.buffer, 0, buf.index);
+    MACs2c=hash.digest();
+
+    try{
+      Class c;
+      String method;
+  
+      method=guess[KeyExchange.PROPOSAL_ENC_ALGS_STOC];
+      c=Class.forName(getConfig(method));
+      s2ccipher=(Cipher)(c.newInstance());
+      while(s2ccipher.getBlockSize()>Es2c.length){
+        buf.reset();
+        buf.putMPInt(K);
+        buf.putByte(H);
+        buf.putByte(Es2c);
+        hash.update(buf.buffer, 0, buf.index);
+        byte[] foo=hash.digest();
+        byte[] bar=new byte[Es2c.length+foo.length];
+	System.arraycopy(Es2c, 0, bar, 0, Es2c.length);
+	System.arraycopy(foo, 0, bar, Es2c.length, foo.length);
+	Es2c=bar;
+      }
+      s2ccipher.init(Cipher.DECRYPT_MODE, Es2c, IVs2c);
+      s2ccipher_size=s2ccipher.getIVSize();
+
+      method=guess[KeyExchange.PROPOSAL_MAC_ALGS_STOC];
+      c=Class.forName(getConfig(method));
+      s2cmac=(MAC)(c.newInstance());
+      s2cmac.init(MACs2c);
+      //mac_buf=new byte[s2cmac.getBlockSize()];
+      s2cmac_result1=new byte[s2cmac.getBlockSize()];
+      s2cmac_result2=new byte[s2cmac.getBlockSize()];
+
+      method=guess[KeyExchange.PROPOSAL_ENC_ALGS_CTOS];
+      c=Class.forName(getConfig(method));
+      c2scipher=(Cipher)(c.newInstance());
+      while(c2scipher.getBlockSize()>Ec2s.length){
+        buf.reset();
+        buf.putMPInt(K);
+        buf.putByte(H);
+        buf.putByte(Ec2s);
+        hash.update(buf.buffer, 0, buf.index);
+        byte[] foo=hash.digest();
+        byte[] bar=new byte[Ec2s.length+foo.length];
+	System.arraycopy(Ec2s, 0, bar, 0, Ec2s.length);
+	System.arraycopy(foo, 0, bar, Ec2s.length, foo.length);
+	Ec2s=bar;
+      }
+      c2scipher.init(Cipher.ENCRYPT_MODE, Ec2s, IVc2s);
+      c2scipher_size=c2scipher.getIVSize();
+
+      method=guess[KeyExchange.PROPOSAL_MAC_ALGS_CTOS];
+      c=Class.forName(getConfig(method));
+      c2smac=(MAC)(c.newInstance());
+      c2smac.init(MACc2s);
+
+      method=guess[KeyExchange.PROPOSAL_COMP_ALGS_CTOS];
+      initDeflater(method);
+
+      method=guess[KeyExchange.PROPOSAL_COMP_ALGS_STOC];
+      initInflater(method);
+    }
+    catch(Exception e){ 
+      if(e instanceof JSchException)
+        throw e;
+      throw new JSchException(e.toString(), e);
+      //System.err.println("updatekeys: "+e); 
+    }
+  }
+
+  /*public*/ /*synchronized*/ void write(Packet packet, Channel c, int length) throws Exception{
+    long t = getTimeout();
+    while(true){
+      if(in_kex){
+        if(t>0L && (System.currentTimeMillis()-kex_start_time)>t){
+          throw new JSchException("timeout in wating for rekeying process.");
+        }
+        try{Thread.sleep(10);}
+        catch(java.lang.InterruptedException e){};
+        continue;
+      }
+      synchronized(c){
+
+        if(c.rwsize<length){
+          try{ 
+            c.notifyme++;
+            c.wait(100); 
+          }
+          catch(java.lang.InterruptedException e){
+          }
+          finally{
+            c.notifyme--;
+          }
+        }
+
+        if(c.rwsize>=length){
+          c.rwsize-=length;
+          break;
+        }
+
+      }
+      if(c.close || !c.isConnected()){
+	throw new IOException("channel is broken");
+      }
+
+      boolean sendit=false;
+      int s=0;
+      byte command=0;
+      int recipient=-1;
+      synchronized(c){
+	if(c.rwsize>0){
+	  long len=c.rwsize;
+          if(len>length){
+            len=length;
+          }
+          if(len!=length){
+            s=packet.shift((int)len, 
+                           (c2scipher!=null ? c2scipher_size : 8),
+                           (c2smac!=null ? c2smac.getBlockSize() : 0));
+          }
+	  command=packet.buffer.getCommand();
+	  recipient=c.getRecipient();
+	  length-=len;
+	  c.rwsize-=len;
+	  sendit=true;
+	}
+      }
+      if(sendit){
+	_write(packet);
+        if(length==0){
+          return;
+        }
+	packet.unshift(command, recipient, s, length);
+      }
+
+      synchronized(c){
+        if(in_kex){
+          continue;
+        }
+        if(c.rwsize>=length){
+          c.rwsize-=length;
+          break;
+        }
+
+        //try{ 
+        //System.out.println("1wait: "+c.rwsize);
+        //  c.notifyme++;
+        //  c.wait(100); 
+        //}
+        //catch(java.lang.InterruptedException e){
+        //}
+        //finally{
+        //  c.notifyme--;
+        //}
+      }
+    }
+    _write(packet);
+  }
+
+  public void write(Packet packet) throws Exception{
+    // System.err.println("in_kex="+in_kex+" "+(packet.buffer.getCommand()));
+    long t = getTimeout();
+    while(in_kex){
+      if(t>0L && (System.currentTimeMillis()-kex_start_time)>t){
+        throw new JSchException("timeout in wating for rekeying process.");
+      }
+      byte command=packet.buffer.getCommand();
+      //System.err.println("command: "+command);
+      if(command==SSH_MSG_KEXINIT ||
+         command==SSH_MSG_NEWKEYS ||
+         command==SSH_MSG_KEXDH_INIT ||
+         command==SSH_MSG_KEXDH_REPLY ||
+         command==SSH_MSG_KEX_DH_GEX_GROUP ||
+         command==SSH_MSG_KEX_DH_GEX_INIT ||
+         command==SSH_MSG_KEX_DH_GEX_REPLY ||
+         command==SSH_MSG_KEX_DH_GEX_REQUEST ||
+         command==SSH_MSG_DISCONNECT){
+        break;
+      }
+      try{Thread.sleep(10);}
+      catch(java.lang.InterruptedException e){};
+    }
+    _write(packet);
+  }
+
+  private void _write(Packet packet) throws Exception{
+    synchronized(lock){
+      encode(packet);
+      if(io!=null){
+        io.put(packet);
+        seqo++;
+      }
+    }
+  }
+
+  Runnable thread;
+  public void run(){
+    thread=this;
+
+    byte[] foo;
+    Buffer buf=new Buffer();
+    Packet packet=new Packet(buf);
+    int i=0;
+    Channel channel;
+    int[] start=new int[1];
+    int[] length=new int[1];
+    KeyExchange kex=null;
+
+    int stimeout=0;
+    try{
+      while(isConnected &&
+	    thread!=null){
+        try{
+          buf=read(buf);
+          stimeout=0;
+        }
+        catch(InterruptedIOException/*SocketTimeoutException*/ ee){
+          if(!in_kex && stimeout<serverAliveCountMax){
+            sendKeepAliveMsg();
+            stimeout++;
+            continue;
+          }
+          else if(in_kex && stimeout<serverAliveCountMax){
+            stimeout++;
+            continue;
+          }
+          throw ee;
+        }
+
+	int msgType=buf.getCommand()&0xff;
+
+	if(kex!=null && kex.getState()==msgType){
+          kex_start_time=System.currentTimeMillis();
+	  boolean result=kex.next(buf);
+	  if(!result){
+	    throw new JSchException("verify: "+result);
+	  }
+	  continue;
+	}
+
+        switch(msgType){
+	case SSH_MSG_KEXINIT:
+//System.err.println("KEXINIT");
+	  kex=receive_kexinit(buf);
+	  break;
+
+	case SSH_MSG_NEWKEYS:
+//System.err.println("NEWKEYS");
+          send_newkeys();
+	  receive_newkeys(buf, kex);
+	  kex=null;
+	  break;
+
+	case SSH_MSG_CHANNEL_DATA:
+          buf.getInt(); 
+          buf.getByte(); 
+          buf.getByte(); 
+          i=buf.getInt(); 
+	  channel=Channel.getChannel(i, this);
+	  foo=buf.getString(start, length);
+	  if(channel==null){
+	    break;
+	  }
+
+          if(length[0]==0){
+	    break;
+          }
+
+try{
+	  channel.write(foo, start[0], length[0]);
+}
+catch(Exception e){
+//System.err.println(e);
+  try{channel.disconnect();}catch(Exception ee){}
+break;
+}
+	  int len=length[0];
+	  channel.setLocalWindowSize(channel.lwsize-len);
+ 	  if(channel.lwsize<channel.lwsize_max/2){
+            packet.reset();
+	    buf.putByte((byte)SSH_MSG_CHANNEL_WINDOW_ADJUST);
+	    buf.putInt(channel.getRecipient());
+	    buf.putInt(channel.lwsize_max-channel.lwsize);
+            synchronized(channel){
+              if(!channel.close)
+                write(packet);
+            }
+	    channel.setLocalWindowSize(channel.lwsize_max);
+	  }
+	  break;
+
+        case SSH_MSG_CHANNEL_EXTENDED_DATA:
+          buf.getInt();
+	  buf.getShort();
+	  i=buf.getInt();
+	  channel=Channel.getChannel(i, this);
+	  buf.getInt();                   // data_type_code == 1
+	  foo=buf.getString(start, length);
+	  //System.err.println("stderr: "+new String(foo,start[0],length[0]));
+	  if(channel==null){
+	    break;
+	  }
+
+          if(length[0]==0){
+	    break;
+          }
+
+	  channel.write_ext(foo, start[0], length[0]);
+
+	  len=length[0];
+	  channel.setLocalWindowSize(channel.lwsize-len);
+ 	  if(channel.lwsize<channel.lwsize_max/2){
+            packet.reset();
+	    buf.putByte((byte)SSH_MSG_CHANNEL_WINDOW_ADJUST);
+	    buf.putInt(channel.getRecipient());
+	    buf.putInt(channel.lwsize_max-channel.lwsize);
+            synchronized(channel){
+              if(!channel.close)
+                write(packet);
+            }
+	    channel.setLocalWindowSize(channel.lwsize_max);
+	  }
+	  break;
+
+	case SSH_MSG_CHANNEL_WINDOW_ADJUST:
+          buf.getInt(); 
+	  buf.getShort(); 
+	  i=buf.getInt(); 
+	  channel=Channel.getChannel(i, this);
+	  if(channel==null){
+	    break;
+	  }
+	  channel.addRemoteWindowSize(buf.getInt()); 
+	  break;
+
+	case SSH_MSG_CHANNEL_EOF:
+          buf.getInt(); 
+          buf.getShort(); 
+          i=buf.getInt(); 
+	  channel=Channel.getChannel(i, this);
+	  if(channel!=null){
+	    //channel.eof_remote=true;
+	    //channel.eof();
+	    channel.eof_remote();
+	  }
+	  /*
+	  packet.reset();
+	  buf.putByte((byte)SSH_MSG_CHANNEL_EOF);
+	  buf.putInt(channel.getRecipient());
+	  write(packet);
+	  */
+	  break;
+	case SSH_MSG_CHANNEL_CLOSE:
+          buf.getInt(); 
+	  buf.getShort(); 
+	  i=buf.getInt(); 
+	  channel=Channel.getChannel(i, this);
+	  if(channel!=null){
+//	      channel.close();
+	    channel.disconnect();
+	  }
+	  /*
+          if(Channel.pool.size()==0){
+	    thread=null;
+	  }
+	  */
+	  break;
+	case SSH_MSG_CHANNEL_OPEN_CONFIRMATION:
+          buf.getInt(); 
+	  buf.getShort(); 
+	  i=buf.getInt(); 
+	  channel=Channel.getChannel(i, this);
+	  if(channel==null){
+	    //break;
+	  }
+          int r=buf.getInt();
+          long rws=buf.getUInt();
+          int rps=buf.getInt();
+
+          channel.setRemoteWindowSize(rws);
+          channel.setRemotePacketSize(rps);
+          channel.open_confirmation=true;
+          channel.setRecipient(r);
+          break;
+	case SSH_MSG_CHANNEL_OPEN_FAILURE:
+          buf.getInt(); 
+	  buf.getShort(); 
+	  i=buf.getInt(); 
+	  channel=Channel.getChannel(i, this);
+	  if(channel==null){
+	    //break;
+	  }
+	  int reason_code=buf.getInt(); 
+	  //foo=buf.getString();  // additional textual information
+	  //foo=buf.getString();  // language tag 
+          channel.setExitStatus(reason_code);
+          channel.close=true;
+	  channel.eof_remote=true;
+	  channel.setRecipient(0);
+	  break;
+	case SSH_MSG_CHANNEL_REQUEST:
+          buf.getInt(); 
+	  buf.getShort(); 
+	  i=buf.getInt(); 
+	  foo=buf.getString(); 
+          boolean reply=(buf.getByte()!=0);
+	  channel=Channel.getChannel(i, this);
+	  if(channel!=null){
+	    byte reply_type=(byte)SSH_MSG_CHANNEL_FAILURE;
+	    if((Util.byte2str(foo)).equals("exit-status")){
+	      i=buf.getInt();             // exit-status
+	      channel.setExitStatus(i);
+	      reply_type=(byte)SSH_MSG_CHANNEL_SUCCESS;
+	    }
+	    if(reply){
+	      packet.reset();
+	      buf.putByte(reply_type);
+	      buf.putInt(channel.getRecipient());
+	      write(packet);
+	    }
+	  }
+	  else{
+	  }
+	  break;
+	case SSH_MSG_CHANNEL_OPEN:
+          buf.getInt(); 
+	  buf.getShort(); 
+	  foo=buf.getString(); 
+	  String ctyp=Util.byte2str(foo);
+          if(!"forwarded-tcpip".equals(ctyp) &&
+	     !("x11".equals(ctyp) && x11_forwarding) &&
+	     !("auth-agent@openssh.com".equals(ctyp) && agent_forwarding)){
+            //System.err.println("Session.run: CHANNEL OPEN "+ctyp); 
+	    //throw new IOException("Session.run: CHANNEL OPEN "+ctyp);
+	    packet.reset();
+	    buf.putByte((byte)SSH_MSG_CHANNEL_OPEN_FAILURE);
+	    buf.putInt(buf.getInt());
+ 	    buf.putInt(Channel.SSH_OPEN_ADMINISTRATIVELY_PROHIBITED);
+	    buf.putString(Util.empty);
+	    buf.putString(Util.empty);
+	    write(packet);
+	  }
+	  else{
+	    channel=Channel.getChannel(ctyp);
+	    addChannel(channel);
+	    channel.getData(buf);
+	    channel.init();
+
+	    Thread tmp=new Thread(channel);
+	    tmp.setName("Channel "+ctyp+" "+host);
+            if(daemon_thread){
+              tmp.setDaemon(daemon_thread);
+            }
+	    tmp.start();
+	    break;
+	  }
+	case SSH_MSG_CHANNEL_SUCCESS:
+          buf.getInt(); 
+	  buf.getShort(); 
+	  i=buf.getInt(); 
+	  channel=Channel.getChannel(i, this);
+	  if(channel==null){
+	    break;
+	  }
+	  channel.reply=1;
+	  break;
+	case SSH_MSG_CHANNEL_FAILURE:
+	  buf.getInt(); 
+	  buf.getShort(); 
+	  i=buf.getInt(); 
+	  channel=Channel.getChannel(i, this);
+	  if(channel==null){
+	    break;
+	  }
+	  channel.reply=0;
+	  break;
+	case SSH_MSG_GLOBAL_REQUEST:
+	  buf.getInt(); 
+	  buf.getShort(); 
+	  foo=buf.getString();       // request name
+	  reply=(buf.getByte()!=0);
+	  if(reply){
+	    packet.reset();
+	    buf.putByte((byte)SSH_MSG_REQUEST_FAILURE);
+	    write(packet);
+	  }
+	  break;
+	case SSH_MSG_REQUEST_FAILURE:
+	case SSH_MSG_REQUEST_SUCCESS:
+          Thread t=grr.getThread();
+          if(t!=null){
+            grr.setReply(msgType==SSH_MSG_REQUEST_SUCCESS? 1 : 0);
+            t.interrupt();
+          }
+	  break;
+	default:
+          //System.err.println("Session.run: unsupported type "+msgType); 
+	  throw new IOException("Unknown SSH message type "+msgType);
+	}
+      }
+    }
+    catch(Exception e){
+      in_kex=false;
+      if(JSch.getLogger().isEnabled(Logger.INFO)){
+        JSch.getLogger().log(Logger.INFO,
+                             "Caught an exception, leaving main loop due to " + e.getMessage());
+      }
+      //System.err.println("# Session.run");
+      //e.printStackTrace();
+    }
+    try{
+      disconnect();
+    }
+    catch(NullPointerException e){
+      //System.err.println("@1");
+      //e.printStackTrace();
+    }
+    catch(Exception e){
+      //System.err.println("@2");
+      //e.printStackTrace();
+    }
+    isConnected=false;
+  }
+
+  public void disconnect(){
+    if(!isConnected) return;
+    //System.err.println(this+": disconnect");
+    //Thread.dumpStack();
+    if(JSch.getLogger().isEnabled(Logger.INFO)){
+      JSch.getLogger().log(Logger.INFO,
+                           "Disconnecting from "+host+" port "+port);
+    }
+    /*
+    for(int i=0; i<Channel.pool.size(); i++){
+      try{
+        Channel c=((Channel)(Channel.pool.elementAt(i)));
+	if(c.session==this) c.eof();
+      }
+      catch(Exception e){
+      }
+    } 
+    */
+
+    Channel.disconnect(this);
+
+    isConnected=false;
+
+    PortWatcher.delPort(this);
+    ChannelForwardedTCPIP.delPort(this);
+    ChannelX11.removeFakedCookie(this);
+
+    synchronized(lock){
+      if(connectThread!=null){
+        Thread.yield();
+        connectThread.interrupt();
+        connectThread=null;
+      }
+    }
+    thread=null;
+    try{
+      if(io!=null){
+	if(io.in!=null) io.in.close();
+	if(io.out!=null) io.out.close();
+	if(io.out_ext!=null) io.out_ext.close();
+      }
+      if(proxy==null){
+        if(socket!=null)
+	  socket.close();
+      }
+      else{
+	synchronized(proxy){
+	  proxy.close();	  
+	}
+	proxy=null;
+      }
+    }
+    catch(Exception e){
+//      e.printStackTrace();
+    }
+    io=null;
+    socket=null;
+//    synchronized(jsch.pool){
+//      jsch.pool.removeElement(this);
+//    }
+
+    jsch.removeSession(this);
+
+    //System.gc();
+  }
+
+  public int setPortForwardingL(int lport, String host, int rport) throws JSchException{
+    return setPortForwardingL("127.0.0.1", lport, host, rport);
+  }
+  public int setPortForwardingL(String boundaddress, int lport, String host, int rport) throws JSchException{
+    return setPortForwardingL(boundaddress, lport, host, rport, null);
+  }
+  public int setPortForwardingL(String boundaddress, int lport, String host, int rport, ServerSocketFactory ssf) throws JSchException{
+    PortWatcher pw=PortWatcher.addPort(this, boundaddress, lport, host, rport, ssf);
+    Thread tmp=new Thread(pw);
+    tmp.setName("PortWatcher Thread for "+host);
+    if(daemon_thread){
+      tmp.setDaemon(daemon_thread);
+    }
+    tmp.start();
+    return pw.lport;
+  }
+  public void delPortForwardingL(int lport) throws JSchException{
+    delPortForwardingL("127.0.0.1", lport);
+  }
+  public void delPortForwardingL(String boundaddress, int lport) throws JSchException{
+    PortWatcher.delPort(this, boundaddress, lport);
+  }
+  public String[] getPortForwardingL() throws JSchException{
+    return PortWatcher.getPortForwarding(this);
+  }
+
+  public void setPortForwardingR(int rport, String host, int lport) throws JSchException{
+    setPortForwardingR(null, rport, host, lport, (SocketFactory)null);
+  }
+  public void setPortForwardingR(String bind_address, int rport, String host, int lport) throws JSchException{
+    setPortForwardingR(bind_address, rport, host, lport, (SocketFactory)null);
+  }
+  public void setPortForwardingR(int rport, String host, int lport, SocketFactory sf) throws JSchException{
+    setPortForwardingR(null, rport, host, lport, sf);
+  }
+  public void setPortForwardingR(String bind_address, int rport, String host, int lport, SocketFactory sf) throws JSchException{
+    ChannelForwardedTCPIP.addPort(this, bind_address, rport, host, lport, sf);
+    setPortForwarding(bind_address, rport);
+  }
+
+  public void setPortForwardingR(int rport, String daemon) throws JSchException{
+    setPortForwardingR(null, rport, daemon, null);
+  }
+  public void setPortForwardingR(int rport, String daemon, Object[] arg) throws JSchException{
+    setPortForwardingR(null, rport, daemon, arg);
+  }
+  public void setPortForwardingR(String bind_address, int rport, String daemon, Object[] arg) throws JSchException{
+    ChannelForwardedTCPIP.addPort(this, bind_address, rport, daemon, arg);
+    setPortForwarding(bind_address, rport);
+  }
+
+  private class GlobalRequestReply{
+    private Thread thread=null;
+    private int reply=-1;
+    void setThread(Thread thread){
+      this.thread=thread;
+      this.reply=-1;
+    }
+    Thread getThread(){ return thread; }
+    void setReply(int reply){ this.reply=reply; }
+    int getReply(){ return this.reply; }
+  }
+  private GlobalRequestReply grr=new GlobalRequestReply();
+  private void setPortForwarding(String bind_address, int rport) throws JSchException{
+    synchronized(grr){
+    Buffer buf=new Buffer(100); // ??
+    Packet packet=new Packet(buf);
+
+    String address_to_bind=ChannelForwardedTCPIP.normalize(bind_address);
+
+    grr.setThread(Thread.currentThread());
+
+    try{
+      // byte SSH_MSG_GLOBAL_REQUEST 80
+      // string "tcpip-forward"
+      // boolean want_reply
+      // string  address_to_bind
+      // uint32  port number to bind
+      packet.reset();
+      buf.putByte((byte) SSH_MSG_GLOBAL_REQUEST);
+      buf.putString(Util.str2byte("tcpip-forward"));
+      buf.putByte((byte)1);
+      buf.putString(Util.str2byte(address_to_bind));
+      buf.putInt(rport);
+      write(packet);
+    }
+    catch(Exception e){
+      grr.setThread(null);
+      if(e instanceof Throwable)
+        throw new JSchException(e.toString(), (Throwable)e);
+      throw new JSchException(e.toString());
+    }
+
+    int count = 0;
+    int reply = grr.getReply();
+    while(count < 10 && reply == -1){
+      try{ Thread.sleep(1000); }
+      catch(Exception e){
+      }
+      count++; 
+      reply = grr.getReply();
+    }
+    grr.setThread(null);
+    if(reply != 1){
+      throw new JSchException("remote port forwarding failed for listen port "+rport);
+    }
+    }
+  }
+  public void delPortForwardingR(int rport) throws JSchException{
+    ChannelForwardedTCPIP.delPort(this, rport);
+  }
+
+  private void initDeflater(String method) throws JSchException{
+    if(method.equals("none")){
+      deflater=null;
+      return;
+    }
+    String foo=getConfig(method);
+    if(foo!=null){
+      if(method.equals("zlib") ||
+         (isAuthed && method.equals("zlib@openssh.com"))){
+        try{
+          Class c=Class.forName(foo);
+          deflater=(Compression)(c.newInstance());
+          int level=6;
+          try{ level=Integer.parseInt(getConfig("compression_level"));}
+          catch(Exception ee){ }
+          deflater.init(Compression.DEFLATER, level);
+        }
+        catch(Exception ee){
+          throw new JSchException(ee.toString(), ee);
+          //System.err.println(foo+" isn't accessible.");
+        }
+      }
+    }
+  }
+  private void initInflater(String method) throws JSchException{
+    if(method.equals("none")){
+      inflater=null;
+      return;
+    }
+    String foo=getConfig(method);
+    if(foo!=null){
+      if(method.equals("zlib") ||
+         (isAuthed && method.equals("zlib@openssh.com"))){
+        try{
+          Class c=Class.forName(foo);
+          inflater=(Compression)(c.newInstance());
+          inflater.init(Compression.INFLATER, 0);
+        }
+        catch(Exception ee){
+          throw new JSchException(ee.toString(), ee);
+	    //System.err.println(foo+" isn't accessible.");
+        }
+      }
+    }
+  }
+
+  void addChannel(Channel channel){
+    channel.setSession(this);
+  }
+
+  public void setProxy(Proxy proxy){ this.proxy=proxy; }
+  public void setHost(String host){ this.host=host; }
+  public void setPort(int port){ this.port=port; }
+  void setUserName(String username){ this.username=username; }
+  public void setUserInfo(UserInfo userinfo){ this.userinfo=userinfo; }
+  public UserInfo getUserInfo(){ return userinfo; }
+  public void setInputStream(InputStream in){ this.in=in; }
+  public void setOutputStream(OutputStream out){ this.out=out; }
+  public void setX11Host(String host){ ChannelX11.setHost(host); }
+  public void setX11Port(int port){ ChannelX11.setPort(port); }
+  public void setX11Cookie(String cookie){ ChannelX11.setCookie(cookie); }
+  public void setPassword(String password){
+    if(password!=null)
+      this.password=Util.str2byte(password);
+  }
+  public void setPassword(byte[] password){ 
+    if(password!=null){
+      this.password=new byte[password.length];
+      System.arraycopy(password, 0, this.password, 0, password.length);
+    }
+  }
+
+  public void setConfig(java.util.Properties newconf){
+    setConfig((java.util.Hashtable)newconf);
+  }
+ 
+  public void setConfig(java.util.Hashtable newconf){
+    synchronized(lock){
+      if(config==null) 
+        config=new java.util.Hashtable();
+      for(java.util.Enumeration e=newconf.keys() ; e.hasMoreElements() ;) {
+        String key=(String)(e.nextElement());
+        config.put(key, (String)(newconf.get(key)));
+      }
+    }
+  }
+
+  public void setConfig(String key, String value){
+    synchronized(lock){ 
+      if(config==null){
+        config=new java.util.Hashtable();
+      }
+      config.put(key, value);
+    }
+  }
+
+  public String getConfig(String key){
+    Object foo=null;
+    if(config!=null){
+      foo=config.get(key);
+      if(foo instanceof String) return (String)foo;
+    }
+    foo=jsch.getConfig(key);
+    if(foo instanceof String) return (String)foo;
+    return null;
+  }
+
+  public void setSocketFactory(SocketFactory sfactory){ 
+    socket_factory=sfactory;
+  }
+  public boolean isConnected(){ return isConnected; }
+  public int getTimeout(){ return timeout; }
+  public void setTimeout(int timeout) throws JSchException {
+    if(socket==null){
+      if(timeout<0){
+        throw new JSchException("invalid timeout value");
+      }
+      this.timeout=timeout;
+      return;
+    }
+    try{
+      socket.setSoTimeout(timeout);
+      this.timeout=timeout;
+    }
+    catch(Exception e){
+      if(e instanceof Throwable)
+        throw new JSchException(e.toString(), (Throwable)e);
+      throw new JSchException(e.toString());
+    }
+  }
+  public String getServerVersion(){
+    return Util.byte2str(V_S);
+  }
+  public String getClientVersion(){
+    return Util.byte2str(V_C);
+  }
+  public void setClientVersion(String cv){
+    V_C=Util.str2byte(cv);
+  }
+
+  public void sendIgnore() throws Exception{
+    Buffer buf=new Buffer();
+    Packet packet=new Packet(buf);
+    packet.reset();
+    buf.putByte((byte)SSH_MSG_IGNORE);
+    write(packet);
+  }
+
+  private static final byte[] keepalivemsg=Util.str2byte("keepalive@jcraft.com");
+  public void sendKeepAliveMsg() throws Exception{
+    Buffer buf=new Buffer();
+    Packet packet=new Packet(buf);
+    packet.reset();
+    buf.putByte((byte)SSH_MSG_GLOBAL_REQUEST);
+    buf.putString(keepalivemsg);
+    buf.putByte((byte)1);
+    write(packet);
+  }
+  
+  private HostKey hostkey=null;
+  public HostKey getHostKey(){ return hostkey; }
+  public String getHost(){return host;}
+  public String getUserName(){return username;}
+  public int getPort(){return port;}
+  public void setHostKeyAlias(String hostKeyAlias){
+    this.hostKeyAlias=hostKeyAlias;
+  }
+  public String getHostKeyAlias(){
+    return hostKeyAlias;
+  }
+
+  public void setServerAliveInterval(int interval) throws JSchException {
+    setTimeout(interval);
+    this.serverAliveInterval=interval;
+  }
+  public void setServerAliveCountMax(int count){
+    this.serverAliveCountMax=count;
+  }
+
+  public int getServerAliveInterval(){
+    return this.serverAliveInterval;
+  }
+  public int getServerAliveCountMax(){
+    return this.serverAliveCountMax;
+  }
+
+  public void setDaemonThread(boolean enable){
+    this.daemon_thread=enable;
+  }
+
+  private String[] checkCiphers(String ciphers){
+    if(ciphers==null || ciphers.length()==0)
+      return null;
+
+    if(JSch.getLogger().isEnabled(Logger.INFO)){
+      JSch.getLogger().log(Logger.INFO, 
+                           "CheckCiphers: "+ciphers);
+    }
+
+    java.util.Vector result=new java.util.Vector();
+    String[] _ciphers=Util.split(ciphers, ",");
+    for(int i=0; i<_ciphers.length; i++){
+      if(!checkCipher(getConfig(_ciphers[i]))){
+        result.addElement(_ciphers[i]);
+      }
+    }
+    if(result.size()==0)
+      return null;
+    String[] foo=new String[result.size()];
+    System.arraycopy(result.toArray(), 0, foo, 0, result.size());
+
+    if(JSch.getLogger().isEnabled(Logger.INFO)){
+      for(int i=0; i<foo.length; i++){
+        JSch.getLogger().log(Logger.INFO, 
+                             foo[i]+" is not available.");
+      }
+    }
+
+    return foo;
+  }
+
+  static boolean checkCipher(String cipher){
+    try{
+      Class c=Class.forName(cipher);
+      Cipher _c=(Cipher)(c.newInstance());
+      _c.init(Cipher.ENCRYPT_MODE,
+              new byte[_c.getBlockSize()],
+              new byte[_c.getIVSize()]);
+      return true;
+    }
+    catch(Exception e){
+      return false;
+    }
+  }
+
+  private String[] checkKexes(String kexes){
+    if(kexes==null || kexes.length()==0)
+      return null;
+
+    if(JSch.getLogger().isEnabled(Logger.INFO)){
+      JSch.getLogger().log(Logger.INFO, 
+                           "CheckKexes: "+kexes);
+    }
+
+    java.util.Vector result=new java.util.Vector();
+    String[] _kexes=Util.split(kexes, ",");
+    for(int i=0; i<_kexes.length; i++){
+      if(!checkKex(this, getConfig(_kexes[i]))){
+        result.addElement(_kexes[i]);
+      }
+    }
+    if(result.size()==0)
+      return null;
+    String[] foo=new String[result.size()];
+    System.arraycopy(result.toArray(), 0, foo, 0, result.size());
+
+    if(JSch.getLogger().isEnabled(Logger.INFO)){
+      for(int i=0; i<foo.length; i++){
+        JSch.getLogger().log(Logger.INFO, 
+                             foo[i]+" is not available.");
+      }
+    }
+
+    return foo;
+  }
+
+  static boolean checkKex(Session s, String kex){
+    try{
+      Class c=Class.forName(kex);
+      KeyExchange _c=(KeyExchange)(c.newInstance());
+      _c.init(s ,null, null, null, null);
+      return true;
+    }
+    catch(Exception e){ return false; }
+  }
+}
diff --git a/java/com/jcraft/jsch/SftpATTRS.java b/java/com/jcraft/jsch/SftpATTRS.java
new file mode 100644
index 0000000..e89b243
--- /dev/null
+++ b/java/com/jcraft/jsch/SftpATTRS.java
@@ -0,0 +1,263 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/*
+  uint32   flags
+  uint64   size           present only if flag SSH_FILEXFER_ATTR_SIZE
+  uint32   uid            present only if flag SSH_FILEXFER_ATTR_UIDGID
+  uint32   gid            present only if flag SSH_FILEXFER_ATTR_UIDGID
+  uint32   permissions    present only if flag SSH_FILEXFER_ATTR_PERMISSIONS
+  uint32   atime          present only if flag SSH_FILEXFER_ACMODTIME
+  uint32   mtime          present only if flag SSH_FILEXFER_ACMODTIME
+  uint32   extended_count present only if flag SSH_FILEXFER_ATTR_EXTENDED
+  string   extended_type
+  string   extended_data
+    ...      more extended data (extended_type - extended_data pairs),
+             so that number of pairs equals extended_count
+*/
+public class SftpATTRS {
+
+  static final int S_ISUID = 04000; // set user ID on execution
+  static final int S_ISGID = 02000; // set group ID on execution
+  static final int S_ISVTX = 01000; // sticky bit   ****** NOT DOCUMENTED *****
+
+  static final int S_IRUSR = 00400; // read by owner
+  static final int S_IWUSR = 00200; // write by owner
+  static final int S_IXUSR = 00100; // execute/search by owner
+  static final int S_IREAD = 00400; // read by owner
+  static final int S_IWRITE= 00200; // write by owner
+  static final int S_IEXEC = 00100; // execute/search by owner
+
+  static final int S_IRGRP = 00040; // read by group
+  static final int S_IWGRP = 00020; // write by group
+  static final int S_IXGRP = 00010; // execute/search by group
+
+  static final int S_IROTH = 00004; // read by others
+  static final int S_IWOTH = 00002; // write by others
+  static final int S_IXOTH = 00001; // execute/search by others
+
+  private static final int pmask = 0xFFF;
+
+  public String getPermissionsString() {
+    StringBuffer buf = new StringBuffer(10);
+
+    if(isDir()) buf.append('d');
+    else if(isLink()) buf.append('l');
+    else buf.append('-');
+
+    if((permissions & S_IRUSR)!=0) buf.append('r');
+    else buf.append('-');
+
+    if((permissions & S_IWUSR)!=0) buf.append('w');
+    else buf.append('-');
+
+    if((permissions & S_ISUID)!=0) buf.append('s');
+    else if ((permissions & S_IXUSR)!=0) buf.append('x');
+    else buf.append('-');
+
+    if((permissions & S_IRGRP)!=0) buf.append('r');
+    else buf.append('-');
+
+    if((permissions & S_IWGRP)!=0) buf.append('w');
+    else buf.append('-');
+
+    if((permissions & S_ISGID)!=0) buf.append('s');
+    else if((permissions & S_IXGRP)!=0) buf.append('x');
+    else buf.append('-');
+
+    if((permissions & S_IROTH) != 0) buf.append('r');
+    else buf.append('-');
+
+    if((permissions & S_IWOTH) != 0) buf.append('w');
+    else buf.append('-');
+
+    if((permissions & S_IXOTH) != 0) buf.append('x');
+    else buf.append('-');
+    return (buf.toString());
+  }
+
+  public String  getAtimeString(){
+    SimpleDateFormat locale=new SimpleDateFormat();
+    return (locale.format(new Date(atime)));
+  }
+
+  public String  getMtimeString(){
+    Date date= new Date(((long)mtime)*1000);
+    return (date.toString());
+  }
+
+  public static final int SSH_FILEXFER_ATTR_SIZE=         0x00000001;
+  public static final int SSH_FILEXFER_ATTR_UIDGID=       0x00000002;
+  public static final int SSH_FILEXFER_ATTR_PERMISSIONS=  0x00000004;
+  public static final int SSH_FILEXFER_ATTR_ACMODTIME=    0x00000008;
+  public static final int SSH_FILEXFER_ATTR_EXTENDED=     0x80000000;
+
+  static final int S_IFDIR=0x4000;
+  static final int S_IFLNK=0xa000;
+
+  int flags=0;
+  long size;
+  int uid;
+  int gid;
+  int permissions;
+  int atime;
+  int mtime;
+  String[] extended=null;
+
+  private SftpATTRS(){
+  }
+
+  static SftpATTRS getATTR(Buffer buf){
+    SftpATTRS attr=new SftpATTRS();	
+    attr.flags=buf.getInt();
+    if((attr.flags&SSH_FILEXFER_ATTR_SIZE)!=0){ attr.size=buf.getLong(); }
+    if((attr.flags&SSH_FILEXFER_ATTR_UIDGID)!=0){
+      attr.uid=buf.getInt(); attr.gid=buf.getInt();
+    }
+    if((attr.flags&SSH_FILEXFER_ATTR_PERMISSIONS)!=0){ 
+      attr.permissions=buf.getInt();
+    }
+    if((attr.flags&SSH_FILEXFER_ATTR_ACMODTIME)!=0){ 
+      attr.atime=buf.getInt();
+    }
+    if((attr.flags&SSH_FILEXFER_ATTR_ACMODTIME)!=0){ 
+      attr.mtime=buf.getInt(); 
+    }
+    if((attr.flags&SSH_FILEXFER_ATTR_EXTENDED)!=0){
+      int count=buf.getInt();
+      if(count>0){
+	attr.extended=new String[count*2];
+	for(int i=0; i<count; i++){
+	  attr.extended[i*2]=Util.byte2str(buf.getString());
+	  attr.extended[i*2+1]=Util.byte2str(buf.getString());
+	}
+      }
+    }
+    return attr;
+  } 
+
+  int length(){
+    int len=4;
+
+    if((flags&SSH_FILEXFER_ATTR_SIZE)!=0){ len+=8; }
+    if((flags&SSH_FILEXFER_ATTR_UIDGID)!=0){ len+=8; }
+    if((flags&SSH_FILEXFER_ATTR_PERMISSIONS)!=0){ len+=4; }
+    if((flags&SSH_FILEXFER_ATTR_ACMODTIME)!=0){ len+=8; }
+    if((flags&SSH_FILEXFER_ATTR_EXTENDED)!=0){
+      len+=4;
+      int count=extended.length/2;
+      if(count>0){
+	for(int i=0; i<count; i++){
+	  len+=4; len+=extended[i*2].length();
+	  len+=4; len+=extended[i*2+1].length();
+	}
+      }
+    }
+    return len;
+  }
+
+  void dump(Buffer buf){
+    buf.putInt(flags);
+    if((flags&SSH_FILEXFER_ATTR_SIZE)!=0){ buf.putLong(size); }
+    if((flags&SSH_FILEXFER_ATTR_UIDGID)!=0){
+      buf.putInt(uid); buf.putInt(gid);
+    }
+    if((flags&SSH_FILEXFER_ATTR_PERMISSIONS)!=0){ 
+      buf.putInt(permissions);
+    }
+    if((flags&SSH_FILEXFER_ATTR_ACMODTIME)!=0){ buf.putInt(atime); }
+    if((flags&SSH_FILEXFER_ATTR_ACMODTIME)!=0){ buf.putInt(mtime); }
+    if((flags&SSH_FILEXFER_ATTR_EXTENDED)!=0){
+      int count=extended.length/2;
+      if(count>0){
+	for(int i=0; i<count; i++){
+	  buf.putString(Util.str2byte(extended[i*2]));
+	  buf.putString(Util.str2byte(extended[i*2+1]));
+	}
+      }
+    }
+  }
+  void setFLAGS(int flags){
+    this.flags=flags;
+  }
+  public void setSIZE(long size){
+    flags|=SSH_FILEXFER_ATTR_SIZE;
+    this.size=size;
+  }
+  public void setUIDGID(int uid, int gid){
+    flags|=SSH_FILEXFER_ATTR_UIDGID;
+    this.uid=uid;
+    this.gid=gid;
+  }
+  public void setACMODTIME(int atime, int mtime){
+    flags|=SSH_FILEXFER_ATTR_ACMODTIME;
+    this.atime=atime;
+    this.mtime=mtime;
+  }
+  public void setPERMISSIONS(int permissions){
+    flags|=SSH_FILEXFER_ATTR_PERMISSIONS;
+    permissions=(this.permissions&~pmask)|(permissions&pmask);
+    this.permissions=permissions;
+  }
+
+  public boolean isDir(){
+    return ((flags&SSH_FILEXFER_ATTR_PERMISSIONS)!=0 && 
+	    ((permissions&S_IFDIR)==S_IFDIR));
+  }      
+  public boolean isLink(){
+    return ((flags&SSH_FILEXFER_ATTR_PERMISSIONS)!=0 && 
+	    ((permissions&S_IFLNK)==S_IFLNK));
+  }      
+  public int getFlags() { return flags; }
+  public long getSize() { return size; }
+  public int getUId() { return uid; }
+  public int getGId() { return gid; }
+  public int getPermissions() { return permissions; }
+  public int getATime() { return atime; }
+  public int getMTime() { return mtime; }
+  public String[] getExtended() { return extended; }
+
+  public String toString() {
+    return (getPermissionsString()+" "+getUId()+" "+getGId()+" "+getSize()+" "+getMtimeString());
+  }
+  /*
+  public String toString(){
+    return (((flags&SSH_FILEXFER_ATTR_SIZE)!=0) ? ("size:"+size+" ") : "")+
+           (((flags&SSH_FILEXFER_ATTR_UIDGID)!=0) ? ("uid:"+uid+",gid:"+gid+" ") : "")+
+           (((flags&SSH_FILEXFER_ATTR_PERMISSIONS)!=0) ? ("permissions:0x"+Integer.toHexString(permissions)+" ") : "")+
+           (((flags&SSH_FILEXFER_ATTR_ACMODTIME)!=0) ? ("atime:"+atime+",mtime:"+mtime+" ") : "")+
+           (((flags&SSH_FILEXFER_ATTR_EXTENDED)!=0) ? ("extended:?"+" ") : "");
+  }
+  */
+}
diff --git a/java/com/jcraft/jsch/SftpException.java b/java/com/jcraft/jsch/SftpException.java
new file mode 100644
index 0000000..6a6c1ff
--- /dev/null
+++ b/java/com/jcraft/jsch/SftpException.java
@@ -0,0 +1,51 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+public class SftpException extends Exception{
+  //private static final long serialVersionUID=-5616888495583253811L;
+  public int id;
+  private Throwable cause=null;
+  public SftpException (int id, String message) {
+    super(message);
+    this.id=id;
+  }
+  public SftpException (int id, String message, Throwable e) {
+    super(message);
+    this.id=id;
+    this.cause=e;
+  }
+  public String toString(){
+    return id+": "+getMessage();
+  }
+  public Throwable getCause(){
+    return this.cause;
+  }
+}
diff --git a/java/com/jcraft/jsch/SftpProgressMonitor.java b/java/com/jcraft/jsch/SftpProgressMonitor.java
new file mode 100644
index 0000000..bd91688
--- /dev/null
+++ b/java/com/jcraft/jsch/SftpProgressMonitor.java
@@ -0,0 +1,39 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+public interface SftpProgressMonitor{
+  public static final int PUT=0;
+  public static final int GET=1;
+  public static final long UNKNOWN_SIZE = -1L;
+  void init(int op, String src, String dest, long max);
+  boolean count(long count);
+  void end();
+}
diff --git a/java/com/jcraft/jsch/SignatureDSA.java b/java/com/jcraft/jsch/SignatureDSA.java
new file mode 100644
index 0000000..6f44b7f
--- /dev/null
+++ b/java/com/jcraft/jsch/SignatureDSA.java
@@ -0,0 +1,39 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+public interface SignatureDSA{
+  void init() throws Exception;
+  void setPubKey(byte[] y, byte[] p, byte[] q, byte[] g) throws Exception;
+  void setPrvKey(byte[] x, byte[] p, byte[] q, byte[] g) throws Exception;
+  void update(byte[] H) throws Exception;
+  boolean verify(byte[] sig) throws Exception;
+  byte[] sign() throws Exception;
+}
diff --git a/java/com/jcraft/jsch/SignatureRSA.java b/java/com/jcraft/jsch/SignatureRSA.java
new file mode 100644
index 0000000..e8e6105
--- /dev/null
+++ b/java/com/jcraft/jsch/SignatureRSA.java
@@ -0,0 +1,39 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+public interface SignatureRSA{
+  void init() throws Exception;
+  void setPubKey(byte[] e, byte[] n) throws Exception;
+  void setPrvKey(byte[] d, byte[] n) throws Exception;
+  void update(byte[] H) throws Exception;
+  boolean verify(byte[] sig) throws Exception;
+  byte[] sign() throws Exception;
+}
diff --git a/java/com/jcraft/jsch/SocketFactory.java b/java/com/jcraft/jsch/SocketFactory.java
new file mode 100644
index 0000000..aaac0dc
--- /dev/null
+++ b/java/com/jcraft/jsch/SocketFactory.java
@@ -0,0 +1,40 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+import java.net.*;
+import java.io.*;
+
+public interface SocketFactory{
+  public Socket createSocket(String host, int port)throws IOException,
+							  UnknownHostException;
+  public InputStream getInputStream(Socket socket)throws IOException;
+  public OutputStream getOutputStream(Socket socket)throws IOException;
+}
diff --git a/java/com/jcraft/jsch/UIKeyboardInteractive.java b/java/com/jcraft/jsch/UIKeyboardInteractive.java
new file mode 100644
index 0000000..23af9c3
--- /dev/null
+++ b/java/com/jcraft/jsch/UIKeyboardInteractive.java
@@ -0,0 +1,38 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+public interface UIKeyboardInteractive{
+  String[] promptKeyboardInteractive(String destination,
+				     String name,
+				     String instruction,
+				     String[] prompt,
+				     boolean[] echo);
+}
diff --git a/java/com/jcraft/jsch/UserAuth.java b/java/com/jcraft/jsch/UserAuth.java
new file mode 100644
index 0000000..085a950
--- /dev/null
+++ b/java/com/jcraft/jsch/UserAuth.java
@@ -0,0 +1,53 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+public abstract class UserAuth{
+  protected static final int SSH_MSG_USERAUTH_REQUEST=               50;
+  protected static final int SSH_MSG_USERAUTH_FAILURE=               51;
+  protected static final int SSH_MSG_USERAUTH_SUCCESS=               52;
+  protected static final int SSH_MSG_USERAUTH_BANNER=                53;
+  protected static final int SSH_MSG_USERAUTH_INFO_REQUEST=          60;
+  protected static final int SSH_MSG_USERAUTH_INFO_RESPONSE=         61;
+  protected static final int SSH_MSG_USERAUTH_PK_OK=                 60;
+
+  protected UserInfo userinfo;
+  protected Packet packet;
+  protected Buffer buf;
+  protected String username;
+
+  public boolean start(Session session) throws Exception{
+    this.userinfo=session.getUserInfo();
+    this.packet=session.packet;
+    this.buf=packet.getBuffer();
+    this.username=session.getUserName();
+    return true;
+  }
+}
diff --git a/java/com/jcraft/jsch/UserAuthGSSAPIWithMIC.java b/java/com/jcraft/jsch/UserAuthGSSAPIWithMIC.java
new file mode 100644
index 0000000..15856cb
--- /dev/null
+++ b/java/com/jcraft/jsch/UserAuthGSSAPIWithMIC.java
@@ -0,0 +1,227 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2006-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION)HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING
+NEGLIGENCE OR OTHERWISE)ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+public class UserAuthGSSAPIWithMIC extends UserAuth {
+  private static final int SSH_MSG_USERAUTH_GSSAPI_RESPONSE=         60;
+  private static final int SSH_MSG_USERAUTH_GSSAPI_TOKEN=            61;
+  private static final int SSH_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE=63;
+  private static final int SSH_MSG_USERAUTH_GSSAPI_ERROR=            64;
+  private static final int SSH_MSG_USERAUTH_GSSAPI_ERRTOK=           65;
+  private static final int SSH_MSG_USERAUTH_GSSAPI_MIC=              66;
+
+  private static final byte[][] supported_oid={
+    // OID 1.2.840.113554.1.2.2 in DER
+    {(byte)0x6,(byte)0x9,(byte)0x2a,(byte)0x86,(byte)0x48,
+     (byte)0x86,(byte)0xf7,(byte)0x12,(byte)0x1,(byte)0x2,
+     (byte)0x2}
+  };
+
+  private static final String[] supported_method={
+    "gssapi-with-mic.krb5"
+  };
+
+  public boolean start(Session session)throws Exception{
+    super.start(session);
+
+    byte[] _username=Util.str2byte(username);
+
+    packet.reset();
+
+    // byte            SSH_MSG_USERAUTH_REQUEST(50)
+    // string          user name(in ISO-10646 UTF-8 encoding)
+    // string          service name(in US-ASCII)
+    // string          "gssapi"(US-ASCII)
+    // uint32          n, the number of OIDs client supports
+    // string[n]       mechanism OIDS
+    buf.putByte((byte)SSH_MSG_USERAUTH_REQUEST);
+    buf.putString(_username);
+    buf.putString(Util.str2byte("ssh-connection"));
+    buf.putString(Util.str2byte("gssapi-with-mic"));
+    buf.putInt(supported_oid.length);
+    for(int i=0; i<supported_oid.length; i++){
+      buf.putString(supported_oid[i]);
+    }
+    session.write(packet);
+
+    String method=null;
+    int command;
+    while(true){
+      buf=session.read(buf);
+      command=buf.getCommand()&0xff;
+
+      if(command==SSH_MSG_USERAUTH_FAILURE){
+        return false;
+      }
+      
+      if(command==SSH_MSG_USERAUTH_GSSAPI_RESPONSE){
+        buf.getInt(); buf.getByte(); buf.getByte();
+        byte[] message=buf.getString();
+
+        for(int i=0; i<supported_oid.length; i++){
+          if(Util.array_equals(message, supported_oid[i])){
+            method=supported_method[i];
+            break;
+          }
+        }
+
+        if(method==null){
+          return false;
+        }
+
+        break; // success
+      }
+
+      if(command==SSH_MSG_USERAUTH_BANNER){
+        buf.getInt(); buf.getByte(); buf.getByte();
+        byte[] _message=buf.getString();
+        byte[] lang=buf.getString();
+        String message=Util.byte2str(_message);
+        if(userinfo!=null){
+          userinfo.showMessage(message);
+        }
+        continue;
+      }
+      return false;
+    }
+
+    GSSContext context=null;
+    try{
+      Class c=Class.forName(session.getConfig(method));
+      context=(GSSContext)(c.newInstance());
+    }
+    catch(Exception e){ 
+      return false;
+    }
+
+    try{
+      context.create(username, session.host);
+    }
+    catch(JSchException e){
+      return false;
+    }
+
+    byte[] token=new byte[0];
+
+    while(!context.isEstablished()){
+      try{
+        token=context.init(token, 0, token.length);
+      }
+      catch(JSchException e){
+        // TODO
+        // ERRTOK should be sent?
+        // byte        SSH_MSG_USERAUTH_GSSAPI_ERRTOK
+        // string      error token
+        return false;
+      }
+
+      if(token!=null){
+        packet.reset();
+        buf.putByte((byte)SSH_MSG_USERAUTH_GSSAPI_TOKEN);
+        buf.putString(token);
+        session.write(packet);
+      }
+
+      if(!context.isEstablished()){
+        buf=session.read(buf);
+        command=buf.getCommand()&0xff;
+        if(command==SSH_MSG_USERAUTH_GSSAPI_ERROR){
+          // uint32    major_status
+          // uint32    minor_status
+          // string    message
+          // string    language tag
+
+          buf=session.read(buf);
+          command=buf.getCommand()&0xff;
+          //return false;
+        }
+        else if(command==SSH_MSG_USERAUTH_GSSAPI_ERRTOK){
+          // string error token
+
+          buf=session.read(buf);
+          command=buf.getCommand()&0xff;
+          //return false;
+        }
+
+        if(command==SSH_MSG_USERAUTH_FAILURE){
+          return false;
+        }
+
+        buf.getInt(); buf.getByte(); buf.getByte();
+        token=buf.getString();
+      }
+    }
+
+    Buffer mbuf=new Buffer();
+    // string    session identifier
+    // byte      SSH_MSG_USERAUTH_REQUEST
+    // string    user name
+    // string    service
+    // string    "gssapi-with-mic"
+    mbuf.putString(session.getSessionId());
+    mbuf.putByte((byte)SSH_MSG_USERAUTH_REQUEST);
+    mbuf.putString(_username);
+    mbuf.putString(Util.str2byte("ssh-connection"));
+    mbuf.putString(Util.str2byte("gssapi-with-mic"));
+
+    byte[] mic=context.getMIC(mbuf.buffer, 0, mbuf.getLength());
+
+    if(mic==null){
+      return false;
+    }
+
+    packet.reset();
+    buf.putByte((byte)SSH_MSG_USERAUTH_GSSAPI_MIC);
+    buf.putString(mic);
+    session.write(packet);
+
+    context.dispose();
+
+    buf=session.read(buf);
+    command=buf.getCommand()&0xff;
+
+    if(command==SSH_MSG_USERAUTH_SUCCESS){
+      return true;
+    }
+    else if(command==SSH_MSG_USERAUTH_FAILURE){
+      buf.getInt(); buf.getByte(); buf.getByte(); 
+      byte[] foo=buf.getString();
+      int partial_success=buf.getByte();
+      //System.err.println(new String(foo)+
+      //		 " partial_success:"+(partial_success!=0));
+      if(partial_success!=0){
+        throw new JSchPartialAuthException(Util.byte2str(foo));
+      }
+    }
+    return false;
+  }
+}
+
+
diff --git a/java/com/jcraft/jsch/UserAuthKeyboardInteractive.java b/java/com/jcraft/jsch/UserAuthKeyboardInteractive.java
new file mode 100644
index 0000000..2994796
--- /dev/null
+++ b/java/com/jcraft/jsch/UserAuthKeyboardInteractive.java
@@ -0,0 +1,203 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+class UserAuthKeyboardInteractive extends UserAuth{
+  public boolean start(Session session) throws Exception{
+    super.start(session);
+
+    if(userinfo!=null && !(userinfo instanceof UIKeyboardInteractive)){
+      return false;
+    }
+
+    String dest=username+"@"+session.host;
+    if(session.port!=22){
+      dest+=(":"+session.port);
+    }
+    byte[] password=session.password;
+
+    boolean cancel=false;
+
+    byte[] _username=null;
+    _username=Util.str2byte(username);
+
+    while(true){
+
+      if(session.auth_failures >= session.max_auth_tries){
+	return false;
+      }
+
+      // send
+      // byte      SSH_MSG_USERAUTH_REQUEST(50)
+      // string    user name (ISO-10646 UTF-8, as defined in [RFC-2279])
+      // string    service name (US-ASCII) "ssh-userauth" ? "ssh-connection"
+      // string    "keyboard-interactive" (US-ASCII)
+      // string    language tag (as defined in [RFC-3066])
+      // string    submethods (ISO-10646 UTF-8)
+      packet.reset();
+      buf.putByte((byte)SSH_MSG_USERAUTH_REQUEST);
+      buf.putString(_username);
+      buf.putString(Util.str2byte("ssh-connection"));
+      //buf.putString("ssh-userauth".getBytes());
+      buf.putString(Util.str2byte("keyboard-interactive"));
+      buf.putString(Util.empty);
+      buf.putString(Util.empty);
+      session.write(packet);
+
+      boolean firsttime=true;
+      loop:
+      while(true){
+        buf=session.read(buf);
+        int command=buf.getCommand()&0xff;
+
+	if(command==SSH_MSG_USERAUTH_SUCCESS){
+	  return true;
+	}
+	if(command==SSH_MSG_USERAUTH_BANNER){
+	  buf.getInt(); buf.getByte(); buf.getByte();
+	  byte[] _message=buf.getString();
+	  byte[] lang=buf.getString();
+	  String message=Util.byte2str(_message);
+	  if(userinfo!=null){
+	    userinfo.showMessage(message);
+	  }
+	  continue loop;
+	}
+	if(command==SSH_MSG_USERAUTH_FAILURE){
+	  buf.getInt(); buf.getByte(); buf.getByte(); 
+	  byte[] foo=buf.getString();
+	  int partial_success=buf.getByte();
+//	  System.err.println(new String(foo)+
+//			     " partial_success:"+(partial_success!=0));
+
+	  if(partial_success!=0){
+	    throw new JSchPartialAuthException(Util.byte2str(foo));
+	  }
+
+	  if(firsttime){
+	    return false;
+	    //throw new JSchException("USERAUTH KI is not supported");
+	    //cancel=true;  // ??
+	  }
+          session.auth_failures++;
+	  break;
+	}
+	if(command==SSH_MSG_USERAUTH_INFO_REQUEST){
+	  firsttime=false;
+	  buf.getInt(); buf.getByte(); buf.getByte();
+	  String name=Util.byte2str(buf.getString());
+	  String instruction=Util.byte2str(buf.getString());
+	  String languate_tag=Util.byte2str(buf.getString());
+	  int num=buf.getInt();
+	  String[] prompt=new String[num];
+	  boolean[] echo=new boolean[num];
+	  for(int i=0; i<num; i++){
+	    prompt[i]=Util.byte2str(buf.getString());
+	    echo[i]=(buf.getByte()!=0);
+	  }
+
+	  byte[][] response=null;
+
+          if(password!=null && 
+             prompt.length==1 &&
+             !echo[0] &&
+             prompt[0].toLowerCase().startsWith("password:")){
+            response=new byte[1][];
+            response[0]=password;
+            password=null;
+          }
+          else if(num>0
+	     ||(name.length()>0 || instruction.length()>0)
+	     ){
+	    if(userinfo!=null){
+              UIKeyboardInteractive kbi=(UIKeyboardInteractive)userinfo;
+              String[] _response=kbi.promptKeyboardInteractive(dest,
+                                                               name,
+                                                               instruction,
+                                                               prompt,
+                                                               echo);
+              if(_response!=null){
+                response=new byte[_response.length][];
+                for(int i=0; i<_response.length; i++){
+                  response[i]=Util.str2byte(_response[i]);
+                }
+              }
+	    }
+	  }
+
+	  // byte      SSH_MSG_USERAUTH_INFO_RESPONSE(61)
+	  // int       num-responses
+	  // string    response[1] (ISO-10646 UTF-8)
+	  // ...
+	  // string    response[num-responses] (ISO-10646 UTF-8)
+	  packet.reset();
+	  buf.putByte((byte)SSH_MSG_USERAUTH_INFO_RESPONSE);
+	  if(num>0 &&
+	     (response==null ||  // cancel
+	      num!=response.length)){
+
+            if(response==null){  
+              // working around the bug in OpenSSH ;-<
+              buf.putInt(num);
+              for(int i=0; i<num; i++){
+                buf.putString(Util.empty);
+              }
+            }
+            else{
+              buf.putInt(0);
+            }
+
+	    if(response==null)
+	      cancel=true;
+	  }
+	  else{
+	    buf.putInt(num);
+	    for(int i=0; i<num; i++){
+	      buf.putString(response[i]);
+	    }
+	  }
+	  session.write(packet);
+          /*
+	  if(cancel)
+	    break;
+          */
+	  continue loop;
+	}
+	//throw new JSchException("USERAUTH fail ("+command+")");
+	return false;
+      }
+      if(cancel){
+	throw new JSchAuthCancelException("keyboard-interactive");
+	//break;
+      }
+    }
+    //return false;
+  }
+}
diff --git a/java/com/jcraft/jsch/UserAuthNone.java b/java/com/jcraft/jsch/UserAuthNone.java
new file mode 100644
index 0000000..b3b0b07
--- /dev/null
+++ b/java/com/jcraft/jsch/UserAuthNone.java
@@ -0,0 +1,129 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+class UserAuthNone extends UserAuth{
+  private static final int SSH_MSG_SERVICE_ACCEPT=                  6;
+  private String methods=null;
+
+  public boolean start(Session session) throws Exception{
+    super.start(session);
+
+
+    // send
+    // byte      SSH_MSG_SERVICE_REQUEST(5)
+    // string    service name "ssh-userauth"
+    packet.reset();
+    buf.putByte((byte)Session.SSH_MSG_SERVICE_REQUEST);
+    buf.putString(Util.str2byte("ssh-userauth"));
+    session.write(packet);
+
+    if(JSch.getLogger().isEnabled(Logger.INFO)){
+      JSch.getLogger().log(Logger.INFO, 
+                           "SSH_MSG_SERVICE_REQUEST sent");
+    }
+
+    // receive
+    // byte      SSH_MSG_SERVICE_ACCEPT(6)
+    // string    service name
+    buf=session.read(buf);
+    int command=buf.getCommand();
+
+    boolean result=(command==SSH_MSG_SERVICE_ACCEPT);
+
+    if(JSch.getLogger().isEnabled(Logger.INFO)){
+      JSch.getLogger().log(Logger.INFO, 
+                           "SSH_MSG_SERVICE_ACCEPT received");
+    }
+    if(!result)
+      return false;
+
+    byte[] _username=null;
+    _username=Util.str2byte(username);
+
+    // send
+    // byte      SSH_MSG_USERAUTH_REQUEST(50)
+    // string    user name
+    // string    service name ("ssh-connection")
+    // string    "none"
+    packet.reset();
+    buf.putByte((byte)SSH_MSG_USERAUTH_REQUEST);
+    buf.putString(_username);
+    buf.putString(Util.str2byte("ssh-connection"));
+    buf.putString(Util.str2byte("none"));
+    session.write(packet);
+
+    loop:
+    while(true){
+      buf=session.read(buf);
+      command=buf.getCommand()&0xff;
+
+      if(command==SSH_MSG_USERAUTH_SUCCESS){
+	return true;
+      }
+      if(command==SSH_MSG_USERAUTH_BANNER){
+	buf.getInt(); buf.getByte(); buf.getByte();
+	byte[] _message=buf.getString();
+	byte[] lang=buf.getString();
+	String message=Util.byte2str(_message);
+	if(userinfo!=null){
+          try{
+            userinfo.showMessage(message);
+          }
+          catch(RuntimeException ee){
+          }
+	}
+	continue loop;
+      }
+      if(command==SSH_MSG_USERAUTH_FAILURE){
+	buf.getInt(); buf.getByte(); buf.getByte(); 
+	byte[] foo=buf.getString();
+	int partial_success=buf.getByte();
+	methods=Util.byte2str(foo);
+//System.err.println("UserAuthNONE: "+methods+
+//		   " partial_success:"+(partial_success!=0));
+//	if(partial_success!=0){
+//	  throw new JSchPartialAuthException(new String(foo));
+//	}
+
+        break;
+      }
+      else{
+//      System.err.println("USERAUTH fail ("+command+")");
+	throw new JSchException("USERAUTH fail ("+command+")");
+      }
+    }
+   //throw new JSchException("USERAUTH fail");
+    return false;
+  }
+  String getMethods(){
+    return methods;
+  }
+}
diff --git a/java/com/jcraft/jsch/UserAuthPassword.java b/java/com/jcraft/jsch/UserAuthPassword.java
new file mode 100644
index 0000000..9b5837f
--- /dev/null
+++ b/java/com/jcraft/jsch/UserAuthPassword.java
@@ -0,0 +1,193 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+class UserAuthPassword extends UserAuth{
+  private final int SSH_MSG_USERAUTH_PASSWD_CHANGEREQ=60;
+
+  public boolean start(Session session) throws Exception{
+    super.start(session);
+
+    byte[] password=session.password;
+    String dest=username+"@"+session.host;
+    if(session.port!=22){
+      dest+=(":"+session.port);
+    }
+
+    try{
+
+    while(true){
+
+      if(session.auth_failures >= session.max_auth_tries){
+        return false;
+      }
+
+      if(password==null){
+	if(userinfo==null){
+	  //throw new JSchException("USERAUTH fail");
+	  return false;
+	}
+	if(!userinfo.promptPassword("Password for "+dest)){
+	  throw new JSchAuthCancelException("password");
+	  //break;
+	}
+
+	String _password=userinfo.getPassword();
+	if(_password==null){
+	  throw new JSchAuthCancelException("password");
+	  //break;
+	}
+        password=Util.str2byte(_password);
+      }
+
+      byte[] _username=null;
+      _username=Util.str2byte(username);
+
+      // send
+      // byte      SSH_MSG_USERAUTH_REQUEST(50)
+      // string    user name
+      // string    service name ("ssh-connection")
+      // string    "password"
+      // boolen    FALSE
+      // string    plaintext password (ISO-10646 UTF-8)
+      packet.reset();
+      buf.putByte((byte)SSH_MSG_USERAUTH_REQUEST);
+      buf.putString(_username);
+      buf.putString(Util.str2byte("ssh-connection"));
+      buf.putString(Util.str2byte("password"));
+      buf.putByte((byte)0);
+      buf.putString(password);
+      session.write(packet);
+
+      loop:
+      while(true){
+	buf=session.read(buf);
+        int command=buf.getCommand()&0xff;
+
+	if(command==SSH_MSG_USERAUTH_SUCCESS){
+	  return true;
+	}
+	if(command==SSH_MSG_USERAUTH_BANNER){
+	  buf.getInt(); buf.getByte(); buf.getByte();
+	  byte[] _message=buf.getString();
+	  byte[] lang=buf.getString();
+          String message=Util.byte2str(_message);
+	  if(userinfo!=null){
+	    userinfo.showMessage(message);
+	  }
+	  continue loop;
+	}
+	if(command==SSH_MSG_USERAUTH_PASSWD_CHANGEREQ){
+	  buf.getInt(); buf.getByte(); buf.getByte(); 
+	  byte[] instruction=buf.getString();
+	  byte[] tag=buf.getString();
+	  if(userinfo==null || 
+             !(userinfo instanceof UIKeyboardInteractive)){
+            if(userinfo!=null){
+              userinfo.showMessage("Password must be changed.");
+            }
+            return false;
+          }
+
+          UIKeyboardInteractive kbi=(UIKeyboardInteractive)userinfo;
+          String[] response;
+          String name="Password Change Required";
+          String[] prompt={"New Password: "};
+          boolean[] echo={false};
+          response=kbi.promptKeyboardInteractive(dest,
+                                                 name,
+                                                 Util.byte2str(instruction),
+                                                 prompt,
+                                                 echo);
+          if(response==null){
+            throw new JSchAuthCancelException("password");
+          }
+
+          byte[] newpassword=Util.str2byte(response[0]);
+
+          // send
+          // byte      SSH_MSG_USERAUTH_REQUEST(50)
+          // string    user name
+          // string    service name ("ssh-connection")
+          // string    "password"
+          // boolen    TRUE
+          // string    plaintext old password (ISO-10646 UTF-8)
+          // string    plaintext new password (ISO-10646 UTF-8)
+          packet.reset();
+          buf.putByte((byte)SSH_MSG_USERAUTH_REQUEST);
+          buf.putString(_username);
+          buf.putString(Util.str2byte("ssh-connection"));
+          buf.putString(Util.str2byte("password"));
+          buf.putByte((byte)1);
+          buf.putString(password);
+          buf.putString(newpassword);
+          Util.bzero(newpassword);
+          response=null;
+          session.write(packet);
+	  continue loop;
+        }
+	if(command==SSH_MSG_USERAUTH_FAILURE){
+	  buf.getInt(); buf.getByte(); buf.getByte(); 
+	  byte[] foo=buf.getString();
+	  int partial_success=buf.getByte();
+	  //System.err.println(new String(foo)+
+	  //		 " partial_success:"+(partial_success!=0));
+	  if(partial_success!=0){
+	    throw new JSchPartialAuthException(Util.byte2str(foo));
+	  }
+          session.auth_failures++;
+	  break;
+	}
+	else{
+          //System.err.println("USERAUTH fail ("+buf.getCommand()+")");
+//	  throw new JSchException("USERAUTH fail ("+buf.getCommand()+")");
+	  return false;
+	}
+      }
+
+      if(password!=null){
+        Util.bzero(password);
+        password=null;
+      }
+
+    }
+
+    }
+    finally{
+      if(password!=null){
+        Util.bzero(password);
+        password=null;
+      }
+    }
+
+    //throw new JSchException("USERAUTH fail");
+    //return false;
+  }
+}
diff --git a/java/com/jcraft/jsch/UserAuthPublicKey.java b/java/com/jcraft/jsch/UserAuthPublicKey.java
new file mode 100644
index 0000000..64e8e72
--- /dev/null
+++ b/java/com/jcraft/jsch/UserAuthPublicKey.java
@@ -0,0 +1,228 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+import java.util.Vector;
+
+class UserAuthPublicKey extends UserAuth{
+
+  public boolean start(Session session) throws Exception{
+    super.start(session);
+
+    Vector identities=session.jsch.getIdentityRepository().getIdentities();
+
+    byte[] passphrase=null;
+    byte[] _username=null;
+
+    int command;
+
+    synchronized(identities){
+      if(identities.size()<=0){
+        return false;
+      }
+
+      _username=Util.str2byte(username);
+
+      for(int i=0; i<identities.size(); i++){
+
+        if(session.auth_failures >= session.max_auth_tries){
+          return false;
+        }
+
+        Identity identity=(Identity)(identities.elementAt(i));
+        byte[] pubkeyblob=identity.getPublicKeyBlob();
+
+//System.err.println("UserAuthPublicKey: "+identity+" "+pubkeyblob);
+
+        if(pubkeyblob!=null){
+          // send
+          // byte      SSH_MSG_USERAUTH_REQUEST(50)
+          // string    user name
+          // string    service name ("ssh-connection")
+          // string    "publickey"
+          // boolen    FALSE
+          // string    plaintext password (ISO-10646 UTF-8)
+          packet.reset();
+          buf.putByte((byte)SSH_MSG_USERAUTH_REQUEST);
+          buf.putString(_username);
+          buf.putString(Util.str2byte("ssh-connection"));
+          buf.putString(Util.str2byte("publickey"));
+          buf.putByte((byte)0);
+          buf.putString(Util.str2byte(identity.getAlgName()));
+          buf.putString(pubkeyblob);
+          session.write(packet);
+
+          loop1:
+          while(true){
+            buf=session.read(buf);
+            command=buf.getCommand()&0xff;
+
+            if(command==SSH_MSG_USERAUTH_PK_OK){
+              break;
+            }
+            else if(command==SSH_MSG_USERAUTH_FAILURE){
+              break;
+            }
+            else if(command==SSH_MSG_USERAUTH_BANNER){
+              buf.getInt(); buf.getByte(); buf.getByte();
+              byte[] _message=buf.getString();
+              byte[] lang=buf.getString();
+              String message=Util.byte2str(_message);
+              if(userinfo!=null){
+                userinfo.showMessage(message);
+              }
+              continue loop1;
+            }
+            else{
+	    //System.err.println("USERAUTH fail ("+command+")");
+	    //throw new JSchException("USERAUTH fail ("+command+")");
+              break;
+            }
+          }
+
+          if(command!=SSH_MSG_USERAUTH_PK_OK){
+            continue;
+          }
+        }
+
+//System.err.println("UserAuthPublicKey: identity.isEncrypted()="+identity.isEncrypted());
+
+        int count=5;
+        while(true){
+          if((identity.isEncrypted() && passphrase==null)){
+            if(userinfo==null) throw new JSchException("USERAUTH fail");
+            if(identity.isEncrypted() &&
+               !userinfo.promptPassphrase("Passphrase for "+identity.getName())){
+              throw new JSchAuthCancelException("publickey");
+              //throw new JSchException("USERAUTH cancel");
+              //break;
+            }
+            String _passphrase=userinfo.getPassphrase();
+            if(_passphrase!=null){
+              passphrase=Util.str2byte(_passphrase);
+            }
+          }
+
+          if(!identity.isEncrypted() || passphrase!=null){
+            if(identity.setPassphrase(passphrase))
+              break;
+          }
+          Util.bzero(passphrase);
+          passphrase=null;
+          count--;
+          if(count==0)break;
+        }
+
+        Util.bzero(passphrase);
+        passphrase=null;
+//System.err.println("UserAuthPublicKey: identity.isEncrypted()="+identity.isEncrypted());
+
+        if(identity.isEncrypted()) continue;
+        if(pubkeyblob==null) pubkeyblob=identity.getPublicKeyBlob();
+
+//System.err.println("UserAuthPublicKey: pubkeyblob="+pubkeyblob);
+
+        if(pubkeyblob==null) continue;
+
+      // send
+      // byte      SSH_MSG_USERAUTH_REQUEST(50)
+      // string    user name
+      // string    service name ("ssh-connection")
+      // string    "publickey"
+      // boolen    TRUE
+      // string    plaintext password (ISO-10646 UTF-8)
+        packet.reset();
+        buf.putByte((byte)SSH_MSG_USERAUTH_REQUEST);
+        buf.putString(_username);
+        buf.putString(Util.str2byte("ssh-connection"));
+        buf.putString(Util.str2byte("publickey"));
+        buf.putByte((byte)1);
+        buf.putString(Util.str2byte(identity.getAlgName()));
+        buf.putString(pubkeyblob);
+
+//      byte[] tmp=new byte[buf.index-5];
+//      System.arraycopy(buf.buffer, 5, tmp, 0, tmp.length);
+//      buf.putString(signature);
+
+        byte[] sid=session.getSessionId();
+        int sidlen=sid.length;
+        byte[] tmp=new byte[4+sidlen+buf.index-5];
+        tmp[0]=(byte)(sidlen>>>24);
+        tmp[1]=(byte)(sidlen>>>16);
+        tmp[2]=(byte)(sidlen>>>8);
+        tmp[3]=(byte)(sidlen);
+        System.arraycopy(sid, 0, tmp, 4, sidlen);
+        System.arraycopy(buf.buffer, 5, tmp, 4+sidlen, buf.index-5);
+        byte[] signature=identity.getSignature(tmp);
+        if(signature==null){  // for example, too long key length.
+          break;
+        }
+        buf.putString(signature);
+        session.write(packet);
+
+        loop2:
+        while(true){
+          buf=session.read(buf);
+          command=buf.getCommand()&0xff;
+
+          if(command==SSH_MSG_USERAUTH_SUCCESS){
+            return true;
+          }
+          else if(command==SSH_MSG_USERAUTH_BANNER){
+            buf.getInt(); buf.getByte(); buf.getByte();
+            byte[] _message=buf.getString();
+            byte[] lang=buf.getString();
+            String message=Util.byte2str(_message);
+            if(userinfo!=null){
+              userinfo.showMessage(message);
+            }
+            continue loop2;
+          }
+          else if(command==SSH_MSG_USERAUTH_FAILURE){
+            buf.getInt(); buf.getByte(); buf.getByte(); 
+            byte[] foo=buf.getString();
+            int partial_success=buf.getByte();
+	  //System.err.println(new String(foo)+
+	  //                   " partial_success:"+(partial_success!=0));
+            if(partial_success!=0){
+              throw new JSchPartialAuthException(Util.byte2str(foo));
+            }
+            session.auth_failures++;
+            break;
+          }
+          //System.err.println("USERAUTH fail ("+command+")");
+          //throw new JSchException("USERAUTH fail ("+command+")");
+          break;
+        }
+      }
+    }
+    return false;
+  }
+}
diff --git a/java/com/jcraft/jsch/UserInfo.java b/java/com/jcraft/jsch/UserInfo.java
new file mode 100644
index 0000000..22552ed
--- /dev/null
+++ b/java/com/jcraft/jsch/UserInfo.java
@@ -0,0 +1,39 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+
+public interface UserInfo{
+  String getPassphrase();
+  String getPassword();
+  boolean promptPassword(String message);
+  boolean promptPassphrase(String message);
+  boolean promptYesNo(String message);
+  void showMessage(String message);
+}
diff --git a/java/com/jcraft/jsch/Util.java b/java/com/jcraft/jsch/Util.java
new file mode 100644
index 0000000..df51b2d
--- /dev/null
+++ b/java/com/jcraft/jsch/Util.java
@@ -0,0 +1,474 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch;
+import java.net.Socket;
+
+class Util{
+
+  private static final byte[] b64 =Util.str2byte("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=");
+  private static byte val(byte foo){
+    if(foo == '=') return 0;
+    for(int j=0; j<b64.length; j++){
+      if(foo==b64[j]) return (byte)j;
+    }
+    return 0;
+  }
+  static byte[] fromBase64(byte[] buf, int start, int length){
+    byte[] foo=new byte[length];
+    int j=0;
+    for (int i=start;i<start+length;i+=4){
+      foo[j]=(byte)((val(buf[i])<<2)|((val(buf[i+1])&0x30)>>>4));
+      if(buf[i+2]==(byte)'='){ j++; break;}
+      foo[j+1]=(byte)(((val(buf[i+1])&0x0f)<<4)|((val(buf[i+2])&0x3c)>>>2));
+      if(buf[i+3]==(byte)'='){ j+=2; break;}
+      foo[j+2]=(byte)(((val(buf[i+2])&0x03)<<6)|(val(buf[i+3])&0x3f));
+      j+=3;
+    }
+    byte[] bar=new byte[j];
+    System.arraycopy(foo, 0, bar, 0, j);
+    return bar;
+  }
+  static byte[] toBase64(byte[] buf, int start, int length){
+
+    byte[] tmp=new byte[length*2];
+    int i,j,k;
+    
+    int foo=(length/3)*3+start;
+    i=0;
+    for(j=start; j<foo; j+=3){
+      k=(buf[j]>>>2)&0x3f;
+      tmp[i++]=b64[k];
+      k=(buf[j]&0x03)<<4|(buf[j+1]>>>4)&0x0f;
+      tmp[i++]=b64[k];
+      k=(buf[j+1]&0x0f)<<2|(buf[j+2]>>>6)&0x03;
+      tmp[i++]=b64[k];
+      k=buf[j+2]&0x3f;
+      tmp[i++]=b64[k];
+    }
+
+    foo=(start+length)-foo;
+    if(foo==1){
+      k=(buf[j]>>>2)&0x3f;
+      tmp[i++]=b64[k];
+      k=((buf[j]&0x03)<<4)&0x3f;
+      tmp[i++]=b64[k];
+      tmp[i++]=(byte)'=';
+      tmp[i++]=(byte)'=';
+    }
+    else if(foo==2){
+      k=(buf[j]>>>2)&0x3f;
+      tmp[i++]=b64[k];
+      k=(buf[j]&0x03)<<4|(buf[j+1]>>>4)&0x0f;
+      tmp[i++]=b64[k];
+      k=((buf[j+1]&0x0f)<<2)&0x3f;
+      tmp[i++]=b64[k];
+      tmp[i++]=(byte)'=';
+    }
+    byte[] bar=new byte[i];
+    System.arraycopy(tmp, 0, bar, 0, i);
+    return bar;
+
+//    return sun.misc.BASE64Encoder().encode(buf);
+  }
+
+  static String[] split(String foo, String split){
+    if(foo==null)
+      return null;
+    byte[] buf=Util.str2byte(foo);
+    java.util.Vector bar=new java.util.Vector();
+    int start=0;
+    int index;
+    while(true){
+      index=foo.indexOf(split, start);
+      if(index>=0){
+	bar.addElement(Util.byte2str(buf, start, index-start));
+	start=index+1;
+	continue;
+      }
+      bar.addElement(Util.byte2str(buf, start, buf.length-start));
+      break;
+    }
+    String[] result=new String[bar.size()];
+    for(int i=0; i<result.length; i++){
+      result[i]=(String)(bar.elementAt(i));
+    }
+    return result;
+  }
+  static boolean glob(byte[] pattern, byte[] name){
+    return glob0(pattern, 0, name, 0);
+  }
+  static private boolean glob0(byte[] pattern, int pattern_index,
+			      byte[] name, int name_index){
+    if(name.length>0 && name[0]=='.'){
+      if(pattern.length>0 && pattern[0]=='.'){
+        if(pattern.length==2 && pattern[1]=='*') return true;
+        return glob(pattern, pattern_index+1, name, name_index+1);
+      }
+      return false;
+    }
+    return glob(pattern, pattern_index, name, name_index);
+  }
+  static private boolean glob(byte[] pattern, int pattern_index,
+			      byte[] name, int name_index){
+    //System.err.println("glob: "+new String(pattern)+", "+pattern_index+" "+new String(name)+", "+name_index);
+
+    int patternlen=pattern.length;
+    if(patternlen==0)
+      return false;
+
+    int namelen=name.length;
+    int i=pattern_index;
+    int j=name_index;
+
+    while(i<patternlen && j<namelen){
+      if(pattern[i]=='\\'){
+	if(i+1==patternlen)
+	  return false;
+	i++;
+	if(pattern[i]!=name[j]) 
+          return false;
+        i+=skipUTF8Char(pattern[i]);
+        j+=skipUTF8Char(name[j]);
+	continue;
+      }
+
+      if(pattern[i]=='*'){
+        while(i<patternlen){
+          if(pattern[i]=='*'){
+            i++;
+            continue;
+          }
+          break;
+        }
+	if(patternlen==i)
+          return true;
+
+	byte foo=pattern[i];
+        if(foo=='?'){
+          while(j<namelen){
+	    if(glob(pattern, i, name, j)){
+	      return true;
+            }
+            j+=skipUTF8Char(name[j]);
+          }
+          return false;
+        }
+        else if(foo=='\\'){
+          if(i+1==patternlen)
+            return false;
+          i++;
+          foo=pattern[i];
+          while(j<namelen){
+            if(foo==name[j]){
+              if(glob(pattern, i+skipUTF8Char(foo),
+                      name, j+skipUTF8Char(name[j]))){
+                return true;
+              }
+            }
+            j+=skipUTF8Char(name[j]);
+          }
+          return false;
+        }
+
+	while(j<namelen){
+	  if(foo==name[j]){
+	    if(glob(pattern, i, name, j)){
+	      return true;
+	    }
+	  }
+          j+=skipUTF8Char(name[j]);
+	}
+	return false;
+      }
+
+      if(pattern[i]=='?'){
+        i++;
+        j+=skipUTF8Char(name[j]);
+	continue;
+      }
+
+      if(pattern[i]!=name[j])
+        return false;
+
+      i+=skipUTF8Char(pattern[i]);
+      j+=skipUTF8Char(name[j]);
+
+      if(!(j<namelen)){         // name is end
+        if(!(i<patternlen)){    // pattern is end
+	  return true;
+	}
+	if(pattern[i]=='*'){    
+          break;
+	}
+      }
+      continue;
+    }
+
+    if(i==patternlen && j==namelen) 
+      return true;
+
+    if(!(j<namelen) &&  // name is end
+       pattern[i]=='*'){
+      boolean ok=true;
+      while(i<patternlen){
+        if(pattern[i++]!='*'){
+          ok=false;
+          break;
+        }
+      }
+      return ok;
+    }
+
+    return false;
+  }
+
+  static String quote(String path){
+    byte[] _path=str2byte(path);
+    int count=0;
+    for(int i=0;i<_path.length; i++){
+      byte b=_path[i];
+      if(b=='\\' || b=='?' || b=='*')
+        count++;
+    }
+    if(count==0)
+      return path;
+    byte[] _path2=new byte[_path.length+count];
+    for(int i=0, j=0; i<_path.length; i++){
+      byte b=_path[i];
+      if(b=='\\' || b=='?' || b=='*'){
+        _path2[j++]='\\';
+      }
+      _path2[j++]=b;
+    }
+    return byte2str(_path2);
+  }
+
+  static String unquote(String path){
+    byte[] foo=str2byte(path);
+    byte[] bar=unquote(foo);
+    if(foo.length==bar.length)
+      return path;
+    return byte2str(bar);
+  }
+  static byte[] unquote(byte[] path){
+    int pathlen=path.length;
+    int i=0;
+    while(i<pathlen){
+      if(path[i]=='\\'){
+        if(i+1==pathlen)
+          break;
+        System.arraycopy(path, i+1, path, i, path.length-(i+1));
+        pathlen--;
+        i++;
+        continue;
+      }
+      i++;
+    }
+    if(pathlen==path.length)
+      return path;
+    byte[] foo=new byte[pathlen];
+    System.arraycopy(path, 0, foo, 0, pathlen);
+    return foo;
+  }
+
+  private static String[] chars={
+    "0","1","2","3","4","5","6","7","8","9", "a","b","c","d","e","f"
+  };
+  static String getFingerPrint(HASH hash, byte[] data){
+    try{
+      hash.init();
+      hash.update(data, 0, data.length);
+      byte[] foo=hash.digest();
+      StringBuffer sb=new StringBuffer();
+      int bar;
+      for(int i=0; i<foo.length;i++){
+        bar=foo[i]&0xff;
+        sb.append(chars[(bar>>>4)&0xf]);
+        sb.append(chars[(bar)&0xf]);
+        if(i+1<foo.length)
+          sb.append(":");
+      }
+      return sb.toString();
+    }
+    catch(Exception e){
+      return "???";
+    }
+  }
+  static boolean array_equals(byte[] foo, byte bar[]){
+    int i=foo.length;
+    if(i!=bar.length) return false;
+    for(int j=0; j<i; j++){ if(foo[j]!=bar[j]) return false; }
+    //try{while(true){i--; if(foo[i]!=bar[i])return false;}}catch(Exception e){}
+    return true;
+  }
+  static Socket createSocket(String host, int port, int timeout) throws JSchException{
+    Socket socket=null;
+    if(timeout==0){
+      try{
+        socket=new Socket(host, port);
+        return socket;
+      }
+      catch(Exception e){
+        String message=e.toString();
+        if(e instanceof Throwable)
+          throw new JSchException(message, (Throwable)e);
+        throw new JSchException(message);
+      }
+    }
+    final String _host=host;
+    final int _port=port;
+    final Socket[] sockp=new Socket[1];
+    final Exception[] ee=new Exception[1];
+    String message="";
+    Thread tmp=new Thread(new Runnable(){
+        public void run(){
+          sockp[0]=null;
+          try{
+            sockp[0]=new Socket(_host, _port);
+          }
+          catch(Exception e){
+            ee[0]=e;
+            if(sockp[0]!=null && sockp[0].isConnected()){
+              try{
+                sockp[0].close();
+              }
+              catch(Exception eee){}
+            }
+            sockp[0]=null;
+          }
+        }
+      });
+    tmp.setName("Opening Socket "+host);
+    tmp.start();
+    try{ 
+      tmp.join(timeout);
+      message="timeout: ";
+    }
+    catch(java.lang.InterruptedException eee){
+    }
+    if(sockp[0]!=null && sockp[0].isConnected()){
+      socket=sockp[0];
+    }
+    else{
+      message+="socket is not established";
+      if(ee[0]!=null){
+        message=ee[0].toString();
+      }
+      tmp.interrupt();
+      tmp=null;
+      throw new JSchException(message);
+    }
+    return socket;
+  } 
+
+  static byte[] str2byte(String str, String encoding){
+    if(str==null) 
+      return null;
+    try{ return str.getBytes(encoding); }
+    catch(java.io.UnsupportedEncodingException e){
+      return str.getBytes();
+    }
+  }
+
+  static byte[] str2byte(String str){
+    return str2byte(str, "UTF-8");
+  }
+
+  static String byte2str(byte[] str, String encoding){
+    return byte2str(str, 0, str.length, encoding);
+  }
+
+  static String byte2str(byte[] str, int s, int l, String encoding){
+    try{ return new String(str, s, l, encoding); }
+    catch(java.io.UnsupportedEncodingException e){
+      return new String(str, s, l);
+    }
+  }
+
+  static String byte2str(byte[] str){
+    return byte2str(str, 0, str.length, "UTF-8");
+  }
+
+  static String byte2str(byte[] str, int s, int l){
+    return byte2str(str, s, l, "UTF-8");
+  }
+
+  static final byte[] empty = str2byte("");
+
+  /*
+  static byte[] char2byte(char[] foo){
+    int len=0;
+    for(int i=0; i<foo.length; i++){
+      if((foo[i]&0xff00)==0) len++;
+      else len+=2;
+    }
+    byte[] bar=new byte[len];
+    for(int i=0, j=0; i<foo.length; i++){
+      if((foo[i]&0xff00)==0){
+        bar[j++]=(byte)foo[i];
+      }
+      else{
+        bar[j++]=(byte)(foo[i]>>>8);
+        bar[j++]=(byte)foo[i];
+      }
+    }
+    return bar;
+  }
+  */
+  static void bzero(byte[] foo){
+    if(foo==null)
+      return;
+    for(int i=0; i<foo.length; i++)
+      foo[i]=0;
+  }
+
+  static String diffString(String str, String[] not_available){
+    String[] stra=Util.split(str, ",");
+    String result=null;
+    loop:
+    for(int i=0; i<stra.length; i++){
+      for(int j=0; j<not_available.length; j++){
+        if(stra[i].equals(not_available[j])){
+          continue loop;
+        }
+      }
+      if(result==null){ result=stra[i]; }
+      else{ result=result+","+stra[i]; }
+    }
+    return result;
+  }
+
+  private static int skipUTF8Char(byte b){
+    if((byte)(b&0x80)==0) return 1;
+    if((byte)(b&0xe0)==(byte)0xc0) return 2;
+    if((byte)(b&0xf0)==(byte)0xe0) return 3;
+    return 1;
+  }
+}
diff --git a/java/com/jcraft/jsch/jce/AES128CBC.java b/java/com/jcraft/jsch/jce/AES128CBC.java
new file mode 100644
index 0000000..8c2b43b
--- /dev/null
+++ b/java/com/jcraft/jsch/jce/AES128CBC.java
@@ -0,0 +1,73 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2005-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch.jce;
+
+import com.jcraft.jsch.Cipher;
+import javax.crypto.spec.*;
+
+public class AES128CBC implements Cipher{
+  private static final int ivsize=16;
+  private static final int bsize=16;
+  private javax.crypto.Cipher cipher;    
+  public int getIVSize(){return ivsize;} 
+  public int getBlockSize(){return bsize;}
+  public void init(int mode, byte[] key, byte[] iv) throws Exception{
+    String pad="NoPadding";      
+    byte[] tmp;
+    if(iv.length>ivsize){
+      tmp=new byte[ivsize];
+      System.arraycopy(iv, 0, tmp, 0, tmp.length);
+      iv=tmp;
+    }
+    if(key.length>bsize){
+      tmp=new byte[bsize];
+      System.arraycopy(key, 0, tmp, 0, tmp.length);
+      key=tmp;
+    }
+
+    try{
+      SecretKeySpec keyspec=new SecretKeySpec(key, "AES");
+      cipher=javax.crypto.Cipher.getInstance("AES/CBC/"+pad);
+      cipher.init((mode==ENCRYPT_MODE?
+                   javax.crypto.Cipher.ENCRYPT_MODE:
+                   javax.crypto.Cipher.DECRYPT_MODE),
+                  keyspec, new IvParameterSpec(iv));
+    }
+    catch(Exception e){
+      cipher=null;
+      throw e;
+    }
+  }
+  public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception{
+    cipher.update(foo, s1, len, bar, s2);
+  }
+
+  public boolean isCBC(){return true; }
+}
diff --git a/java/com/jcraft/jsch/jce/AES128CTR.java b/java/com/jcraft/jsch/jce/AES128CTR.java
new file mode 100644
index 0000000..470a896
--- /dev/null
+++ b/java/com/jcraft/jsch/jce/AES128CTR.java
@@ -0,0 +1,73 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2008-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch.jce;
+
+import com.jcraft.jsch.Cipher;
+import javax.crypto.spec.*;
+
+public class AES128CTR implements Cipher{
+  private static final int ivsize=16;
+  private static final int bsize=16;
+  private javax.crypto.Cipher cipher;    
+  public int getIVSize(){return ivsize;} 
+  public int getBlockSize(){return bsize;}
+  public void init(int mode, byte[] key, byte[] iv) throws Exception{
+    String pad="NoPadding";      
+    byte[] tmp;
+    if(iv.length>ivsize){
+      tmp=new byte[ivsize];
+      System.arraycopy(iv, 0, tmp, 0, tmp.length);
+      iv=tmp;
+    }
+    if(key.length>bsize){
+      tmp=new byte[bsize];
+      System.arraycopy(key, 0, tmp, 0, tmp.length);
+      key=tmp;
+    }
+
+    try{
+      SecretKeySpec keyspec=new SecretKeySpec(key, "AES");
+      cipher=javax.crypto.Cipher.getInstance("AES/CTR/"+pad);
+      cipher.init((mode==ENCRYPT_MODE?
+                   javax.crypto.Cipher.ENCRYPT_MODE:
+                   javax.crypto.Cipher.DECRYPT_MODE),
+                  keyspec, new IvParameterSpec(iv));
+    }
+    catch(Exception e){
+      cipher=null;
+      throw e;
+    }
+  }
+  public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception{
+    cipher.update(foo, s1, len, bar, s2);
+  }
+
+  public boolean isCBC(){return false; }
+}
diff --git a/java/com/jcraft/jsch/jce/AES192CBC.java b/java/com/jcraft/jsch/jce/AES192CBC.java
new file mode 100644
index 0000000..615d494
--- /dev/null
+++ b/java/com/jcraft/jsch/jce/AES192CBC.java
@@ -0,0 +1,71 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2005-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch.jce;
+
+import com.jcraft.jsch.Cipher;
+import javax.crypto.spec.*;
+
+public class AES192CBC implements Cipher{
+  private static final int ivsize=16;
+  private static final int bsize=24;
+  private javax.crypto.Cipher cipher;    
+  public int getIVSize(){return ivsize;} 
+  public int getBlockSize(){return bsize;}
+  public void init(int mode, byte[] key, byte[] iv) throws Exception{
+    String pad="NoPadding";      
+    byte[] tmp;
+    if(iv.length>ivsize){
+      tmp=new byte[ivsize];
+      System.arraycopy(iv, 0, tmp, 0, tmp.length);
+      iv=tmp;
+    }
+    if(key.length>bsize){
+      tmp=new byte[bsize];
+      System.arraycopy(key, 0, tmp, 0, tmp.length);
+      key=tmp;
+    }
+    try{
+      SecretKeySpec keyspec=new SecretKeySpec(key, "AES");
+      cipher=javax.crypto.Cipher.getInstance("AES/CBC/"+pad);
+      cipher.init((mode==ENCRYPT_MODE?
+                   javax.crypto.Cipher.ENCRYPT_MODE:
+                   javax.crypto.Cipher.DECRYPT_MODE),
+                  keyspec, new IvParameterSpec(iv));
+    }
+    catch(Exception e){
+      cipher=null;
+      throw e;
+    }
+  }
+  public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception{
+    cipher.update(foo, s1, len, bar, s2);
+  }
+  public boolean isCBC(){return true; }
+}
diff --git a/java/com/jcraft/jsch/jce/AES192CTR.java b/java/com/jcraft/jsch/jce/AES192CTR.java
new file mode 100644
index 0000000..74090bf
--- /dev/null
+++ b/java/com/jcraft/jsch/jce/AES192CTR.java
@@ -0,0 +1,71 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2008-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch.jce;
+
+import com.jcraft.jsch.Cipher;
+import javax.crypto.spec.*;
+
+public class AES192CTR implements Cipher{
+  private static final int ivsize=16;
+  private static final int bsize=24;
+  private javax.crypto.Cipher cipher;    
+  public int getIVSize(){return ivsize;} 
+  public int getBlockSize(){return bsize;}
+  public void init(int mode, byte[] key, byte[] iv) throws Exception{
+    String pad="NoPadding";      
+    byte[] tmp;
+    if(iv.length>ivsize){
+      tmp=new byte[ivsize];
+      System.arraycopy(iv, 0, tmp, 0, tmp.length);
+      iv=tmp;
+    }
+    if(key.length>bsize){
+      tmp=new byte[bsize];
+      System.arraycopy(key, 0, tmp, 0, tmp.length);
+      key=tmp;
+    }
+    try{
+      SecretKeySpec keyspec=new SecretKeySpec(key, "AES");
+      cipher=javax.crypto.Cipher.getInstance("AES/CTR/"+pad);
+      cipher.init((mode==ENCRYPT_MODE?
+                   javax.crypto.Cipher.ENCRYPT_MODE:
+                   javax.crypto.Cipher.DECRYPT_MODE),
+                  keyspec, new IvParameterSpec(iv));
+    }
+    catch(Exception e){
+      cipher=null;
+      throw e;
+    }
+  }
+  public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception{
+    cipher.update(foo, s1, len, bar, s2);
+  }
+  public boolean isCBC(){return false; }
+}
diff --git a/java/com/jcraft/jsch/jce/AES256CBC.java b/java/com/jcraft/jsch/jce/AES256CBC.java
new file mode 100644
index 0000000..9018a20
--- /dev/null
+++ b/java/com/jcraft/jsch/jce/AES256CBC.java
@@ -0,0 +1,71 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2005-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch.jce;
+
+import com.jcraft.jsch.Cipher;
+import javax.crypto.spec.*;
+
+public class AES256CBC implements Cipher{
+  private static final int ivsize=16;
+  private static final int bsize=32;
+  private javax.crypto.Cipher cipher;    
+  public int getIVSize(){return ivsize;} 
+  public int getBlockSize(){return bsize;}
+  public void init(int mode, byte[] key, byte[] iv) throws Exception{
+    String pad="NoPadding";      
+    byte[] tmp;
+    if(iv.length>ivsize){
+      tmp=new byte[ivsize];
+      System.arraycopy(iv, 0, tmp, 0, tmp.length);
+      iv=tmp;
+    }
+    if(key.length>bsize){
+      tmp=new byte[bsize];
+      System.arraycopy(key, 0, tmp, 0, tmp.length);
+      key=tmp;
+    }
+    try{
+      SecretKeySpec keyspec=new SecretKeySpec(key, "AES");
+      cipher=javax.crypto.Cipher.getInstance("AES/CBC/"+pad);
+      cipher.init((mode==ENCRYPT_MODE?
+                   javax.crypto.Cipher.ENCRYPT_MODE:
+                   javax.crypto.Cipher.DECRYPT_MODE),
+                  keyspec, new IvParameterSpec(iv));
+    }
+    catch(Exception e){
+      cipher=null;
+      throw e;
+    }
+  }
+  public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception{
+    cipher.update(foo, s1, len, bar, s2);
+  }
+  public boolean isCBC(){return true; }
+}
diff --git a/java/com/jcraft/jsch/jce/AES256CTR.java b/java/com/jcraft/jsch/jce/AES256CTR.java
new file mode 100644
index 0000000..b7472e9
--- /dev/null
+++ b/java/com/jcraft/jsch/jce/AES256CTR.java
@@ -0,0 +1,71 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2008-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch.jce;
+
+import com.jcraft.jsch.Cipher;
+import javax.crypto.spec.*;
+
+public class AES256CTR implements Cipher{
+  private static final int ivsize=16;
+  private static final int bsize=32;
+  private javax.crypto.Cipher cipher;    
+  public int getIVSize(){return ivsize;} 
+  public int getBlockSize(){return bsize;}
+  public void init(int mode, byte[] key, byte[] iv) throws Exception{
+    String pad="NoPadding";      
+    byte[] tmp;
+    if(iv.length>ivsize){
+      tmp=new byte[ivsize];
+      System.arraycopy(iv, 0, tmp, 0, tmp.length);
+      iv=tmp;
+    }
+    if(key.length>bsize){
+      tmp=new byte[bsize];
+      System.arraycopy(key, 0, tmp, 0, tmp.length);
+      key=tmp;
+    }
+    try{
+      SecretKeySpec keyspec=new SecretKeySpec(key, "AES");
+      cipher=javax.crypto.Cipher.getInstance("AES/CTR/"+pad);
+      cipher.init((mode==ENCRYPT_MODE?
+                   javax.crypto.Cipher.ENCRYPT_MODE:
+                   javax.crypto.Cipher.DECRYPT_MODE),
+                  keyspec, new IvParameterSpec(iv));
+    }
+    catch(Exception e){
+      cipher=null;
+      throw e;
+    }
+  }
+  public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception{
+    cipher.update(foo, s1, len, bar, s2);
+  }
+  public boolean isCBC(){return false; }
+}
diff --git a/java/com/jcraft/jsch/jce/ARCFOUR.java b/java/com/jcraft/jsch/jce/ARCFOUR.java
new file mode 100644
index 0000000..9f6537c
--- /dev/null
+++ b/java/com/jcraft/jsch/jce/ARCFOUR.java
@@ -0,0 +1,68 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2008-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch.jce;
+
+import com.jcraft.jsch.Cipher;
+import javax.crypto.*;
+import javax.crypto.spec.*;
+
+public class ARCFOUR implements Cipher{
+  private static final int ivsize=8;
+  private static final int bsize=16;
+  private javax.crypto.Cipher cipher;    
+  public int getIVSize(){return ivsize;} 
+  public int getBlockSize(){return bsize;}
+  public void init(int mode, byte[] key, byte[] iv) throws Exception{
+    String pad="NoPadding";      
+    byte[] tmp;
+    if(key.length>bsize){
+      tmp=new byte[bsize];
+      System.arraycopy(key, 0, tmp, 0, tmp.length);
+      key=tmp;
+    }
+
+    try{
+      cipher=javax.crypto.Cipher.getInstance("RC4");
+      SecretKeySpec _key = new SecretKeySpec(key, "RC4");
+      cipher.init((mode==ENCRYPT_MODE?
+		   javax.crypto.Cipher.ENCRYPT_MODE:
+		   javax.crypto.Cipher.DECRYPT_MODE),
+		  _key);
+    }
+    catch(Exception e){
+      cipher=null;
+      throw e;
+    }
+  }
+  public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception{
+    cipher.update(foo, s1, len, bar, s2);
+  }
+  public boolean isCBC(){return false; }
+}
diff --git a/java/com/jcraft/jsch/jce/ARCFOUR128.java b/java/com/jcraft/jsch/jce/ARCFOUR128.java
new file mode 100644
index 0000000..d8b4613
--- /dev/null
+++ b/java/com/jcraft/jsch/jce/ARCFOUR128.java
@@ -0,0 +1,71 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2008-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch.jce;
+
+import com.jcraft.jsch.Cipher;
+import javax.crypto.*;
+import javax.crypto.spec.*;
+
+public class ARCFOUR128 implements Cipher{
+  private static final int ivsize=8;
+  private static final int bsize=16;
+  private static final int skip=1536; 
+  private javax.crypto.Cipher cipher;    
+  public int getIVSize(){return ivsize;} 
+  public int getBlockSize(){return bsize;}
+  public void init(int mode, byte[] key, byte[] iv) throws Exception{
+    byte[] tmp;
+    if(key.length>bsize){
+      tmp=new byte[bsize];
+      System.arraycopy(key, 0, tmp, 0, tmp.length);
+      key=tmp;
+    }
+    try{
+      cipher=javax.crypto.Cipher.getInstance("RC4");
+      SecretKeySpec _key = new SecretKeySpec(key, "RC4");
+      cipher.init((mode==ENCRYPT_MODE?
+		   javax.crypto.Cipher.ENCRYPT_MODE:
+		   javax.crypto.Cipher.DECRYPT_MODE),
+		  _key);
+      byte[] foo=new byte[1];
+      for(int i=0; i<skip; i++){
+        cipher.update(foo, 0, 1, foo, 0);
+      }
+    }
+    catch(Exception e){
+      cipher=null;
+      throw e;
+    }
+  }
+  public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception{
+    cipher.update(foo, s1, len, bar, s2);
+  }
+  public boolean isCBC(){return false; }
+}
diff --git a/java/com/jcraft/jsch/jce/ARCFOUR256.java b/java/com/jcraft/jsch/jce/ARCFOUR256.java
new file mode 100644
index 0000000..a4a9f69
--- /dev/null
+++ b/java/com/jcraft/jsch/jce/ARCFOUR256.java
@@ -0,0 +1,71 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2008-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch.jce;
+
+import com.jcraft.jsch.Cipher;
+import javax.crypto.*;
+import javax.crypto.spec.*;
+
+public class ARCFOUR256 implements Cipher{
+  private static final int ivsize=8;
+  private static final int bsize=32;
+  private static final int skip=1536; 
+  private javax.crypto.Cipher cipher;    
+  public int getIVSize(){return ivsize;} 
+  public int getBlockSize(){return bsize;}
+  public void init(int mode, byte[] key, byte[] iv) throws Exception{
+    byte[] tmp;
+    if(key.length>bsize){
+      tmp=new byte[bsize];
+      System.arraycopy(key, 0, tmp, 0, tmp.length);
+      key=tmp;
+    }
+    try{
+      cipher=javax.crypto.Cipher.getInstance("RC4");
+      SecretKeySpec _key = new SecretKeySpec(key, "RC4");
+      cipher.init((mode==ENCRYPT_MODE?
+		   javax.crypto.Cipher.ENCRYPT_MODE:
+		   javax.crypto.Cipher.DECRYPT_MODE),
+		  _key);
+      byte[] foo=new byte[1];
+      for(int i=0; i<skip; i++){
+        cipher.update(foo, 0, 1, foo, 0);
+      }
+    }
+    catch(Exception e){
+      cipher=null;
+      throw e;
+    }
+  }
+  public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception{
+    cipher.update(foo, s1, len, bar, s2);
+  }
+  public boolean isCBC(){return false; }
+}
diff --git a/java/com/jcraft/jsch/jce/BlowfishCBC.java b/java/com/jcraft/jsch/jce/BlowfishCBC.java
new file mode 100644
index 0000000..3853ab7
--- /dev/null
+++ b/java/com/jcraft/jsch/jce/BlowfishCBC.java
@@ -0,0 +1,71 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch.jce;
+
+import com.jcraft.jsch.Cipher;
+import javax.crypto.spec.*;
+
+public class BlowfishCBC implements Cipher{
+  private static final int ivsize=8;
+  private static final int bsize=16;
+  private javax.crypto.Cipher cipher;    
+  public int getIVSize(){return ivsize;} 
+  public int getBlockSize(){return bsize;}
+  public void init(int mode, byte[] key, byte[] iv) throws Exception{
+    String pad="NoPadding";      
+//  if(padding) pad="PKCS5Padding";
+    byte[] tmp;
+    if(iv.length>ivsize){
+      tmp=new byte[ivsize];
+      System.arraycopy(iv, 0, tmp, 0, tmp.length);
+      iv=tmp;
+    }
+    if(key.length>bsize){
+      tmp=new byte[bsize];
+      System.arraycopy(key, 0, tmp, 0, tmp.length);
+      key=tmp;
+    }
+    try{
+      SecretKeySpec skeySpec = new SecretKeySpec(key, "Blowfish");
+      cipher=javax.crypto.Cipher.getInstance("Blowfish/CBC/"+pad);
+      cipher.init((mode==ENCRYPT_MODE?
+		   javax.crypto.Cipher.ENCRYPT_MODE:
+		   javax.crypto.Cipher.DECRYPT_MODE),
+		  skeySpec, new IvParameterSpec(iv));
+    }
+    catch(Exception e){
+      throw e;
+    }
+  }
+  public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception{
+    cipher.update(foo, s1, len, bar, s2);
+  }
+  public boolean isCBC(){return true; }
+}
diff --git a/java/com/jcraft/jsch/jce/DH.java b/java/com/jcraft/jsch/jce/DH.java
new file mode 100644
index 0000000..da03c1d
--- /dev/null
+++ b/java/com/jcraft/jsch/jce/DH.java
@@ -0,0 +1,91 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch.jce;
+
+import java.math.BigInteger;
+import java.security.*;
+import javax.crypto.*;
+import javax.crypto.spec.*;
+
+public class DH implements com.jcraft.jsch.DH{
+  BigInteger p;
+  BigInteger g;
+  BigInteger e;  // my public key
+  byte[] e_array;
+  BigInteger f;  // your public key
+  BigInteger K;  // shared secret key
+  byte[] K_array;
+
+  private KeyPairGenerator myKpairGen;
+  private KeyAgreement myKeyAgree;
+  public void init() throws Exception{
+    myKpairGen=KeyPairGenerator.getInstance("DH");
+//    myKpairGen=KeyPairGenerator.getInstance("DiffieHellman");
+    myKeyAgree=KeyAgreement.getInstance("DH");
+//    myKeyAgree=KeyAgreement.getInstance("DiffieHellman");
+  }
+  public byte[] getE() throws Exception{
+    if(e==null){
+      DHParameterSpec dhSkipParamSpec=new DHParameterSpec(p, g);
+      myKpairGen.initialize(dhSkipParamSpec);
+      KeyPair myKpair=myKpairGen.generateKeyPair();
+      myKeyAgree.init(myKpair.getPrivate());
+//    BigInteger x=((javax.crypto.interfaces.DHPrivateKey)(myKpair.getPrivate())).getX();
+      byte[] myPubKeyEnc=myKpair.getPublic().getEncoded();
+      e=((javax.crypto.interfaces.DHPublicKey)(myKpair.getPublic())).getY();
+      e_array=e.toByteArray();
+    }
+    return e_array;
+  }
+  public byte[] getK() throws Exception{
+    if(K==null){
+      KeyFactory myKeyFac=KeyFactory.getInstance("DH");
+      DHPublicKeySpec keySpec=new DHPublicKeySpec(f, p, g);
+      PublicKey yourPubKey=myKeyFac.generatePublic(keySpec);
+      myKeyAgree.doPhase(yourPubKey, true);
+      byte[] mySharedSecret=myKeyAgree.generateSecret();
+      K=new BigInteger(mySharedSecret);
+      K_array=K.toByteArray();
+
+//System.err.println("K.signum(): "+K.signum()+
+//		   " "+Integer.toHexString(mySharedSecret[0]&0xff)+
+//		   " "+Integer.toHexString(K_array[0]&0xff));
+
+      K_array=mySharedSecret;
+    }
+    return K_array;
+  }
+  public void setP(byte[] p){ setP(new BigInteger(p)); }
+  public void setG(byte[] g){ setG(new BigInteger(g)); }
+  public void setF(byte[] f){ setF(new BigInteger(f)); }
+  void setP(BigInteger p){this.p=p;}
+  void setG(BigInteger g){this.g=g;}
+  void setF(BigInteger f){this.f=f;}
+}
diff --git a/java/com/jcraft/jsch/jce/HMACMD5.java b/java/com/jcraft/jsch/jce/HMACMD5.java
new file mode 100644
index 0000000..def3747
--- /dev/null
+++ b/java/com/jcraft/jsch/jce/HMACMD5.java
@@ -0,0 +1,75 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch.jce;
+
+import com.jcraft.jsch.MAC;
+import javax.crypto.*;
+import javax.crypto.spec.*;
+
+public class HMACMD5 implements MAC{
+  private static final String name="hmac-md5";
+  private static final int BSIZE=16;
+  private Mac mac;
+  public int getBlockSize(){return BSIZE;};
+  public void init(byte[] key) throws Exception{
+    if(key.length>BSIZE){
+      byte[] tmp=new byte[BSIZE];
+      System.arraycopy(key, 0, tmp, 0, BSIZE);	  
+      key=tmp;
+    }
+
+    SecretKeySpec skey=new SecretKeySpec(key, "HmacMD5");
+    mac=Mac.getInstance("HmacMD5");
+    mac.init(skey);
+  } 
+
+  private final byte[] tmp=new byte[4];
+  public void update(int i){
+    tmp[0]=(byte)(i>>>24);
+    tmp[1]=(byte)(i>>>16);
+    tmp[2]=(byte)(i>>>8);
+    tmp[3]=(byte)i;
+    update(tmp, 0, 4);
+  }
+  public void update(byte foo[], int s, int l){
+    mac.update(foo, s, l);      
+  }
+  public void doFinal(byte[] buf, int offset){
+    try{
+      mac.doFinal(buf, offset);
+    }
+    catch(ShortBufferException e){
+    }
+  }
+
+  public String getName(){
+    return name;
+  }
+}
diff --git a/java/com/jcraft/jsch/jce/HMACMD596.java b/java/com/jcraft/jsch/jce/HMACMD596.java
new file mode 100644
index 0000000..a296a5d
--- /dev/null
+++ b/java/com/jcraft/jsch/jce/HMACMD596.java
@@ -0,0 +1,77 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch.jce;
+
+import com.jcraft.jsch.MAC;
+import javax.crypto.*;
+import javax.crypto.spec.*;
+
+public class HMACMD596 implements MAC{
+  private static final String name="hmac-md5-96";
+  private static final int bsize=12;
+  private Mac mac;
+  public int getBlockSize(){return bsize;};
+  public void init(byte[] key) throws Exception{
+    if(key.length>16){
+      byte[] tmp=new byte[16];
+      System.arraycopy(key, 0, tmp, 0, 16);	  
+      key=tmp;
+    }
+    SecretKeySpec skey=new SecretKeySpec(key, "HmacMD5");
+    mac=Mac.getInstance("HmacMD5");
+    mac.init(skey);
+  } 
+  private final byte[] tmp=new byte[4];
+  public void update(int i){
+    tmp[0]=(byte)(i>>>24);
+    tmp[1]=(byte)(i>>>16);
+    tmp[2]=(byte)(i>>>8);
+    tmp[3]=(byte)i;
+    update(tmp, 0, 4);
+  }
+
+  public void update(byte foo[], int s, int l){
+    mac.update(foo, s, l);      
+  }
+
+  private final byte[] _buf16=new byte[16];
+  public void doFinal(byte[] buf, int offset){
+    try{
+      mac.doFinal(_buf16, 0);
+    }
+    catch(ShortBufferException e){
+    }
+    System.arraycopy(_buf16, 0, buf, offset, 12);
+  }
+
+  public String getName(){
+    return name;
+  }
+}
diff --git a/java/com/jcraft/jsch/jce/HMACSHA1.java b/java/com/jcraft/jsch/jce/HMACSHA1.java
new file mode 100644
index 0000000..13feaab
--- /dev/null
+++ b/java/com/jcraft/jsch/jce/HMACSHA1.java
@@ -0,0 +1,75 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch.jce;
+
+import com.jcraft.jsch.MAC;
+import javax.crypto.*;
+import javax.crypto.spec.*;
+
+public class HMACSHA1 implements MAC{
+  private static final String name="hmac-sha1";
+  private static final int bsize=20;
+  private Mac mac;
+  public int getBlockSize(){return bsize;};
+  public void init(byte[] key) throws Exception{
+    if(key.length>bsize){
+      byte[] tmp=new byte[bsize];
+      System.arraycopy(key, 0, tmp, 0, bsize);	  
+      key=tmp;
+    }
+    SecretKeySpec skey=new SecretKeySpec(key, "HmacSHA1");
+    mac=Mac.getInstance("HmacSHA1");
+    mac.init(skey);
+  } 
+  private final byte[] tmp=new byte[4];
+  public void update(int i){
+    tmp[0]=(byte)(i>>>24);
+    tmp[1]=(byte)(i>>>16);
+    tmp[2]=(byte)(i>>>8);
+    tmp[3]=(byte)i;
+    update(tmp, 0, 4);
+  }
+
+  public void update(byte foo[], int s, int l){
+    mac.update(foo, s, l);      
+  }
+
+  public void doFinal(byte[] buf, int offset){
+    try{
+      mac.doFinal(buf, offset);
+    }
+    catch(ShortBufferException e){
+    }
+  }
+
+  public String getName(){
+    return name;
+  }
+}
diff --git a/java/com/jcraft/jsch/jce/HMACSHA196.java b/java/com/jcraft/jsch/jce/HMACSHA196.java
new file mode 100644
index 0000000..e879176
--- /dev/null
+++ b/java/com/jcraft/jsch/jce/HMACSHA196.java
@@ -0,0 +1,76 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch.jce;
+
+import com.jcraft.jsch.MAC;
+import javax.crypto.*;
+import javax.crypto.spec.*;
+
+public class HMACSHA196 implements MAC{
+  private static final String name="hmac-sha1-96";
+  private static final int bsize=12;
+  private Mac mac;
+  public int getBlockSize(){return bsize;};
+  public void init(byte[] key) throws Exception{
+    if(key.length>20){
+      byte[] tmp=new byte[20];
+      System.arraycopy(key, 0, tmp, 0, 20);	  
+      key=tmp;
+    }
+    SecretKeySpec skey=new SecretKeySpec(key, "HmacSHA1");
+    mac=Mac.getInstance("HmacSHA1");
+    mac.init(skey);
+  } 
+  private final byte[] tmp=new byte[4];
+  public void update(int i){
+    tmp[0]=(byte)(i>>>24);
+    tmp[1]=(byte)(i>>>16);
+    tmp[2]=(byte)(i>>>8);
+    tmp[3]=(byte)i;
+    update(tmp, 0, 4);
+  }
+  public void update(byte foo[], int s, int l){
+    mac.update(foo, s, l);      
+  }
+
+  private final byte[] _buf20=new byte[20];
+  public void doFinal(byte[] buf, int offset){
+    try{
+      mac.doFinal(_buf20, 0);
+    }
+    catch(ShortBufferException e){
+    }
+    System.arraycopy(_buf20, 0, buf, offset, 12);
+  }
+
+  public String getName(){
+    return name;
+  }
+}
diff --git a/java/com/jcraft/jsch/jce/KeyPairGenDSA.java b/java/com/jcraft/jsch/jce/KeyPairGenDSA.java
new file mode 100644
index 0000000..67ad54e
--- /dev/null
+++ b/java/com/jcraft/jsch/jce/KeyPairGenDSA.java
@@ -0,0 +1,62 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch.jce;
+
+import java.security.*;
+import java.security.interfaces.*;
+
+public class KeyPairGenDSA implements com.jcraft.jsch.KeyPairGenDSA{
+  byte[] x;  // private
+  byte[] y;  // public
+  byte[] p;
+  byte[] q;
+  byte[] g;
+
+  public void init(int key_size) throws Exception{
+    KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA");
+    keyGen.initialize(key_size, new SecureRandom());
+    KeyPair pair = keyGen.generateKeyPair();
+    PublicKey pubKey=pair.getPublic();
+    PrivateKey prvKey=pair.getPrivate();
+
+    x=((DSAPrivateKey)prvKey).getX().toByteArray();
+    y=((DSAPublicKey)pubKey).getY().toByteArray();
+
+    DSAParams params=((DSAKey)prvKey).getParams();
+    p=params.getP().toByteArray();
+    q=params.getQ().toByteArray();
+    g=params.getG().toByteArray();
+  }
+  public byte[] getX(){return x;}
+  public byte[] getY(){return y;}
+  public byte[] getP(){return p;}
+  public byte[] getQ(){return q;}
+  public byte[] getG(){return g;}
+}
diff --git a/java/com/jcraft/jsch/jce/KeyPairGenRSA.java b/java/com/jcraft/jsch/jce/KeyPairGenRSA.java
new file mode 100644
index 0000000..543f0f7
--- /dev/null
+++ b/java/com/jcraft/jsch/jce/KeyPairGenRSA.java
@@ -0,0 +1,72 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch.jce;
+
+import java.security.*;
+import java.security.interfaces.*;
+
+public class KeyPairGenRSA implements com.jcraft.jsch.KeyPairGenRSA{
+  byte[] d;  // private
+  byte[] e;  // public
+  byte[] n;
+
+  byte[] c; //  coefficient
+  byte[] ep; // exponent p
+  byte[] eq; // exponent q
+  byte[] p;  // prime p
+  byte[] q;  // prime q
+
+  public void init(int key_size) throws Exception{
+    KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
+    keyGen.initialize(key_size, new SecureRandom());
+    KeyPair pair = keyGen.generateKeyPair();
+
+    PublicKey pubKey=pair.getPublic();
+    PrivateKey prvKey=pair.getPrivate();
+
+    d=((RSAPrivateKey)prvKey).getPrivateExponent().toByteArray();
+    e=((RSAPublicKey)pubKey).getPublicExponent().toByteArray();
+    n=((RSAPrivateKey)prvKey).getModulus().toByteArray();
+
+    c=((RSAPrivateCrtKey)prvKey).getCrtCoefficient().toByteArray();
+    ep=((RSAPrivateCrtKey)prvKey).getPrimeExponentP().toByteArray();
+    eq=((RSAPrivateCrtKey)prvKey).getPrimeExponentQ().toByteArray();
+    p=((RSAPrivateCrtKey)prvKey).getPrimeP().toByteArray();
+    q=((RSAPrivateCrtKey)prvKey).getPrimeQ().toByteArray();
+  }
+  public byte[] getD(){return d;}
+  public byte[] getE(){return e;}
+  public byte[] getN(){return n;}
+  public byte[] getC(){return c;}
+  public byte[] getEP(){return ep;}
+  public byte[] getEQ(){return eq;}
+  public byte[] getP(){return p;}
+  public byte[] getQ(){return q;}
+}
diff --git a/java/com/jcraft/jsch/jce/MD5.java b/java/com/jcraft/jsch/jce/MD5.java
new file mode 100644
index 0000000..538ae34
--- /dev/null
+++ b/java/com/jcraft/jsch/jce/MD5.java
@@ -0,0 +1,51 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch.jce;
+
+import com.jcraft.jsch.HASH;
+
+import java.security.*;
+
+public class MD5 implements HASH{
+  MessageDigest md;
+  public int getBlockSize(){return 16;}
+  public void init() throws Exception{
+    try{ md=MessageDigest.getInstance("MD5"); }
+    catch(Exception e){
+      System.err.println(e);
+    }
+  }
+  public void update(byte[] foo, int start, int len) throws Exception{
+    md.update(foo, start, len);
+  }
+  public byte[] digest() throws Exception{
+    return md.digest();
+  }
+}
diff --git a/java/com/jcraft/jsch/jce/Random.java b/java/com/jcraft/jsch/jce/Random.java
new file mode 100644
index 0000000..8668a01
--- /dev/null
+++ b/java/com/jcraft/jsch/jce/Random.java
@@ -0,0 +1,81 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch.jce;
+
+import java.security.SecureRandom;
+
+public class Random implements com.jcraft.jsch.Random{
+  private byte[] tmp=new byte[16];
+  private SecureRandom random=null;
+  public Random(){
+
+    // We hope that 'new SecureRandom()' will use NativePRNG algorithm
+    // on Sun's Java5 for GNU/Linux and Solaris.
+    // It seems NativePRNG refers to /dev/urandom and it must not be blocked,
+    // but NativePRNG is slower than SHA1PRNG ;-<
+    // TIPS: By adding option '-Djava.security.egd=file:/dev/./urandom'
+    //       SHA1PRNG will be used instead of NativePRNG.
+    // On MacOSX, 'new SecureRandom()' will use NativePRNG algorithm and
+    // it is also slower than SHA1PRNG.
+    // On Windows, 'new SecureRandom()' will use SHA1PRNG algorithm.
+    random=new SecureRandom();
+
+    /*
+    try{ 
+      random=SecureRandom.getInstance("SHA1PRNG"); 
+      return;
+    }
+    catch(java.security.NoSuchAlgorithmException e){ 
+      // System.err.println(e); 
+    }
+
+    // The following code is for IBM's JCE
+    try{ 
+      random=SecureRandom.getInstance("IBMSecureRandom"); 
+      return;
+    }
+    catch(java.security.NoSuchAlgorithmException ee){ 
+      //System.err.println(ee); 
+    }
+    */
+  }
+  public void fill(byte[] foo, int start, int len){
+    /*
+    // This case will not become true in our usage.
+    if(start==0 && foo.length==len){
+      random.nextBytes(foo);
+      return;
+    }
+    */
+    if(len>tmp.length){ tmp=new byte[len]; }
+    random.nextBytes(tmp);
+    System.arraycopy(tmp, 0, foo, start, len);
+  }
+}
diff --git a/java/com/jcraft/jsch/jce/SHA1.java b/java/com/jcraft/jsch/jce/SHA1.java
new file mode 100644
index 0000000..08fce4b
--- /dev/null
+++ b/java/com/jcraft/jsch/jce/SHA1.java
@@ -0,0 +1,51 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch.jce;
+
+import com.jcraft.jsch.HASH;
+
+import java.security.*;
+
+public class SHA1 implements HASH{
+  MessageDigest md;
+  public int getBlockSize(){return 20;}
+  public void init() throws Exception{
+    try{ md=MessageDigest.getInstance("SHA-1"); }
+    catch(Exception e){
+      System.err.println(e);
+    }
+  }
+  public void update(byte[] foo, int start, int len) throws Exception{
+    md.update(foo, start, len);
+  }
+  public byte[] digest() throws Exception{
+    return md.digest();
+  }
+}
diff --git a/java/com/jcraft/jsch/jce/SignatureDSA.java b/java/com/jcraft/jsch/jce/SignatureDSA.java
new file mode 100644
index 0000000..262dfc5
--- /dev/null
+++ b/java/com/jcraft/jsch/jce/SignatureDSA.java
@@ -0,0 +1,147 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch.jce;
+
+import java.math.BigInteger;
+import java.security.*;
+import java.security.spec.*;
+
+public class SignatureDSA implements com.jcraft.jsch.SignatureDSA{
+
+  java.security.Signature signature;
+  KeyFactory keyFactory;
+
+  public void init() throws Exception{
+    signature=java.security.Signature.getInstance("SHA1withDSA");
+    keyFactory=KeyFactory.getInstance("DSA");
+  }     
+  public void setPubKey(byte[] y, byte[] p, byte[] q, byte[] g) throws Exception{
+    DSAPublicKeySpec dsaPubKeySpec = 
+	new DSAPublicKeySpec(new BigInteger(y),
+			     new BigInteger(p),
+			     new BigInteger(q),
+			     new BigInteger(g));
+    PublicKey pubKey=keyFactory.generatePublic(dsaPubKeySpec);
+    signature.initVerify(pubKey);
+  }
+  public void setPrvKey(byte[] x, byte[] p, byte[] q, byte[] g) throws Exception{
+    DSAPrivateKeySpec dsaPrivKeySpec = 
+	new DSAPrivateKeySpec(new BigInteger(x),
+			      new BigInteger(p),
+			      new BigInteger(q),
+			      new BigInteger(g));
+    PrivateKey prvKey = keyFactory.generatePrivate(dsaPrivKeySpec);
+    signature.initSign(prvKey);
+  }
+  public byte[] sign() throws Exception{
+    byte[] sig=signature.sign();      
+/*
+System.err.print("sign["+sig.length+"] ");
+for(int i=0; i<sig.length;i++){
+System.err.print(Integer.toHexString(sig[i]&0xff)+":");
+}
+System.err.println("");
+*/
+    // sig is in ASN.1
+    // SEQUENCE::={ r INTEGER, s INTEGER }
+    int len=0;	
+    int index=3;
+    len=sig[index++]&0xff;
+//System.err.println("! len="+len);
+    byte[] r=new byte[len];
+    System.arraycopy(sig, index, r, 0, r.length);
+    index=index+len+1;
+    len=sig[index++]&0xff;
+//System.err.println("!! len="+len);
+    byte[] s=new byte[len];
+    System.arraycopy(sig, index, s, 0, s.length);
+
+    byte[] result=new byte[40];
+
+    // result must be 40 bytes, but length of r and s may not be 20 bytes  
+
+    System.arraycopy(r, (r.length>20)?1:0,
+		     result, (r.length>20)?0:20-r.length,
+		     (r.length>20)?20:r.length);
+    System.arraycopy(s, (s.length>20)?1:0,
+		     result, (s.length>20)?20:40-s.length,
+		     (s.length>20)?20:s.length);
+ 
+//  System.arraycopy(sig, (sig[3]==20?4:5), result, 0, 20);
+//  System.arraycopy(sig, sig.length-20, result, 20, 20);
+
+    return result;
+  }
+  public void update(byte[] foo) throws Exception{
+   signature.update(foo);
+  }
+  public boolean verify(byte[] sig) throws Exception{
+    int i=0;
+    int j=0;
+    byte[] tmp;
+
+    if(sig[0]==0 && sig[1]==0 && sig[2]==0){
+    j=((sig[i++]<<24)&0xff000000)|((sig[i++]<<16)&0x00ff0000)|
+	((sig[i++]<<8)&0x0000ff00)|((sig[i++])&0x000000ff);
+    i+=j;
+    j=((sig[i++]<<24)&0xff000000)|((sig[i++]<<16)&0x00ff0000)|
+	((sig[i++]<<8)&0x0000ff00)|((sig[i++])&0x000000ff);
+    tmp=new byte[j]; 
+    System.arraycopy(sig, i, tmp, 0, j); sig=tmp;
+    }
+
+    // ASN.1
+    int frst=((sig[0]&0x80)!=0?1:0);
+    int scnd=((sig[20]&0x80)!=0?1:0);
+    //System.err.println("frst: "+frst+", scnd: "+scnd);
+
+    int length=sig.length+6+frst+scnd;
+    tmp=new byte[length];
+    tmp[0]=(byte)0x30; tmp[1]=(byte)0x2c; 
+    tmp[1]+=frst; tmp[1]+=scnd;
+    tmp[2]=(byte)0x02; tmp[3]=(byte)0x14;
+    tmp[3]+=frst;
+    System.arraycopy(sig, 0, tmp, 4+frst, 20);
+    tmp[4+tmp[3]]=(byte)0x02; tmp[5+tmp[3]]=(byte)0x14;
+    tmp[5+tmp[3]]+=scnd;
+    System.arraycopy(sig, 20, tmp, 6+tmp[3]+scnd, 20);
+    sig=tmp;
+
+/*
+    tmp=new byte[sig.length+6];
+    tmp[0]=(byte)0x30; tmp[1]=(byte)0x2c; 
+    tmp[2]=(byte)0x02; tmp[3]=(byte)0x14;
+    System.arraycopy(sig, 0, tmp, 4, 20);
+    tmp[24]=(byte)0x02; tmp[25]=(byte)0x14;
+    System.arraycopy(sig, 20, tmp, 26, 20); sig=tmp;
+*/  
+    return signature.verify(sig);
+  }
+}
diff --git a/java/com/jcraft/jsch/jce/SignatureRSA.java b/java/com/jcraft/jsch/jce/SignatureRSA.java
new file mode 100644
index 0000000..50d8b5a
--- /dev/null
+++ b/java/com/jcraft/jsch/jce/SignatureRSA.java
@@ -0,0 +1,83 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch.jce;
+
+import java.math.BigInteger;
+import java.security.*;
+import java.security.spec.*;
+
+public class SignatureRSA implements com.jcraft.jsch.SignatureRSA{
+
+  java.security.Signature signature;
+  KeyFactory keyFactory;
+
+  public void init() throws Exception{
+    signature=java.security.Signature.getInstance("SHA1withRSA");
+    keyFactory=KeyFactory.getInstance("RSA");
+  }     
+  public void setPubKey(byte[] e, byte[] n) throws Exception{
+    RSAPublicKeySpec rsaPubKeySpec = 
+	new RSAPublicKeySpec(new BigInteger(n),
+			     new BigInteger(e));
+    PublicKey pubKey=keyFactory.generatePublic(rsaPubKeySpec);
+    signature.initVerify(pubKey);
+  }
+  public void setPrvKey(byte[] d, byte[] n) throws Exception{
+    RSAPrivateKeySpec rsaPrivKeySpec = 
+	new RSAPrivateKeySpec(new BigInteger(n),
+			      new BigInteger(d));
+    PrivateKey prvKey = keyFactory.generatePrivate(rsaPrivKeySpec);
+    signature.initSign(prvKey);
+  }
+  public byte[] sign() throws Exception{
+    byte[] sig=signature.sign();      
+    return sig;
+  }
+  public void update(byte[] foo) throws Exception{
+   signature.update(foo);
+  }
+  public boolean verify(byte[] sig) throws Exception{
+    int i=0;
+    int j=0;
+    byte[] tmp;
+
+    if(sig[0]==0 && sig[1]==0 && sig[2]==0){
+    j=((sig[i++]<<24)&0xff000000)|((sig[i++]<<16)&0x00ff0000)|
+	((sig[i++]<<8)&0x0000ff00)|((sig[i++])&0x000000ff);
+    i+=j;
+    j=((sig[i++]<<24)&0xff000000)|((sig[i++]<<16)&0x00ff0000)|
+	((sig[i++]<<8)&0x0000ff00)|((sig[i++])&0x000000ff);
+    tmp=new byte[j]; 
+    System.arraycopy(sig, i, tmp, 0, j); sig=tmp;
+    }
+//System.err.println("j="+j+" "+Integer.toHexString(sig[0]&0xff));
+    return signature.verify(sig);
+  }
+}
diff --git a/java/com/jcraft/jsch/jce/TripleDESCBC.java b/java/com/jcraft/jsch/jce/TripleDESCBC.java
new file mode 100644
index 0000000..2cbf9b7
--- /dev/null
+++ b/java/com/jcraft/jsch/jce/TripleDESCBC.java
@@ -0,0 +1,84 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch.jce;
+
+import com.jcraft.jsch.Cipher;
+import javax.crypto.*;
+import javax.crypto.spec.*;
+
+public class TripleDESCBC implements Cipher{
+  private static final int ivsize=8;
+  private static final int bsize=24;
+  private javax.crypto.Cipher cipher;    
+  public int getIVSize(){return ivsize;} 
+  public int getBlockSize(){return bsize;}
+  public void init(int mode, byte[] key, byte[] iv) throws Exception{
+    String pad="NoPadding";      
+    //if(padding) pad="PKCS5Padding";
+    byte[] tmp;
+    if(iv.length>ivsize){
+      tmp=new byte[ivsize];
+      System.arraycopy(iv, 0, tmp, 0, tmp.length);
+      iv=tmp;
+    }
+    if(key.length>bsize){
+      tmp=new byte[bsize];
+      System.arraycopy(key, 0, tmp, 0, tmp.length);
+      key=tmp;
+    }
+
+    try{
+      cipher=javax.crypto.Cipher.getInstance("DESede/CBC/"+pad);
+/*
+      // The following code does not work on IBM's JDK 1.4.1
+      SecretKeySpec skeySpec = new SecretKeySpec(key, "DESede");
+      cipher.init((mode==ENCRYPT_MODE?
+		   javax.crypto.Cipher.ENCRYPT_MODE:
+		   javax.crypto.Cipher.DECRYPT_MODE),
+		  skeySpec, new IvParameterSpec(iv));
+*/
+      DESedeKeySpec keyspec=new DESedeKeySpec(key);
+      SecretKeyFactory keyfactory=SecretKeyFactory.getInstance("DESede");
+      SecretKey _key=keyfactory.generateSecret(keyspec);
+      cipher.init((mode==ENCRYPT_MODE?
+		   javax.crypto.Cipher.ENCRYPT_MODE:
+		   javax.crypto.Cipher.DECRYPT_MODE),
+		  _key, new IvParameterSpec(iv));
+    }
+    catch(Exception e){
+      cipher=null;
+      throw e;
+    }
+  }
+  public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception{
+    cipher.update(foo, s1, len, bar, s2);
+  }
+  public boolean isCBC(){return true; }
+}
diff --git a/java/com/jcraft/jsch/jce/TripleDESCTR.java b/java/com/jcraft/jsch/jce/TripleDESCTR.java
new file mode 100644
index 0000000..899f03b
--- /dev/null
+++ b/java/com/jcraft/jsch/jce/TripleDESCTR.java
@@ -0,0 +1,84 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2008-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch.jce;
+
+import com.jcraft.jsch.Cipher;
+import javax.crypto.*;
+import javax.crypto.spec.*;
+
+public class TripleDESCTR implements Cipher{
+  private static final int ivsize=8;
+  private static final int bsize=24;
+  private javax.crypto.Cipher cipher;    
+  public int getIVSize(){return ivsize;} 
+  public int getBlockSize(){return bsize;}
+  public void init(int mode, byte[] key, byte[] iv) throws Exception{
+    String pad="NoPadding";      
+    //if(padding) pad="PKCS5Padding";
+    byte[] tmp;
+    if(iv.length>ivsize){
+      tmp=new byte[ivsize];
+      System.arraycopy(iv, 0, tmp, 0, tmp.length);
+      iv=tmp;
+    }
+    if(key.length>bsize){
+      tmp=new byte[bsize];
+      System.arraycopy(key, 0, tmp, 0, tmp.length);
+      key=tmp;
+    }
+
+    try{
+      cipher=javax.crypto.Cipher.getInstance("DESede/CTR/"+pad);
+/*
+      // The following code does not work on IBM's JDK 1.4.1
+      SecretKeySpec skeySpec = new SecretKeySpec(key, "DESede");
+      cipher.init((mode==ENCRYPT_MODE?
+		   javax.crypto.Cipher.ENCRYPT_MODE:
+		   javax.crypto.Cipher.DECRYPT_MODE),
+		  skeySpec, new IvParameterSpec(iv));
+*/
+      DESedeKeySpec keyspec=new DESedeKeySpec(key);
+      SecretKeyFactory keyfactory=SecretKeyFactory.getInstance("DESede");
+      SecretKey _key=keyfactory.generateSecret(keyspec);
+      cipher.init((mode==ENCRYPT_MODE?
+		   javax.crypto.Cipher.ENCRYPT_MODE:
+		   javax.crypto.Cipher.DECRYPT_MODE),
+		  _key, new IvParameterSpec(iv));
+    }
+    catch(Exception e){
+      cipher=null;
+      throw e;
+    }
+  }
+  public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception{
+    cipher.update(foo, s1, len, bar, s2);
+  }
+  public boolean isCBC(){return false; }
+}
diff --git a/java/com/jcraft/jsch/jcraft/Compression.java b/java/com/jcraft/jsch/jcraft/Compression.java
new file mode 100644
index 0000000..dddcaed
--- /dev/null
+++ b/java/com/jcraft/jsch/jcraft/Compression.java
@@ -0,0 +1,140 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch.jcraft;
+import com.jcraft.jzlib.*;
+import com.jcraft.jsch.*;
+
+public class Compression implements com.jcraft.jsch.Compression {
+  static private final int BUF_SIZE=4096;
+  private final int buffer_margin=32+20; // AES256 + HMACSHA1
+  private int type;
+  private ZStream stream;
+  private byte[] tmpbuf=new byte[BUF_SIZE];
+
+  public Compression(){
+    stream=new ZStream();
+  }
+
+  public void init(int type, int level){
+    if(type==DEFLATER){
+      stream.deflateInit(level);
+      this.type=DEFLATER;
+    }
+    else if(type==INFLATER){
+      stream.inflateInit();
+      inflated_buf=new byte[BUF_SIZE];
+      this.type=INFLATER;
+    }
+  }
+
+  private byte[] inflated_buf;
+
+  public byte[] compress(byte[] buf, int start, int[] len){
+    stream.next_in=buf;
+    stream.next_in_index=start;
+    stream.avail_in=len[0]-start;
+    int status;
+    int outputlen=start;
+    byte[] outputbuf=buf;
+    int tmp=0;
+
+    do{
+      stream.next_out=tmpbuf;
+      stream.next_out_index=0;
+      stream.avail_out=BUF_SIZE;
+      status=stream.deflate(JZlib.Z_PARTIAL_FLUSH);
+      switch(status){
+        case JZlib.Z_OK:
+          tmp=BUF_SIZE-stream.avail_out;
+          if(outputbuf.length<outputlen+tmp+buffer_margin){
+            byte[] foo=new byte[(outputlen+tmp+buffer_margin)*2];
+            System.arraycopy(outputbuf, 0, foo, 0, outputbuf.length);
+            outputbuf=foo;
+          }
+          System.arraycopy(tmpbuf, 0, outputbuf, outputlen, tmp);
+          outputlen+=tmp;
+          break;
+        default:
+	    System.err.println("compress: deflate returnd "+status);
+      }
+    }
+    while(stream.avail_out==0);
+
+    len[0]=outputlen;
+    return outputbuf;
+  }
+
+  public byte[] uncompress(byte[] buffer, int start, int[] length){
+    int inflated_end=0;
+
+    stream.next_in=buffer;
+    stream.next_in_index=start;
+    stream.avail_in=length[0];
+
+    while(true){
+      stream.next_out=tmpbuf;
+      stream.next_out_index=0;
+      stream.avail_out=BUF_SIZE;
+      int status=stream.inflate(JZlib.Z_PARTIAL_FLUSH);
+      switch(status){
+        case JZlib.Z_OK:
+	  if(inflated_buf.length<inflated_end+BUF_SIZE-stream.avail_out){
+            int len=inflated_buf.length*2;
+            if(len<inflated_end+BUF_SIZE-stream.avail_out)
+              len=inflated_end+BUF_SIZE-stream.avail_out;
+            byte[] foo=new byte[len];
+	    System.arraycopy(inflated_buf, 0, foo, 0, inflated_end);
+	    inflated_buf=foo;
+	  }
+	  System.arraycopy(tmpbuf, 0,
+			   inflated_buf, inflated_end,
+			   BUF_SIZE-stream.avail_out);
+	  inflated_end+=(BUF_SIZE-stream.avail_out);
+          length[0]=inflated_end;
+	  break;
+        case JZlib.Z_BUF_ERROR:
+          if(inflated_end>buffer.length-start){
+            byte[] foo=new byte[inflated_end+start];
+            System.arraycopy(buffer, 0, foo, 0, start);
+            System.arraycopy(inflated_buf, 0, foo, start, inflated_end);
+	    buffer=foo;
+	  }
+	  else{
+            System.arraycopy(inflated_buf, 0, buffer, start, inflated_end);
+	  }
+          length[0]=inflated_end;
+	  return buffer;
+	default:
+	  System.err.println("uncompress: inflate returnd "+status);
+          return null;
+      }
+    }
+  }
+}
diff --git a/java/com/jcraft/jsch/jcraft/HMAC.java b/java/com/jcraft/jsch/jcraft/HMAC.java
new file mode 100644
index 0000000..9aedc27
--- /dev/null
+++ b/java/com/jcraft/jsch/jcraft/HMAC.java
@@ -0,0 +1,107 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2006-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch.jcraft;
+
+import java.security.*;
+
+class HMAC{
+
+  /*
+   * Refer to RFC2104.
+   *
+   * H(K XOR opad, H(K XOR ipad, text))
+   *
+   * where K is an n byte key
+   * ipad is the byte 0x36 repeated 64 times
+   * opad is the byte 0x5c repeated 64 times
+   * and text is the data being protected
+   */
+  private static final int B=64;
+  private byte[] k_ipad=null;
+  private byte[] k_opad=null;
+
+  private MessageDigest md=null;
+
+  private int bsize=0;
+
+  protected void setH(MessageDigest md){
+    this.md=md;
+    bsize=md.getDigestLength();
+  }
+
+  public int getBlockSize(){return bsize;};
+  public void init(byte[] key) throws Exception{
+    if(key.length>bsize){
+      byte[] tmp=new byte[bsize];
+      System.arraycopy(key, 0, tmp, 0, bsize);	  
+      key=tmp;
+    }
+
+    /* if key is longer than B bytes reset it to key=MD5(key) */
+    if(key.length>B){
+      md.update(key, 0, key.length);
+      key=md.digest();
+    }
+
+    k_ipad=new byte[B];
+    System.arraycopy(key, 0, k_ipad, 0, key.length);
+    k_opad=new byte[B];
+    System.arraycopy(key, 0, k_opad, 0, key.length);
+
+    /* XOR key with ipad and opad values */
+    for(int i=0; i<B; i++) {
+      k_ipad[i]^=(byte)0x36;
+      k_opad[i]^=(byte)0x5c;
+    }
+
+    md.update(k_ipad, 0, B);
+  }
+
+  private final byte[] tmp=new byte[4];
+  public void update(int i){
+    tmp[0]=(byte)(i>>>24);
+    tmp[1]=(byte)(i>>>16);
+    tmp[2]=(byte)(i>>>8);
+    tmp[3]=(byte)i;
+    update(tmp, 0, 4);
+  }
+
+  public void update(byte foo[], int s, int l){
+    md.update(foo, s, l);
+  }
+
+  public void doFinal(byte[] buf, int offset){
+    byte[] result=md.digest();
+    md.update(k_opad, 0, B);
+    md.update(result, 0, bsize);
+    try{md.digest(buf, offset, bsize);}catch(Exception e){}
+    md.update(k_ipad, 0, B);
+  }
+}
diff --git a/java/com/jcraft/jsch/jcraft/HMACMD5.java b/java/com/jcraft/jsch/jcraft/HMACMD5.java
new file mode 100644
index 0000000..9096011
--- /dev/null
+++ b/java/com/jcraft/jsch/jcraft/HMACMD5.java
@@ -0,0 +1,51 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2006-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch.jcraft;
+
+import com.jcraft.jsch.MAC;
+import java.security.*;
+
+public class HMACMD5 extends HMAC implements MAC{
+  private static final String name="hmac-md5";
+
+  public HMACMD5(){
+    super();
+    MessageDigest md=null;
+    try{ md=MessageDigest.getInstance("MD5"); }
+    catch(Exception e){
+      System.err.println(e);
+    }
+    setH(md);
+  }
+
+  public String getName(){
+    return name;
+  }
+}
diff --git a/java/com/jcraft/jsch/jcraft/HMACMD596.java b/java/com/jcraft/jsch/jcraft/HMACMD596.java
new file mode 100644
index 0000000..95c6f60
--- /dev/null
+++ b/java/com/jcraft/jsch/jcraft/HMACMD596.java
@@ -0,0 +1,50 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2006-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch.jcraft;
+
+import com.jcraft.jsch.MAC;
+
+public class HMACMD596 extends HMACMD5{
+
+  private static final String name="hmac-md5-96";
+  private static final int BSIZE=12;
+
+  public int getBlockSize(){return BSIZE;};
+
+  private final byte[] _buf16=new byte[16];
+  public void doFinal(byte[] buf, int offset){
+    super.doFinal(_buf16, 0);
+    System.arraycopy(_buf16, 0, buf, offset, BSIZE);
+  }
+
+  public String getName(){
+    return name;
+  }
+}
diff --git a/java/com/jcraft/jsch/jcraft/HMACSHA1.java b/java/com/jcraft/jsch/jcraft/HMACSHA1.java
new file mode 100644
index 0000000..ea9eccf
--- /dev/null
+++ b/java/com/jcraft/jsch/jcraft/HMACSHA1.java
@@ -0,0 +1,51 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2006-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch.jcraft;
+
+import com.jcraft.jsch.MAC;
+import java.security.*;
+
+public class HMACSHA1 extends HMAC implements MAC{
+  private static final String name="hmac-sha1";
+
+  public HMACSHA1(){
+    super();
+    MessageDigest md=null;
+    try{ md=MessageDigest.getInstance("SHA-1"); }
+    catch(Exception e){
+      System.err.println(e);
+    }
+    setH(md);
+  }
+
+  public String getName(){
+    return name;
+  }
+}
diff --git a/java/com/jcraft/jsch/jcraft/HMACSHA196.java b/java/com/jcraft/jsch/jcraft/HMACSHA196.java
new file mode 100644
index 0000000..86a81b5
--- /dev/null
+++ b/java/com/jcraft/jsch/jcraft/HMACSHA196.java
@@ -0,0 +1,50 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2006-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch.jcraft;
+
+import com.jcraft.jsch.MAC;
+
+public class HMACSHA196 extends HMACSHA1{
+
+  private static final String name="hmac-sha1-96";
+  private static final int BSIZE=12;
+
+  public int getBlockSize(){return BSIZE;};
+
+  private final byte[] _buf16=new byte[20];
+  public void doFinal(byte[] buf, int offset){
+    super.doFinal(_buf16, 0);
+    System.arraycopy(_buf16, 0, buf, offset, BSIZE);
+  }
+
+  public String getName(){
+    return name;
+  }
+}
diff --git a/java/com/jcraft/jsch/jgss/GSSContextKrb5.java b/java/com/jcraft/jsch/jgss/GSSContextKrb5.java
new file mode 100644
index 0000000..9ee1560
--- /dev/null
+++ b/java/com/jcraft/jsch/jgss/GSSContextKrb5.java
@@ -0,0 +1,177 @@
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/*
+Copyright (c) 2006-2012 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
+     the documentation and/or other materials provided with the distribution.
+
+  3. The names of the authors may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.jcraft.jsch.jgss;
+
+import com.jcraft.jsch.JSchException;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import org.ietf.jgss.GSSContext;
+import org.ietf.jgss.GSSCredential;
+import org.ietf.jgss.GSSException;
+import org.ietf.jgss.GSSManager;
+import org.ietf.jgss.GSSName;
+import org.ietf.jgss.MessageProp;
+import org.ietf.jgss.Oid;
+
+public class GSSContextKrb5 implements com.jcraft.jsch.GSSContext{
+
+  private static final String pUseSubjectCredsOnly = 
+    "javax.security.auth.useSubjectCredsOnly";
+  private static String useSubjectCredsOnly = 
+    getSystemProperty(pUseSubjectCredsOnly);
+
+  private GSSContext context=null;
+  public void create(String user, String host) throws JSchException{
+    try{
+      // RFC 1964
+      Oid krb5=new Oid("1.2.840.113554.1.2.2");
+      // Kerberos Principal Name Form
+      Oid principalName=new Oid("1.2.840.113554.1.2.2.1");
+
+      GSSManager mgr=GSSManager.getInstance();
+
+      GSSCredential crd=null;
+      /*
+      try{
+        GSSName _user=mgr.createName(user, principalName);
+        crd=mgr.createCredential(_user,
+                                 GSSCredential.DEFAULT_LIFETIME,
+                                 krb5,
+                                 GSSCredential.INITIATE_ONLY);
+      }
+      catch(GSSException crdex){
+      }
+      */
+
+      String cname=host;
+      try{
+        cname=InetAddress.getByName(cname).getCanonicalHostName();
+      }
+      catch(UnknownHostException e){
+      }
+      GSSName _host=mgr.createName("host/"+cname, principalName);
+
+      context=mgr.createContext(_host,
+                                krb5,
+                                crd,
+                                GSSContext.DEFAULT_LIFETIME);
+
+      // RFC4462  3.4.  GSS-API Session
+      //
+      // When calling GSS_Init_sec_context(), the client MUST set
+      // integ_req_flag to "true" to request that per-message integrity
+      // protection be supported for this context.  In addition,
+      // deleg_req_flag MAY be set to "true" to request access delegation, if
+      // requested by the user.
+      //
+      // Since the user authentication process by its nature authenticates
+      // only the client, the setting of mutual_req_flag is not needed for
+      // this process.  This flag SHOULD be set to "false".
+
+      // TODO: OpenSSH's sshd does accepts 'false' for mutual_req_flag
+      //context.requestMutualAuth(false);
+      context.requestMutualAuth(true);
+      context.requestConf(true);
+      context.requestInteg(true);             // for MIC
+      context.requestCredDeleg(true);
+      context.requestAnonymity(false);
+
+      return;
+    }
+    catch(GSSException ex){
+      throw new JSchException(ex.toString());
+    }
+  }
+
+  public boolean isEstablished(){
+    return context.isEstablished();
+  }
+
+  public byte[] init(byte[] token, int s, int l) throws JSchException {
+    try{
+      // Without setting "javax.security.auth.useSubjectCredsOnly" to "false",
+      // Sun's JVM for Un*x will show messages to stderr in
+      // processing context.initSecContext().
+      // This hack is not thread safe ;-<.
+      // If that property is explicitly given as "true" or "false",
+      // this hack must not be invoked.
+      if(useSubjectCredsOnly==null){
+        setSystemProperty(pUseSubjectCredsOnly, "false");
+      }
+      return context.initSecContext(token, 0, l);
+    }
+    catch(GSSException ex){
+      throw new JSchException(ex.toString());
+    }
+    catch(java.lang.SecurityException ex){
+      throw new JSchException(ex.toString());
+    }
+    finally{
+      if(useSubjectCredsOnly==null){
+        // By the default, it must be "true".
+        setSystemProperty(pUseSubjectCredsOnly, "true");
+      }
+    }
+  }
+
+  public byte[] getMIC(byte[] message, int s, int l){
+    try{
+      MessageProp prop =  new MessageProp(0, true);
+      return context.getMIC(message, s, l, prop);
+    }
+    catch(GSSException ex){
+      return null;
+    }
+  }
+
+  public void dispose(){
+    try{
+      context.dispose();
+    }
+    catch(GSSException ex){
+    }
+  }
+
+  private static String getSystemProperty(String key){
+    try{ return System.getProperty(key); }
+    catch(Exception e){ 
+      // We are not allowed to get the System properties.
+      return null; 
+    } 
+  }
+
+  private static void setSystemProperty(String key, String value){
+    try{ System.setProperty(key, value); }
+    catch(Exception e){ 
+      // We are not allowed to set the System properties.
+    }
+  }
+}
diff --git a/java/com/tigervnc/network/TcpListener.java b/java/com/tigervnc/network/TcpListener.java
index 4cc8c0d..cb0a69a 100644
--- a/java/com/tigervnc/network/TcpListener.java
+++ b/java/com/tigervnc/network/TcpListener.java
@@ -100,7 +100,7 @@
 
     // Accept an incoming connection
     try {
-      if (selector.select() > 0) {
+      if (selector.select(0) > 0) {
         Set keys = selector.selectedKeys();
         Iterator iter = keys.iterator();
         while (iter.hasNext()) {
diff --git a/java/com/tigervnc/network/TcpSocket.java b/java/com/tigervnc/network/TcpSocket.java
index 9277dd1..1d127f5 100644
--- a/java/com/tigervnc/network/TcpSocket.java
+++ b/java/com/tigervnc/network/TcpSocket.java
@@ -171,29 +171,23 @@
     return ((InetSocketAddress)((SocketDescriptor)getFd()).socket().getRemoteSocketAddress()).getPort();
   }
 
+  /* Tunnelling support. */
+  public static int findFreeTcpPort() {
+    java.net.ServerSocket sock;
+    int port;
+    try {
+      sock = new java.net.ServerSocket(0);
+      port = sock.getLocalPort();
+      sock.close();
+    } catch (java.io.IOException e) {
+      throw new SocketException("unable to create socket: "+e.toString());
+    }
+    return port;
+  }
+
   private boolean closeFd;
   static LogWriter vlog = new LogWriter("TcpSocket");
 
 }
 
-/* Tunnelling support. */
-/*
-public int findFreeTcpPort() {
-  int sock;
-
-  if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
-    throw SocketException("unable to create socket", errorNumber);
-
-  int port = 0;
-  if (bind (sock, (struct sockaddr *)&addr, sizeof (addr)) < 0)
-    throw SocketException("unable to find free port", errorNumber);
-
-  socklen_t n = sizeof(addr);
-  if (getsockname (sock, (struct sockaddr *)&addr, &n) < 0)
-    throw SocketException("unable to get port number", errorNumber);
-
-  closesocket(sock);
-  return ntohs(addr.sin_port);
-}
-*/
 
diff --git a/java/com/tigervnc/vncviewer/CConn.java b/java/com/tigervnc/vncviewer/CConn.java
index a87ddae..053bef2 100644
--- a/java/com/tigervnc/vncviewer/CConn.java
+++ b/java/com/tigervnc/vncviewer/CConn.java
@@ -314,7 +314,7 @@
       }
     }
     if (passwd != null)
-      passwd.append(dlg.passwdEntry.getText());
+      passwd.append(new String(dlg.passwdEntry.getPassword()));
     return true;
   }
 
diff --git a/java/com/tigervnc/vncviewer/PasswdDialog.java b/java/com/tigervnc/vncviewer/PasswdDialog.java
index d947828..51c268f 100644
--- a/java/com/tigervnc/vncviewer/PasswdDialog.java
+++ b/java/com/tigervnc/vncviewer/PasswdDialog.java
@@ -18,10 +18,14 @@
 
 package com.tigervnc.vncviewer;
 
+import java.awt.*;
 import java.awt.event.*;
 import javax.swing.*;
+import com.jcraft.jsch.*;
 
-class PasswdDialog extends Dialog implements KeyListener{
+class PasswdDialog extends Dialog implements KeyListener,
+                                             UserInfo,
+                                             UIKeyboardInteractive {
 
   public PasswdDialog(String title, boolean userDisabled, boolean passwdDisabled) {
     super(true);
@@ -79,8 +83,90 @@
     }
   }
 
+  public String getPassword(){ 
+    return new String(passwdEntry.getPassword());
+  }
+  public String getPassphrase(){ return null; }
+  public boolean promptPassphrase(String message){ return false; }
+  public boolean promptPassword(String message){
+    setTitle(message);
+    showDialog();
+    if (passwdEntry != null)
+      return true;
+    return false;
+  }
+  public void showMessage(String message){
+    JOptionPane.showMessageDialog(null, message);
+  }
+  public boolean promptYesNo(String str){
+    Object[] options={ "yes", "no" };
+    int foo=JOptionPane.showOptionDialog(null, 
+           str,
+           "Warning", 
+           JOptionPane.DEFAULT_OPTION, 
+           JOptionPane.WARNING_MESSAGE,
+           null, options, options[0]);
+     return foo==0;
+  }
+  public String[] promptKeyboardInteractive(String destination,
+                                            String name,
+                                            String instruction,
+                                            String[] prompt,
+                                            boolean[] echo){
+    Container panel = new JPanel();
+    panel.setLayout(new GridBagLayout());
+
+    GridBagConstraints gbc = 
+      new GridBagConstraints(0,0,1,1,1,1,
+                             GridBagConstraints.NORTHWEST,
+                             GridBagConstraints.NONE,
+                             new Insets(0,0,0,0),0,0);
+    gbc.weightx = 1.0;
+    gbc.gridwidth = GridBagConstraints.REMAINDER;
+    gbc.gridx = 0;
+    panel.add(new JLabel(instruction), gbc);
+    gbc.gridy++;
+
+    gbc.gridwidth = GridBagConstraints.RELATIVE;
+
+    JTextField[] texts=new JTextField[prompt.length];
+    for(int i=0; i<prompt.length; i++){
+      gbc.fill = GridBagConstraints.NONE;
+      gbc.gridx = 0;
+      gbc.weightx = 1;
+      panel.add(new JLabel(prompt[i]),gbc);
+
+      gbc.gridx = 1;
+      gbc.fill = GridBagConstraints.HORIZONTAL;
+      gbc.weighty = 1;
+      if(echo[i]){
+        texts[i]=new JTextField(20);
+      }
+      else{
+        texts[i]=new JPasswordField(20);
+      }
+      panel.add(texts[i], gbc);
+      gbc.gridy++;
+    }
+
+    if(JOptionPane.showConfirmDialog(null, panel, 
+                                     destination+": "+name,
+                                     JOptionPane.OK_CANCEL_OPTION,
+                                     JOptionPane.QUESTION_MESSAGE)
+       ==JOptionPane.OK_OPTION){
+      String[] response=new String[prompt.length];
+      for(int i=0; i<prompt.length; i++){
+        response[i]=texts[i].getText();
+      }
+	return response;
+    }
+    else{
+      return null;  // cancel
+    }
+  }
+
   JLabel userLabel;
   JTextField userEntry;
   JLabel passwdLabel;
-  JTextField passwdEntry;
+  JPasswordField passwdEntry;
 }
diff --git a/java/com/tigervnc/vncviewer/VncViewer.java b/java/com/tigervnc/vncviewer/VncViewer.java
index 91504d2..f7d1f62 100644
--- a/java/com/tigervnc/vncviewer/VncViewer.java
+++ b/java/com/tigervnc/vncviewer/VncViewer.java
@@ -33,15 +33,21 @@
 import java.awt.Image;
 import java.io.InputStream;
 import java.io.IOException;
+import java.io.File;
 import java.lang.Character;
 import java.util.jar.Attributes;
 import java.util.jar.Manifest;
+import java.util.ArrayList;
+import java.util.Iterator;
 import javax.swing.*;
 
 import com.tigervnc.rdr.*;
 import com.tigervnc.rfb.*;
 import com.tigervnc.network.*;
 
+import com.jcraft.jsch.JSch;
+import com.jcraft.jsch.Session;
+
 public class VncViewer extends java.applet.Applet implements Runnable
 {
   public static final String about1 = "TigerVNC Viewer for Java";
@@ -130,6 +136,82 @@
     System.exit(1);
   }
 
+  /* Tunnelling support. */
+  private void interpretViaParam(StringParameter gatewayHost,
+    StringParameter remoteHost, IntParameter remotePort, 
+    StringParameter vncServerName, IntParameter localPort)
+  {
+    final int SERVER_PORT_OFFSET = 5900;;
+    int pos = vncServerName.getValueStr().indexOf(":");
+    if (pos == -1)
+      remotePort.setParam(""+SERVER_PORT_OFFSET+"");
+    else {
+      int portOffset = SERVER_PORT_OFFSET;
+      int len;
+      pos++;
+      len =  vncServerName.getValueStr().substring(pos).length();
+      if (vncServerName.getValueStr().substring(pos, pos).equals(":")) {
+        /* Two colons is an absolute port number, not an offset. */
+        pos++;
+        len--;
+        portOffset = 0;
+      }
+      try {
+        if (len <= 0 || !vncServerName.getValueStr().substring(pos).matches("[0-9]+"))
+          usage();
+        portOffset += Integer.parseInt(vncServerName.getValueStr().substring(pos));
+        remotePort.setParam(""+portOffset+"");
+      } catch (java.lang.NumberFormatException e) {
+        usage();
+      }
+    }
+  
+    if (vncServerName != null)
+      remoteHost.setParam(vncServerName.getValueStr().split(":")[0]);
+  
+    gatewayHost.setParam(via.getValueStr());
+    vncServerName.setParam("localhost::"+localPort.getValue());
+  }
+
+  private void
+  createTunnel(String gatewayHost, String remoteHost,
+          int remotePort, int localPort)
+  {
+    try{
+      JSch jsch=new JSch();
+      String homeDir = new String("");
+      try {
+        homeDir = System.getProperty("user.home");
+      } catch(java.security.AccessControlException e) {
+        System.out.println("Cannot access user.home system property");
+      }
+      // NOTE: jsch does not support all ciphers.  User may be
+      //       prompted to accept host key authenticy even if
+      //       the key is in the known_hosts file.
+      File knownHosts = new File(homeDir+"/.ssh/known_hosts");
+      if (knownHosts.exists() && knownHosts.canRead())
+	      jsch.setKnownHosts(knownHosts.getAbsolutePath());
+      ArrayList<File> privateKeys = new ArrayList<File>();
+      privateKeys.add(new File(homeDir+"/.ssh/id_rsa"));
+      privateKeys.add(new File(homeDir+"/.ssh/id_dsa"));
+      for (Iterator i = privateKeys.iterator(); i.hasNext();) {
+        File privateKey = (File)i.next();
+        if (privateKey.exists() && privateKey.canRead())
+	        jsch.addIdentity(privateKey.getAbsolutePath());
+      }
+      // username and passphrase will be given via UserInfo interface.
+      PasswdDialog dlg = new PasswdDialog(new String("SSH Authentication"), false, false);
+      dlg.userEntry.setText((String)System.getProperties().get("user.name"));
+      Session session=jsch.getSession(dlg.userEntry.getText(), gatewayHost, 22);
+      session.setUserInfo(dlg);
+      session.connect();
+
+      session.setPortForwardingL(localPort, remoteHost, remotePort);
+    } catch (java.lang.Exception e) {
+      System.out.println(e);
+    }
+  }
+
   public VncViewer() {
     applet = true;
     firstApplet = true;
@@ -193,6 +275,21 @@
     CConn cc = null;
     Socket sock = null;
 
+    /* Tunnelling support. */
+    if (via.getValueStr() != null) {
+      StringParameter gatewayHost = new StringParameter("", "", "");
+      StringParameter remoteHost = new StringParameter("", "", "localhost");
+      IntParameter localPort = 
+        new IntParameter("", "", TcpSocket.findFreeTcpPort());
+      IntParameter remotePort = new IntParameter("", "", 5900);
+      if (vncServerName.getValueStr() == null)
+        usage();
+      interpretViaParam(gatewayHost, remoteHost, remotePort, 
+        vncServerName, localPort);
+      createTunnel(gatewayHost.getValueStr(), remoteHost.getValueStr(), 
+        remotePort.getValue(), localPort.getValue());
+    }
+
     if (listenMode.getValue()) {
       int port = 5500;
 
@@ -322,6 +419,9 @@
   = new BoolParameter("AcceptBell",
                       "Produce a system beep when requested to by the server.", 
                       true);
+  StringParameter via
+  = new StringParameter("via", "Gateway to tunnel via", null);
+
   BoolParameter customCompressLevel
   = new BoolParameter("CustomCompressLevel",
                           "Use custom compression level. "+
