/*******************************************************************************
 * Copyright (c) 2000, 2018 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * 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.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.FileDialog;
import org.eclipse.swt.widgets.Label;
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);
	}

	@Override
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(){
			@Override
			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(){
			@Override
			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(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(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(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(){
			@Override
			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);
				}
			}

			@Override
			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(){
			@Override
			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(), () -> {
						try {
							_kpair[0] = KeyPair.genKeyPair(getJSch(), __type);
						} catch (JSchException e1) {
							_e[0] = e1;
						}
					});
					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(){
			@Override
			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(){
			@Override
			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(() -> {
					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(){
			@Override
	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{
		@Override
		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;
			}
		}

		@Override
		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, 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(){
			@Override
			public void dispose(){
				// nothing to do
			}

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

			@Override
			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, 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(){

			@Override
			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(){

			@Override
			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(){

			@Override
			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<String> 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(){

			@Override
			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(){

			@Override
			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(){

			@Override
			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<String> 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(){

			@Override
			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(){

			@Override
			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(){

			@Override
			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<String> 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);
	}

	@Override
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();
	}

	@Override
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);
	}

	@Override
public void performApply(){
		performOk();
	}

	@Override
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;
		}

		@Override
		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;
		}
	}
}
