/*******************************************************************************
 * Copyright (c) 2000, 2018 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
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Atsuhiko Yamanaka, JCraft,Inc. - initial API and implementation.
 *     IBM Corporation - ongoing maintenance
 *     Atsuhiko Yamanaka, JCraft,Inc. - re-implement the public key transfer by using IJSchLocation.
 *     Atsuhiko Yamanaka, JCraft,Inc. - Bug 351094 SSH2 Key Management Comment Field stuck on RSA-1024
 *******************************************************************************/
package org.eclipse.jsch.internal.ui.preference;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Preferences;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TableLayout;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jsch.core.IJSchLocation;
import org.eclipse.jsch.core.IJSchService;
import org.eclipse.jsch.internal.core.IConstants;
import org.eclipse.jsch.internal.core.JSchCorePlugin;
import org.eclipse.jsch.internal.core.Utils;
import org.eclipse.jsch.internal.ui.JSchUIPlugin;
import org.eclipse.jsch.internal.ui.Messages;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.custom.CTabItem;
import org.eclipse.swt.custom.TableEditor;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.DirectoryDialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;
import org.eclipse.ui.PlatformUI;

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.HostKey;
import com.jcraft.jsch.HostKeyRepository;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.KeyPair;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpATTRS;
import com.jcraft.jsch.SftpException;

public class PreferencePage extends org.eclipse.jface.preference.PreferencePage
    implements IWorkbenchPreferencePage{

  private static final String SSH2_PREFERENCE_PAGE_CONTEXT="org.eclipse.jsch.ui.ssh2_preference_page_context"; //$NON-NLS-1$

  private Label ssh2HomeLabel;
  private Label privateKeyLabel;
  Text ssh2HomeText;
  Text privateKeyText;
  private Button privateKeyAdd;

  private Button ssh2HomeBrowse;
  Button keyGenerateDSA;
  Button keyGenerateRSA;
  private Button keyLoad;
  private Button keyExport;
  Button saveKeyPair;
  private Label keyCommentLabel;
  Text keyCommentText;
  private Label keyFingerPrintLabel;
  Text keyFingerPrintText;
  private Label keyPassphrase1Label;
  Text keyPassphrase1Text;
  private Label keyPassphrase2Label;
  Text keyPassphrase2Text;
  private Label publicKeylabel;
  Text publicKeyText;
  KeyPair kpair=null;
  String kpairComment;

  public static final String AUTH_SCHEME="";//$NON-NLS-1$

  public PreferencePage(){
    setDescription(Messages.CVSSSH2PreferencePage_18);
  }

  protected Control createContents(Composite parent){
    Composite container=new Composite(parent, SWT.NULL);
    GridLayout layout=new GridLayout();
    container.setLayout(layout);
    initializeDialogUnits(container);

    CTabFolder tabFolder=new CTabFolder(container, SWT.NONE);
    tabFolder.setLayoutData(new GridData(GridData.FILL_BOTH));

    CTabItem tabItem=new CTabItem(tabFolder, SWT.NONE);
    tabItem.setText(Messages.CVSSSH2PreferencePage_19);
    tabItem.setControl(createGeneralPage(tabFolder));

    tabItem=new CTabItem(tabFolder, SWT.NONE);
    tabItem.setText(Messages.CVSSSH2PreferencePage_21);
    tabItem.setControl(createKeyManagementPage(tabFolder));

    tabItem=new CTabItem(tabFolder, SWT.NONE);
    tabItem.setText(Messages.CVSSSH2PreferencePage_133);
    tabItem.setControl(createHostKeyManagementPage(tabFolder));

    tabItem=new CTabItem(tabFolder, SWT.NONE);
    tabItem.setText(Messages.CVSSSH2PreferencePage_137);
    tabItem.setControl(createPreferredAuthenticationPage(tabFolder));

    tabItem=new CTabItem(tabFolder, SWT.NONE);
    tabItem.setText(Messages.CVSSSH2PreferencePage_144);
    tabItem.setControl(createPreferredKeyExchangePage(tabFolder));

    tabItem=new CTabItem(tabFolder, SWT.NONE);
    tabItem.setText(Messages.CVSSSH2PreferencePage_145);
    tabItem.setControl(createPreferredMACPage(tabFolder));

    tabItem=new CTabItem(tabFolder, SWT.NONE);
    tabItem.setText(Messages.CVSSSH2PreferencePage_146);
    tabItem.setControl(createPreferredSSHAgentPage(tabFolder));
    tabFolder.setSelection(0);
    initControls();

    Dialog.applyDialogFont(parent);
    PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(),
        SSH2_PREFERENCE_PAGE_CONTEXT);
    return container;
  }

  private Control createGeneralPage(Composite parent){
    Composite group=new Composite(parent, SWT.NULL);
    GridLayout layout=new GridLayout();
    layout.numColumns=3;
    layout.marginHeight=convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
    layout.marginWidth=convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
    layout.verticalSpacing=convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
    layout.horizontalSpacing=convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
    group.setLayout(layout);
    GridData data=new GridData();
    data.horizontalAlignment=GridData.FILL;
    group.setLayoutData(data);

    ssh2HomeLabel=new Label(group, SWT.NONE);
    ssh2HomeLabel.setText(Messages.CVSSSH2PreferencePage_23);

    ssh2HomeText=new Text(group, SWT.SINGLE|SWT.BORDER);
    ssh2HomeText.setFont(group.getFont());
    GridData gd=new GridData(GridData.FILL_HORIZONTAL);
    gd.horizontalSpan=1;
    ssh2HomeText.setLayoutData(gd);

    ssh2HomeBrowse=new Button(group, SWT.NULL);
    ssh2HomeBrowse.setText(Messages.CVSSSH2PreferencePage_24);
    gd=new GridData(GridData.HORIZONTAL_ALIGN_FILL);
    gd.horizontalSpan=1;
    ssh2HomeBrowse.setLayoutData(gd);

    createSpacer(group, 3);

    privateKeyLabel=new Label(group, SWT.NONE);
    privateKeyLabel.setText(Messages.CVSSSH2PreferencePage_25);

    privateKeyText=new Text(group, SWT.SINGLE|SWT.BORDER);
    privateKeyText.setFont(group.getFont());
    gd=new GridData(GridData.FILL_HORIZONTAL);
    gd.horizontalSpan=1;
    privateKeyText.setLayoutData(gd);

    privateKeyAdd=new Button(group, SWT.NULL);
    privateKeyAdd.setText(Messages.CVSSSH2PreferencePage_26);
    gd=new GridData(GridData.HORIZONTAL_ALIGN_FILL);
    gd.horizontalSpan=1;
    privateKeyAdd.setLayoutData(gd);

    ssh2HomeBrowse.addSelectionListener(new SelectionAdapter(){
      public void widgetSelected(SelectionEvent e){
        String home=ssh2HomeText.getText();

        if(!new File(home).exists()){
          while(true){
            int foo=home.lastIndexOf(java.io.File.separator, home.length());
            if(foo==-1)
              break;
            home=home.substring(0, foo);
            if(new File(home).exists())
              break;
          }
        }

        DirectoryDialog dd=new DirectoryDialog(getShell());
        dd.setFilterPath(home);
        dd.setMessage(Messages.CVSSSH2PreferencePage_27);
        String dir=dd.open();
        if(dir==null){ // cancel
          return;
        }
        ssh2HomeText.setText(dir);
      }
    });

    privateKeyAdd.addSelectionListener(new SelectionAdapter(){
      public void widgetSelected(SelectionEvent e){
        String home=ssh2HomeText.getText();

        FileDialog fd=new FileDialog(getShell(), SWT.OPEN|SWT.MULTI);
        fd.setFilterPath(home);
        Object o=fd.open();
        if(o==null){ // cancel
          return;
        }
        String[] files=fd.getFileNames();
        String keys=privateKeyText.getText();
        String dir=fd.getFilterPath();
        if(dir.equals(home)){
          dir="";} //$NON-NLS-1$
        else{
          dir+=java.io.File.separator;
        }

        for(int i=0; i<files.length; i++){
          String foo=files[i];
          if(keys.length()!=0)
            keys=keys+","; //$NON-NLS-1$
          keys=keys+dir+foo;
        }
        privateKeyText.setText(keys);
      }
    });

    return group;
  }

  private Control createKeyManagementPage(Composite parent){
    int columnSpan=3;
    Composite group=new Composite(parent, SWT.NULL);
    GridLayout layout=new GridLayout();
    layout.numColumns=3;
    layout.marginHeight=convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
    layout.marginWidth=convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
    layout.verticalSpacing=convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
    layout.horizontalSpacing=convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
    group.setLayout(layout);
    GridData gd=new GridData();
    gd.horizontalAlignment=GridData.FILL;
    group.setLayoutData(gd);

    keyGenerateDSA=new Button(group, SWT.NULL);
    keyGenerateDSA.setText(Messages.CVSSSH2PreferencePage_131);
    gd=new GridData();
    gd.horizontalSpan=1;
    keyGenerateDSA.setLayoutData(gd);

    keyGenerateRSA=new Button(group, SWT.NULL);
    keyGenerateRSA.setText(Messages.CVSSSH2PreferencePage_132);
    gd=new GridData();
    gd.horizontalSpan=1;
    keyGenerateRSA.setLayoutData(gd);

    keyLoad=new Button(group, SWT.NULL);
    keyLoad.setText(Messages.CVSSSH2PreferencePage_128);
    gd=new GridData();
    gd.horizontalSpan=1;
    keyLoad.setLayoutData(gd);

    publicKeylabel=new Label(group, SWT.NONE);
    publicKeylabel.setText(Messages.CVSSSH2PreferencePage_39);
    gd=new GridData();
    gd.horizontalSpan=columnSpan;
    publicKeylabel.setLayoutData(gd);

    publicKeyText=new Text(group, SWT.MULTI|SWT.BORDER|SWT.V_SCROLL|SWT.WRAP|SWT.LEFT_TO_RIGHT);
    publicKeyText.setText(""); //$NON-NLS-1$
    publicKeyText.setEditable(false);
    gd=new GridData();
    gd.horizontalSpan=columnSpan;
    gd.horizontalAlignment=GridData.FILL;
    gd.verticalAlignment=GridData.FILL;
    gd.grabExcessHorizontalSpace=true;
    gd.grabExcessVerticalSpace=true;
    publicKeyText.setLayoutData(gd);

    keyFingerPrintLabel=new Label(group, SWT.NONE);
    keyFingerPrintLabel.setText(Messages.CVSSSH2PreferencePage_41);
    keyFingerPrintText=new Text(group, SWT.SINGLE|SWT.BORDER|SWT.LEFT_TO_RIGHT);
    keyFingerPrintText.setFont(group.getFont());
    keyFingerPrintText.setEditable(false);
    gd=new GridData(GridData.FILL_HORIZONTAL);
    gd.horizontalSpan=2;
    keyFingerPrintText.setLayoutData(gd);

    keyCommentLabel=new Label(group, SWT.NONE);
    keyCommentLabel.setText(Messages.CVSSSH2PreferencePage_42);
    keyCommentText=new Text(group, SWT.SINGLE|SWT.BORDER);
    keyCommentText.setFont(group.getFont());
    gd=new GridData(GridData.FILL_HORIZONTAL);
    gd.horizontalSpan=2;
    keyCommentText.setLayoutData(gd);

    keyCommentText.addModifyListener(new ModifyListener(){
      public void modifyText(ModifyEvent e){
        if(kpair==null)
          return;
        try{
          ByteArrayOutputStream out=new ByteArrayOutputStream();
          kpairComment = keyCommentText.getText();
          kpair.writePublicKey(out, kpairComment);
          out.close();
          publicKeyText.setText(out.toString());
        }
        catch(IOException ee){
          // Ignore
        }
      }
    });

    keyPassphrase1Label=new Label(group, SWT.NONE);
    keyPassphrase1Label.setText(Messages.CVSSSH2PreferencePage_43);
    keyPassphrase1Text=new Text(group, SWT.SINGLE|SWT.BORDER);
    keyPassphrase1Text.setFont(group.getFont());
    keyPassphrase1Text.setEchoChar('*');
    gd=new GridData(GridData.FILL_HORIZONTAL);
    gd.horizontalSpan=2;
    keyPassphrase1Text.setLayoutData(gd);

    keyPassphrase2Label=new Label(group, SWT.NONE);
    keyPassphrase2Label.setText(Messages.CVSSSH2PreferencePage_44);
    keyPassphrase2Text=new Text(group, SWT.SINGLE|SWT.BORDER);
    keyPassphrase2Text.setFont(group.getFont());
    keyPassphrase2Text.setEchoChar('*');
    gd=new GridData(GridData.FILL_HORIZONTAL);
    gd.horizontalSpan=2;
    keyPassphrase2Text.setLayoutData(gd);

    keyPassphrase1Text.addModifyListener(new ModifyListener(){
      public void modifyText(ModifyEvent e){
        String pass1=keyPassphrase1Text.getText();
        String pass2=keyPassphrase2Text.getText();
        if(kpair!=null&&pass1.equals(pass2)){
          saveKeyPair.setEnabled(true);
        }
        else{
          saveKeyPair.setEnabled(false);
        }
        if(pass2.length()==0){
          setErrorMessage(null);
          return;
        }
        if(pass1.equals(pass2)){
          setErrorMessage(null);
        }
        else{
          setErrorMessage(Messages.CVSSSH2PreferencePage_48);
        }
      }
    });

    keyPassphrase2Text.addModifyListener(new ModifyListener(){
      public void modifyText(ModifyEvent e){
        String pass1=keyPassphrase1Text.getText();
        String pass2=keyPassphrase2Text.getText();
        if(kpair!=null&&pass1.equals(pass2)){
          saveKeyPair.setEnabled(true);
        }
        else{
          saveKeyPair.setEnabled(false);
        }
        if(pass2.length()<pass1.length()){
          if(pass1.startsWith(pass2)){
            setErrorMessage(null);
          }
          else{
            setErrorMessage(Messages.CVSSSH2PreferencePage_48);
          }
          return;
        }
        if(pass1.equals(pass2)){
          setErrorMessage(null);
        }
        else{
          setErrorMessage(Messages.CVSSSH2PreferencePage_48);
        }
      }
    });

    keyPassphrase2Text.addFocusListener(new FocusListener(){
      public void focusGained(FocusEvent e){
        String pass1=keyPassphrase1Text.getText();
        String pass2=keyPassphrase2Text.getText();
        if(pass2.length()<pass1.length()){
          if(pass1.startsWith(pass2)){
            setErrorMessage(null);
          }
          else{
            setErrorMessage(Messages.CVSSSH2PreferencePage_48);
          }
          return;
        }
        if(pass1.equals(pass2)){
          setErrorMessage(null);
        }
        else{
          setErrorMessage(Messages.CVSSSH2PreferencePage_48);
        }
      }

      public void focusLost(FocusEvent e){
        String pass1=keyPassphrase1Text.getText();
        String pass2=keyPassphrase2Text.getText();
        if(pass1.equals(pass2)){
          setErrorMessage(null);
        }
        else{
          setErrorMessage(Messages.CVSSSH2PreferencePage_48);
        }
      }
    });

    Composite buttons=new Composite(group, SWT.NONE);
    layout=new GridLayout(2, true);
    layout.marginWidth=0;
    layout.marginHeight=0;
    layout.horizontalSpacing=convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
    buttons.setLayout(layout);
    gd=new GridData(GridData.HORIZONTAL_ALIGN_END);
    gd.horizontalSpan=columnSpan;
    buttons.setLayoutData(gd);

    keyExport=new Button(buttons, SWT.NULL);
    keyExport.setText(Messages.CVSSSH2PreferencePage_105);
    gd=new GridData(GridData.FILL_BOTH);
    keyExport.setLayoutData(gd);

    saveKeyPair=new Button(buttons, SWT.NULL);
    saveKeyPair.setText(Messages.CVSSSH2PreferencePage_45);
    gd=new GridData(GridData.FILL_BOTH);
    saveKeyPair.setLayoutData(gd);

    SelectionAdapter keygenadapter=new SelectionAdapter(){
      public void widgetSelected(SelectionEvent e){
        boolean ok=true;
        String _type=""; //$NON-NLS-1$

        try{
          int type=0;
          if(e.widget==keyGenerateDSA){
            type=KeyPair.DSA;
            _type=IConstants.DSA;
          }
          else if(e.widget==keyGenerateRSA){
            type=KeyPair.RSA;
            _type=IConstants.RSA;
          }
          else{
            return;
          }

          final KeyPair[] _kpair=new KeyPair[1];
          final int __type=type;
          final JSchException[] _e=new JSchException[1];
          BusyIndicator.showWhile(getShell().getDisplay(), new Runnable(){
            public void run(){
              try{
                _kpair[0]=KeyPair.genKeyPair(getJSch(), __type);
              }
              catch(JSchException e){
                _e[0]=e;
              }
            }
          });
          if(_e[0]!=null){
            throw _e[0];
          }
          kpair=_kpair[0];

          ByteArrayOutputStream out=new ByteArrayOutputStream();
          kpairComment=_type+"-1024"; //$NON-NLS-1$
          kpair.writePublicKey(out, kpairComment);
          out.close();
          publicKeyText.setText(out.toString());
          keyFingerPrintText.setText(kpair.getFingerPrint());
          keyCommentText.setText(kpairComment);
          keyPassphrase1Text.setText(""); //$NON-NLS-1$
          keyPassphrase2Text.setText(""); //$NON-NLS-1$
          updateControls();
        }
        catch(IOException ee){
          ok=false;
        }
        catch(JSchException ee){
          ok=false;
        }
        if(!ok){
          MessageDialog.openError(getShell(),
              Messages.CVSSSH2PreferencePage_error,
              Messages.CVSSSH2PreferencePage_47);
        }
      }
    };
    keyGenerateDSA.addSelectionListener(keygenadapter);
    keyGenerateRSA.addSelectionListener(keygenadapter);

    keyLoad.addSelectionListener(new SelectionAdapter(){
      public void widgetSelected(SelectionEvent e){
        boolean ok=true;
        String home=ssh2HomeText.getText();
        FileDialog fd=new FileDialog(getShell(), SWT.OPEN);
        fd.setFilterPath(home);
        Object o=fd.open();
        if(o==null){ // cancel
          return;
        }
        String pkey=fd.getFileName();
        String pkeyab=(new File(fd.getFilterPath(), pkey)).getAbsolutePath();
        try{
          KeyPair _kpair=KeyPair.load(getJSch(), pkeyab);
          PassphrasePrompt prompt=null;
          while(_kpair.isEncrypted()){
            if(prompt==null){
              prompt=new PassphrasePrompt(NLS.bind(
                  Messages.CVSSSH2PreferencePage_126, new String[] {pkey}));
            }
            Display.getDefault().syncExec(prompt);
            String passphrase=prompt.getPassphrase();
            if(passphrase==null)
              break;
            if(_kpair.decrypt(passphrase)){
              break;
            }
            MessageDialog.openError(getShell(),
                Messages.CVSSSH2PreferencePage_error, NLS.bind(
                    Messages.CVSSSH2PreferencePage_129, new String[] {pkey}));
          }
          if(_kpair.isEncrypted()){
            return;
          }
          kpair=_kpair;
          String _type=(kpair.getKeyType()==KeyPair.DSA) ? IConstants.DSA
              : IConstants.RSA;
          kpairComment=_type+"-1024"; //$NON-NLS-1$

          // TODO Bug 351094 The comment should be from kpair object,
          // but the JSch API does not provided such a method.
          // In the version 0.1.45, JSch will support such a method,
          // and the following code should be replaced with it at that time.
          java.io.FileInputStream fis=null;
          try{
            java.io.File f=new java.io.File(pkeyab+".pub"); //$NON-NLS-1$
            int i=0;
            fis=new java.io.FileInputStream(f);
            byte[] buf=new byte[(int)f.length()];
            while(i<buf.length){
              int j=fis.read(buf, i, buf.length-i);
              if(j<=0)
                break;
              i+=j;
            }
            String pubkey=new String(buf);
            if(pubkey.indexOf(' ')>0
                &&pubkey.indexOf(' ', pubkey.indexOf(' ')+1)>0){
              int j=pubkey.indexOf(' ', pubkey.indexOf(' ')+1)+1;
              kpairComment=pubkey.substring(j);
              if(kpairComment.indexOf('\n')>0){
                kpairComment=kpairComment.substring(0,
                    kpairComment.indexOf('\n'));
              }
            }
          }
          catch(IOException ioe){
            // ignore if public-key does not exist.
          }
          finally{
            if(fis!=null)
              fis.close();
          }

          ByteArrayOutputStream out=new ByteArrayOutputStream();

          kpair.writePublicKey(out, kpairComment);
          out.close();
          publicKeyText.setText(out.toString());
          keyFingerPrintText.setText(kpair.getFingerPrint());
          keyCommentText.setText(kpairComment);
          keyPassphrase1Text.setText(""); //$NON-NLS-1$
          keyPassphrase2Text.setText(""); //$NON-NLS-1$
          updateControls();
        }
        catch(IOException ee){
          ok=false;
        }
        catch(JSchException ee){
          ok=false;
        }
        if(!ok){
          MessageDialog.openError(getShell(),
              Messages.CVSSSH2PreferencePage_error,
              Messages.CVSSSH2PreferencePage_130);
        }
      }
    });

    keyExport.addSelectionListener(new SelectionAdapter(){
      public void widgetSelected(SelectionEvent e){
        if(kpair==null)
          return;

        setErrorMessage(null);

        final String[] target=new String[1];
        final String title=Messages.CVSSSH2PreferencePage_106;
        final String message=Messages.CVSSSH2PreferencePage_107;
        Display.getDefault().syncExec(new Runnable(){
          public void run(){
            Display display=Display.getCurrent();
            Shell shell=new Shell(display);
            ExportDialog dialog=new ExportDialog(shell, title, message);
            dialog.open();
            shell.dispose();
            target[0]=dialog.getTarget();
          }
        });
        if(target[0]==null){
          return;
        }
        String user=""; //$NON-NLS-1$
        String host=""; //$NON-NLS-1$
        int port=22;

        if(target[0].indexOf('@')>0){
          user=target[0].substring(0, target[0].indexOf('@'));
          host=target[0].substring(target[0].indexOf('@')+1);
        }
        if(host.indexOf(':')>0){
          try{
            port=Integer.parseInt(host.substring(host.indexOf(':')+1));
          }
          catch(NumberFormatException ee){
            port=-1;
          }
          host=host.substring(0, host.indexOf(':'));
        }

        if(user.length()==0||host.length()==0||port==-1){
          setErrorMessage(NLS.bind(Messages.CVSSSH2PreferencePage_108,
              new String[] {target[0]}));
          return;
        }

        String options=""; //$NON-NLS-1$
        try{
          ByteArrayOutputStream bos=new ByteArrayOutputStream();
          if(options.length()!=0){
            try{
              bos.write((options+" ").getBytes());} //$NON-NLS-1$
            catch(IOException eeee){
              // Ignore
            }
          }
          kpair.writePublicKey(bos, kpairComment);
          bos.close();
          export_via_sftp(user, host, port, /* ".ssh/authorized_keys", //$NON-NLS-1$ */
              bos.toByteArray());
        }
        catch(IOException ee){
       // Ignore
        }
        catch(JSchException ee){
          setErrorMessage(Messages.CVSSSH2PreferencePage_111);
        }
      }
    });

    saveKeyPair.addSelectionListener(new SelectionAdapter(){
      public void widgetSelected(SelectionEvent e){
        if(kpair==null)
          return;

        String pass=keyPassphrase1Text.getText();
        /*
         * if(!pass.equals(keyPassphrase2Text.getText())){
         * setErrorMessage(Policy.bind("CVSSSH2PreferencePage.48"));
         * //$NON-NLS-1$ return; }
         */
        if(pass.length()==0){
          if(!MessageDialog.openConfirm(getShell(),
              Messages.CVSSSH2PreferencePage_confirmation,
              Messages.CVSSSH2PreferencePage_49)){
            return;
          }
        }

        kpair.setPassphrase(pass);

        String home=ssh2HomeText.getText();

        File _home=new File(home);

        if(!_home.exists()){
          if(!MessageDialog.openConfirm(getShell(),
              Messages.CVSSSH2PreferencePage_confirmation, NLS.bind(
                  Messages.CVSSSH2PreferencePage_50, new String[] {home}))){
            return;
          }
          if(!_home.mkdirs()){
            setErrorMessage(Messages.CVSSSH2PreferencePage_100+home);
            return;
          }
        }

        FileDialog fd=new FileDialog(getShell(), SWT.SAVE);
        fd.setFilterPath(home);
        String file=(kpair.getKeyType()==KeyPair.RSA) ? "id_rsa" : "id_dsa"; //$NON-NLS-1$ //$NON-NLS-2$
        fd.setFileName(file);
        file=fd.open();
        if(file==null){ // cancel
          return;
        }

        if(new File(file).exists()){
          if(!MessageDialog.openConfirm(getShell(),
              Messages.CVSSSH2PreferencePage_confirmation, //
              NLS.bind(Messages.CVSSSH2PreferencePage_53, new String[] {file}))){
            return;
          }
        }

        boolean ok=true;
        try{
          kpair.writePrivateKey(file);
          kpair.writePublicKey(file+".pub", kpairComment); //$NON-NLS-1$
        }
        catch(Exception ee){
          ok=false;
        }

        if(ok){
          MessageDialog.openInformation(getShell(),
              Messages.CVSSSH2PreferencePage_information,
              Messages.CVSSSH2PreferencePage_55+"\n"+ //$NON-NLS-1$
                  Messages.CVSSSH2PreferencePage_57+file+"\n"+ //$NON-NLS-1$
                  Messages.CVSSSH2PreferencePage_59+file+".pub"); //$NON-NLS-1$
        }
        else{
          return;
        }

        // The generated key should be added to privateKeyText.

        String dir=fd.getFilterPath();
        File mypkey=new java.io.File(dir, fd.getFileName());
        String pkeys=privateKeyText.getText();

        // Check if the generated key has been included in pkeys?
        String[] pkeysa=pkeys.split(","); //$NON-NLS-1$
        for(int i=0; i<pkeysa.length; i++){
          File pkey=new java.io.File(pkeysa[i]);
          if(!pkey.isAbsolute()){
            pkey=new java.io.File(home, pkeysa[i]);
          }
          if(pkey.equals(mypkey))
            return;
        }

        if(dir.equals(home)){
          dir="";} //$NON-NLS-1$
        else{
          dir+=java.io.File.separator;
        }
        if(pkeys.length()>0)
          pkeys+=","; //$NON-NLS-1$
        pkeys=pkeys+dir+fd.getFileName();
        privateKeyText.setText(pkeys);
      }
    });

    return group;
  }

  private TableViewer viewer;
  private Button removeHostKeyButton;

  Table preferedAuthMethodTable;
  Table preferedSSHAgentTable;
  Table preferedKeyExchangeMethodTable;
  Table preferedMACMethodTable;

  Button up;
  Button down;
  Button kex_up;
  Button kex_down;
  Button mac_up;
  Button mac_down;

  class TableLabelProvider extends LabelProvider implements ITableLabelProvider{
    public String getColumnText(Object element, int columnIndex){
      HostKey entry=(HostKey)element;
      switch(columnIndex){
        case 0:
          return entry.getHost();
        case 1:
          return entry.getType();
        case 2:
          return entry.getFingerPrint(getJSch());
        default:
          return null;
      }
    }

    public Image getColumnImage(Object element, int columnIndex){
      return null;
    }
  }

  private Control createHostKeyManagementPage(Composite parent){
    Composite group=new Composite(parent, SWT.NULL);
    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;
    group.setLayout(layout);
    GridData gd=new GridData();
    gd.horizontalAlignment=GridData.FILL;
    gd.verticalAlignment=GridData.FILL;
    group.setLayoutData(gd);

    Label label=new Label(group, SWT.NONE);
    label.setText(Messages.CVSSSH2PreferencePage_139);
    gd=new GridData();
    gd.horizontalSpan=2;
    label.setLayoutData(gd);

    viewer=new TableViewer(group, SWT.MULTI|SWT.FULL_SELECTION|SWT.H_SCROLL
        |SWT.V_SCROLL|SWT.BORDER);
    Table table=viewer.getTable();
    new TableEditor(table);
    table.setHeaderVisible(true);
    table.setLinesVisible(true);
    gd=new GridData(GridData.FILL_BOTH);
    gd.widthHint=convertWidthInCharsToPixels(30);
    /*
     * The hardcoded hint does not look elegant, but in reality it does not make
     * anything bound to this 100-pixel value, because in any case the tree on
     * the left is taller and that's what really determines the height.
     */
    gd.heightHint=100;
    table.setLayoutData(gd);
    table.addListener(SWT.Selection, new Listener(){
      public void handleEvent(Event e){
        handleSelection();
      }
    });
    // Create the table columns
    new TableColumn(table, SWT.NULL);
    new TableColumn(table, SWT.NULL);
    new TableColumn(table, SWT.NULL);
    TableColumn[] columns=table.getColumns();
    columns[0].setText(Messages.CVSSSH2PreferencePage_134);
    columns[1].setText(Messages.CVSSSH2PreferencePage_135);
    columns[2].setText(Messages.CVSSSH2PreferencePage_136);
    viewer.setColumnProperties(new String[] {
        Messages.CVSSSH2PreferencePage_134, //
        Messages.CVSSSH2PreferencePage_135, //
        Messages.CVSSSH2PreferencePage_136});
    viewer.setLabelProvider(new TableLabelProvider());
    viewer.setContentProvider(new IStructuredContentProvider(){
      public void dispose(){
        // nothing to do
      }

      public void inputChanged(Viewer viewer, Object oldInput, Object newInput){
        // nothing to do
      }

      public Object[] getElements(Object inputElement){
        if(inputElement==null)
          return null;
        return (Object[])inputElement;
      }
    });
    TableLayout tl=new TableLayout();
    tl.addColumnData(new ColumnWeightData(30));
    tl.addColumnData(new ColumnWeightData(20));
    tl.addColumnData(new ColumnWeightData(70));
    table.setLayout(tl);

    Composite buttons=new Composite(group, SWT.NULL);
    buttons.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING));
    layout=new GridLayout();
    layout.marginHeight=0;
    layout.marginWidth=0;
    buttons.setLayout(layout);

    removeHostKeyButton=new Button(buttons, SWT.PUSH);
    removeHostKeyButton.setText(Messages.CVSSSH2PreferencePage_138);
    int buttonWidth=SWTUtils
        .calculateControlSize(SWTUtils.createDialogPixelConverter(parent),
            new Button[] {removeHostKeyButton});
    removeHostKeyButton.setLayoutData(SWTUtils.createGridData(buttonWidth,
        SWT.DEFAULT, SWT.END, SWT.CENTER, false, false));
    removeHostKeyButton.setEnabled(false);
    removeHostKeyButton.addListener(SWT.Selection, new Listener(){
      public void handleEvent(Event e){
        removeHostKey();
      }
    });

    Dialog.applyDialogFont(parent);

    // JSchSession.loadKnownHosts(JSchContext.getDefaultContext().getJSch());
    JSchCorePlugin.getPlugin().loadKnownHosts();
    HostKeyRepository hkr=getJSch().getHostKeyRepository();
    viewer.setInput(hkr.getHostKey());
    handleSelection();

    return group;
  }

  private Control createPreferredAuthenticationPage(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_4);

    preferedAuthMethodTable=new Table(root, SWT.CHECK | SWT.BORDER);
    GridData layoutData=new GridData(SWT.FILL, SWT.BEGINNING, true, true);
    layoutData.verticalSpan = 3;
    preferedAuthMethodTable.setLayoutData(layoutData);
    layoutData.minimumHeight = 150;
    layoutData.minimumWidth = 200;
    populateAuthMethods();

    up=new Button(root, SWT.PUSH);
    up.setText(Messages.CVSSSH2PreferencePage_2);
    up.setEnabled(false);
    setButtonLayoutData(up);

    down=new Button(root, SWT.PUSH);
    down.setText(Messages.CVSSSH2PreferencePage_3);
    down.setEnabled(false);
    setButtonLayoutData(down);

    preferedAuthMethodTable.addSelectionListener(new SelectionAdapter(){

      public void widgetSelected(SelectionEvent e){
        boolean anySelected = false;
        for(int i = 0; i < preferedAuthMethodTable.getItemCount(); i++){
          anySelected |= preferedAuthMethodTable.getItem(i).getChecked();
        }

        if(anySelected){
          setErrorMessage(null);
          setValid(true);
        }
        else{
          setErrorMessage(Messages.CVSSSH2PreferencePage_5);
          setValid(false);
        }
        up.setEnabled(preferedAuthMethodTable.getSelectionIndex()>0);
        down
            .setEnabled(preferedAuthMethodTable.getSelectionIndex()<preferedAuthMethodTable
                .getItemCount()-1);
      }

    });
    up.addSelectionListener(new SelectionAdapter(){

      public void widgetSelected(SelectionEvent e){
        int selectedIndex=preferedAuthMethodTable.getSelectionIndex();
        if(selectedIndex == 1){ //this is the last possible swap
          up.setEnabled(false);
        }
        down.setEnabled(true);
        TableItem sourceItem = preferedAuthMethodTable.getItem(selectedIndex);
        TableItem targetItem = preferedAuthMethodTable.getItem(selectedIndex-1);

        //switch text
        String stemp = targetItem.getText();
        targetItem.setText(sourceItem.getText());
        sourceItem.setText(stemp);

        //switch selection
        boolean btemp = targetItem.getChecked();
        targetItem.setChecked(sourceItem.getChecked());
        sourceItem.setChecked(btemp);

        preferedAuthMethodTable.setSelection(targetItem);
      }
    });

    down.addSelectionListener(new SelectionAdapter(){

      public void widgetSelected(SelectionEvent e){
        int selectedIndex=preferedAuthMethodTable.getSelectionIndex();
        if(selectedIndex == preferedAuthMethodTable.getItemCount()-2){ //this is the last possible swap
          down.setEnabled(false);
        }
        up.setEnabled(true);
        TableItem sourceItem = preferedAuthMethodTable.getItem(selectedIndex);
        TableItem targetItem = preferedAuthMethodTable.getItem(selectedIndex+1);

        //switch text
        String stemp = targetItem.getText();
        targetItem.setText(sourceItem.getText());
        sourceItem.setText(stemp);

        //switch selection
        boolean btemp = targetItem.getChecked();
        targetItem.setChecked(sourceItem.getChecked());
        sourceItem.setChecked(btemp);

        preferedAuthMethodTable.setSelection(targetItem);
      }
    });

    return root;
  }

  private void populateAuthMethods(){
    preferedAuthMethodTable.removeAll();
    String[] methods = Utils.getEnabledPreferredAuthMethods().split(","); //$NON-NLS-1$
    Set smethods  = new HashSet(Arrays.asList(methods));

    String[] order = Utils.getMethodsOrder().split(","); //$NON-NLS-1$

    for(int i=0; i<order.length; i++){
      TableItem tableItem= new TableItem(preferedAuthMethodTable, SWT.NONE);
      tableItem.setText(0, order[i]);
      if(smethods.contains(order[i])){
        tableItem.setChecked(true);
      }
    }
  }

  private Control createPreferredKeyExchangePage(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_140);

    preferedKeyExchangeMethodTable=new Table(root, SWT.CHECK | SWT.BORDER);
    GridData layoutData=new GridData(SWT.FILL, SWT.BEGINNING, true, true);
    layoutData.verticalSpan = 3;
    preferedKeyExchangeMethodTable.setLayoutData(layoutData);
    layoutData.minimumHeight = 150;
    layoutData.minimumWidth = 200;
    populateAuthMethods();

    kex_up=new Button(root, SWT.PUSH);
    kex_up.setText(Messages.CVSSSH2PreferencePage_2);
    kex_up.setEnabled(false);
    setButtonLayoutData(kex_up);

    kex_down=new Button(root, SWT.PUSH);
    kex_down.setText(Messages.CVSSSH2PreferencePage_3);
    kex_down.setEnabled(false);
    setButtonLayoutData(kex_down);

    preferedKeyExchangeMethodTable.addSelectionListener(new SelectionAdapter(){

      public void widgetSelected(SelectionEvent e){
        boolean anySelected = false;
        for(int i = 0; i < preferedKeyExchangeMethodTable.getItemCount(); i++){
          anySelected |= preferedKeyExchangeMethodTable.getItem(i).getChecked();
        }

        if(anySelected){
          setErrorMessage(null);
          setValid(true);
        }
        else{
          setErrorMessage(Messages.CVSSSH2PreferencePage_142);
          setValid(false);
        }
        kex_up.setEnabled(preferedKeyExchangeMethodTable.getSelectionIndex()>0);
        kex_down
            .setEnabled(preferedKeyExchangeMethodTable.getSelectionIndex()<preferedKeyExchangeMethodTable
                .getItemCount()-1);
      }

    });
    kex_up.addSelectionListener(new SelectionAdapter(){

      public void widgetSelected(SelectionEvent e){
        int selectedIndex=preferedKeyExchangeMethodTable.getSelectionIndex();
        if(selectedIndex == 1){ //this is the last possible swap
          kex_up.setEnabled(false);
        }
        kex_down.setEnabled(true);
        TableItem sourceItem = preferedKeyExchangeMethodTable.getItem(selectedIndex);
        TableItem targetItem = preferedKeyExchangeMethodTable.getItem(selectedIndex-1);

        //switch text
        String stemp = targetItem.getText();
        targetItem.setText(sourceItem.getText());
        sourceItem.setText(stemp);

        //switch selection
        boolean btemp = targetItem.getChecked();
        targetItem.setChecked(sourceItem.getChecked());
        sourceItem.setChecked(btemp);

        preferedKeyExchangeMethodTable.setSelection(targetItem);
      }
    });

    kex_down.addSelectionListener(new SelectionAdapter(){

      public void widgetSelected(SelectionEvent e){
        int selectedIndex=preferedKeyExchangeMethodTable.getSelectionIndex();
        if(selectedIndex == preferedKeyExchangeMethodTable.getItemCount()-2){ //this is the last possible swap
          kex_down.setEnabled(false);
        }
        kex_up.setEnabled(true);
        TableItem sourceItem = preferedKeyExchangeMethodTable.getItem(selectedIndex);
        TableItem targetItem = preferedKeyExchangeMethodTable.getItem(selectedIndex+1);

        //switch text
        String stemp = targetItem.getText();
        targetItem.setText(sourceItem.getText());
        sourceItem.setText(stemp);

        //switch selection
        boolean btemp = targetItem.getChecked();
        targetItem.setChecked(sourceItem.getChecked());
        sourceItem.setChecked(btemp);

        preferedKeyExchangeMethodTable.setSelection(targetItem);
      }
    });

    return root;
  }

  private void populateKeyExchangeMethods(){
    preferedKeyExchangeMethodTable.removeAll();
    String[] methods = Utils.getEnabledPreferredKEXMethods().split(","); //$NON-NLS-1$
    Set smethods  = new HashSet(Arrays.asList(methods));

    String[] order = Utils.getKEXMethodsOrder().split(","); //$NON-NLS-1$

    for(int i=0; i<order.length; i++){
      TableItem tableItem= new TableItem(preferedKeyExchangeMethodTable, SWT.NONE);
      tableItem.setText(0, order[i]);
      if(smethods.contains(order[i])){
        tableItem.setChecked(true);
      }
    }
  }

  private Control createPreferredMACPage(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_141);

    preferedMACMethodTable=new Table(root, SWT.CHECK | SWT.BORDER);
    GridData layoutData=new GridData(SWT.FILL, SWT.BEGINNING, true, true);
    layoutData.verticalSpan = 3;
    preferedMACMethodTable.setLayoutData(layoutData);
    layoutData.minimumHeight = 150;
    layoutData.minimumWidth = 200;
    populateMACMethods();

    mac_up=new Button(root, SWT.PUSH);
    mac_up.setText(Messages.CVSSSH2PreferencePage_2);
    mac_up.setEnabled(false);
    setButtonLayoutData(mac_up);

    mac_down=new Button(root, SWT.PUSH);
    mac_down.setText(Messages.CVSSSH2PreferencePage_3);
    mac_down.setEnabled(false);
    setButtonLayoutData(mac_down);

    preferedMACMethodTable.addSelectionListener(new SelectionAdapter(){

      public void widgetSelected(SelectionEvent e){
        boolean anySelected = false;
        for(int i = 0; i < preferedMACMethodTable.getItemCount(); i++){
          anySelected |= preferedMACMethodTable.getItem(i).getChecked();
        }

        if(anySelected){
          setErrorMessage(null);
          setValid(true);
        }
        else{
          setErrorMessage(Messages.CVSSSH2PreferencePage_143);
          setValid(false);
        }
        mac_up.setEnabled(preferedMACMethodTable.getSelectionIndex()>0);
        mac_down
            .setEnabled(preferedMACMethodTable.getSelectionIndex()<preferedMACMethodTable
                .getItemCount()-1);
      }

    });
    mac_up.addSelectionListener(new SelectionAdapter(){

      public void widgetSelected(SelectionEvent e){
        int selectedIndex=preferedMACMethodTable.getSelectionIndex();
        if(selectedIndex == 1){ //this is the last possible swap
          mac_up.setEnabled(false);
        }
        mac_down.setEnabled(true);
        TableItem sourceItem = preferedMACMethodTable.getItem(selectedIndex);
        TableItem targetItem = preferedMACMethodTable.getItem(selectedIndex-1);

        //switch text
        String stemp = targetItem.getText();
        targetItem.setText(sourceItem.getText());
        sourceItem.setText(stemp);

        //switch selection
        boolean btemp = targetItem.getChecked();
        targetItem.setChecked(sourceItem.getChecked());
        sourceItem.setChecked(btemp);

        preferedMACMethodTable.setSelection(targetItem);
      }
    });

    mac_down.addSelectionListener(new SelectionAdapter(){

      public void widgetSelected(SelectionEvent e){
        int selectedIndex=preferedMACMethodTable.getSelectionIndex();
        if(selectedIndex == preferedMACMethodTable.getItemCount()-2){ //this is the last possible swap
          mac_down.setEnabled(false);
        }
        mac_up.setEnabled(true);
        TableItem sourceItem = preferedMACMethodTable.getItem(selectedIndex);
        TableItem targetItem = preferedMACMethodTable.getItem(selectedIndex+1);

        //switch text
        String stemp = targetItem.getText();
        targetItem.setText(sourceItem.getText());
        sourceItem.setText(stemp);

        //switch selection
        boolean btemp = targetItem.getChecked();
        targetItem.setChecked(sourceItem.getChecked());
        sourceItem.setChecked(btemp);

        preferedMACMethodTable.setSelection(targetItem);
      }
    });

    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$
    Set smethods  = new HashSet(Arrays.asList(methods));

    String[] order = Utils.getMACMethodsOrder().split(","); //$NON-NLS-1$

    for(int i=0; i<order.length; i++){
      TableItem tableItem= new TableItem(preferedMACMethodTable, SWT.NONE);
      tableItem.setText(0, order[i]);
      if(smethods.contains(order[i])){
        tableItem.setChecked(true);
      }
    }
  }

  void handleSelection(){
    boolean empty=viewer.getSelection().isEmpty();
    removeHostKeyButton.setEnabled(!empty);
  }

  void removeHostKey(){
    IStructuredSelection selection=viewer.getStructuredSelection();
    HostKeyRepository hkr=getJSch().getHostKeyRepository();
    for(Iterator iterator=selection.iterator(); iterator.hasNext();){
      HostKey hostkey=(HostKey)iterator.next();
      hkr.remove(hostkey.getHost(), hostkey.getType());
      viewer.remove(hostkey);
    }
  }

  void export_via_sftp(String user, String host, int port, byte[] pkey) throws JSchException{
    try{

      int timeout = 60000;
      IJSchService service = JSchUIPlugin.getPlugin().getJSchService();
      if (service == null) {
        MessageDialog.openInformation(getShell(), Messages.PreferencePage_0, Messages.PreferencePage_1);
        return;
      }

      IJSchLocation location=service.getLocation(user, host, port);
      // We hope that prompts for jsch are given by IJSchService, so "null" should be passed.
      Session session = service.createSession(location, null);
      session.setTimeout(timeout);
      try {
        service.connect(session, timeout, new NullProgressMonitor());
	      if(session.getServerVersion().indexOf("OpenSSH")==-1){ //$NON-NLS-1$
	        setErrorMessage(Messages.CVSSSH2PreferencePage_110);
	        return;
	      }
	      Channel channel=session.openChannel("sftp"); //$NON-NLS-1$
	      channel.connect();
	      ChannelSftp c=(ChannelSftp)channel;

	      SftpATTRS attr=null;

	      try{
	        attr=c.stat(".ssh");} //$NON-NLS-1$
	      catch(SftpException ee){
          // Ignore
	      }
	      if(attr==null){
	        try{
	          c.mkdir(".ssh");} //$NON-NLS-1$
	        catch(SftpException ee){
	          setErrorMessage(ee.getMessage());
	          return;
	        }
	      }
	      try{
	        c.cd(".ssh");} //$NON-NLS-1$
	      catch(SftpException ee){
	        setErrorMessage(ee.getMessage());
	        return;
	      }

	      try{
	        ByteArrayInputStream bis=new ByteArrayInputStream(pkey);
	        c.put(bis, "authorized_keys", null, ChannelSftp.APPEND); //$NON-NLS-1$
	        bis.close();
	        checkPermission(c, "authorized_keys"); //$NON-NLS-1$
	        checkPermission(c, "."); // .ssh //$NON-NLS-1$
	        c.cd(".."); //$NON-NLS-1$
	        checkPermission(c, "."); // home directory //$NON-NLS-1$
	      }
	      catch(SftpException ee){
	        // setErrorMessage(debug+ee.message);
	      }

	      MessageDialog.openInformation(getShell(),
	          Messages.CVSSSH2PreferencePage_information,
	          NLS.bind(Messages.CVSSSH2PreferencePage_109, (user
	              +"@"+host+(port==22 ? "" : ":"+port)+":~/.ssh/authorized_keys"))); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$

	      c.quit();
	      c.disconnect();
      } finally {
        session.disconnect();
      }
    } catch(IOException eee){
      setErrorMessage(eee.toString());
    }
  }

  private void checkPermission(ChannelSftp c, String path) throws SftpException{
    SftpATTRS attr=c.stat(path);
    int permissions=attr.getPermissions();
    if((permissions&00022)!=0){
      permissions&=~00022;
      c.chmod(permissions, path);
    }
  }

  void updateControls(){
    boolean enable=(kpair!=null);
    publicKeylabel.setEnabled(enable);
    publicKeyText.setEnabled(enable);
    keyFingerPrintLabel.setEnabled(enable);
    keyFingerPrintText.setEnabled(enable);
    keyCommentLabel.setEnabled(enable);
    keyCommentText.setEnabled(enable);
    keyPassphrase1Label.setEnabled(enable);
    keyPassphrase1Text.setEnabled(enable);
    keyPassphrase2Label.setEnabled(enable);
    keyPassphrase2Text.setEnabled(enable);
    keyExport.setEnabled(enable);
    saveKeyPair.setEnabled(enable);
    populateAuthMethods();
    populateKeyExchangeMethods();
    populateMACMethods();
    up.setEnabled(false);
    down.setEnabled(false);
    kex_up.setEnabled(false);
    kex_down.setEnabled(false);
    mac_up.setEnabled(false);
    mac_down.setEnabled(false);
  }

  public void init(IWorkbench workbench){
    // super.init(workbench);
    // initControls();
  }

  public void initialize(){
    initControls();
  }

  private void initControls(){
    Preferences preferences=JSchCorePlugin.getPlugin().getPluginPreferences();
    ssh2HomeText.setText(preferences
        .getString(org.eclipse.jsch.internal.core.IConstants.KEY_SSH2HOME));
    privateKeyText.setText(preferences
        .getString(org.eclipse.jsch.internal.core.IConstants.KEY_PRIVATEKEY));
    updateControls();
  }

  public boolean performOk(){
    boolean result=super.performOk();
    storeAuthenticationMethodSettings();
    storeSSHAgentSettings();
    storeKeyExchangeMethodSettings();
    storeMACMethodSettings();

    if(result){
      setErrorMessage(null);
      String home=ssh2HomeText.getText();
      File _home=new File(home);
      if(!_home.exists()){
        if(MessageDialog.openQuestion(getShell(),
            Messages.CVSSSH2PreferencePage_question, NLS.bind(
                Messages.CVSSSH2PreferencePage_99, new String[] {home}))){
          if(!(_home.mkdirs())){
            setErrorMessage(Messages.CVSSSH2PreferencePage_100+home);
            return false;
          }
        }
      }

      Preferences preferences=JSchCorePlugin.getPlugin().getPluginPreferences();
      preferences.setValue(
          org.eclipse.jsch.internal.core.IConstants.KEY_SSH2HOME, home);
      preferences.setValue(
          org.eclipse.jsch.internal.core.IConstants.KEY_PRIVATEKEY,
          privateKeyText.getText());
    }
    JSchCorePlugin.getPlugin().setNeedToLoadKnownHosts(true);
    JSchCorePlugin.getPlugin().setNeedToLoadKeys(true);
    JSchCorePlugin.getPlugin().setIdentityRepository();
    JSchCorePlugin.getPlugin().savePluginPreferences();
    return result;
  }

  private void storeAuthenticationMethodSettings(){
    String selected = null;
    String order = null;
    for(int i = 0; i < preferedAuthMethodTable.getItemCount(); i++){
      TableItem item=preferedAuthMethodTable.getItem(i);
      if(item.getChecked()){
        if(selected==null){
          selected=item.getText();
        }
        else{
          selected+=","+item.getText(); //$NON-NLS-1$
        }
      }
      if(order == null){
        order = item.getText();
      } else {
        order += "," + item.getText(); //$NON-NLS-1$
      }
    }
    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;
    for(int i = 0; i < preferedKeyExchangeMethodTable.getItemCount(); i++){
      TableItem item=preferedKeyExchangeMethodTable.getItem(i);
      if(item.getChecked()){
        if(selected==null){
          selected=item.getText();
        }
        else{
          selected+=","+item.getText(); //$NON-NLS-1$
        }
      }
      if(order == null){
        order = item.getText();
      } else {
        order += "," + item.getText(); //$NON-NLS-1$
      }
    }
    Utils.setEnabledPreferredKEXMethods(selected, order);
  }

  private void storeMACMethodSettings(){
    String selected = null;
    String order = null;
    for(int i = 0; i < preferedMACMethodTable.getItemCount(); i++){
      TableItem item=preferedMACMethodTable.getItem(i);
      if(item.getChecked()){
        if(selected==null){
          selected=item.getText();
        }
        else{
          selected+=","+item.getText(); //$NON-NLS-1$
        }
      }
      if(order == null){
        order = item.getText();
      } else {
        order += "," + item.getText(); //$NON-NLS-1$
      }
    }
    Utils.setEnabledPreferredMACMethods(selected, order);
  }

  public void performApply(){
    performOk();
  }

  protected void performDefaults(){
    super.performDefaults();
    Utils.setEnabledPreferredAuthMethods(Utils.getDefaultAuthMethods(), Utils
        .getDefaultAuthMethods());
    Preferences preferences=JSchCorePlugin.getPlugin().getPluginPreferences();
    ssh2HomeText
        .setText(preferences
            .getDefaultString(org.eclipse.jsch.internal.core.IConstants.KEY_SSH2HOME));
    privateKeyText
        .setText(preferences
            .getDefaultString(org.eclipse.jsch.internal.core.IConstants.KEY_PRIVATEKEY));
    updateControls();
  }

  protected void createSpacer(Composite composite, int columnSpan){
    Label label=new Label(composite, SWT.NONE);
    GridData gd=new GridData();
    gd.horizontalSpan=columnSpan;
    label.setLayoutData(gd);
  }

  JSch getJSch(){
    return JSchCorePlugin.getPlugin().getJSch();
  }

  class PassphrasePrompt implements Runnable{
    private String message;
    private String passphrase;

    PassphrasePrompt(String message){
      this.message=message;
    }

    public void run(){
      Display display=Display.getCurrent();
      Shell shell=new Shell(display);
      PassphraseDialog dialog=new PassphraseDialog(shell, message);
      dialog.open();
      shell.dispose();
      passphrase=dialog.getPassphrase();
    }

    public String getPassphrase(){
      return passphrase;
    }
  }
}
