Bug 179924 - [SSH2] SSH connection should respect ssh-agent in publickey
authentication

  * The extension point identityrepository is added.
    The connectors to ssh-agent and pageant will implement
    IIdentityRepositoryFactory, and those implementations will be
    given through this entry point.

  * A preference page is added to manage connectors.
    Connectors will provide an implementation of
    IIdentityRespositoryFactory, which allows to communicate with agents
    like ssh-agent and pageant.

Change-Id: Id1a8691ecb1202e204705c70831d4d18133f5979
diff --git a/bundles/org.eclipse.jsch.core/META-INF/MANIFEST.MF b/bundles/org.eclipse.jsch.core/META-INF/MANIFEST.MF
index f63a52f..fec1188 100644
--- a/bundles/org.eclipse.jsch.core/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.jsch.core/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.jsch.core;singleton:=true
-Bundle-Version: 1.1.500.qualifier
+Bundle-Version: 1.2.0.qualifier
 Bundle-Activator: org.eclipse.jsch.internal.core.JSchCorePlugin
 Bundle-Vendor: %providerName
 Bundle-Localization: plugin
diff --git a/bundles/org.eclipse.jsch.core/plugin.xml b/bundles/org.eclipse.jsch.core/plugin.xml
index 0bce2cd..2aff6e8 100644
--- a/bundles/org.eclipse.jsch.core/plugin.xml
+++ b/bundles/org.eclipse.jsch.core/plugin.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <?eclipse version="3.2"?>
 <!--
-    Copyright (c) 2007, 2011 IBM Corporation and others.
+    Copyright (c) 2007, 2014 IBM Corporation and others.
     All rights reserved. This program and the accompanying materials
     are made available under the terms of the Eclipse Public License v1.0
     which accompanies this distribution, and is available at
@@ -13,6 +13,7 @@
 
 <plugin>
    <extension-point id="authenticator" name="%Authenticator" schema="schema/authenticator.exsd" /> 
+   <extension-point id="identityrepository" name="identityrepository" schema="schema/identity_repository.exsd"/>
    <extension
          point="org.eclipse.core.runtime.preferences">
       <initializer
diff --git a/bundles/org.eclipse.jsch.core/pom.xml b/bundles/org.eclipse.jsch.core/pom.xml
index f0ab4db..ef2c541 100644
--- a/bundles/org.eclipse.jsch.core/pom.xml
+++ b/bundles/org.eclipse.jsch.core/pom.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
-  Copyright (c) 2012, 2013 Eclipse Foundation and others.
+  Copyright (c) 2012, 2014 Eclipse Foundation and others.
   All rights reserved. This program and the accompanying materials
   are made available under the terms of the Eclipse Distribution License v1.0
   which accompanies this distribution, and is available at
@@ -19,6 +19,6 @@
   </parent>
   <groupId>org.eclipse.jsch</groupId>
   <artifactId>org.eclipse.jsch.core</artifactId>
-  <version>1.1.500-SNAPSHOT</version>
+  <version>1.2.0-SNAPSHOT</version>
   <packaging>eclipse-plugin</packaging>
 </project>
diff --git a/bundles/org.eclipse.jsch.core/schema/identity_repository.exsd b/bundles/org.eclipse.jsch.core/schema/identity_repository.exsd
new file mode 100644
index 0000000..4f9a9b8
--- /dev/null
+++ b/bundles/org.eclipse.jsch.core/schema/identity_repository.exsd
@@ -0,0 +1,114 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.jsch.core" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+      <appInfo>
+         <meta.schema plugin="org.eclipse.jsch.core" id="identityrepository" name="identityrepository"/>
+      </appInfo>
+      <documentation>
+         This extension point allows a plug-in to register an identity repository factory.
+This factory is expected to create an instance of &lt;samp&gt;com.jcraft.jsch.IdentityRepository&lt;/samp&gt;, which abstracts communications with ssh-agent and Pageant.  This extension point must implement the abstract class &lt;samp&gt;org.eclipse.jsch.core.AbstractIdentityRepositoryFactory&lt;/samp&gt;.
+      </documentation>
+   </annotation>
+
+   <element name="extension">
+      <annotation>
+         <appInfo>
+            <meta.element />
+         </appInfo>
+      </annotation>
+      <complexType>
+         <sequence>
+            <element ref="identityrepository"/>
+         </sequence>
+         <attribute name="point" type="string" use="required">
+            <annotation>
+               <documentation>
+                  a fully qualified identifier of the target extension point
+               </documentation>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="identityrepository">
+      <complexType>
+         <sequence>
+            <element ref="run"/>
+         </sequence>
+      </complexType>
+   </element>
+
+   <element name="run">
+      <complexType>
+         <attribute name="class" type="string" use="required">
+            <annotation>
+               <documentation>
+                  a fully qualified name of a class that implements &lt;code&gt;org.eclipse.jsch.core.AbstractIdentityRepositoryFactory&lt;/code&gt;
+               </documentation>
+               <appInfo>
+                  <meta.attribute kind="java" basedOn="org.eclipse.jsch.core.AbstractIdentityRepositoryFactory:"/>
+               </appInfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="since"/>
+      </appInfo>
+      <documentation>
+         1.2
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="examples"/>
+      </appInfo>
+      <documentation>
+         The following is an example of an identity repository factory for ssh-agent:
+&lt;p&gt;
+&lt;pre&gt;
+&lt;extension point = &quot;org.eclipse.jsch.core.identityrepository&quot;&gt;
+     &lt;identityrepository&gt;
+       &lt;run
+         class=&quot;com.jcraft.jsch.agentproxy.eclipse.sshagent.IdentityRepositoryFactory&quot;&gt;
+       &lt;/run&gt;
+     &lt;/identityrepository&gt;
+&lt;/extension&gt;
+&lt;/pre&gt;
+&lt;/p&gt;
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="apiinfo"/>
+      </appInfo>
+      <documentation>
+         The contributed class must implement &lt;code&gt;org.eclipse.jsch.core.AbstractIdentityRepositoryFactory&lt;/code&gt;.
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="implementation"/>
+      </appInfo>
+      <documentation>
+         The Eclipse jsch-agent-proxy plugin defines identity repository factories.
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="copyright"/>
+      </appInfo>
+      <documentation>
+         Copyright (c) 2014 IBM Corporation and others.&lt;br&gt;
+All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0 which accompanies this distribution, and is available at &lt;a href=&quot;http://www.eclipse.org/legal/epl-v10.html&quot;&gt;http://www.eclipse.org/legal/epl-v10.html&lt;/a&gt;
+      </documentation>
+   </annotation>
+
+</schema>
diff --git a/bundles/org.eclipse.jsch.core/src/org/eclipse/jsch/core/AbstractIdentityRepositoryFactory.java b/bundles/org.eclipse.jsch.core/src/org/eclipse/jsch/core/AbstractIdentityRepositoryFactory.java
new file mode 100644
index 0000000..4627735
--- /dev/null
+++ b/bundles/org.eclipse.jsch.core/src/org/eclipse/jsch/core/AbstractIdentityRepositoryFactory.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2014 JCraft,Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     JCraft,Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jsch.core;
+
+import com.jcraft.jsch.IdentityRepository;
+
+/**
+ * This class abstracts the communications with the identity repository,
+ * and will be mainly used for ssh-agent.
+ * @since 1.2
+ */
+public abstract class AbstractIdentityRepositoryFactory{
+  /**
+   * This method will return an instance of
+   * <code>com.jcraft.com.jsch.IdentityRepository</code>. The ssh client will
+   * retrieve public keys from it, ask for signing data with a private key
+   * included in it.
+   * 
+   * @return an instance of <code>IdentityRepository</code>
+   */
+  public abstract IdentityRepository create();
+}
diff --git a/bundles/org.eclipse.jsch.core/src/org/eclipse/jsch/internal/core/IConstants.java b/bundles/org.eclipse.jsch.core/src/org/eclipse/jsch/internal/core/IConstants.java
index 872c79b..964920a 100644
--- a/bundles/org.eclipse.jsch.core/src/org/eclipse/jsch/internal/core/IConstants.java
+++ b/bundles/org.eclipse.jsch.core/src/org/eclipse/jsch/internal/core/IConstants.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -55,6 +55,8 @@
   public static final String PREF_PREFERRED_AUTHENTICATION_METHODS="CVSSSH2PreferencePage.PREF_AUTH_METHODS"; //$NON-NLS-1$
   public static final String PREF_PREFERRED_AUTHENTICATION_METHODS_ORDER="CVSSSH2PreferencePage.PREF_AUTH_METHODS_ORDER"; //$NON-NLS-1$
   
+  public static final String PREF_PREFERRED_SSHAGENT="CVSSSH2PreferencePage.PREF_SSHAGENT"; //$NON-NLS-1$
+
   public static final String PREF_PREFERRED_KEYEXCHANGE_METHODS="CVSSSH2PreferencePage.PREF_KEX_METHODS"; //$NON-NLS-1$
   public static final String PREF_PREFERRED_KEYEXCHANGE_METHODS_ORDER="CVSSSH2PreferencePage.PREF_KEX_METHODS_ORDER"; //$NON-NLS-1$
   
diff --git a/bundles/org.eclipse.jsch.core/src/org/eclipse/jsch/internal/core/JSchCorePlugin.java b/bundles/org.eclipse.jsch.core/src/org/eclipse/jsch/internal/core/JSchCorePlugin.java
index 92c2243..df14279 100644
--- a/bundles/org.eclipse.jsch.core/src/org/eclipse/jsch/internal/core/JSchCorePlugin.java
+++ b/bundles/org.eclipse.jsch.core/src/org/eclipse/jsch/internal/core/JSchCorePlugin.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -12,15 +12,18 @@
 package org.eclipse.jsch.internal.core;
 
 import java.util.Hashtable;
+import java.util.ArrayList;
 
 import org.eclipse.core.net.proxy.IProxyService;
 import org.eclipse.core.runtime.*;
+import org.eclipse.jsch.core.AbstractIdentityRepositoryFactory;
 import org.eclipse.jsch.core.IJSchService;
 import org.eclipse.osgi.util.NLS;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceRegistration;
 import org.osgi.util.tracker.ServiceTracker;
 
+import com.jcraft.jsch.IdentityRepository;
 import com.jcraft.jsch.JSch;
 import com.jcraft.jsch.JSchException;
 
@@ -39,6 +42,7 @@
   private String current_pkeys=""; //$NON-NLS-1$
 
   public static final String PT_AUTHENTICATOR="authenticator"; //$NON-NLS-1$
+  public static final String PT_IDENTITYREPOSITORY="identityrepository"; //$NON-NLS-1$
 
   private static JSchCorePlugin plugin;
   private ServiceTracker tracker;
@@ -100,11 +104,86 @@
   }
 
   public synchronized JSch getJSch(){
-    if(jsch==null)
+    if(jsch==null){
       jsch=new JSch();
+      setIdentityRepository();
+    }
     return jsch;
   }
 
+  public synchronized void setIdentityRepository(){
+
+    IdentityRepository[] repositories = getPluggedInIdentityRepositries();
+    String[] selected = Utils.getSelectedSSHAgent().split(","); //$NON-NLS-1$
+    IdentityRepository irepo = null;
+
+    for(int i=0; i<selected.length; i++){
+      for(int j=0; j<repositories.length; j++){
+        IdentityRepository _irepo = repositories[j];
+        if(selected[i].equals(_irepo.getName()) &&
+           _irepo.getStatus()==IdentityRepository.RUNNING){
+          irepo = _irepo;
+          break;
+        }
+      }
+      if(irepo!=null)
+        break;
+    }
+
+    if(irepo!=null){
+      jsch.setIdentityRepository(irepo);
+    }
+    else{
+      // set the internal default IdentityRepository
+      jsch.setIdentityRepository(null);
+    }
+
+  }
+
+  public IdentityRepository[] getPluggedInIdentityRepositries(){
+
+    IExtension[] extensions=Platform.getExtensionRegistry().getExtensionPoint(
+        JSchCorePlugin.ID, JSchCorePlugin.PT_IDENTITYREPOSITORY).getExtensions();
+
+    if(extensions.length==0)
+      return new IdentityRepository[0];
+
+    ArrayList tmp = new ArrayList();
+    for(int i=0; i<extensions.length; i++){
+      IExtension extension=extensions[i];
+      IConfigurationElement[] configs=extension.getConfigurationElements();
+      if(configs.length==0){
+        JSchCorePlugin
+            .log(
+                IStatus.ERROR,
+                NLS
+                    .bind(
+                        "IdentityRepository {0} is missing required fields", (new Object[] {extension.getUniqueIdentifier()})), null);//$NON-NLS-1$
+        continue;
+      }
+      try{
+        IConfigurationElement config=configs[0];
+        AbstractIdentityRepositoryFactory iirf =
+            (AbstractIdentityRepositoryFactory)config.createExecutableExtension("run");//$NON-NLS-1$
+        tmp.add(iirf.create());
+      }
+      catch(CoreException ex){
+        JSchCorePlugin
+            .log(
+                IStatus.ERROR,
+                NLS
+                    .bind(
+                        "Unable to instantiate identity repository {0}", (new Object[] {extension.getUniqueIdentifier()})), ex);//$NON-NLS-1$
+      }
+    }
+
+    IdentityRepository[] repositories = new IdentityRepository[tmp.size()];
+    for(int i=0; i<tmp.size(); i++){
+      repositories[i]=(IdentityRepository)tmp.get(i);
+    }
+    return repositories;
+  }
+
   public void loadKnownHosts(){
     Preferences preferences=JSchCorePlugin.getPlugin().getPluginPreferences();
     String ssh_home=preferences.getString(IConstants.KEY_SSH2HOME);
diff --git a/bundles/org.eclipse.jsch.core/src/org/eclipse/jsch/internal/core/Utils.java b/bundles/org.eclipse.jsch.core/src/org/eclipse/jsch/internal/core/Utils.java
index 44a7143..e822a46 100644
--- a/bundles/org.eclipse.jsch.core/src/org/eclipse/jsch/internal/core/Utils.java
+++ b/bundles/org.eclipse.jsch.core/src/org/eclipse/jsch/internal/core/Utils.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2013 IBM Corporation and others.
+ * Copyright (c) 2007, 2014 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -21,6 +21,7 @@
 import org.eclipse.core.runtime.preferences.InstanceScope;
 import org.osgi.service.prefs.BackingStoreException;
 
+import com.jcraft.jsch.IdentityRepository;
 import com.jcraft.jsch.JSch;
 import com.jcraft.jsch.JSchException;
 import com.jcraft.jsch.Proxy;
@@ -28,6 +29,7 @@
 import com.jcraft.jsch.ProxySOCKS5;
 import com.jcraft.jsch.Session;
 
+
 /**
  * 
  * @since 1.0
@@ -255,6 +257,18 @@
         IConstants.PREF_PREFERRED_AUTHENTICATION_METHODS, getDefaultAuthMethods(), null);
   }
 
+  public static String getAvailableSSHAgents(){
+    IdentityRepository[] repositories = JSchCorePlugin.getPlugin().getPluggedInIdentityRepositries();
+    String s=""; //$NON-NLS-1$
+    for(int i=0; i<repositories.length; i++){
+      IdentityRepository c = repositories[i];
+      s+=c.getName();
+      if(i+1<repositories.length)
+        s+=","; //$NON-NLS-1$
+    }
+    return s;
+  }
+
   public static String getMethodsOrder(){
     IPreferencesService service = Platform.getPreferencesService();
     return service.getString(JSchCorePlugin.ID,
@@ -267,7 +281,19 @@
         IConstants.PREF_PREFERRED_AUTHENTICATION_METHODS, methods);
     service.getRootNode().node(InstanceScope.SCOPE).node(JSchCorePlugin.ID).put(
         IConstants.PREF_PREFERRED_AUTHENTICATION_METHODS_ORDER, order);}
-  
+
+  public static String getSelectedSSHAgent(){
+    IPreferencesService service = Platform.getPreferencesService();
+    return service.getString(JSchCorePlugin.ID,
+        IConstants.PREF_PREFERRED_SSHAGENT, "", null); //$NON-NLS-1$
+  }
+
+  public static void setSelectedSSHAgents(String methods){
+    IPreferencesService service=Platform.getPreferencesService();
+    service.getRootNode().node(InstanceScope.SCOPE).node(JSchCorePlugin.ID).put(
+        IConstants.PREF_PREFERRED_SSHAGENT, methods);
+  }
+
   public static String getEnabledPreferredKEXMethods(){
     IPreferencesService service = Platform.getPreferencesService();
     return service.getString(JSchCorePlugin.ID,
diff --git a/bundles/org.eclipse.jsch.ui/META-INF/MANIFEST.MF b/bundles/org.eclipse.jsch.ui/META-INF/MANIFEST.MF
index 2ad2101..7b980d4 100644
--- a/bundles/org.eclipse.jsch.ui/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.jsch.ui/META-INF/MANIFEST.MF
@@ -2,13 +2,13 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.jsch.ui;singleton:=true
-Bundle-Version: 1.1.500.qualifier
+Bundle-Version: 1.2.0.qualifier
 Bundle-Activator: org.eclipse.jsch.internal.ui.JSchUIPlugin
 Bundle-Vendor: %providerName
 Bundle-Localization: plugin
 Require-Bundle: org.eclipse.ui;bundle-version="[3.5.0,4.0.0)",
  org.eclipse.core.runtime;bundle-version="[3.3.0,4.0.0)",
- org.eclipse.jsch.core;bundle-version="[1.0.0,2.0.0)",
+ org.eclipse.jsch.core;bundle-version="[1.2.0,2.0.0)",
  com.jcraft.jsch;bundle-version="[0.1.50,1.0.0)"
 Eclipse-LazyStart: true
 Bundle-RequiredExecutionEnvironment: J2SE-1.4
diff --git a/bundles/org.eclipse.jsch.ui/pom.xml b/bundles/org.eclipse.jsch.ui/pom.xml
index d5ed754..e311694 100644
--- a/bundles/org.eclipse.jsch.ui/pom.xml
+++ b/bundles/org.eclipse.jsch.ui/pom.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
-  Copyright (c) 2012, 2013 Eclipse Foundation and others.
+  Copyright (c) 2012, 2014 Eclipse Foundation and others.
   All rights reserved. This program and the accompanying materials
   are made available under the terms of the Eclipse Distribution License v1.0
   which accompanies this distribution, and is available at
@@ -19,6 +19,6 @@
   </parent>
   <groupId>org.eclipse.jsch</groupId>
   <artifactId>org.eclipse.jsch.ui</artifactId>
-  <version>1.1.500-SNAPSHOT</version>
+  <version>1.2.0-SNAPSHOT</version>
   <packaging>eclipse-plugin</packaging>
 </project>
diff --git a/bundles/org.eclipse.jsch.ui/src/org/eclipse/jsch/internal/ui/Messages.java b/bundles/org.eclipse.jsch.ui/src/org/eclipse/jsch/internal/ui/Messages.java
index cfc1a61..583ab42 100644
--- a/bundles/org.eclipse.jsch.ui/src/org/eclipse/jsch/internal/ui/Messages.java
+++ b/bundles/org.eclipse.jsch.ui/src/org/eclipse/jsch/internal/ui/Messages.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -94,6 +94,8 @@
   public static String CVSSSH2PreferencePage_143;
   public static String CVSSSH2PreferencePage_144;
   public static String CVSSSH2PreferencePage_145;
+  public static String CVSSSH2PreferencePage_146;
+  public static String CVSSSH2PreferencePage_147;
   public static String KeyboardInteractiveDialog_0;
   public static String KeyboardInteractiveDialog_1;
   public static String KeyboardInteractiveDialog_2;
diff --git a/bundles/org.eclipse.jsch.ui/src/org/eclipse/jsch/internal/ui/messages.properties b/bundles/org.eclipse.jsch.ui/src/org/eclipse/jsch/internal/ui/messages.properties
index d228d56..7d03e07 100644
--- a/bundles/org.eclipse.jsch.ui/src/org/eclipse/jsch/internal/ui/messages.properties
+++ b/bundles/org.eclipse.jsch.ui/src/org/eclipse/jsch/internal/ui/messages.properties
@@ -1,5 +1,5 @@
 ###############################################################################
-# Copyright (c) 2000, 2013 IBM Corporation and others.
+# Copyright (c) 2000, 2014 IBM Corporation and others.
 # All rights reserved. This program and the accompanying materials
 # are made available under the terms of the Eclipse Public License v1.0
 # which accompanies this distribution, and is available at
@@ -84,6 +84,8 @@
 CVSSSH2PreferencePage_143=You must select at least one MAC method.
 CVSSSH2PreferencePage_144=Key Exchange &Methods
 CVSSSH2PreferencePage_145=MA&C Methods
+CVSSSH2PreferencePage_146=SSH Agent
+CVSSSH2PreferencePage_147=Select preferred SSH Agent
 UserInfoPrompter_0=SSH2 Message
 UserInfoPrompter_1=SSH2 Message
 KeyboardInteractiveDialog_0=Keyboard Interactive authentication for {0}: {1}
diff --git a/bundles/org.eclipse.jsch.ui/src/org/eclipse/jsch/internal/ui/preference/PreferencePage.java b/bundles/org.eclipse.jsch.ui/src/org/eclipse/jsch/internal/ui/preference/PreferencePage.java
index 1945516..2c83596 100644
--- a/bundles/org.eclipse.jsch.ui/src/org/eclipse/jsch/internal/ui/preference/PreferencePage.java
+++ b/bundles/org.eclipse.jsch.ui/src/org/eclipse/jsch/internal/ui/preference/PreferencePage.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -155,6 +155,10 @@
     tabItem.setText(Messages.CVSSSH2PreferencePage_145);
     tabItem.setControl(createPreferredMACPage(tabFolder));
 
+    tabItem=new TabItem(tabFolder, SWT.NONE);
+    tabItem.setText(Messages.CVSSSH2PreferencePage_146);
+    tabItem.setControl(createPreferredSSHAgentPage(tabFolder));
+
     initControls();
 
     Dialog.applyDialogFont(parent);
@@ -815,6 +819,7 @@
   private Button removeHostKeyButton;
 
   Table preferedAuthMethodTable;
+  Table preferedSSHAgentTable;
   Table preferedKeyExchangeMethodTable;
   Table preferedMACMethodTable;
 
@@ -1313,6 +1318,51 @@
     return root;
   }
 
+  private Control createPreferredSSHAgentPage(Composite parent){
+    Composite root = new Composite(parent, SWT.NONE);
+    GridLayout layout=new GridLayout();
+    layout.marginHeight=convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
+    layout.marginWidth=convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
+    layout.verticalSpacing=convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
+    layout.horizontalSpacing=convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
+    layout.numColumns = 2;
+    root.setLayout(layout);
+
+    Label label=new Label(root, SWT.NONE);
+    GridData textLayoutData=new GridData(SWT.BEGINNING, SWT.BEGINNING, true, false);
+    textLayoutData.horizontalSpan = 2;
+    label.setLayoutData(textLayoutData);
+    label.setText(Messages.CVSSSH2PreferencePage_147);
+
+    preferedSSHAgentTable=new Table(root, SWT.CHECK | SWT.BORDER);
+    GridData layoutData=new GridData(SWT.FILL, SWT.BEGINNING, true, true);
+    layoutData.verticalSpan = 3;
+    preferedSSHAgentTable.setLayoutData(layoutData);
+    layoutData.minimumHeight = 150;
+    layoutData.minimumWidth = 200;
+    populateSSHAgents();
+    return root;
+  }
+
+  private void populateSSHAgents(){
+    preferedSSHAgentTable.removeAll();
+    String[] methods = Utils.getAvailableSSHAgents().split(","); //$NON-NLS-1$
+    String[] selected = Utils.getSelectedSSHAgent().split(","); //$NON-NLS-1$
+
+    for(int i=0; i<methods.length; i++){
+      if(methods[i].length()==0)
+        continue;
+      TableItem tableItem= new TableItem(preferedSSHAgentTable, SWT.NONE);
+      tableItem.setText(0, methods[i]);
+      for(int j=0; j<selected.length; j++){
+        if(selected[j].equals(methods[i])){
+          tableItem.setChecked(true);
+          break;
+        }
+      }
+    }
+  }
+
   private void populateMACMethods(){
     preferedMACMethodTable.removeAll();
     String[] methods = Utils.getEnabledPreferredMACMethods().split(","); //$NON-NLS-1$
@@ -1328,7 +1378,7 @@
       }
     }
   }
-  
+
   void handleSelection(){
     boolean empty=viewer.getSelection().isEmpty();
     removeHostKeyButton.setEnabled(!empty);
@@ -1473,8 +1523,10 @@
   public boolean performOk(){
     boolean result=super.performOk();
     storeAuthenticationMethodSettings();
+    storeSSHAgentSettings();
     storeKeyExchangeMethodSettings();
     storeMACMethodSettings();
+
     if(result){
       setErrorMessage(null);
       String home=ssh2HomeText.getText();
@@ -1499,6 +1551,7 @@
     }
     JSchCorePlugin.getPlugin().setNeedToLoadKnownHosts(true);
     JSchCorePlugin.getPlugin().setNeedToLoadKeys(true);
+    JSchCorePlugin.getPlugin().setIdentityRepository();
     JSchCorePlugin.getPlugin().savePluginPreferences();
     return result;
   }
@@ -1525,6 +1578,22 @@
     Utils.setEnabledPreferredAuthMethods(selected, order);
   }
   
+  private void storeSSHAgentSettings(){
+    String selected = ""; //$NON-NLS-1$
+    for(int i = 0; i < preferedSSHAgentTable.getItemCount(); i++){
+      TableItem item=preferedSSHAgentTable.getItem(i);
+      if(item.getChecked()){
+        if(selected.length()==0){
+          selected=item.getText();
+        }
+        else{
+          selected+=","+item.getText(); //$NON-NLS-1$
+        }
+      }
+    }
+    Utils.setSelectedSSHAgents(selected);
+  }
+
   private void storeKeyExchangeMethodSettings(){
     String selected = null;
     String order = null;