public enum ConsoleOptions_Params{
	c,
	d,
	e,
	t,
	prov,
	cred,
	cloak,
	verbose,
}
 public class CrocoFilereader {
	static{
		InitCrypto.INIT();
	}
	
	private SuccessCallback cb;
	private Suite suite;
	private File croco;
	private File destdir;
	private StatusUpdate stat;
	
	public CrocoFilereader(SuccessCallback cb, Suite suite, File croco, File destdir){
		this.cb = cb;
		this.suite = suite;
		this.croco = croco;
		this.destdir = destdir;
	}
	
	public void execute(StatusUpdate status) {
		stat = status;
		if(croco.isDirectory() || !croco.exists()) return;
		
		new Thread(new Runnable() {
			@Override
			public void run() {
				SUCCESS success = SUCCESS.FALSE;

				try {
					if(suite == null) return;
					if(stat != null) stat.start();
					
					FileInputStream is = new FileInputStream(croco);
					if(!(suite instanceof PBECloaked_AES2F_Main)) StreamMachine.read(is, SUITES.MAGICNUMBER_LENGTH);
					suite.readFrom(is);
					
					if(stat != null && !stat.isActive()){
						success = SUCCESS.CANCEL;
						return;
					}
					
					DumpHeader dh = new DumpHeader(suite);
					dh.readFrom(is);
					is.close();
					if(!dh.isValid()) return;
					
					if(stat != null) stat.receiveMessageSummary(_T.Decrypt_Start.msg(dh.ATTRIBUTE_DUMPCOUNT));
					DumpReader rf = new DumpReader(suite.suiteLength() + dh.headerLength());
					rf.setStatusReader(stat);
					rf.main(croco.getAbsolutePath(), destdir.getAbsolutePath(), suite, dh);
					
					if(stat == null || stat.isActive())
						success = SUCCESS.TRUE;
					if(stat != null && !stat.isActive())
						success = SUCCESS.CANCEL;
				}
				catch (FileNotFoundException e) {
					CrococryptFile.LASTERROR = _T.DecryptWindow_folderreadonly.val();
					e.printStackTrace();
				}
				catch (IOException e) {
					e.printStackTrace();
				}
				catch (Exception e) {
					e.printStackTrace();
				}
				
				
				finally {
					if(cb != null) cb.callbackValue(this, success);
					if(stat != null) stat.finished();
					if(suite != null) suite.deinit();
				}
			}
		}).start();
	}
}
 public class CrocoFilewriter {
	static{
		InitCrypto.INIT();
	}
	
	private SuccessCallback cb;
	private Suite suite;
	private File[] files;
	private File outfile;
	private StatusUpdate stat;

	public CrocoFilewriter(SuccessCallback cb, Suite suite, File[] files, File outfile){
		this.cb = cb;
		this.suite = suite;
		this.files = files;
		this.outfile = outfile;
	}
	
	public void execute() {
		execute(null);
	}

	public void execute(StatusUpdate status) {
		this.stat = status;

		new Thread(new Runnable() {
			@Override
			public void run() {
				SUCCESS success = SUCCESS.FALSE;
				Index index = null;
				OutputStream os = null;
				
				try {
					if(suite == null) return;
					if(outfile.isDirectory()) return;
					
					if(stat != null) stat.start();
					
					index = new Index(new File(outfile.getParentFile(), outfile.getName() + ".parttmp"));
					DumpWriter wf = new DumpWriter(suite, index);
					wf.setStatusReader(stat);
					wf.setOutfile(outfile);
					
					os = new FileOutputStream(outfile);
					if(!(suite instanceof PBECloaked_AES2F_Main)) SUITES.create(os, SUITES.numberFromClass(suite));
					suite.writeTo(os);
					DumpHeader dh = new DumpHeader(suite);
					dh.createOut(os);
					
					wf.initStreams(os);

					int len = files.length;
					int i=0;
					
					for(File tmp: files){
						if(!tmp.exists()) continue;
						
						wf.write(tmp.getAbsolutePath());
						if(stat != null) {
							if(!stat.isActive()) break;
							i++;
							stat.receiveProgress((int)(((float)i/(float)len) * 100f));
						}
					}
					wf.close(false);
					
					if(stat != null){
						if(stat.isActive()){
							stat.receiveDetailsProgress(100);
							stat.receiveMessageSummary(_T.General_done.val());
						}
						else{
							success = SUCCESS.CANCEL;
							outfile.delete();
							index.delete();
							return;
						}
					}
				
					long dumplen = outfile.length();
					long ct = index.getCount();
					
					wf.seal(false, outfile);
					
					RandomAccessFile raf = new RandomAccessFile(outfile, "rw");
					raf.seek(suite.suiteLength());
					FileOutputStream fos = new FileOutputStream(raf.getFD());
					dh.ATTRIBUTE_DUMPLEN = dumplen;
					dh.ATTRIBUTE_DUMPCOUNT = ct;
					dh.createOut(fos);
					
					if(suite instanceof PBECloaked_AES2F_Main && ((PBECloaked_AES2F_Main)suite).fill()){
						int mbs = (int) (raf.length() % (1024*1024));
						mbs = (1024*1024) - mbs;
						if(mbs > 0){
							byte[] rand = CryptoUtils.randIv(mbs);
							raf.seek(raf.length());
							raf.write(rand);
							CryptoUtils.kill(rand);
						}
					}

					fos.close();
					raf.close();
					
					success = SUCCESS.TRUE;
				}
				catch (FileNotFoundException e) {
					CrococryptFile.LASTERROR = _T.EncryptWindow_folderreadonly.val();
					e.printStackTrace();
				}
				catch (IOException e) {
					CrococryptFile.LASTERROR = _T.EncryptWindow_folderreadonly.val();
					e.printStackTrace();
				}
				finally{
					if(success != SUCCESS.TRUE){
						try {
							index.delete();
							os.close();
						} catch (Exception e2) {}
						outfile.delete();
					}
					
					if(cb != null) cb.callbackValue(this, success);
					if(stat != null) stat.finished();
					if(suite != null) suite.deinit();
				}
			}
		}).start();
	}
}
 public interface BasicFileinfo {
	public static final String FILEEXTENSION = "croco";
	public static final String FILEEXTENSIONwDOT = "." + FILEEXTENSION;
	public static final int FILEEXTENSIONwDOT_LENGTH = FILEEXTENSIONwDOT.length();

	public static final int BASENUMBER = 191908000;
	public static final int MAGICNUMBER_LENGTH = 4;
}
 public enum SUITES implements BasicFileinfo{
	PBE1_AES(BASENUMBER + 10),
	PBE1_TWOFISH(BASENUMBER + 13),
	PBE1_SERPENT(BASENUMBER + 14),
	PBE1_CAMELLIA(BASENUMBER + 15),
	CAPI_RSAAES(BASENUMBER + 20),
	PGP_AES(BASENUMBER + 30),
	PBECLOAKED_AESTWO(BASENUMBER + 1000),
	PBECLOAKED1MB_AESTWO(BASENUMBER + 1001),

	;
	
	private int magicnumber;
	private ArrayList<OS> osspec = null;
	private SuitePARAM[] encparams, decparams;
	private SUITES(int magicnumber){
		this.magicnumber = magicnumber;
	}
	
	protected final void setOS(OS os){
		setOS(new OS[]{os});
	}

	protected final void setOS(OS[] oss){
		if(oss != null && oss.length > 0){
			osspec = new ArrayList<>();
			Collections.addAll(osspec, oss);
		}
	}
	
	protected final void setEncParams(SuitePARAM[] params){
		encparams = params;
	}
	
	protected final void setDecParams(SuitePARAM[] params){
		decparams = params;
	}
	
	public final SuitePARAM[] getEncryptParameters(){
		return encparams;
	}
	
	public final SuitePARAM[] getDecryptParameters(){
		return decparams;
	}
	
	public final boolean hasEncryptParameters(){
		return encparams != null && encparams.length > 0;
	}
	
	public final boolean hasDecryptParameters(){
		return decparams != null && decparams.length > 0;
	}
	
	public final int magicNumber(){
		return magicnumber;
	}
	
	public final boolean isAvailable(){
		if(osspec == null || osspec.contains(OSDetector.which())) return true;
		return false;
	}

	
	@SuppressWarnings("rawtypes")
	public static final ArrayList<Class> headers = new ArrayList<>();
	public static final ArrayList<Integer> numbers = new ArrayList<>();
	public static final ArrayList<String> descriptor = new ArrayList<>();
	public static final HashMap<Integer, SUITES> id = new HashMap<>();

	static{
		add(PBE1AESMain.class, PBE1_AES);
		add(PBE1TwofishMain.class, PBE1_TWOFISH);
		add(PBE1SerpentMain.class, PBE1_SERPENT);
		add(PBE1CamelliaMain.class, PBE1_CAMELLIA);
		add(CAPIRSAAESMain.class, CAPI_RSAAES);
		add(PGPAESMain.class, PGP_AES);
		add(PBECloaked_AES2F_Main.class, PBECLOAKED_AESTWO);
		add(PBECloaked_AES2F_Main_1MB.class, PBECLOAKED1MB_AESTWO);

		
				SUITES[] passworders = {
				PBE1_AES,
				PBE1_TWOFISH,
				PBE1_SERPENT,
				PBE1_CAMELLIA,
				PBECLOAKED_AESTWO,
				PBECLOAKED1MB_AESTWO,
		};
		
		for(SUITES s: passworders){
			s.setEncParams(new SuitePARAM[]{SuitePARAM.password});
			s.setDecParams(new SuitePARAM[]{SuitePARAM.password});
		}
		
		CAPI_RSAAES.setOS(OS.WIN);
		CAPI_RSAAES.setEncParams(new SuitePARAM[]{SuitePARAM.capi_alias});
		
		PGP_AES.setEncParams(new SuitePARAM[]{SuitePARAM.pgp_enc});
		PGP_AES.setDecParams(new SuitePARAM[]{SuitePARAM.pgp_dec});
		
		
		HashSet<Integer> nos = new HashSet<>();
		for(SUITES s: SUITES.values()){
			if(nos.contains(s.magicNumber()))
				System.err.println("WARNING: Same magic number used twice!");
			else
				nos.add(s.magicNumber());
		}
	}
	
	private static final void add(@SuppressWarnings("rawtypes") Class suiteClass, SUITES s){
		headers.add(suiteClass);
		numbers.add(s.magicNumber());
		descriptor.add(_T.valueOf("Suite_" + s.name()).val());
		id.put(s.magicNumber(), s);
	}
	
	public static final int numberFromClass(Suite header){
		int no = headers.indexOf(header.getClass());
		return numbers.get(no);
	}

	@SuppressWarnings("rawtypes")
	public static final Class classFromSuites(SUITES suite){
		int no = numbers.indexOf(suite.magicNumber());
		return headers.get(no);
	}

	
	public static void create(OutputStream out, int magicnumber) throws IOException{
		StreamMachine.write(out, magicnumber);
	}
	
	public static SUITES read(File f){
		try {
			return readNclose(new FileInputStream(f));
		} catch (Exception e) {
			return null;
		}
	}
	
	public static SUITES readNclose(InputStream is){
		SUITES suite = null;
		suite = read(is);

		try {
			is.close();
		} catch (Exception e) {}
		
		return suite;
	}

	public static SUITES read(InputStream is){
		int i = -1;
		i = StreamMachine.readO(is, i);
		return id.get(i);
	}
	
	private static String providerline;
	public static String providerListAsLine(){
		if(providerline == null){
			providerline = "";
			for(SUITES sx: SUITES.values())
				providerline += sx.name() + " ";
			providerline = providerline.trim();
		}
		return providerline;
	}
}
 public abstract class Suite {
	private SuiteMODE mode;
	private StatusUpdate status;
	private boolean initialized = false;
	
	protected Suite(){}
	
	public final void init(SuiteMODE mode, HashMap<SuitePARAM, Object> params, StatusUpdate status) throws IllegalArgumentException{
		if(mode == null) throw new IllegalArgumentException("no mode specified");
		
		this.status = status;
		_init(mode, params);
		
		this.mode = mode;
		initialized = true;
	}
	
	public SuiteMODE getMode(){
		return mode;
	}
	
	public final void writeTo(OutputStream out) throws IllegalStateException{
		if(!initialized) throw new IllegalStateException("not initialized");
		if(getMode() != SuiteMODE.ENCRYPT) throw new IllegalStateException("wrong mode");
		
		_writeTo(out);
	}
	
	public final void readFrom(InputStream is) throws IllegalStateException{
		if(!initialized) throw new IllegalStateException("not initialized");
		if(getMode() != SuiteMODE.DECRYPT) throw new IllegalStateException("wrong mode");
		
		_readFrom(is);
	}

	abstract protected void _init(SuiteMODE mode, HashMap<SuitePARAM, Object> params) throws IllegalArgumentException;
	abstract protected void _writeTo(OutputStream out) throws IllegalStateException;
	abstract protected void _readFrom(InputStream is) throws IllegalStateException;
	abstract public CipherMain getCipher();
	abstract public byte[] getAttributeIV();
	abstract public int headerLength();
	abstract public void deinit();
	
	public final byte[] getAlteredIV(int add){
		add = add % CryptoCodes.STANDARD_IVSIZE;
		byte[] buf = Arrays.copyOf(getAttributeIV(), CryptoCodes.STANDARD_IVSIZE);
		buf[add]++;
		return buf;
	}
	
	private int len = -1;
	public final int suiteLength(){
		if(len < 0){
			len = headerLength();
			if(!(this instanceof PBECloaked_AES2F_Main)) len += SUITES.MAGICNUMBER_LENGTH;
		}
		return len;
	}
	
	public final StatusUpdate getStatus(){
		return status;
	}
	
	
	public static final Suite getInstance(SUITES suite){
		try {
			return (Suite)(SUITES.classFromSuites(suite).newInstance());
		} catch (Exception e) {
			System.err.println("getInstance: " + e.getLocalizedMessage());
			return null;	
		}
	}

	public static final Suite getInitializedInstance(SUITES suite, SuiteMODE mode, HashMap<SuitePARAM, Object> params, StatusUpdate status){
		try {
			Suite instance = (Suite)(SUITES.classFromSuites(suite).newInstance());
			instance.init(mode, params, status);
			return instance;
		} catch (Exception e) {
			e.printStackTrace();
			System.err.println("getInitializedInstance: " + e.getLocalizedMessage());
			return null;	
		}
	}
	
	
	public static final void getInitializedInstanceAsync(final SUITES suite, final SuiteMODE mode,
			final HashMap<SuitePARAM, Object> params, final StatusUpdate status, final SuiteReceiver rec){
		if(rec == null){
			System.err.println("SuiteReceiver == null");
			return;
		}

		if(suite == null){
			System.err.println("Requested SUITES == null");
			rec.receiveInitializedInstance(null);
			return;
		}
		
		new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					Suite instance = (Suite)(SUITES.classFromSuites(suite).newInstance());
					instance.init(mode, params, status);
					rec.receiveInitializedInstance(instance);
				} catch (Exception e) {
					e.printStackTrace();
					System.err.println("getInitializedInstanceAsync: " + e.getLocalizedMessage());
					rec.receiveInitializedInstance(null);
				}
			}
		}).start();
	}
	
	
	public static final Suite getInitializedInstance(SUITES suite, SuiteMODE mode, SuitePARAM aparam, Object avalue){
		HashMap<SuitePARAM, Object> params = new HashMap<>();
		params.put(aparam, avalue);
		return getInitializedInstance(suite, mode, params, null);
	}
	

	public interface SuiteReceiver{
		public void receiveInitializedInstance(Suite suite);
	}
}
 public interface SuiteReceiver{
	public void receiveInitializedInstance(Suite suite);
}
 public enum SuiteMODE {
	ENCRYPT,
	DECRYPT,
}
 public enum SuitePARAM {
	password,
	itcount,
	
	capi_alias,
	
	
	pgp_enc,
	pgp_dec,
	
	pgp_keyidlist,
	pgp_pubkeyfile,
	pgp_privkeyfile,
	
	
	;
}
 public interface CbIDecrypt{
	public void callbackDecrypt(Object source, File destinationFolder);
	public boolean isDecryptRunning(Object source);
}
 public interface CbIEncrypt{
	public void callbackEncrypt(Object source, File destination, SUITES provider);
	public boolean isEncryptRunning(Object source);
}
 public class UICenter {
	private static boolean CONSOLE = false;
	private static boolean INITIALIZED = false;
	
	static{
		INIT();
	}

	public static final void INIT(){
		if(INITIALIZED) return;
		INITIALIZED = true;
		
		try {
			boolean headless = false;
			try {
				headless = GraphicsEnvironment.isHeadless();
			} catch (Throwable t) {
				headless = true;
				System.err.println(t.getLocalizedMessage());
			}
			
			if(headless){
				CONSOLE = true;
			}
			else{
				UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
				JOptionPane.setDefaultLocale(ResourceCenter.getLocale());
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		if(OSDetector.isMac()){
			System.setProperty("apple.laf.useScreenMenuBar", "true");
			System.setProperty("com.apple.mrj.application.apple.menu.about.name", ResourceCenter.TITLE);
		}
	}
	
	public static final boolean isGUI(){
		return CONSOLE == false;
	}

	public static final boolean isCUI(){
		return CONSOLE;
	}
	
	public static final void setCUI(){
		CONSOLE = true;
	}
	
	public static final void setGUI(){
		if(GraphicsEnvironment.isHeadless()) return;
		CONSOLE = false;
	}
	
	
	public static final void message(String s){
		if(isGUI())
			SimpleDialogs.message(s);
		else
			CPrint.line(s);
	}
	
	public static final void message(_T text){
		message(text.val());
	}
}
 public class CPrint {
	public static final void print(Object o){
		System.out.print(o);
	}
	
	public static final void line(Object o){
		System.out.println(o);
	}

	public static final void linefeed(){
		System.out.println();
	}

	public static final void error(Object o){
		System.err.println(o);
	}
}
 public class PasswordCreateConsole {
	public void main(SimpleCallback<char[]> cb) {
		Console con = System.console();
		
		if(con == null){
			System.err.println("Your system does not support an interactive console for this operation");
			return;
		}
		
		CPrint.print(_T.PasswordEncrypt_title + ": ");
		char[] pass = con.readPassword();
		CPrint.print(_T.PasswordEncrypt_retype + ": ");
		char[] pass2 = con.readPassword();
		
		if(pass == null || pass2 == null || pass.length == 0 || pass2.length == 0){
			cb.callbackValue(this, null);
			return;
		}
		
		int minlen = CryptoCodes.STANDARD_PBKDF2_PWLEN;

		if(Arrays.equals(pass, pass2) && pass.length >= minlen){
			CryptoUtils.kill(pass2);
			cb.callbackValue(this, pass);
		}
		else{
			CryptoUtils.kill(pass);
			CryptoUtils.kill(pass2);
			
			if(pass.length < minlen)
				CPrint.line(_T.PasswordEncrypt_len.msg(minlen));
			else
				CPrint.line(_T.PasswordEncrypt_nomatch);
			
			main(cb);
		}
	}
}
 public class PasswordInputConsole {
	public void main(SimpleCallback<char[]> cb) {
		Console con = System.console();
		
		if(con == null){
			System.err.println("Your system does not support an interactive console for this operation");
			return;
		}
		
		CPrint.print(_T.PasswordDecrypt_title + ": ");
		char[] pass = con.readPassword();
		
		if(pass == null || pass.length == 0){
			cb.callbackValue(this, null);
			return;
		}
		
		cb.callbackValue(this, pass);
	}
}
 public class StatusConsole implements StatusUpdate{
	@Override
	public void start() {
		CPrint.line("Starting...");
	}

	@Override
	public void finished() {
	}

	@Override
	public boolean isActive() {
		return true;
	}

	@Override
	public void receiveMessageSummary(String msg) {
		CPrint.linefeed();
		CPrint.line("===" + msg + "===");
	}

	@Override
	public void receiveMessageDetails(String msg) {
		CPrint.linefeed();
		CPrint.line(msg);
	}

	@Override
	public void receiveProgress(int perc) {
		CPrint.linefeed();
		CPrint.line("Overall: " + perc + "%");
	}

	@Override
	public void receiveDetailsProgress(int perc) {
		if(perc <= 0) return;
		if(perc % 100 == 0) CPrint.print(" " + perc + "%");
	}
}
 public class CrocoparamsDialog{
	private SimpleCallback<CrococryptParameters> cb;
	private CrococryptParameters params = new CrococryptParameters();
	private String title;
	
	private CrocoparamsDialog(SimpleCallback<CrococryptParameters> cb, CrococryptParameters base, String title){
		this.cb = cb;
		this.title = title;
		if(base == null)
			params = new CrococryptParameters();
		else
			params = base;
		startSequence();
	}
	
	private SimpleCallback<File[]> cbfiles = new SimpleCallback<File[]>(){
		@Override public void callbackValue(Object source, File[] ret) {
			receive(ret);
		}
	};
	
	private void receive(File[] ret){
		if(ret == null || ret.length == 0) return;

		Collections.addAll(params.filesanddirs, ret);

		for(File f: ret){
			if(f.isFile())
				params.filecount++;
			else
				params.dircount++;
		}
		
		cb.callbackValue(this, params);
	}
	
	private void startSequence(){
		FileSelectdialog.Options opt = new FileSelectdialog.Options();
		opt.buttoncaption = _T.FileSelection_selectbutton.val();
		opt.title = title;
		if(opt.title == null) opt.title = _T.FileSelection_title.val();
		opt.multiselect = true;
		opt.foldersonly = false;
		FileSelectdialog.select(cbfiles, opt);
	}

	public static final void requestParams(SimpleCallback<CrococryptParameters> cb, CrococryptParameters base){
		requestParams(cb, base, null);
	}
	
	public static final void requestParams(SimpleCallback<CrococryptParameters> cb, CrococryptParameters base, String title){
		new CrocoparamsDialog(cb, base, title);
	}
}
 public class PGP_PrivatekeyDialog {
	private SimpleCallback<HashMap<SuitePARAM, Object>> cb;
	private HashMap<SuitePARAM, Object> params = new HashMap<>();
	Object source = null;
	
	private PGP_PrivatekeyDialog(Object src, SimpleCallback<HashMap<SuitePARAM, Object>> cb){
		this.cb = cb;
		source = src;
		
		File sec = null;
		String tmp = ResourceCenter.getSettings().get(Settings.lastpgp_privfile);
		if(tmp == null){
			sec = PGPUtils.getPrivRing();
		}
		else{
			File ftmp = new File(tmp);
			if(ftmp.exists() && ftmp.isFile()) sec = ftmp;
			else sec = PGPUtils.getPrivRing();
		}
		
		if(sec != null && sec.length() > 1){
			params.put(SuitePARAM.pgp_privkeyfile, sec.getAbsolutePath());
			new PasswordInputdialog(source).main(cbpass, _T.PGP_privkeypasstitle.val());
		}
		else{
			startSequence();
		}
	}
	
	private SimpleCallback<char[]> cbpass= new SimpleCallback<char[]>() {
		@Override
		public void callbackValue(Object source, char[] ret) {
			params.put(SuitePARAM.password, ret);
			cb.callbackValue(this, params);
		}
	};
	
	private SimpleCallback<File[]> cbfiles = new SimpleCallback<File[]>(){
		@Override public void callbackValue(Object source, File[] ret) {
			receive(ret);
		}
	};
	
	private void receive(File[] ret){
		boolean succ = true;
		
		if(ret == null || ret.length == 0 || !ret[0].isFile() || !ret[0].exists()) succ = false;

		if(succ){
			PGPSecretKeyFinder finder = new PGPSecretKeyFinder(ret[0]);
			if(!finder.validFile()){
				finder.close();
				succ = false;
			}
		}

		if(!succ){
			UICenter.message(_T.PGP_privkey_wrongfile.val());
			return;
		}
		
		String tmppath = ResourceCenter.getSettings().get(Settings.lastpgp_privfile);
		if(tmppath == null || !tmppath.equals(ret[0].getAbsolutePath())){
			ResourceCenter.getSettings().set(Settings.lastpgp_privfile, ret[0].getAbsolutePath());
			ResourceCenter.getSettings().save();
		}
		
		params.put(SuitePARAM.pgp_privkeyfile, ret[0].getAbsolutePath());
		new PasswordInputdialog(source).main(cbpass, _T.PGP_privkeypasstitle.val());
	}
	
	private void startSequence(){
		SimpleDialogs.message(_T.PGP_selprivkey, new SuccessCallback() {
			@Override
			public void callbackValue(Object source, SUCCESS ret) {
				FileSelectdialog.Options opt = new FileSelectdialog.Options();
				opt.buttoncaption = _T.FileSelection_selectbutton.val();
				opt.title = _T.PGP_selprivkeyTitle.val();
				opt.multiselect = false;
				opt.foldersonly = false;
				
				FileSelectdialog.select(cbfiles, opt);
			}
		});
	}
	
	public static final void requestParams(Object source, SimpleCallback<HashMap<SuitePARAM, Object>> cb){
		new PGP_PrivatekeyDialog(source, cb);
	}
}
 public abstract class Page {
	public static final String HTML_PARAM_SEP = "###";
	public static final String HTML_FORM_SEP = "\\Q?|?\\E";
	private static final String KEYWORD_ACTION = "action_";
	private static final String KEYWORD_PARAM = "param_";

	protected abstract void action(PageLauncher pl, Object action, PageActionparameters params);
	protected abstract void generate(HashMap<String, String> uiparams);
	
	protected Object extractAction(String tmp){
		if(isAction(tmp)) return tmp.substring(KEYWORD_ACTION.length(), tmp.length());
		return null;
	}

	protected Object extractParam(String tmp){
		if(isParam(tmp)) return tmp.substring(KEYWORD_PARAM.length(), tmp.length());
		return null;
	}
	
	public Dimension getSize(){
		return new Dimension(425, 300);
	}
	
	public final String HTML(PageLauncher pl){
		this.pl = pl;

		HashMap<String, String> params = new HashMap<>();
		generate(params);
		return setParameters(loadPage(), params);
	}
	
	private PageLauncher pl;
	public final PageLauncher getPageLauncher(){
		return pl;
	}
	
	public final void exit(){
		if(pl != null) pl.exit();
	}

	public static final void exitPage(Object source){
		if(source == null || !(source instanceof Page)) return;
		
		((Page)source).exit();
	}
	
	
	protected final boolean isAction(String tmp){
		if(tmp == null || tmp.length() == 0) return false;
		return tmp.startsWith(KEYWORD_ACTION);
	}
	
	protected final boolean isParam(String tmp){
		if(tmp == null || tmp.length() == 0) return false;
		return tmp.startsWith(KEYWORD_PARAM);
	}
	
	private String cachebase;
	private final String loadPage(){
		try {
			String tmp = cachebase; 
			if(cachebase == null){
				tmp = StreamCopy.read(ResourceCenter.getAbsoluteStreamRes(file()));
				if(tmp == null) return "Page resource for " + name() + " not found!";
				cachebase = tmp;
			}
			
			return tmp;
		} catch (Exception e) {
			e.printStackTrace();
			return name();
		}
	}
	
	private final String name(){
		return this.getClass().getSimpleName().toLowerCase();
	}

	private final String file(){
		String name = name();
		String locale_file = ResourceCenter.getHTMLRelative() + name + "_" + ResourceCenter.getLocaleCode() + ".html";
		InputStream tmp = ResourceCenter.getAbsoluteStreamRes(locale_file);
		if(tmp == null)
			locale_file = ResourceCenter.getHTMLRelative() + name + ".html";
		
		return locale_file;
	}
	
	
	protected static final String _quoteString(String tmp){
		return tmp.replace("\"", "&quot;");
	}
	
	protected static final String _quoteStringFull(String tmp){
		return _quoteString(tmp).replace("<", "&lt;").replace(">", "&gt;");
	}
	
	protected static final int _s2i(String tmp){
		int ret = -1;
		try {
			ret = Integer.parseInt(tmp);
		} catch (Exception e) {
			return -1;
		}
		return ret;
	}

	private static final String setParameters(String raw, HashMap<String, String> params){
		if(params != null && params.size() > 0){
			Iterator<String> it = params.keySet().iterator();
			while(it.hasNext()){
				String key = it.next();
				raw = raw.replace(HTML_PARAM_SEP+key+HTML_PARAM_SEP, params.get(key));
			}
		}
		
		raw = raw
				.replace(HTML_PARAM_SEP + "base" + HTML_PARAM_SEP, ResourceCenter.getAbsoluteBase())
				.replace(HTML_PARAM_SEP + "pathhtml" + HTML_PARAM_SEP, ResourceCenter.getHTMLAbsolute())
				.replace(HTML_PARAM_SEP + "pathimages" + HTML_PARAM_SEP, ResourceCenter.getImagesAbsolute())
				;

		return raw;
	}
}
 public class PageLauncher {
	static {
		UICenter.INIT();
		SwingHacks.makeHTMLButtonSpacable();
	}

	public static class Options{
		public String title = ResourceCenter.TITLE;
		public boolean resizable = false;
		public boolean forcescrollpane = false;
		public Window mainwindow = null;
		
		public Options(){}
		
		public Options(Object page){
			if(page instanceof Page)
				mainwindow = ((Page)page).getPageLauncher().getWindow();
		}
	}

	public static PageLauncher launch(Page page){
		return launch(null, page);
	}

	public static PageLauncher launch(Options opt, Page page){
		return new PageLauncher(opt, page);
	}

	private Window window;
	private JEditorPane epane;
	private Page cur;

	private PageLauncher(Options opt, Page page){
		if(opt == null) opt = new Options();
		
		cur = page;

		if(opt.mainwindow == null)
			window = makeJFrameWindow(opt);
		else
			window = makeJDialogWindow(opt);

		epane = new JEditorPane();
		JScrollPane jsc = new JScrollPane(epane);
		jsc.setBorder(null);
		jsc.setBackground(Color.WHITE);
		if(opt.forcescrollpane) jsc.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
		jsc.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
		epane.setContentType("text/html");

		initHTML();
		show(page);

		window.setMinimumSize(cur.getSize());
		window.setIconImages(ResourceCenter.icons);
		window.setBackground(Color.WHITE);
		window.add(jsc);
		window.setSize(cur.getSize());
		window.setLocationRelativeTo(null);
		window.setVisible(true);
		epane.requestFocus();
	}
	
	public Window getWindow(){
		return window;
	}

	public Page getPage(){
		return cur;
	}
	
	public void exit(){
		window.dispose();
	}

	public void refresh() {
		show(cur);
	}

	private void show(Page page) {
		epane.setText(page.HTML(this));
		epane.setCaretPosition(0);
	}

	private JFrame makeJFrameWindow(Options opt){
		JFrame jf = new JFrame();
		jf.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
		jf.setResizable(opt.resizable);
		jf.setTitle(opt.title);
		jf.getContentPane().setBackground(Color.WHITE);
		
		jf.addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				int ret = JOptionPane.showConfirmDialog(window, _T.Launcher_reallyquit, ResourceCenter.TITLE, JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
				if (ret == JOptionPane.YES_OPTION)
					window.dispose();
			}
		});

		return jf;
	}
	
	private JDialog makeJDialogWindow(Options opt){
		JDialog jd = new JDialog(opt.mainwindow);
		jd.setModal(true);
		jd.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		jd.setResizable(opt.resizable);
		jd.setTitle(opt.title);
		jd.getContentPane().setBackground(Color.WHITE);
		
		return jd;
	}
	
	private void initHTML() {
		epane.setBackground(Color.WHITE);
		epane.setOpaque(false);
		epane.putClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES, Boolean.FALSE);
		epane.setEditable(false);
		epane.setCaret(new SwingEmptyCaret());
		epane.addCaretListener(new CaretListener() {
			@Override
			public void caretUpdate(CaretEvent e) {
				epane.requestFocus();
			}
		});
		((HTMLEditorKit) epane.getEditorKit()).setAutoFormSubmission(false);

		epane.addHyperlinkListener(new HyperlinkListener() {
			@Override
			public void hyperlinkUpdate(HyperlinkEvent e) {
				if (e instanceof FormSubmitEvent) {
					try {
						FormSubmitEvent fe = (FormSubmitEvent) e;
						String data = URLDecoder.decode(fe.getData(), Charset.defaultCharset().toString());
						if (data == null || data.length() == 0) return;
						
						String[] parts = data.split("&");
						PageActionparameters params = new PageActionparameters();
						Object act = null;
						for(String tmp: parts){
							String[] paramlist = tmp.split("=");
							String check = paramlist[0];
							if (check == null || check.length() == 0) continue;
							
							if(cur.isAction(check)){
								if(check.endsWith(".x") || check.endsWith(".y")) check = check.substring(0, check.length() - 2);
								if(act == null){
									act = cur.extractAction(check);
								}
							}
							else{
								Object param = cur.extractParam(check);
								if(param != null && paramlist.length > 1){
									String tmpval = paramlist[1];
									if(tmpval != null){
										if(tmpval.startsWith("\"") && tmpval.endsWith("\"") && tmpval.length() >= 2)
											tmpval = tmpval.substring(1, tmpval.length() - 1);
										tmpval = tmpval.trim();
									}
									params.add(param, tmpval);
								}
							}
						}
						
						cur.action(PageLauncher.this, act, params);
					} catch (Exception e2) {
						e2.printStackTrace();
					}
				}
				else {
					if (e.getEventType() != HyperlinkEvent.EventType.ACTIVATED) return;
					try {
						if (e.getURL() == null) return;
						URL theurl = e.getURL();

						if (theurl.getProtocol().startsWith("http")) {
							try {
								Desktop.getDesktop().browse(theurl.toURI());
							} catch (Exception e2) {}
							return;
						}

						String url = e.getURL().getFile();

						if (url.startsWith("/NOOP")) return;
						if (url == null || url.length() == 0) return;

						url = url.substring(1);
						cur.action(PageLauncher.this, cur.extractAction(url), null);
					} catch (Exception e2) {}
				}
			}
		});
	}
}
 public static class Options{
	public String title = ResourceCenter.TITLE;
	public boolean resizable = false;
	public boolean forcescrollpane = false;
	public Window mainwindow = null;
		
	public Options(){}
		
	public Options(Object page){
		if(page instanceof Page)
			mainwindow = ((Page)page).getPageLauncher().getWindow();
	}
}
 public class PasswordCreatedialog {
	private static final String DUMMYTEXT = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
	

	private Window mainwindow;
	private Window thiswindow;
	
	public PasswordCreatedialog(){
	}

	public PasswordCreatedialog(Window mainwindow){
		this.mainwindow = mainwindow;
	}
	
	public PasswordCreatedialog(Object page){
		if(page instanceof Page)
			mainwindow = ((Page)page).getPageLauncher().getWindow();
	}
	
	public void main(final SimpleCallback<char[]> sr) {
		if(mainwindow == null){
			JFrame jf = new JFrame();
			jf.setTitle(_T.PasswordEncrypt_title.val());
			jf.setResizable(false);
	    	jf.setIconImages(ResourceCenter.icons);
			jf.getContentPane().setLayout(new BoxLayout(jf.getContentPane(), BoxLayout.Y_AXIS)); 
			jf.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
			thiswindow = jf;
		}
		else{
			JDialog jd = new JDialog(mainwindow);
			jd.setModal(true);
			jd.setTitle(_T.PasswordEncrypt_title.val());
			jd.setResizable(false);
			jd.setIconImages(ResourceCenter.icons);
			jd.getContentPane().setLayout(new BoxLayout(jd.getContentPane(), BoxLayout.Y_AXIS)); 
			jd.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
			thiswindow = jd;
		}
		
		JPanel line1 = new JPanel(new FlowLayout(FlowLayout.RIGHT));
		JPanel line2 = new JPanel(new FlowLayout(FlowLayout.RIGHT));
		JPanel lineok = new JPanel(new GridBagLayout());

		final JPasswordField tf = new JPasswordField();
		tf.setPreferredSize(new Dimension(200, 25));
		
		final JPasswordField tf2 = new JPasswordField();
		tf2.setPreferredSize(new Dimension(200, 25));
		
		JButton b = new JButton("OK");
		
		ActionListener act = new ActionListener(){
			@Override
			public void actionPerformed(ActionEvent e) {
				char[] s1 = tf.getPassword();
				char[] s2 = tf2.getPassword();
				
				if(s1 == null || s2 == null || s1.length == 0 || s2.length == 0)
					return;
				
				int minlen = CryptoCodes.STANDARD_PBKDF2_PWLEN;

				tf.setText(DUMMYTEXT);
				tf2.setText(DUMMYTEXT);
				
				tf.setText("");
				tf2.setText("");
				
				if(Arrays.equals(s1, s2) && s1.length >= minlen){
					thiswindow.dispose();
					CryptoUtils.kill(s2);
					sr.callbackValue(PasswordCreatedialog.this, s1);
				}
				else{
					CryptoUtils.kill(s1);
					CryptoUtils.kill(s2);
					tf.requestFocus();
					
					if(s1.length < minlen)
						JOptionPane.showMessageDialog(thiswindow, _T.PasswordEncrypt_len.msg(minlen));
					else
						JOptionPane.showMessageDialog(thiswindow, _T.PasswordEncrypt_nomatch);
				}
			}
		};
		
		b.addActionListener(act);
		tf.addActionListener(act);
		tf2.addActionListener(act);
		
		JLabel jl = new JLabel(_T.PasswordEncrypt_label + ": ");
		line1.add(jl);
		line1.add(tf);
		thiswindow.add(line1);

		jl = new JLabel(_T.PasswordEncrypt_retype + ": ");
		line2.add(jl);
		line2.add(tf2);
		thiswindow.add(line2);

		b.setPreferredSize(new Dimension(200, 35));
		GridBagConstraints gbc = new GridBagConstraints();
		gbc.insets = new Insets(5, 5, 5, 5);
		gbc.fill = GridBagConstraints.BOTH;
		gbc.weightx = gbc.weighty = 1.0;
		lineok.add(b, gbc);
		thiswindow.add(lineok);
		
		thiswindow.pack();
		
		thiswindow.setLocationRelativeTo(mainwindow);
		thiswindow.setVisible(true);
		
		thiswindow.addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosed(WindowEvent e) {
				try {
					tf.setText(DUMMYTEXT);
					tf2.setText(DUMMYTEXT);
					
					tf.setText("");
					tf2.setText("");
				} catch (Exception ex) {}
			}
		});
		
		if(Toolkit.getDefaultToolkit().getLockingKeyState(KeyEvent.VK_CAPS_LOCK)){
			JOptionPane.showMessageDialog(thiswindow, _T.Password_caps);
		}
	}
}
 public class PasswordCreatedialogWithOptions {
	private static final String DUMMYTEXT = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
	

	private Window mainwindow;
	private Window thiswindow;
	
	private HashMap<SuitePARAM, Object> suiteParams = new HashMap<>();

	public PasswordCreatedialogWithOptions(){
	}

	public PasswordCreatedialogWithOptions(Window mainwindow){
		this.mainwindow = mainwindow;
	}
	
	public PasswordCreatedialogWithOptions(Object page){
		if(page instanceof Page)
			mainwindow = ((Page)page).getPageLauncher().getWindow();
	}
	
	public void main(final SimpleCallback<HashMap<SuitePARAM, Object>> sr) {
		if(mainwindow == null){
			JFrame jf = new JFrame();
			jf.setTitle(_T.PasswordEncrypt_title.val());
			jf.setResizable(false);
	    	jf.setIconImages(ResourceCenter.icons);
			jf.getContentPane().setLayout(new BoxLayout(jf.getContentPane(), BoxLayout.Y_AXIS)); 
			jf.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
			thiswindow = jf;
		}
		else{
			JDialog jd = new JDialog(mainwindow);
			jd.setModal(true);
			jd.setTitle(_T.PasswordEncrypt_title.val());
			jd.setResizable(false);
			jd.setIconImages(ResourceCenter.icons);
			jd.getContentPane().setLayout(new BoxLayout(jd.getContentPane(), BoxLayout.Y_AXIS)); 
			jd.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
			thiswindow = jd;
		}
		
		JPanel line1 = new JPanel(new FlowLayout(FlowLayout.RIGHT));
		JPanel line2 = new JPanel(new FlowLayout(FlowLayout.RIGHT));
		JPanel lineok = new JPanel(new GridBagLayout());
		JPanel line3 = new JPanel(new FlowLayout(FlowLayout.RIGHT));
		final JPanel lineopt = new JPanel(new FlowLayout(FlowLayout.RIGHT));

		final JPasswordField tf = new JPasswordField();
		tf.setPreferredSize(new Dimension(200, 25));
		
		final JPasswordField tf2 = new JPasswordField();
		tf2.setPreferredSize(new Dimension(200, 25));
		
		final JTextField jtf = new JTextField(""+CryptoCodes.STANDARD_PBKDF2_ITERATIONS); 
		
		JButton b = new JButton("OK");
		
		ActionListener act = new ActionListener(){
			@Override
			public void actionPerformed(ActionEvent e) {
				char[] s1 = tf.getPassword();
				char[] s2 = tf2.getPassword();
				
				if(s1 == null || s2 == null || s1.length == 0 || s2.length == 0)
					return;
				
				int minlen = CryptoCodes.STANDARD_PBKDF2_PWLEN;

				tf.setText(DUMMYTEXT);
				tf2.setText(DUMMYTEXT);
				
				tf.setText("");
				tf2.setText("");
				
				if(Arrays.equals(s1, s2) && s1.length >= minlen){
					thiswindow.dispose();
					CryptoUtils.kill(s2);


					suiteParams.put(SuitePARAM.password, s1);
					if(lineopt.isVisible()){
						String tmp = jtf.getText();
						if(FilterNumbers.validate(tmp)) suiteParams.put(SuitePARAM.itcount, tmp);
					}
					sr.callbackValue(this, suiteParams);
				}
				else{
					CryptoUtils.kill(s1);
					CryptoUtils.kill(s2);
					tf.requestFocus();
					
					if(s1.length < minlen)
						JOptionPane.showMessageDialog(thiswindow, _T.PasswordEncrypt_len.msg(minlen));
					else
						JOptionPane.showMessageDialog(thiswindow, _T.PasswordEncrypt_nomatch);
				}
			}
		};
		
		b.addActionListener(act);
		tf.addActionListener(act);
		tf2.addActionListener(act);
		jtf.addActionListener(act);
		
		JLabel jl = new JLabel(_T.PasswordEncrypt_label + ": ");
		line1.add(jl);
		line1.add(tf);
		thiswindow.add(line1);

		jl = new JLabel(_T.PasswordEncrypt_retype + ": ");
		line2.add(jl);
		line2.add(tf2);
		thiswindow.add(line2);
		
		b.setPreferredSize(new Dimension(200, 35));
		GridBagConstraints gbc = new GridBagConstraints();
		gbc.insets = new Insets(5, 5, 5, 5);
		gbc.fill = GridBagConstraints.BOTH;
		gbc.weightx = gbc.weighty = 1.0;
		lineok.add(b, gbc);
		thiswindow.add(lineok);
		
		javax.swing.ToolTipManager.sharedInstance().setDismissDelay(7000);

		((PlainDocument) jtf.getDocument()).setDocumentFilter(new FilterNumbers());
		jtf.setPreferredSize(new Dimension(200, 25));
		jtf.setToolTipText(_T.PasswordEncrypt_itcountdescr.val());
		jl = new JLabel(_T.PasswordEncrypt_itcount + ": ");
		jl.setToolTipText(_T.PasswordEncrypt_itcountdescr.val());
		lineopt.add(jl);
		lineopt.add(jtf);
		
		final JButton jb = new JButton(new ImageIcon(ResourceCenter.optsup));
        line3.add(jb);
		thiswindow.add(line3);
		
		thiswindow.add(lineopt);
		lineopt.setVisible(false);

		jb.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				if(lineopt.isVisible()){
					lineopt.setVisible(false);
					jb.setIcon(new ImageIcon(ResourceCenter.optsup));
				}
				else{
					lineopt.setVisible(true);
					jb.setIcon(new ImageIcon(ResourceCenter.optsdown));
				}
				
				thiswindow.pack();
			}
		});
		
		thiswindow.pack();
		
		thiswindow.setLocationRelativeTo(mainwindow);
		thiswindow.setVisible(true);
		
		thiswindow.addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosed(WindowEvent e) {
				try {
					tf.setText(DUMMYTEXT);
					tf2.setText(DUMMYTEXT);
					
					tf.setText("");
					tf2.setText("");
				} catch (Exception ex) {}
			}
		});
		
		if(Toolkit.getDefaultToolkit().getLockingKeyState(KeyEvent.VK_CAPS_LOCK)){
			JOptionPane.showMessageDialog(thiswindow, _T.Password_caps);
		}
	}
}
 public class PasswordInputdialog {
	private static final String DUMMYTEXT = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
	

	private Window mainwindow;
	private Window thiswindow;
	
	public PasswordInputdialog(){
	}

	public PasswordInputdialog(Window mainwindow){
		this.mainwindow = mainwindow;
	}

	public PasswordInputdialog(Object page){
		if(page instanceof Page)
			mainwindow = ((Page)page).getPageLauncher().getWindow();
	}
	
	public void main(final SimpleCallback<char[]> sr) {
		main(sr, null);
	}
	
	public void main(final SimpleCallback<char[]> sr, String title) {
		if(title == null) title = _T.PasswordDecrypt_title.val();
		
		if(mainwindow == null){
			JFrame jf = new JFrame();
			jf.setTitle(title);
			jf.setResizable(false);
	    	jf.setIconImages(ResourceCenter.icons);
			jf.getContentPane().setLayout(new FlowLayout()); 
			jf.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
			thiswindow = jf;
		}
		else{
			JDialog jd = new JDialog(mainwindow);
			jd.setModal(true);
			jd.setTitle(title);
			jd.setResizable(false);
			jd.setIconImages(ResourceCenter.icons);
			jd.getContentPane().setLayout(new FlowLayout()); 
			jd.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
			thiswindow = jd;
		}
		
		final JPasswordField tf = new JPasswordField();
		tf.setPreferredSize(new Dimension(200, 25));
		JButton b = new JButton("OK");
		
		ActionListener act = new ActionListener(){
			@Override
			public void actionPerformed(ActionEvent e) {
				char[] pw = tf.getPassword();
				
				if(pw == null || pw.length == 0) return;
				
				tf.setText(DUMMYTEXT);
				tf.setText("");

				thiswindow.dispose();
				sr.callbackValue(PasswordInputdialog.this, pw);
			}
		};
		

		b.addActionListener(act);
		tf.addActionListener(act);
		
		thiswindow.add(tf);
		thiswindow.add(b);
		
		thiswindow.pack();
		
		thiswindow.setLocationRelativeTo(mainwindow);
		thiswindow.setVisible(true);
		

		if(Toolkit.getDefaultToolkit().getLockingKeyState(KeyEvent.VK_CAPS_LOCK)){
			JOptionPane.showMessageDialog(thiswindow, _T.Password_caps);
		}
	}
}
 public class ProgressDoubleWindow {
	private Window parent;
	private JDialog jd;
	
	public ProgressDoubleWindow(Window parent){
		this.parent = parent;
	}

	public StatusUpdate prepare() {
		jd = new JDialog(parent);
		jd.setTitle(ResourceCenter.TITLE);
		jd.setResizable(false);
		jd.setLayout(null);
		jd.getContentPane().setLayout(null);

		jd.setIconImages(ResourceCenter.icons);
		jd.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);

		final JProgressBar jp = new JProgressBar(0, 100);
		jp.setSize(new Dimension(350, 35));
		jp.setLocation(0, 0);
		jp.setBorderPainted(true);
		jp.setStringPainted(true);
		jp.setForeground(Color.decode("#1755E6"));
		jd.add(jp);
		
		final JProgressBar jp2 = new JProgressBar(0, 100);
		jp2.setSize(new Dimension(350, 20));
		jp2.setLocation(0, jp.getHeight());
		jp2.setBorderPainted(true);
		jp2.setStringPainted(true);
		jp2.setForeground(Color.decode("#608AEE"));
		jd.add(jp2);

		final DefaultListModel<String> model = new DefaultListModel<>();
		JList<String> jl = new JList<>(model);
		jl.setSelectionModel(new DefaultListSelectionModel() {
			private static final long serialVersionUID = 1L;

			@Override
			public void setSelectionInterval(int i0, int i1) {
				super.setSelectionInterval(-1, -1);
			}
		});
		model.addElement(" ");

		jl.setVisibleRowCount(5);
		jl.setSize(new Dimension(jp.getWidth(), jl.getPreferredScrollableViewportSize().height + 10));
		jl.setLocation(0, jp.getHeight() + jp2.getHeight());
		jl.setBorder(new EmptyBorder(5, 5, 5, 5));
		jd.add(jl);

		Dimension thesize = new Dimension(jp.getWidth(), jp.getHeight() + jp2.getHeight() + jl.getHeight());
		jd.getContentPane().setPreferredSize(thesize);
		jd.setSize(thesize);
		jd.setLocationRelativeTo(parent);
		
		model.remove(0);

		return new StatusUpdate() {
			private boolean active = true;
			
			private WindowListener wl = new WindowAdapter() {
				@Override
				public void windowClosing(WindowEvent e) {
					finished();
					active = false;
				}
			};
			
			{
				jd.addWindowListener(wl);
				if(parent != null) parent.addWindowListener(wl);
			}

			
			@Override
			public void start() {
				SwingUtilities.invokeLater(new Runnable() {
					@Override
					public void run() {
						jd.setVisible(true);
						jd.pack();
						jd.setLocationRelativeTo(null);
					}
				});
			}
			
			@Override
			public void finished() {
				if(active){
					jd.removeWindowListener(wl);
					if(parent != null) parent.removeWindowListener(wl);
					jd.dispose();
				}
			}
			
			@Override
			public void receiveProgress(int perc) {
				jp.setValue(perc);
			}
			
			@Override
			public void receiveDetailsProgress(int perc) {
				jp2.setValue(perc);
			}

			@Override
			public void receiveMessageSummary(String msg) {
				receiveMessageDetails(msg);
			}

			@Override
			public void receiveMessageDetails(final String msg) {
				SwingUtilities.invokeLater(new Runnable() {
					public void run() {
						try {
							while (model.size() >= 5) {
								model.remove(0);
							}
							model.addElement(msg);
						} catch (Exception e) {
							e.printStackTrace();
						}
					}
				});
			}

			@Override
			public boolean isActive() {
				return active;
			}
		};
	}
}
 public class ProgressWindow {
	private Window parent;
	private JDialog jd;
	
	public ProgressWindow(Window parent){
		this.parent = parent;
	}

	public StatusUpdate prepare() {
		jd = new JDialog(parent);
		jd.setTitle(ResourceCenter.TITLE);
		jd.setResizable(false);
		jd.setLayout(null);
		jd.getContentPane().setLayout(null);

		jd.setIconImages(ResourceCenter.icons);
		jd.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);

		final JProgressBar jp = new JProgressBar(0, 100);
		jp.setSize(new Dimension(350, 35));
		jp.setLocation(0, 0);
		jp.setBorderPainted(true);
		jp.setStringPainted(true);
		jp.setForeground(Color.decode("#608AEE"));
		jd.add(jp);

		final DefaultListModel<String> model = new DefaultListModel<>();
		JList<String> jl = new JList<>(model);
		jl.setSelectionModel(new DefaultListSelectionModel() {
			private static final long serialVersionUID = 1L;

			@Override
			public void setSelectionInterval(int i0, int i1) {
				super.setSelectionInterval(-1, -1);
			}
		});
		model.addElement(" ");

		jl.setVisibleRowCount(5);
		jl.setSize(new Dimension(jp.getWidth(), jl.getPreferredScrollableViewportSize().height + 10));
		jl.setLocation(0, jp.getHeight());
		jl.setBorder(new EmptyBorder(5, 5, 5, 5));
		jd.add(jl);

		Dimension thesize = new Dimension(jp.getWidth(), jp.getHeight() + jl.getHeight());
		jd.getContentPane().setPreferredSize(thesize);
		jd.setSize(thesize);
		jd.setLocationRelativeTo(parent);
		
		model.remove(0);

		return new StatusUpdate() {
			private boolean active = true;
			
			private WindowListener wl = new WindowAdapter() {
				@Override
				public void windowClosing(WindowEvent e) {
					finished();
					active = false;
				}
			};
			
			{
				jd.addWindowListener(wl);
				if(parent != null) parent.addWindowListener(wl);
			}

			@Override
			public void start() {
				SwingUtilities.invokeLater(new Runnable() {
					@Override
					public void run() {
						jd.setVisible(true);
						jd.pack();
						jd.setLocationRelativeTo(null);
					}
				});
			}
			
			@Override
			public void finished() {
				if(active){
					jd.removeWindowListener(wl);
					if(parent != null) parent.removeWindowListener(wl);
					jd.dispose();
				}
			}
			
			@Override
			public void receiveProgress(int perc) {
				jp.setValue(perc);
			}
			
			@Override
			public void receiveDetailsProgress(int perc) {
			}

			@Override
			public void receiveMessageSummary(String msg) {
				receiveMessageDetails(msg);
			}

			@Override
			public void receiveMessageDetails(final String msg) {
				SwingUtilities.invokeLater(new Runnable() {
					public void run() {
						try {
							while (model.size() >= 5) {
								model.remove(0);
							}
							model.addElement(msg);
						} catch (Exception e) {
							e.printStackTrace();
						}
					}
				});
			}

			@Override
			public boolean isActive() {
				return active;
			}
		};
	}
}
 public class SimpleDialogs {
	public static final void message(_T text, SuccessCallback cb){
		message(text.val(), cb);
	}

	public static final void message(_T text){
		message(text.val(), null);
	}

	public static final void message(final String text, final SuccessCallback cb){
		SwingUtilities.invokeLater(new Runnable() {
			@Override
			public void run() {
				try {
				    JOptionPane jop = new JOptionPane(text, JOptionPane.INFORMATION_MESSAGE, JOptionPane.DEFAULT_OPTION);
					showup(jop);
					if(cb != null) cb.callbackValue(SimpleDialogs.class, SUCCESS.TRUE);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}
	
	public static final void message(final String text){
		message(text, null);
	}

	
	public static void questionYesNo(final String text, final SuccessCallback cb){
		SwingUtilities.invokeLater(new Runnable() {
			@Override
			public void run() {
				try {
					JOptionPane jop = new JOptionPane(text, JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_OPTION);
					showup(jop);

			        if(Integer.valueOf(JOptionPane.YES_OPTION).equals(jop.getValue())){
						cb.callbackValue(SimpleDialogs.class, SUCCESS.TRUE);
						return;
			        }
				} catch (Exception e) {
					e.printStackTrace();
				}
				cb.callbackValue(SimpleDialogs.class, SUCCESS.FALSE);
			}
		});
	}
	
	private static final void showup(JOptionPane jop){
        JDialog dialog = jop.createDialog(ResourceCenter.TITLE);
        dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
        dialog.setIconImages(ResourceCenter.icons);
        dialog.setModal(true);
        dialog.setVisible(true);
        dialog.dispose();
	}
}
 public class CAPI_DNList extends Page{
	private SimpleCallback<String> cb;
	private CAPIRSAAliases dnlist = CAPIRSAUtils.getAll();

	public CAPI_DNList(SimpleCallback<String> cb){
		this.cb = cb;
	}
	
	@Override
	protected void generate(HashMap<String, String> params){
		String listui = null;
		String lastdnalias = ResourceCenter.getSettings().get(Settings.lastcapidn);
		
		if(dnlist == null || dnlist.aliases.size() == 0){
			listui = _T.CAPIDNListWindow_nokeys.val();
		}
		else{
			final String listbase = "<option SELECTED value=\"CODE\">DESCR</option>";
			StringBuilder sbmenu = new StringBuilder();
			for(int i=0; i<dnlist.displaytexts.size(); i++){
				String tmp = listbase;
				if(!dnlist.aliases.get(i).equals(lastdnalias)) tmp = tmp.replace("SELECTED", "");
				tmp = tmp.replace("CODE", i+"");
				tmp = tmp.replace("DESCR", dnlist.displaytexts.get(i));
				sbmenu.append(_quoteString(tmp));
			}
			listui = sbmenu.toString();
		}
		
		params.put("dnlist", listui);
		params.put("title", _T.CAPIDNListWindow_title.val());
		params.put("text", _T.DecryptWindow_text.val());
	}
	
	@Override
	protected void action(PageLauncher pl, Object action, PageActionparameters params) {
		if(params == null || action == null || !action.equals("ok")) return;
		
		if(dnlist == null || dnlist.aliases.size() == 0){
			pl.exit();
			return;
		}
		
		int i = _s2i(params.getString("alias"));
		if(i >= 0){
			String lastdnalias = ResourceCenter.getSettings().get(Settings.lastcapidn);
			if(!dnlist.aliases.get(i).equals(lastdnalias)){
				ResourceCenter.getSettings().set(Settings.lastcapidn, dnlist.aliases.get(i));
				ResourceCenter.getSettings().save();
			}
			cb.callbackValue(this, dnlist.aliases.get(i));
		}
		else{
			cb.callbackValue(this, null);
		}
		
		pl.exit();
	}
}
 public class Decrypt extends Page{
	private enum OPT{
		choose,
		decrypt,
		
		infobutton,
		
		
		folder,
	}
	
	
	private CbIDecrypt cb;
	private File destFolder;
	private PageLauncher pl = null;

	public Decrypt(CbIDecrypt cb){
		this.cb = cb;
	}
	
	public void setFolder(File f){
		this.destFolder = f;
	}

	@Override
	protected void generate(HashMap<String, String> params){
		final String listbase = "<option SELECTED value=\"CODE\">DESCR</option>";
		SUITES[] suites = SUITES.values();
		StringBuilder sbmenu = new StringBuilder();
		for(int i=0; i<suites.length; i++){
			SUITES suite = suites[i];
			String tmp = listbase;
			tmp = tmp.replace("SELECTED", "");
			tmp = tmp.replace("CODE", suite.name());
			tmp = tmp.replace("DESCR", SUITES.descriptor.get(i));
			sbmenu.append(tmp);
		}

		params.put("providerlist", sbmenu.toString());
		params.put("title", _T.DecryptWindow_title.val());
		params.put("text", _T.DecryptWindow_text.val());
		params.put("destination", _T.DecryptWindow_destination.val());
		
		String defaultFile = null;
		if(destFolder != null) defaultFile = destFolder.getAbsolutePath();
		if(defaultFile == null) defaultFile = OSFolders.getUserChooserstart().getAbsolutePath();
		params.put("startfile", _quoteString(defaultFile)); 
	}
	
	@Override
	protected Object extractAction(String tmp) {
		return SystemUtils.s2E(super.extractAction(tmp), OPT.class);
	}

	@Override
	protected Object extractParam(String tmp) {
		return SystemUtils.s2E(super.extractParam(tmp), OPT.class);
	}

	@Override
	protected void action(PageLauncher pl, Object action, PageActionparameters params) {
		OPT opt = (OPT) action;
		if(opt == null) opt = OPT.decrypt;
		
		switch (opt) {
		case infobutton:
			PageLauncher.launch(new Options(this), new InfoWindow());
			return;

		case choose:
			if(cb.isDecryptRunning(this)) return;

			this.pl = pl;
			choose();
			return;
			
		case decrypt:
			if(cb.isDecryptRunning(this)) return;

			String fstring = params.getString(OPT.folder);
			if(fstring == null) return;
			File tmpdst = new File(fstring);
			File sanidst = sanitize(tmpdst);
			
			if(sanidst == null){
				UICenter.message(_T.DecryptWindow_invalid);
				return;
			}

			if(!tmpdst.equals(sanidst) || !fstring.equals(sanidst.getAbsolutePath())){
				setFolder(sanidst);
				pl.refresh();
			}
			
			if(sanidst.exists()){
				if(sanidst.isDirectory() && FileUtils.noOfFiles(sanidst.toPath()) > 0){
					int retval = JOptionPane.showConfirmDialog(pl.getWindow(), 
			                _T.DecryptWindow_already, ResourceCenter.TITLE,
			                JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);

					if(retval != JOptionPane.YES_OPTION) return;
				}
				else if(sanidst.isFile()){
					SimpleDialogs.message(_T.DecryptWindow_folderisfile);
					return;
				}
			}

			cb.callbackDecrypt(this, sanidst);
			return;
		}
		
		UICenter.message("Unknown Operation");
	}
	
	private final void choose(){
		FileSelectdialog.Options opt = new FileSelectdialog.Options();
		opt.multiselect = false;
		opt.foldersonly = true;
		opt.startFolder = destFolder.getParentFile();
		while(opt.startFolder != null && !opt.startFolder.exists())
			opt.startFolder = opt.startFolder.getParentFile();
		
		FileSelectdialog.select(new SimpleCallback<File[]>() {
			@Override
			public void callbackValue(Object source, File[] ret) {
				if(ret == null || ret.length == 0) return;
				
				File tmp = sanitize(ret[0]);
				if(tmp == null) return;
				
				setFolder(tmp);
				if(pl != null) pl.refresh();
			}
		}, opt);
	}
	
	private File sanitize(File dest){
		File tmp = null;
		try {
			tmp = dest.getCanonicalFile();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return tmp;
	}
}
 public class Encrypt extends Page{
	private enum OPT{
		choose,
		encrypt,
		
		infobutton,
		
		
		provider,
		file,
	}
	
	private CrococryptParameters co;
	private File destfile;
	private CbIEncrypt cb;
	private PageLauncher pl = null;
	
	public Encrypt(CbIEncrypt cb, CrococryptParameters co, File destfile){
		this.cb = cb;
		this.co = co;
		setFile(destfile);
	}
	
	public void setFile(File destfile){
		this.destfile = sanitize(destfile);
	}
	
	@Override
	protected void generate(HashMap<String, String> params){
		String lastprov = ResourceCenter.getSettings().get(Settings.lastprovider);
		if(co.suite != null) lastprov = co.suite.name();
		
		final String listbase = "<option SELECTED value=\"CODE\">DESCR</option>";
		SUITES[] suites = SUITES.values();
		StringBuilder sbmenu = new StringBuilder();
		for(int i=0; i<suites.length; i++){
			SUITES suite = suites[i];
			if(!suite.isAvailable()) continue;
			String tmp = listbase;
			if(!suite.name().equals(lastprov)){
				tmp = tmp.replace("SELECTED", "");
			}
			else{
				if(suite == SUITES.PBECLOAKED_AESTWO || suite == SUITES.PBECLOAKED1MB_AESTWO ) co.cloakedfile = true;
			}
			tmp = tmp.replace("CODE", suite.name());
			tmp = tmp.replace("DESCR", SUITES.descriptor.get(i));
			sbmenu.append(tmp);
		}
		
		params.put("providerlist", sbmenu.toString());
		params.put("title", _T.EncryptWindow_title.val());
		params.put("destination", _T.EncryptWindow_destination.val());
		
		String text = null;
		File tmp = co.filesanddirs.get(0);
		if(!OSFolders.isRoot(tmp)) tmp = tmp.getParentFile();
		String s_source = FileUtils.shortenDisplayFile(tmp).replace(" ", "&nbsp;");
		if(!co.singlesource)
			s_source = _T.EncryptWindow_multisources.val();
		
		if(co.dircount == 0){
			if(co.filecount == 1)
				text = _T.EncryptWindow_Singlefile.msg(co.filesanddirs.get(0).getName(), s_source);
			else
				text = _T.EncryptWindow_Multifile.msg(co.filecount, s_source);
		}
		else if(co.filecount == 0){
			if(co.dircount == 1)
				text = _T.EncryptWindow_Singledir.msg(co.filesanddirs.get(0).getName(), s_source);
			else
				text = _T.EncryptWindow_Multidir.msg(co.dircount, s_source);
		}
		else{
			if(co.filecount == 1 && co.dircount == 1)
				text = _T.EncryptWindow_SinglefileSingledir.msg(s_source);
			else if(co.filecount > 1 && co.dircount > 1)
				text = _T.EncryptWindow_MultifileMultidir.msg(co.filecount, co.dircount, s_source);
			else if(co.filecount > 1)
				text = _T.EncryptWindow_MultifileSingledir.msg(co.filecount, s_source);
			else if(co.dircount > 1)
				text = _T.EncryptWindow_SinglefileMultidir.msg(co.dircount, s_source);
		}

		params.put("text", text);

		destfile = sanitize(destfile);
		if(destfile == null) destfile = sanitize(new File(OSFolders.getUserChooserstart(), _T.EncryptWindow_EncryptedFile + BasicFileinfo.FILEEXTENSIONwDOT));
		String defaultFileShow = null;
		if(destfile != null) defaultFileShow = destfile.getAbsolutePath();
		if(defaultFileShow == null) defaultFileShow = new File(OSFolders.getUserChooserstart(), _T.EncryptWindow_EncryptedFile + BasicFileinfo.FILEEXTENSIONwDOT).getAbsolutePath();
		params.put("startfile", _quoteString(defaultFileShow)); 
	}
	
	@Override
	public Object extractAction(String tmp) {
		return SystemUtils.s2E(super.extractAction(tmp), OPT.class);
	}

	@Override
	public Object extractParam(String tmp) {
		return SystemUtils.s2E(super.extractParam(tmp), OPT.class);
	}
	
	@Override
	protected void action(PageLauncher pl, Object action, PageActionparameters params) {
		OPT opt = (OPT) action;
		if(opt == null) opt = OPT.encrypt;
		
		switch (opt) {
		case infobutton:
			PageLauncher.launch(new Options(this), new InfoWindow());
			return;
			
		case choose:
			if(cb.isEncryptRunning(this)) return;

			this.pl = pl;
			choose();
			return;

		case encrypt:
			if(cb.isEncryptRunning(this)) return;

			SUITES suitex = SystemUtils.s2E(params.getString(OPT.provider), SUITES.class);
			if(suitex != null){
				co.suite = suitex;
				if(!suitex.name().equals(ResourceCenter.getSettings().get(Settings.lastprovider))){
					ResourceCenter.getSettings().set(Settings.lastprovider, suitex.name());
					ResourceCenter.getSettings().save();
				}
			}
			else{
				UICenter.message("Internal error: No crypto suite");
				return;
			}
			if(suitex == SUITES.PBECLOAKED_AESTWO || suitex == SUITES.PBECLOAKED1MB_AESTWO ) co.cloakedfile = true;
			else co.cloakedfile = false;

			String fstring = params.getString(OPT.file);
			if(fstring == null) return;
			File tmpdst = new File(fstring);
			File sanidst = sanitize(tmpdst);
			
			if(sanidst == null){
				UICenter.message(_T.FilepathFailure);
				return;
			}

			if(!tmpdst.equals(sanidst) || !fstring.equals(sanidst.getAbsolutePath())){
				setFile(sanidst);
				pl.refresh();
			}
			
			if(sanidst.exists() && sanidst.isDirectory()){
				UICenter.message(_T.EncryptWindow_alreadydir);
				return;
			}
			else if(sanidst.exists()){
				int retval = JOptionPane.showConfirmDialog(pl.getWindow(), 
		                _T.EncryptWindow_already, ResourceCenter.TITLE,
		                JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);

				if(retval != JOptionPane.YES_OPTION) return;
			}
			else if(!sanidst.getParentFile().exists()){
				int retval = JOptionPane.showConfirmDialog(pl.getWindow(), 
		                _T.EncryptWindow_createdir, ResourceCenter.TITLE,
		                JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);

				if(retval != JOptionPane.YES_OPTION) return;
			}
			
			
			cb.callbackEncrypt(this, sanidst, suitex);
			return;
		}

		UICenter.message("Unknown Operation");
	}
	
	private final void choose(){
		FileSelectdialog.Options opt = new FileSelectdialog.Options();
		opt.multiselect = false;
		if(destfile != null) opt.startFolder = destfile.getParentFile();
		while(opt.startFolder != null && !opt.startFolder.exists())
			opt.startFolder = opt.startFolder.getParentFile();
		
		FileSelectdialog.select(new SimpleCallback<File[]>() {
			@Override
			public void callbackValue(Object source, File[] ret) {
				if(ret == null || ret.length == 0) return;
				
				File tmp = sanitize(ret[0]);
				if(tmp == null) return;

				setFile(tmp);
				if(pl != null) pl.refresh();
			}
		}, opt);
	}
	
	private File sanitize(File dest){
		if(dest == null) return null;
		
		File tmp = null;
		try {
			tmp = dest.getCanonicalFile();
		} catch (Exception e) {
			e.printStackTrace();
		}
		if(tmp == null) return null;
		String tmpname = tmp.getName();
		
		
		String ext = "";
		if(!co.cloakedfile){
			ext = BasicFileinfo.FILEEXTENSIONwDOT;

			if(!tmpname.endsWith(ext)){
				tmp = new File(tmp.getParentFile(), tmpname + ext);
			}
		}
		else{
			if(tmpname.endsWith(BasicFileinfo.FILEEXTENSIONwDOT)){
				tmpname = tmpname.substring(0, tmpname.length() - BasicFileinfo.FILEEXTENSIONwDOT_LENGTH);
			}
			tmp = new File(tmp.getParentFile(), tmpname);
		}
		
		return tmp;
	}
}
 public class JCEPolicyError extends Page{
	@Override
	protected void generate(HashMap<String, String> params){
		params.put("title", _T.JCEPolicyError_title.val());
		params.put("text", _T.JCEPolicyError_text.val());
	}
	
	@Override
	protected void action(PageLauncher pl, Object action, PageActionparameters params) {
		if(params == null || action == null || !action.equals("ok")) return;
		
		pl.exit();
	}
	
	@Override
	public Dimension getSize() {
		return new Dimension(400, 200);
	}
}
 public class PGP_Keylist extends Page{
	private final String alias = "alias";
	
	private PageLauncher pl = null;
	private HashMap<SuitePARAM, Object> suiteParams = new HashMap<>();
	private SimpleCallback<HashMap<SuitePARAM, Object>> cb;	
	
	private File pubkeyfile = null;
	{
		String tmp = ResourceCenter.getSettings().get(Settings.lastpgp_pubfile);
		if(tmp == null){
			pubkeyfile = PGPUtils.getPubRing();
		}
		else{
			File ftmp = new File(tmp);
			if(ftmp.exists() && ftmp.isFile()) pubkeyfile = ftmp;
		}
	}

	public PGP_Keylist(SimpleCallback<HashMap<SuitePARAM, Object>> cb){
		this.cb = cb;
	}

	@Override
	protected void action(PageLauncher pl, Object action, PageActionparameters params) {
		this.pl = pl;
		if(action == null) return;
		String act = action.toString();
		
		if("ok".equals(act)){
			if(params == null || !params.exists(alias)) return;
			
			ArrayList<Long> kids = new ArrayList<>();
			if(params.isList(alias)){
				@SuppressWarnings("unchecked")
				ArrayList<String> arr = (ArrayList<String>) params.getRaw(alias);
				for(String s: arr)
					kids.add(Long.parseLong(s));
			}
			else{
				kids.add(Long.parseLong(params.getString(alias)));
			}
			
			suiteParams.put(SuitePARAM.pgp_pubkeyfile, pubkeyfile.getAbsolutePath());
			suiteParams.put(SuitePARAM.pgp_keyidlist, kids);
			
			cb.callbackValue(this, suiteParams);
			pl.exit();
		}
		else if("choose".equals(act)){
			choose();
		}
	}

	@Override
	protected void generate(HashMap<String, String> uiparams) {
		uiparams.put("title", _T.EncryptListChooseMulti.val());
		
		if(pubkeyfile == null || !pubkeyfile.exists() || !pubkeyfile.isFile())
			uiparams.put("keyfile", _T.PGP_nokeyfile.val());
		else
			uiparams.put("keyfile", FileUtils.shortenDisplayFile(pubkeyfile));
		
		try {
			if(pubkeyfile != null) PGPPublickeyList.main(pubkeyfile);
		} catch (Exception e) {
			System.err.println(e.getLocalizedMessage());
		}
		
		String tmppath = ResourceCenter.getSettings().get(Settings.lastpgp_pubfile);
		if(pubkeyfile != null && (tmppath == null || !tmppath.equals(pubkeyfile.getAbsolutePath()))){
			ResourceCenter.getSettings().set(Settings.lastpgp_pubfile, pubkeyfile.getAbsolutePath());
			ResourceCenter.getSettings().save();
		}
		
		StringBuilder sb = new StringBuilder();
		final String listbase = "<option value=\"CODE\">DESCR</option>";
		
		for(int i=0; i<PGPPublickeyList.items.size(); i++){
			PGPPublickeyListItem item = PGPPublickeyList.items.get(i);
			
			String tmp = listbase;
			tmp = tmp.replace("CODE", "" + item.id);
			tmp = tmp.replace("DESCR", _quoteStringFull(item.show));
			sb.append(tmp);
		}
		
		uiparams.put("keylist", sb.toString());
	}
	
	private final void choose(){
		FileSelectdialog.Options opt = new FileSelectdialog.Options();
		opt.multiselect = false;
		opt.foldersonly = false;
		opt.title = _T.PGP_selpubkey.val();
		
		FileSelectdialog.select(new SimpleCallback<File[]>() {
			@Override
			public void callbackValue(Object source, File[] ret) {
				if(ret == null || ret.length == 0) return;
				
				File tmp = sanitize(ret[0]);
				if(tmp == null) return;
				
				pubkeyfile = tmp;
				if(pl != null) pl.refresh();
			}
		}, opt);
	}
	
	private File sanitize(File dest){
		File tmp = null;
		try {
			tmp = dest.getCanonicalFile();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return tmp;
	}
	
	
	@Override
	public Dimension getSize() {
		Dimension dim = super.getSize();
		
		if(OSDetector.isLin())
			dim.height += 150;
		
		return dim;
	}
}
 public enum _T {
	CAPIDNListWindow_nokeys,
	CAPIDNListWindow_title,
	CAPI_DNnotfound,
	CrocoFilereader_already,
	CrocoFilereader_decrypting,
	CrocoFilewriter_encrypting,
	DecryptWindow_already,
	DecryptWindow_cancel,
	DecryptWindow_destination,
	DecryptWindow_failedgeneral,
	DecryptWindow_failedspecific,
	DecryptWindow_folderisfile,
	DecryptWindow_folderreadonly,
	DecryptWindow_invalid,
	DecryptWindow_nofile,
	DecryptWindow_success,
	DecryptWindow_text,
	DecryptWindow_title,
	DecryptWindow_unknownfile,
	DecryptWindow_wrongversion,
	Decrypt_Start,
	EncryptListChoose,
	EncryptListChooseMulti,
	EncryptWindow_EncryptedFile,
	EncryptWindow_Multidir,
	EncryptWindow_Multifile,
	EncryptWindow_MultifileMultidir,
	EncryptWindow_MultifileSingledir,
	EncryptWindow_Singledir,
	EncryptWindow_Singlefile,
	EncryptWindow_SinglefileMultidir,
	EncryptWindow_SinglefileSingledir,
	EncryptWindow_already,
	EncryptWindow_alreadydir,
	EncryptWindow_cancel,
	EncryptWindow_createdir,
	EncryptWindow_destination,
	EncryptWindow_failedgeneral,
	EncryptWindow_failedspecific,
	EncryptWindow_folderreadonly,
	EncryptWindow_multisources,
	EncryptWindow_success,
	EncryptWindow_title,
	FileSelection_dec4cloak,
	FileSelection_dec4enc,
	FileSelection_selectbutton,
	FileSelection_title,
	FileSelection_title4cloak,
	FilepathFailure,
	General_cancel,
	General_done,
	General_empty,
	General_none,
	General_open,
	General_password,
	General_quit,
	General_synchronize,
	JCEPolicyError_title,
	JCEPolicyError_text,
	Launcher_jcepolicyerr,
	Launcher_reallyquit,
	PasswordDecrypt_title,
	PasswordEncrypt_label,
	PasswordEncrypt_len,
	PasswordEncrypt_nomatch,
	PasswordEncrypt_retype,
	PasswordEncrypt_itcount,
	PasswordEncrypt_itcountdescr,
	PasswordEncrypt_title,
	Password_caps,
	Password_PBEinProgress,
	PGP_errorNokey,
	PGP_errorSeckeyfailed,
	PGP_nokeyfile,
	PGP_novalidprivkey,
	PGP_privkey_wrongfile,
	PGP_privkeypasstitle,
	PGP_selprivkey,
	PGP_selprivkeyTitle,
	PGP_selpubkey,
	PBKDF2Interstep_start,
	PBKDF2Interstep_found,
	PBKDF2Interstep_steplong,
	Suite_CAPI_RSAAES,
	Suite_PBE1_AES,
	Suite_PBE1_TWOFISH,
	Suite_PBE1_SERPENT,
	Suite_PBE1_CAMELLIA,
	Suite_PGP_AES,
	Suite_PBECLOAKED_AESTWO,
	Suite_PBECLOAKED1MB_AESTWO,

	;
	
	
	private static ResourceBundle rb;
	static{
		try {
			rb = ResourceBundle.getBundle(ResourceCenter.getTexts() + "text", ResourceCenter.getLocale());
		} catch (Exception e) {
			rb = ResourceBundle.getBundle(ResourceCenter.getTexts() + "text", Locale.ENGLISH);
		}
	}
	
	
	public String val(){
		return rb.getString(name());
	}
	
	public String msg(Object... obj){
		return MessageFormat.format(toString(), obj);
	}
	
	@Override
	public String toString() {
		return val();
	};
}
 public enum SUCCESS {
	TRUE,
	FALSE,
	CANCEL,
}
 public interface SimpleCallback<T> {
	public void callbackValue(Object source, T ret);
}
 public abstract class SuccessCallback implements SimpleCallback<SUCCESS> {
	@Override
	public abstract void callbackValue(Object source, SUCCESS ret);
}
 public class CryptoCodes {
	public static final String KEY_AES = "AES";
	public static final String KEY_RSA = "RSA";
	
	public static final String HMAC_SHA512 = "HmacSHA512";
	public static final String HMAC_WHIRL = "HmacWhirlpool";
	
	public static final String HASH_SHA512 = "SHA512";
	
	public static final int AES_KEYSIZE_BITS = 256;
	public static final int AES_KEYSIZE = AES_KEYSIZE_BITS / 8;

	public static final int STANDARD_BLOCKSIZE = 16;
	public static final int STANDARD_IVSIZE = STANDARD_BLOCKSIZE;
	public static final int STANDARD_SALTSIZE = 64;
	public static final int STANDARD_PBKDF2_ITERATIONS = 100000; 
	public static final int STANDARD_PBKDF2_PWLEN = 8; 


	private static HashMap<BASECIPHER, String> ecbCodes = new HashMap<>();
	private static HashMap<BASECIPHER, String> cbcpadCodes = new HashMap<>();
	private static HashMap<BASECIPHER, String> cbcnopadCodes = new HashMap<>();

	static{
		for(BASECIPHER b: BASECIPHER.values()){
			ecbCodes.put(b, b.getCipherCode() + "/ECB/NoPadding");
			cbcpadCodes.put(b, b.getCipherCode() + "/CBC/PKCS5Padding");
			cbcnopadCodes.put(b, b.getCipherCode() + "/CBC/NoPadding");
		}
	}

	public enum BASECIPHER{
		AES,
		TWOFISH ("Twofish"),
		SERPENT ("Serpent"),
		CAMELLIA ("Camellia"),
		
		;
		
		private String cipherCode = null;
		private BASECIPHER(){}
		private BASECIPHER(String cipherCode){
			this.cipherCode = cipherCode;
		}
		
		private String getCipherCode(){
			if(cipherCode != null)
				return cipherCode;
			
			return name();
		}
		
		public String getECB(){
			return ecbCodes.get(this);
		}
		
		public String getCBCPad(){
			return cbcpadCodes.get(this);
		}
		
		public String getCBCNopad(){
			return cbcnopadCodes.get(this);
		}
	}
}
 public class InitCrypto {
	private static boolean initialized = false;
	
	public static final void INIT(){
		if(initialized) return;
		
		initialized = true;
		BouncyCastleProvider bc = new BouncyCastleProvider();
		Security.addProvider(bc);
	}

	static{
		INIT();
	}
}
 public class ByteUtils {
	public static final byte[] stringToBytes(String str) {
		byte[] b = new byte[str.length() << 1];
		for (int i = 0; i < str.length(); i++) {
			char strChar = str.charAt(i);
			int bpos = i << 1;
			b[bpos] = (byte) ((strChar & 0xFF00) >> 8);
			b[bpos + 1] = (byte) (strChar & 0x00FF);
		}
		return b;
	}
	
	public static final byte[] charsToBytes(char[] chars) {
		byte[] b = new byte[chars.length << 1];
		for (int i = 0; i < chars.length; i++) {
			char strChar = chars[i];
			int bpos = i << 1;
			b[bpos] = (byte) ((strChar & 0xFF00) >> 8);
			b[bpos + 1] = (byte) (strChar & 0x00FF);
		}
		return b;
	}
	
	public static final char[] bytesToChars(byte[] bytes) {
		char[] buffer = new char[bytes.length >> 1];
		for (int i = 0; i < buffer.length; i++) {
			int bpos = i << 1;
			char c = (char) (((bytes[bpos] & 0x00FF) << 8) + (bytes[bpos + 1] & 0x00FF));
			buffer[i] = c;
		}
		
		return buffer;
	}

	public static final String bytesToString(byte[] bytes) {
		return new String(bytesToChars(bytes));
	}
	
	
	public static final byte[] longToBytes(long x) {
	    ByteBuffer buffer = ByteBuffer.allocate(Long.SIZE / 8);
	    buffer.putLong(x);
	    return buffer.array();
	}

	public static final long bytesToLong(byte[] bytes) {
	    ByteBuffer buffer = ByteBuffer.allocate(Long.SIZE / 8);
	    buffer.put(bytes);
	    buffer.flip(); 
	    return buffer.getLong();
	}

	
	public static final byte[] intToBytes(int x) {
	    ByteBuffer buffer = ByteBuffer.allocate(Integer.SIZE / 8);
	    buffer.putInt(x);
	    return buffer.array();
	}

	public static final int bytesToInt(byte[] bytes) {
	    ByteBuffer buffer = ByteBuffer.allocate(Integer.SIZE / 8);
	    buffer.put(bytes);
	    buffer.flip(); 
	    return buffer.getInt();
	}
	
	public static final byte[] objToBytes(Object o){
		JTYPE type = null;
		try {
			type = typeFromObj(o);
		} catch (Exception e) {
			System.err.println("OBJ unknown");
			return null;
		}
		
	    ByteBuffer buffer = ByteBuffer.allocate(type.size());
		switch (type) {
		case Long:
			buffer.putLong((Long)o);
			break;
		case Integer:
			buffer.putInt((Integer)o);
			break;
		case Byte:
			buffer.put((Byte)o);
			break;
		case Short:
			buffer.putShort((Short)o);
			break;
		case Double:
			buffer.putDouble((Double)o);
			break;
		case Float:
			buffer.putFloat((Float)o);
			break;
		case Character:
			buffer.putChar((char)o);
			break;
		default:
			System.err.println("OBJ unknown");
		}

	    return buffer.array();
	}
	
	@SuppressWarnings("unchecked")
	public static final <T>T bytesToObject(byte[] bytes, T o){
		JTYPE type = null;
		try {
			type = typeFromObj(o);
		} catch (Exception e) {
			System.err.println("OBJ unknown");
			return null;
		}
		
		if(bytes.length > type.size) bytes = cut(bytes, type.size);
		
	    ByteBuffer buffer = ByteBuffer.allocate(type.size());
	    buffer.put(bytes);
	    buffer.flip(); 
	    
		switch (type) {
		case Long:
			return (T) (Long)buffer.getLong();
		case Integer:
			return (T) (Integer)buffer.getInt();
		case Byte:
			return (T) (Byte)buffer.get();
		case Short:
			return (T) (Short)buffer.getShort();
		case Double:
			return (T) (Double)buffer.getDouble();
		case Float:
			return (T) (Float)buffer.getFloat();
		case Character:
			return (T) (Character)buffer.getChar();
		default:
			System.err.println("OBJ unknown");
			return null;
		}
	}
	
	public enum JTYPE{
		Long(8),
		Integer(4),
		Byte(1),
		Short(2),
		Double(64),
		Float(32),
		Character(2),
		
		;
		
		private int size;
		private JTYPE(int size){
			this.size = size;
		}
		
		public int size(){
			return size;
		}
	}
	
	public static final JTYPE typeFromObj(Object obj){
		JTYPE type = null;
		try {
			type = JTYPE.valueOf(obj.getClass().getSimpleName());
		} catch (Exception e) {
		}
		return type;
	}
	
	public static final int sizeObject(Object o){
		return typeFromObj(o).size();
	}
	
	public static final int sizeInBytes(Object o){
		if(o instanceof byte[]) return ((byte[]) o).length;
		return typeFromObj(o).size();
	}
	
	public static final int sizeInBytes(Object... o){
		int ret = 0;
		for(Object ox: o)
			ret += sizeInBytes(ox);
		return ret;
	}
	
	public static final int b2i(byte b){
		if(b >= 0) return b;
		return b + 256;
	}
	
	public static final byte i2b(int i){
		if(i > 128) return (byte)(i - 256);
		return (byte) i;
	}
	
	public static final byte[] copyTogetherNwipeO(Object... arr){
		byte[][] b = new byte[arr.length][];
		
		for(int i=0; i<arr.length; i++){
			if(arr[i] != null)
				b[i] = objToBytes(arr[i]);
			else
				b[i] = new byte[]{1};
		}
		
		return copyTogetherNwipeB(b);
	}
	
	public static final byte[] copyTogetherNwipeB(byte[]... arr){
		int len = 0;
		for(byte[] b: arr){
			if(b == null) continue;
			
			len += b.length;
		}
		
		byte[] ret = new byte[len];
		int start = 0;
		for(byte[] b: arr){
			if(b == null) continue;
			
			System.arraycopy(b, 0, ret, start, b.length);
			start += b.length;
			CryptoUtils.kill(b);
		}
		
		return ret;
	}

	public static final byte[] cut(byte[] bytes, int newlen){
		byte[] ret = new byte[newlen];
		System.arraycopy(bytes, 0, ret, 0, newlen);
		return ret;
	}
	
	public static final byte[] fill(byte[] bytes, int newlen){
		byte[] ret = new byte[newlen];
		System.arraycopy(bytes, 0, ret, 0, bytes.length);
		return ret;
	}
	
	public static final byte[] fill(Object o, int newlen){
		byte[] o_bytes = objToBytes(o);
		byte[] ret = new byte[newlen];
		System.arraycopy(o_bytes, 0, ret, 0, o_bytes.length);
		return ret;
	}
}
 public class OSFolders {
	public static final File getUserChooserstart(){
		String tmp;
		File ftmp;
		
		switch (OSDetector.which()) {
		case WIN:
			tmp = System.getenv("USERPROFILE");
			ftmp = new File(tmp);
			if(ftmp.exists() && ftmp.isDirectory()) return ftmp;

		case LIN:
		case MAC:
			tmp = System.getProperty("user.home");
			ftmp = new File(tmp);
			if(ftmp.exists() && ftmp.isDirectory()) return ftmp;
			
			if(OSDetector.which() == OS.WIN){
				tmp = System.getenv("SystemDrive");
				ftmp = new File(tmp);
				if(ftmp.exists() && ftmp.isDirectory()) return ftmp;
			}

		default:
			return new File("."); 
		}
	}
	
	public static final File getUserAppfolder(String keyword){
		File base = getUserBasefolder();
		if(!OSDetector.isWin()){
			keyword = "." + keyword.toLowerCase();
		}
		base = new File(base, keyword);
		return base;
	}
	
	public static final File makeUserAppfolder(String keyword){
		File base = getUserAppfolder(keyword);
		if(!base.exists()) base.mkdir();
		return base;
	}
	
	public static final File getUserBasefolder(){
		String tmp;
		File ftmp;
		
		switch (OSDetector.which()) {
		case WIN:
			tmp = System.getenv("appdata");
			ftmp = new File(tmp);
			if(ftmp.exists() && ftmp.isDirectory()) return ftmp;

		case LIN:
		case MAC:
			tmp = System.getProperty("user.home");
			ftmp = new File(tmp);
			if(ftmp.exists() && ftmp.isDirectory()) return ftmp;
		}
		
		return null;
	}

	public static final boolean isRoot(File f){
		if(f == null) return false;
		return isRoot(f.getAbsolutePath());
	}

	public static final boolean isRoot(String path){
		return isDriveRoot(path) || isNetworkRoot(path);
	}

	public static final boolean isNetworkRoot(File f){
		if(f == null) return false;
		return isNetworkRoot(f.getAbsolutePath());
	}

	public static final boolean isNetworkRoot(String path){
		if(path == null || path.length() == 0) return false;
		if(OSDetector.which() == OS.WIN){
			if(path.length() > 2 && path.startsWith("\\\\")){
				int i = path.indexOf('\\', 2);
				if(i < 0 || i== path.length() - 1) return true;
			}
		}
		return false;
	}

	public static final boolean isDriveRoot(File f){
		if(f == null) return false;
		return isDriveRoot(f.getAbsolutePath());
	}

	public static final boolean isDriveRoot(String path){
		if(path == null || path.length() == 0) return false;
		
		switch (OSDetector.which()) {
		case WIN:
			if(path.length() == 1 || path.length() > 3) return false;
			else if(path.length() == 2 && path.charAt(1) == ':') return true;
			else if(path.length() == 3 && path.charAt(1) == ':' && path.charAt(2) == '\\') return true;
			return false;

		case LIN:
		case MAC:
			if(path.length() > 1) return false;
			else if(path.length() == 1 && path.equals(File.separator)) return true;
			return false;
		}
		return false;
	}
	
	public static final String cutRoot(String abspath){
		if(abspath == null || abspath.length() == 0) return null;
		
		if(isRoot(abspath)){
			if(abspath.endsWith(File.separator)) return abspath;
			return abspath + File.separator;
		}

		switch (OSDetector.which()) {
		case LIN:
		case MAC:
			return File.separator;
			
		case WIN:
			if(abspath.startsWith("\\\\")){
				if(!abspath.endsWith(File.separator)) abspath += File.separator;
				return abspath.substring(0, abspath.indexOf('\\', 2) + 1);
			}
			else{
				return abspath.substring(0, 3);
			}
		}
		return null;
	}
}
 public interface StatusUpdate {
	public void start();
	public void finished();
	public boolean isActive();
	public void receiveMessageSummary(String msg);
	public void receiveMessageDetails(String msg);
	public void receiveProgress(int perc);
	public void receiveDetailsProgress(int perc);
}

import java.awt.Desktop;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import javax.crypto.Cipher;
import org.bouncycastle.util.encoders.Hex;
import org.crococryptfile.ConsoleOptions.ConsoleOptions_Params;
import org.crococryptfile.datafile.CrocoFilereader;
import org.crococryptfile.datafile.CrocoFilewriter;
import org.crococryptfile.suites.BasicFileinfo;
import org.crococryptfile.suites.SUITES;
import org.crococryptfile.suites.Suite;
import org.crococryptfile.suites.Suite.SuiteReceiver;
import org.crococryptfile.suites.SuiteMODE;
import org.crococryptfile.suites.SuitePARAM;
import org.crococryptfile.ui.CbIDecrypt;
import org.crococryptfile.ui.CbIEncrypt;
import org.crococryptfile.ui.UICenter;
import org.crococryptfile.ui.cui.CPrint;
import org.crococryptfile.ui.cui.PasswordCreateConsole;
import org.crococryptfile.ui.cui.PasswordInputConsole;
import org.crococryptfile.ui.cui.StatusConsole;
import org.crococryptfile.ui.gui.CrocoparamsDialog;
import org.crococryptfile.ui.gui.PGP_PrivatekeyDialog;
import org.crococryptfile.ui.gui.Page;
import org.crococryptfile.ui.gui.PageLauncher;
import org.crococryptfile.ui.gui.PageLauncher.Options;
import org.crococryptfile.ui.gui.PasswordCreatedialog;
import org.crococryptfile.ui.gui.PasswordCreatedialogWithOptions;
import org.crococryptfile.ui.gui.PasswordInputdialog;
import org.crococryptfile.ui.gui.ProgressDoubleWindow;
import org.crococryptfile.ui.gui.ProgressWindow;
import org.crococryptfile.ui.gui.SimpleDialogs;
import org.crococryptfile.ui.gui.pages.CAPI_DNList;
import org.crococryptfile.ui.gui.pages.Decrypt;
import org.crococryptfile.ui.gui.pages.Encrypt;
import org.crococryptfile.ui.gui.pages.JCEPolicyError;
import org.crococryptfile.ui.gui.pages.PGP_Keylist;
import org.crococryptfile.ui.resources._T;
import org.fhissen.callbacks.SUCCESS;
import org.fhissen.callbacks.SimpleCallback;
import org.fhissen.callbacks.SuccessCallback;
import org.fhissen.crypto.CryptoCodes;
import org.fhissen.crypto.InitCrypto;
import org.fhissen.utils.ByteUtils;
import org.fhissen.utils.os.OSFolders;
import org.fhissen.utils.ui.StatusUpdate;

			}
			else{
				operationParams.put(SuitePARAM.password, value);
			}
		}
		else if(c == CAPI_DNList.class){
			operationParams.put(SuitePARAM.capi_alias, value);
		}
		else if(value instanceof HashMap){
			HashMap hm = (HashMap) value;
			if(hm.isEmpty()) return;
			
			if(hm.keySet().iterator().next() instanceof SuitePARAM){
				operationParams.putAll(hm);
			}
		}
	}
	
	private void setRawParams(ArrayList<String> raw){
		if(reqparams == null || reqparams.length == 0 || raw == null || raw.size() < reqparams.length) return;

		for(reqparams_index = 0; reqparams_index < reqparams.length; reqparams_index++){
			SuitePARAM tmp = reqparams[reqparams_index];
			switch (tmp) {
			case capi_alias:
				operationParams.put(tmp, raw.get(reqparams_index));
				continue;

			case password:
				UICenter.message("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" +
						"You are providing a password as commandline option, this is NOT RECOMMEND" +
						"\nsince your password might be easily gathered." +
						"\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
				char[] pw = raw.get(reqparams_index).toCharArray();
				if(pw.length < CryptoCodes.STANDARD_PBKDF2_PWLEN){
					CPrint.line(_T.PasswordEncrypt_len.msg(CryptoCodes.STANDARD_PBKDF2_PWLEN));
					continue;
				}
				operationParams.put(tmp, pw);
				continue;
				
			case pgp_enc:
				if(raw.size() < 2) {
					System.err.println("Not enough parameters specified");
					return;
				}
				operationParams.put(SuitePARAM.pgp_pubkeyfile, raw.get(0));
				
				ArrayList<Long> kids = new ArrayList<>();
				for(int i=1; i<raw.size(); i++){
					String rawid = raw.get(i).trim();
					if(rawid.length() < 16){
						System.err.println("Only long keyid format supported");
						continue;
					}

					Long l = 0L;
					if(rawid.length() == 16){
						try {
							l = ByteUtils.bytesToLong(Hex.decode(rawid));
						} catch (Exception e) {}
					}
					else{
						try {
							l = Long.parseLong(rawid);
						} catch (Exception e) {}
					}

					if(l != 0) {
						kids.add(l);
					}
					else{
						System.err.println("keyid " + rawid + " could not be read");
					}
				}
				if(kids.size() == 0) return;
				
				operationParams.put(SuitePARAM.pgp_keyidlist, kids);
				continue;

			case pgp_dec:
				if(raw.size() < 2) {
					System.err.println("Not enough parameters specified");
					return;
				}
				
				UICenter.message("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" +
						"You are providing a password as commandline option, this is NOT RECOMMEND" +
						"\nsince your password might be easily gathered." +
						"\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
				char[] pwpgp = raw.get(1).toCharArray();

				operationParams.put(SuitePARAM.pgp_privkeyfile, raw.get(0));
				operationParams.put(SuitePARAM.password, pwpgp);
				continue;

			default:
				UICenter.message("unknown credential");
				break;
			}
		}
	}
	
	private void doEncrypt(){
		final StatusUpdate stat;
		if(UICenter.isGUI()){
			stat = new ProgressDoubleWindow(((Page)currentSource).getPageLauncher().getWindow()).prepare();
		}
		else if(inputparams.verboseconsole){
			stat = new StatusConsole();
		}
		else{
			stat = null;
		}

		if(stat != null){
			stat.start();
			stat.receiveMessageSummary(_T.Password_PBEinProgress.val());
		}
		

		Suite.getInitializedInstanceAsync(inputparams.suite, SuiteMODE.ENCRYPT, operationParams, stat, new SuiteReceiver() {
