[Esbox-commits] r976 - in branches/work_Ed: org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/api/maemosdk/core org.maemo.esbox.maemosdk.tests/src/org/maemo/esbox/scratchbox/tests org.maemo.esbox.maemosdk.ui/src/org/maemo/esbox/internal/api/maemosdk/ui/preferences org.maemo.esbox.scratchbox.sb1/src/org/maemo/esbox/internal/scratchbox/sb1/launcher org.maemo.esbox.vm/conf org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/core org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/ui/preferences org.maemo.esbox.vm/src/org/maemo/esbox/vm/core org.maemo.esbox.vm.vmware org.maemo.esbox.vm.vmware/about_files

eswartz at garage.maemo.org eswartz at garage.maemo.org
Fri Nov 21 23:49:05 EET 2008


Author: eswartz
Date: 2008-11-21 23:49:05 +0200 (Fri, 21 Nov 2008)
New Revision: 976

Added:
   branches/work_Ed/org.maemo.esbox.vm.vmware/about.html
   branches/work_Ed/org.maemo.esbox.vm.vmware/about_files/
   branches/work_Ed/org.maemo.esbox.vm.vmware/about_files/epl-v10.html
Modified:
   branches/work_Ed/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/api/maemosdk/core/SharedFilesystemMounter.java
   branches/work_Ed/org.maemo.esbox.maemosdk.tests/src/org/maemo/esbox/scratchbox/tests/ESboxProductTestSuite.java
   branches/work_Ed/org.maemo.esbox.maemosdk.ui/src/org/maemo/esbox/internal/api/maemosdk/ui/preferences/SharedFolderPreferenceConverter.java
   branches/work_Ed/org.maemo.esbox.maemosdk.ui/src/org/maemo/esbox/internal/api/maemosdk/ui/preferences/SharedFolderTableViewer.java
   branches/work_Ed/org.maemo.esbox.maemosdk.ui/src/org/maemo/esbox/internal/api/maemosdk/ui/preferences/SharedFoldersPreferencePage.java
   branches/work_Ed/org.maemo.esbox.maemosdk.ui/src/org/maemo/esbox/internal/api/maemosdk/ui/preferences/ValidateMachineRunner.java
   branches/work_Ed/org.maemo.esbox.scratchbox.sb1/src/org/maemo/esbox/internal/scratchbox/sb1/launcher/Scratchbox1ProcessLauncher.java
   branches/work_Ed/org.maemo.esbox.vm/conf/vm_prefs.xml
   branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/core/BaseCustomVirtualMachineConfiguration.java
   branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/core/BasePreferenceVirtualMachineConfiguration.java
   branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/core/BaseVirtualMachineController.java
   branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/ui/preferences/CommonVirtualMachineSettingsPreferencePage.java
   branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/vm/core/VirtualMachinePreferenceConstants.java
Log:
Final (?) commit for VM support.  
-- Reworked some issues with the shared folder UI, machine validation, and reporting of mounting problems. 
-- Allow for auto-mounted shares.  
-- Handle cleaning up in some cases where sftp protocol goes wonky
-- Support encrypting passwords for memory and preference storage

Modified: branches/work_Ed/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/api/maemosdk/core/SharedFilesystemMounter.java
===================================================================
--- branches/work_Ed/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/api/maemosdk/core/SharedFilesystemMounter.java	2008-11-21 20:29:07 UTC (rev 975)
+++ branches/work_Ed/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/api/maemosdk/core/SharedFilesystemMounter.java	2008-11-21 21:49:05 UTC (rev 976)
@@ -11,22 +11,15 @@
 
 package org.maemo.esbox.internal.api.maemosdk.core;
 
-import org.eclipse.core.filesystem.IFileStore;
+import com.nokia.cpp.internal.api.utils.core.StatusBuilder;
+
 import org.eclipse.core.runtime.*;
-import org.eclipse.jface.dialogs.IDialogConstants;
 import org.maemo.esbox.internal.maemosdk.core.Activator;
-import org.maemo.mica.common.core.*;
 import org.maemo.mica.common.core.machine.*;
-import org.maemo.mica.common.core.process.*;
-import org.maemo.mica.common.core.process.ProcessLauncherUtils.Results;
-import org.maemo.mica.common.ui.dialogs.DialogUtils;
-import org.maemo.mica.common.ui.dialogs.PasswordInputDialog;
-import org.maemo.mica.internal.api.common.core.machine.IMountVisitor;
-import org.maemo.mica.internal.api.common.core.machine.MountWalker;
+import org.maemo.mica.common.ui.SambaCredentialsProvider;
+import org.maemo.mica.internal.api.common.core.machine.SambaSharedFolderHandler;
+import org.maemo.mica.internal.api.common.core.machine.SharedFolderTransactionInfo;
 
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.text.MessageFormat;
 import java.util.List;
 
 /**
@@ -44,213 +37,51 @@
 	 * and launching 'mount_share.sh' to mount them otherwise.
 	 * <p>
 	 * XXX: this must be rewritten at some point to handle shares which aren't handled by mount_share.sh!
-	 * @param subProgressMonitor 
+	 * @param localMachine
+	 * @param remoteMachine
+	 * @param monitor 
 	 * @return Status of mount
 	 */
-	public static IStatus validateSharedMounts(IMachine machine, IProgressMonitor monitor) {
+	public static IStatus validateSharedMounts(IMachine localMachine, IMachine remoteMachine, IProgressMonitor monitor) {
 
 		ISharedFilesystemProvider sharedFilesystemProvider = 
-			machine.getSharedFilesystemProvider();
+			remoteMachine.getSharedFilesystemProvider();
 		if (sharedFilesystemProvider == null)
 			return Status.OK_STATUS;
 		
 		List<ISharedFolder> sharedFolders = sharedFilesystemProvider.getSharedFolders();
 		
 		monitor.beginTask("Validating shared folders", sharedFolders.size() * 2);
+
+		// go through the folders and pass th
 		
-		boolean neededMount = false;
-		
-		String fsTypePattern = "smbfs|cifs";
-		for (ISharedFolder share : sharedFolders) {
-			if (!isPathMounted(machine, share.getRemotePath(), fsTypePattern, null)) {
-				neededMount = true;
-				PasswordInputDialog dialog = new PasswordInputDialog(
-						DialogUtils.getShell(), 
-						"Password Required",
-						MessageFormat.format(
-								"Enter the password for user ''{0}'' to mount the share ''{1}'':",
-								MachineRegistry.getInstance().getLocalMachine().getUserName(),
-								share.getLocalPath()));
-				if (IDialogConstants.CANCEL_ID == dialog.open())
-					continue;
-				
-				// TODO: this assumes a certain script exists on the VM
-				try {
-					mountSharesWithPassword(machine, dialog.getPassword());
-				} catch (MicaException e) {
-					return Activator.createErrorStatus(
-							MessageFormat.format(
-									"Could not mount ''{0}'' in {1}",
-									share.getLocalPath().toString(),
-									machine.getName()), e);
-				}
-				
-				monitor.worked(1);
-				if (monitor.isCanceled())
-					return Policy.getCancelStatus(Activator.getDefault());
+		StatusBuilder builder = new StatusBuilder(Activator.getDefault());
+		for (ISharedFolder sharedFolder : sharedFolders) {
+			if (sharedFolder.getShareType() != EShareType.SAMBA) {
+				throw new IllegalStateException("Need to handle mounting " + sharedFolder.getShareType());
 			}
+			
+			SambaSharedFolderHandler handler = new SambaSharedFolderHandler();
+			
+			SharedFolderTransactionInfo info = new SharedFolderTransactionInfo(
+					sharedFolder, localMachine, remoteMachine, 
+					SambaCredentialsProvider.getInstance());
+			
+			IStatus status = handler.validateShare(info,
+					new SubProgressMonitor(monitor, 2));
+			
+			builder.add(status);
 		}
 		
-		// verify that the mounting succeeded
-		boolean allSharesMounted = true;
-		if (neededMount) {
-			for (ISharedFolder share : sharedFolders) {
-				if (!isPathMounted(machine, share.getRemotePath(), fsTypePattern, null)) {
-					allSharesMounted = false;
-				}
-				monitor.worked(1);
-				if (monitor.isCanceled())
-					return Policy.getCancelStatus(Activator.getDefault());
-			}
-		}
-		
 		monitor.done();
 		
-		if (!allSharesMounted) {
-			return Activator.createStatus(IStatus.WARNING, 
-					MessageFormat.format(
+		if (builder.getErrorCount() > 0 || builder.getWarningCount() > 0) {
+			return builder.createMultiStatus( 
 							"Not all the known shares were mounted in {0}; builds may fail",
-							machine.getName()));
+							new Object[] { remoteMachine.getName() });
 		}
 
 		return Status.OK_STATUS;
 	}
-	
-	/**
-	 * Run the 'mount_share.sh' script to mount shares.
-	 * @param password
-	 */
-	protected static void mountSharesWithPassword(IMachine machine, final String password) throws MicaException {
-		IProcessLauncherFactory processLauncherFactory = machine.getProcessLauncherFactory();
-		final IProcessLauncher processLauncher = ProcessLauncherCreator.createProcessLauncher(processLauncherFactory,
-				machine.getUserHome(),
-				CommandLineArguments.createFromVarArgs(
-						"sh",
-						"mount_share.sh"));
-		
-		processLauncher.usePTY(true);
-		//final Process process = processLauncher.createProcess();
-		final MicaException[] exceptions = { null };
-		
-		Thread thread = new Thread("Send password to mount") {
 
-			/* (non-Javadoc)
-			 * @see java.lang.Thread#run()
-			 */
-			@Override
-			public void run() {
-				//try {
-					/* this goes to a weird stream (somehow) so we can't read it,
-					 even though it shows up when we put stuff to the Console!
-					InputStream is = process.getInputStream();
-					int ch;
-					// read "Password:"
-					while ((ch = is.read()) != -1) {
-						if (ch == ':') {
-							break;
-						}
-					}
-					*/
-					
-					try {
-						Results results = ProcessLauncherUtils.launchAndReadStandardStreamsWithInput(processLauncher, 
-								new ByteArrayInputStream((password + "\n").getBytes()),
-								null);
-						String stdout = results.stdout.trim();
-						String stderr = results.stderr.replaceAll("Password:", "").trim();
-						if (results.exitCode != 0 || stdout.length() + stderr.length() > 0) {
-							exceptions[0] = new MicaException("Mounting script did not succeed:\n\n"
-									+ stdout + "\n" + stderr);
-						}
-					} catch (MicaException e) {
-						exceptions[0] = e;
-					}
-					System.out.println(exceptions[0]);
-					
-					/* this process adds noise to the console window without much use
-					// send password
-					OutputStream os = process.getOutputStream();
-					os.write((password + "\n").getBytes());
-					os.close();
-
-					// now let the remaining output go to the Console
-					processLauncher.redirectToConsole(false, null, "Mounting shares");
-					try {
-						int exit = process.waitFor();
-						if (exit != 0) {
-							exceptions[0] = new MicaException("Mounting script did not succeed; check Console for errors");
-							return;
-						}
-					} catch (InterruptedException e) {
-					}
-					
-				} catch (IOException e) {
-					exceptions[0] = new MicaException("Failed to send password", e);
-					return;
-				}
-				*/
-			}
-		};
-		thread.start();
-		
-		boolean timedOut = !JobUtils.waitForThread(thread, 10000, null);
-
-		//process.destroy();
-		
-		MicaException result = exceptions[0];
-		if (thread.isAlive())
-			thread.interrupt();
-		
-		if (result != null) {
-			throw result;
-		}
-		if (timedOut) {
-			throw new MicaException("Timeout sending password");
-		}
-	}
-
-	/**
-	 * Tell whether the given path is mounted on the machine.
-	 * @param value the path to check
-	 * @param fsTypePattern if not null, the regex of fsTypes that should match
-	 * @param devicePattern if not null, the regex of devices that should match 
-	 * @return true: an entry in /proc/mounts matches, else false
-	 */
-	public static boolean isPathMounted(IMachine machine, IPath value, final String fsTypePattern, final String devicePattern) {
-		IFileStore store = machine.getFileSystemAccess().getFileStore(new Path("/proc/mounts"));
-		InputStream is = null;
-		try {
-			MountWalker walker = new MountWalker();
-			final boolean[] found = { false };
-			final String path = value.toPortableString();
-			is = store.openInputStream(0, null);
-			walker.accept(is, new IMountVisitor() {
-	
-				public boolean handleMount(String device, String point,
-						String fsType, String options) {
-					if (point.equals(path)) {
-						// XXX hack until we distinguish WHERE shares are mounted to/from
-						if (point.equals("/scratchbox")) {
-							found[0] = true;
-							return true;
-						}
-						
-						if ((devicePattern == null || device.matches(devicePattern)) &&
-								(fsTypePattern == null || fsType.matches(fsTypePattern))) {
-							found[0] = true;
-							return false;
-						}
-					}
-					return true;
-				}
-				
-			});
-			return found[0];
-		} catch (CoreException e) {
-			Activator.getErrorLogger().logError("Cannot parse mounts", e);
-			return false;
-		} finally {
-			Policy.close(is);
-		}
-	}
 }

Modified: branches/work_Ed/org.maemo.esbox.maemosdk.tests/src/org/maemo/esbox/scratchbox/tests/ESboxProductTestSuite.java
===================================================================
--- branches/work_Ed/org.maemo.esbox.maemosdk.tests/src/org/maemo/esbox/scratchbox/tests/ESboxProductTestSuite.java	2008-11-21 20:29:07 UTC (rev 975)
+++ branches/work_Ed/org.maemo.esbox.maemosdk.tests/src/org/maemo/esbox/scratchbox/tests/ESboxProductTestSuite.java	2008-11-21 21:49:05 UTC (rev 976)
@@ -11,7 +11,10 @@
 
 package org.maemo.esbox.scratchbox.tests;
 
+import org.eclipse.core.runtime.IStatus;
+import org.maemo.mica.common.core.ErrorLogger;
 import org.maemo.mica.common.core.MicaException;
+import org.maemo.mica.common.core.ErrorLogger.Listener;
 import org.maemo.mica.common.core.machine.*;
 import org.maemo.mica.common.core.tests.TestMachineUtils;
 
@@ -43,6 +46,15 @@
 		} catch (MicaException e) {
 		}
 		
+		ErrorLogger.Listener listener = new Listener() {
+
+			public void statusLogged(IStatus status) {
+				System.out.println(status);
+			}
+			
+		};
+		ErrorLogger.addListener(listener);
+		
 		suite.addTest(org.maemo.mica.common.core.tests.MicaCoreTestSuite.suite());
 		suite.addTest(org.maemo.esbox.scratchbox.tests.ESboxMaemoSDKTestSuite.suite());
 		suite.addTest(org.maemo.mica.linux.tests.MicaLinuxTestSuite.suite());

Modified: branches/work_Ed/org.maemo.esbox.maemosdk.ui/src/org/maemo/esbox/internal/api/maemosdk/ui/preferences/SharedFolderPreferenceConverter.java
===================================================================
--- branches/work_Ed/org.maemo.esbox.maemosdk.ui/src/org/maemo/esbox/internal/api/maemosdk/ui/preferences/SharedFolderPreferenceConverter.java	2008-11-21 20:29:07 UTC (rev 975)
+++ branches/work_Ed/org.maemo.esbox.maemosdk.ui/src/org/maemo/esbox/internal/api/maemosdk/ui/preferences/SharedFolderPreferenceConverter.java	2008-11-21 21:49:05 UTC (rev 976)
@@ -11,7 +11,10 @@
 
 package org.maemo.esbox.internal.api.maemosdk.ui.preferences;
 
+import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.Path;
+import org.maemo.esbox.internal.maemosdk.ui.UIActivator;
+import org.maemo.mica.common.core.machine.EShareType;
 import org.maemo.mica.common.core.machine.ISharedFolder;
 import org.maemo.mica.internal.api.common.core.machine.BaseSharedFolder;
 
@@ -43,7 +46,10 @@
 				continue;
 			String entry = element.getLocalPath().toOSString() 
 				+ "|" + element.getRemotePath().toPortableString()
-				+ "|" + element.isAlias();
+				+ "|" + element.isManual() 
+				+ "|" + element.isHostProvidedShare() 
+				+ "|" + element.getShareType()
+				+ "|" + element.getShareName();
 			if (first)
 				first = false;
 			else
@@ -60,10 +66,37 @@
 		String[] entries = preference.split(",");
 		List<ISharedFolder> elements = new ArrayList<ISharedFolder>();
 		for (String entry : entries) {
+			// host|target|alias|hostprovided|type
 			String[] hostTarget = entry.split("\\|");
-			if (hostTarget.length == 3) {
-				elements.add(new BaseSharedFolder(new Path(hostTarget[0]), new Path(hostTarget[1]),
-						Boolean.parseBoolean(hostTarget[2])));
+			IPath host, target;
+			boolean isAlias = false;
+			boolean isHostProvided = true;
+			EShareType type = EShareType.SAMBA;
+			String shareName = null;
+			
+			if (hostTarget.length >= 2) {
+				host = new Path(hostTarget[0]);
+				target =  new Path(hostTarget[1]);
+				if (hostTarget.length >= 3) {
+					isAlias = Boolean.parseBoolean(hostTarget[2]);
+					if (hostTarget.length >= 4) {
+						isHostProvided = Boolean.parseBoolean(hostTarget[3]);
+						if (hostTarget.length >= 5) {
+							try {
+								type = EShareType.valueOf(hostTarget[4]);
+							} catch (IllegalArgumentException e) {
+								UIActivator.getErrorLogger().logError("Invalid shared folder type in: " + entry, null);
+							}
+							if (hostTarget.length >= 6) {
+								shareName = hostTarget[5];
+							}
+						}
+					}
+				}
+				elements.add(new BaseSharedFolder(type,
+						host, target, shareName, isAlias, isHostProvided));
+			} else {
+				UIActivator.getErrorLogger().logError("Invalid shared folder stored: " + entry, null);
 			}
 		}
 		return elements;

Modified: branches/work_Ed/org.maemo.esbox.maemosdk.ui/src/org/maemo/esbox/internal/api/maemosdk/ui/preferences/SharedFolderTableViewer.java
===================================================================
--- branches/work_Ed/org.maemo.esbox.maemosdk.ui/src/org/maemo/esbox/internal/api/maemosdk/ui/preferences/SharedFolderTableViewer.java	2008-11-21 20:29:07 UTC (rev 975)
+++ branches/work_Ed/org.maemo.esbox.maemosdk.ui/src/org/maemo/esbox/internal/api/maemosdk/ui/preferences/SharedFolderTableViewer.java	2008-11-21 21:49:05 UTC (rev 976)
@@ -16,6 +16,7 @@
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.*;
 import org.eclipse.swt.widgets.*;
+import org.maemo.mica.common.core.machine.EShareType;
 import org.maemo.mica.common.core.machine.ISharedFolder;
 
 import java.util.Collection;
@@ -27,13 +28,26 @@
  */
 public class SharedFolderTableViewer extends TableViewer {
 
+	final int HOST_COLUMN = 0;
+	final int FROMTO_COLUMN = 1;
+	final int TARGET_COLUMN = 2;
+	final int NAME_COLUMN = 3;
+	final int AUTO_COLUMN = 4;
+	final int TYPE_COLUMN = 5;
+	
 	private Collection<ISharedFolder> mappings;
 	private TableColumn targetColumn;
+	private TableColumn fromToColumn;
 	private TableColumn hostColumn;
-	private TableColumn aliasColumn;
+	private TableColumn nameColumn;
+	private TableColumn autoColumn;
+	private TableColumn typeColumn;
 	private TableViewerColumn hostViewerColumn;
 	private TableViewerColumn targetViewerColumn;
-	private TableViewerColumn aliasViewerColumn;
+	private TableViewerColumn fromToViewerColumn;
+	private TableViewerColumn nameViewerColumn;
+	private TableViewerColumn autoViewerColumn;
+	private TableViewerColumn typeViewerColumn;
 	
 	public SharedFolderTableViewer(Composite parent, int style) {
 		super(parent, style | SWT.FULL_SELECTION | SWT.SINGLE);
@@ -46,15 +60,33 @@
 		hostColumn = new TableColumn(table, SWT.LEFT);
 		hostColumn.setText("Host");
 		hostColumn.pack();
+		hostColumn.setToolTipText("This is the host path matched with the target.");
 		
+		fromToColumn = new TableColumn(table, SWT.LEFT);
+		fromToColumn.setText("");
+		fromToColumn.pack();
+		fromToColumn.setToolTipText("This tells who provides the shared folder.\n\"<-\" means the target provides the share, \"->\" means the host provides the share.");
+		
 		targetColumn = new TableColumn(table, SWT.LEFT);
 		targetColumn.setText("Target");
 		targetColumn.pack();
+		targetColumn.setToolTipText("This is the target-side path matched with the host.");
 		
-		aliasColumn = new TableColumn(table, SWT.CENTER);
-		aliasColumn.setText("Alias?");
-		aliasColumn.pack();
+		nameColumn = new TableColumn(table, SWT.LEFT);
+		nameColumn.setText("Name");
+		nameColumn.pack();
+		nameColumn.setToolTipText("This is the name of the share exposed by the provider.");
 		
+		autoColumn = new TableColumn(table, SWT.CENTER);
+		autoColumn.setText("Auto?");
+		autoColumn.pack();
+		autoColumn.setToolTipText("If \"yes\", ESbox will attempt to mount the share itself.  Otherwise, you must do this on your own.");
+		
+		typeColumn = new TableColumn(table, SWT.LEFT);
+		typeColumn.setText("Type");
+		typeColumn.pack();
+		typeColumn.setToolTipText("The method for mounting the share.\nCurrently only used when auto-mounting the share,\nbut may serve other purposes later.");
+		
 		hostViewerColumn = new TableViewerColumn(this, hostColumn);
 		hostViewerColumn.setLabelProvider(new ColumnLabelProvider() {
 			@Override
@@ -63,6 +95,14 @@
 				return entry.getLocalPath().toOSString();
 			}
 		});
+		fromToViewerColumn = new TableViewerColumn(this, fromToColumn);
+		fromToViewerColumn.setLabelProvider(new ColumnLabelProvider() {
+			@Override
+			public String getText(Object element) {
+				ISharedFolder entry = (ISharedFolder) element;
+				return entry.isHostProvidedShare() ? "->" : "<-";
+			}
+		});
 		targetViewerColumn = new TableViewerColumn(this, targetColumn);
 		targetViewerColumn.setLabelProvider(new ColumnLabelProvider() {
 			@Override
@@ -71,22 +111,48 @@
 				return entry.getRemotePath().toPortableString();
 			}
 		});
-		aliasViewerColumn = new TableViewerColumn(this, aliasColumn);
-		aliasViewerColumn.setLabelProvider(new ColumnLabelProvider() {
+		nameViewerColumn = new TableViewerColumn(this, nameColumn);
+		nameViewerColumn.setLabelProvider(new ColumnLabelProvider() {
 			@Override
 			public String getText(Object element) {
 				ISharedFolder entry = (ISharedFolder) element;
-				return entry.isAlias() ? "yes" : "no";
+				return entry.getShareName();
 			}
 		});
+		autoViewerColumn = new TableViewerColumn(this, autoColumn);
+		autoViewerColumn.setLabelProvider(new ColumnLabelProvider() {
+			@Override
+			public String getText(Object element) {
+				ISharedFolder entry = (ISharedFolder) element;
+				return entry.isManual() ? "no" : "yes";
+			}
+		});
+		typeViewerColumn = new TableViewerColumn(this, typeColumn);
+		typeViewerColumn.setLabelProvider(new ColumnLabelProvider() {
+			@Override
+			public String getText(Object element) {
+				ISharedFolder entry = (ISharedFolder) element;
+				if (entry.getShareType() == EShareType.SAMBA) {
+					return "SMB";
+				} else {
+					return entry.getShareType().toString();
+				}
+			}
+		});
 		
 		table.addControlListener(new ControlAdapter() {
 			@Override
 			public void controlResized(ControlEvent e) {
-				int fullSize = table.getSize().x - 48;
-				hostColumn.setWidth(fullSize / 2 - 3);
-				targetColumn.setWidth(fullSize / 2 - 3);
-				aliasColumn.setWidth(48);
+				int fullSize = table.getSize().x - 48 - 24 - 64;
+				
+				// allocate 4/5 for the paths and 1/5 for the share name
+				hostColumn.setWidth(fullSize * 2 / 5 - 3);
+				targetColumn.setWidth(fullSize * 2 / 5 - 3);
+				nameColumn.setWidth(fullSize / 5);
+				
+				fromToColumn.setWidth(24);
+				autoColumn.setWidth(48);
+				typeColumn.setWidth(64);
 			}
 		});
 		
@@ -115,8 +181,17 @@
 				((Text) editor.getControl()).addTraverseListener(new TraverseListener() {
 
 					public void keyTraversed(TraverseEvent e) {
+						int column;
+						if (e.detail == SWT.TRAVERSE_ARROW_NEXT || e.detail == SWT.TRAVERSE_TAB_NEXT
+								|| e.detail == SWT.TRAVERSE_RETURN)
+							column = TARGET_COLUMN;
+						else if (e.detail == SWT.TRAVERSE_ARROW_PREVIOUS || e.detail == SWT.TRAVERSE_TAB_PREVIOUS)
+							column = NAME_COLUMN;
+						else
+							return;
+						
 						editor.deactivate();
-						editElement(element, 1);
+						editElement(element, column);
 					}
 					
 				});
@@ -138,6 +213,33 @@
 			
 		});
 		
+		fromToViewerColumn.setEditingSupport(new EditingSupport(this) {
+			
+			@Override
+			protected boolean canEdit(Object element) {
+				return true;
+			}
+			
+			@Override
+			protected CellEditor getCellEditor(Object element) {
+				return new CheckboxCellEditor(getTable());
+			}
+			
+			@Override
+			protected Object getValue(Object element) {
+				ISharedFolder pair = (ISharedFolder) element;
+				return pair.isHostProvidedShare();
+			}
+			
+			@Override
+			protected void setValue(Object element, Object value) {
+				ISharedFolder pair = (ISharedFolder) element;
+				pair.setHostProvidedShare((Boolean) value);
+				refresh(pair);
+			}
+			
+		});
+
 		targetViewerColumn.setEditingSupport(new EditingSupport(this) {
 
 			@Override
@@ -146,9 +248,27 @@
 			}
 
 			@Override
-			protected CellEditor getCellEditor(Object element) {
-				// do NOT automatically proceed to the next cell -- boolean cells CHANGE when you enter them
-				return new TextCellEditor(getTable());
+			protected CellEditor getCellEditor(final Object element) {
+				// allow TAB to go to next field (table seems to hide this functionality away)
+				final TextCellEditor editor = new TextCellEditor(getTable());
+				((Text) editor.getControl()).addTraverseListener(new TraverseListener() {
+
+					public void keyTraversed(TraverseEvent e) {
+						int column;
+						if (e.detail == SWT.TRAVERSE_ARROW_NEXT || e.detail == SWT.TRAVERSE_TAB_NEXT
+								|| e.detail == SWT.TRAVERSE_RETURN)
+							column = NAME_COLUMN;
+						else if (e.detail == SWT.TRAVERSE_ARROW_PREVIOUS || e.detail == SWT.TRAVERSE_TAB_PREVIOUS)
+							column = HOST_COLUMN;
+						else
+							return;
+						
+						editor.deactivate();
+						editElement(element, column);
+					}
+					
+				});
+				return editor;
 			}
 
 			@Override
@@ -166,7 +286,7 @@
 			
 		});
 		
-		aliasViewerColumn.setEditingSupport(new EditingSupport(this) {
+		nameViewerColumn.setEditingSupport(new EditingSupport(this) {
 			
 			@Override
 			protected boolean canEdit(Object element) {
@@ -174,6 +294,54 @@
 			}
 			
 			@Override
+			protected CellEditor getCellEditor(final Object element) {
+				// allow TAB to go to next field (table seems to hide this functionality away)
+				final TextCellEditor editor = new TextCellEditor(getTable());
+				((Text) editor.getControl()).addTraverseListener(new TraverseListener() {
+
+					public void keyTraversed(TraverseEvent e) {
+						int column;
+						if (e.detail == SWT.TRAVERSE_ARROW_NEXT || e.detail == SWT.TRAVERSE_TAB_NEXT
+								|| e.detail == SWT.TRAVERSE_RETURN) {
+							// do NOT automatically proceed to the next cell -- boolean cells CHANGE when you enter them
+							return;
+						}
+						else if (e.detail == SWT.TRAVERSE_ARROW_PREVIOUS || e.detail == SWT.TRAVERSE_TAB_PREVIOUS)
+							column = TARGET_COLUMN;
+						else
+							return;
+						
+						editor.deactivate();
+						editElement(element, column);
+					}
+					
+				});
+				return editor;
+			}
+			
+			@Override
+			protected Object getValue(Object element) {
+				ISharedFolder pair = (ISharedFolder) element;
+				return pair.getShareName();
+			}
+			
+			@Override
+			protected void setValue(Object element, Object value) {
+				ISharedFolder pair = (ISharedFolder) element;
+				pair.setShareName(value.toString());
+				refresh(pair);
+			}
+			
+		});
+		
+		autoViewerColumn.setEditingSupport(new EditingSupport(this) {
+			
+			@Override
+			protected boolean canEdit(Object element) {
+				return true;
+			}
+			
+			@Override
 			protected CellEditor getCellEditor(Object element) {
 				return new CheckboxCellEditor(getTable());
 			}
@@ -181,16 +349,18 @@
 			@Override
 			protected Object getValue(Object element) {
 				ISharedFolder pair = (ISharedFolder) element;
-				return pair.isAlias();
+				return pair.isManual();
 			}
 			
 			@Override
 			protected void setValue(Object element, Object value) {
 				ISharedFolder pair = (ISharedFolder) element;
-				pair.setAlias((Boolean) value);
+				pair.setManual((Boolean) value);
 				refresh(pair);
 			}
 			
 		});
+		
+		// no editing support for type yet
 	}
 }

Modified: branches/work_Ed/org.maemo.esbox.maemosdk.ui/src/org/maemo/esbox/internal/api/maemosdk/ui/preferences/SharedFoldersPreferencePage.java
===================================================================
--- branches/work_Ed/org.maemo.esbox.maemosdk.ui/src/org/maemo/esbox/internal/api/maemosdk/ui/preferences/SharedFoldersPreferencePage.java	2008-11-21 20:29:07 UTC (rev 975)
+++ branches/work_Ed/org.maemo.esbox.maemosdk.ui/src/org/maemo/esbox/internal/api/maemosdk/ui/preferences/SharedFoldersPreferencePage.java	2008-11-21 21:49:05 UTC (rev 976)
@@ -11,7 +11,6 @@
 
 package org.maemo.esbox.internal.api.maemosdk.ui.preferences;
 
-import org.eclipse.core.runtime.Path;
 import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.jface.viewers.*;
 import org.eclipse.swt.SWT;
@@ -184,7 +183,7 @@
 	 * 
 	 */
 	protected void doAdd() {
-		ISharedFolder share = new BaseSharedFolder(Path.EMPTY, Path.EMPTY, false);
+		ISharedFolder share = new BaseSharedFolder();
 		model.add(share);
 		tableViewer.refresh();
 		tableViewer.setSelection(new StructuredSelection(share));

Modified: branches/work_Ed/org.maemo.esbox.maemosdk.ui/src/org/maemo/esbox/internal/api/maemosdk/ui/preferences/ValidateMachineRunner.java
===================================================================
--- branches/work_Ed/org.maemo.esbox.maemosdk.ui/src/org/maemo/esbox/internal/api/maemosdk/ui/preferences/ValidateMachineRunner.java	2008-11-21 20:29:07 UTC (rev 975)
+++ branches/work_Ed/org.maemo.esbox.maemosdk.ui/src/org/maemo/esbox/internal/api/maemosdk/ui/preferences/ValidateMachineRunner.java	2008-11-21 21:49:05 UTC (rev 976)
@@ -11,8 +11,7 @@
 
 package org.maemo.esbox.internal.api.maemosdk.ui.preferences;
 
-import org.eclipse.core.filesystem.EFS;
-import org.eclipse.core.filesystem.IFileStore;
+import org.eclipse.core.filesystem.*;
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.*;
 import org.eclipse.jface.dialogs.MessageDialog;
@@ -30,7 +29,7 @@
 import java.io.OutputStream;
 import java.lang.reflect.InvocationTargetException;
 import java.text.MessageFormat;
-import java.util.List;
+import java.util.*;
 
 /**
  * This class validates that a machine is properly configured.
@@ -86,27 +85,24 @@
 		if (monitor == null)
 			monitor = new NullProgressMonitor();
 		
-		monitor.beginTask("Testing machine ''" + machine.getName() + "''", 10);
+		monitor.beginTask("Testing machine ''" + machine.getName() + "''", 4);
 		
-		if (!testMachineRunning(machine))
+		if (!testMachineRunning(machine, new SubProgressMonitor(monitor, 1)))
 			return;
-		monitor.worked(1);
 		if (monitor.isCanceled())
 			return;
 
-		if (!testProcessLaunching(machine))
+		if (!testProcessLaunching(machine, new SubProgressMonitor(monitor, 1)))
 			return;
-		monitor.worked(1);
 		if (monitor.isCanceled())
 			return;
 		
-		if (!testBasicFileSystem(machine))
+		if (!testBasicFileSystem(machine, new SubProgressMonitor(monitor, 1)))
 			return;
-		monitor.worked(1);
 		if (monitor.isCanceled())
 			return;
 		
-		if (!testSharedFolders(monitor))
+		if (!testSharedFolders(new SubProgressMonitor(monitor, 1)))
 			return;
 		
 		info("Everything seems to work!");
@@ -115,25 +111,12 @@
 
 	/**
 	 * @param machine
+	 * @param monitor 
 	 */
-	private boolean testMachineRunning(final IMachine machine) {
+	private boolean testMachineRunning(final IMachine machine, IProgressMonitor monitor) {
 		// make sure it's running
 		final IStatus[] statuses = { null };
-		ProgressMonitorDialog dialog = new ProgressMonitorDialog(null);
-		try {
-			dialog.run(false, true, new IRunnableWithProgress() {
-
-				public void run(IProgressMonitor monitor)
-						throws InvocationTargetException, InterruptedException {
-					statuses[0] = MachineManager.getInstance().acquireMachine(machine, monitor);
-				}
-				
-			});
-		} catch (InvocationTargetException e) {
-			fail(e.getMessage());
-		} catch (InterruptedException e) {
-			fail(e.getMessage());
-		}
+		statuses[0] = MachineManager.getInstance().acquireMachine(machine, monitor);
 		IStatus status = statuses[0];
 		if (!status.isOK()) {
 			if (status.getSeverity() == IStatus.ERROR) {
@@ -150,13 +133,18 @@
 
 	/**
 	 * @param machine
+	 * @param monitor 
 	 */
-	private boolean testProcessLaunching(final IMachine machine) {
+	private boolean testProcessLaunching(final IMachine machine, IProgressMonitor monitor) {
+		monitor.beginTask("", 1);
+		monitor.subTask("Testing process launching");
+		
 		// check the process launcher
 		IProcessLauncherFactory processLauncherFactory = machine.getProcessLauncherFactory();
 		IProcessLauncher processLauncher = ProcessLauncherCreator.createProcessLauncher(processLauncherFactory, 
 				"ls " + machine.getUserHome());
-		MessageConsole console = CoreConsoleManager.getInstance().getConsole(true, null, "Virtual machine ~devel home directory listing");
+		MessageConsole console = CoreConsoleManager.getInstance().getConsole(
+				true, null, "Virtual machine ~devel home directory listing");
 		
 		Process process;
 		try {
@@ -179,8 +167,12 @@
 
 	/**
 	 * @param machine
+	 * @param monitor 
 	 */
-	private boolean testBasicFileSystem(final IMachine machine) {
+	private boolean testBasicFileSystem(final IMachine machine, IProgressMonitor monitor) {
+		monitor.beginTask("", 2);
+		monitor.subTask("Testing basic filesystem access");
+		
 		// check the basic filesystem access
 		IFileStore store = machine.getFileSystemAccess().getFileStore(machine.getUserHome());
 		if (!store.fetchInfo().exists()) {
@@ -188,13 +180,18 @@
 					store);
 			return false;
 		}
+		monitor.worked(1);
+		if (monitor.isCanceled())
+			return false;
 		
 		// see if the workspace is visible on the machine
 		IPath workspaceRoot = ResourcesPlugin.getWorkspace().getRoot().getLocation();
 		IPath remoteWorkspace = machine.getFileSystemMapping().convertHostToTargetPath(workspaceRoot);
 		if (remoteWorkspace == null) {
-			warn("Could not access the workspace root on the build machine.\n\nThis will usually complicate new project creation.\n\nPlease place the workspace somewhere under\n'c:/sources/shared' for best results.");
+			warn("Could not access the workspace root on the build machine.\n\nThis will usually complicate new project creation, but it is allowed.\n\nPlace the workspace somewhere under one of your shares for best results.");
 		}
+		monitor.worked(1);
+		
 		return true;
 	}
 
@@ -209,7 +206,8 @@
 			return true;
 		
 		List<ISharedFolder> sharedFolders = sharedFilesystemProvider.getSharedFolders();
-		monitor.beginTask("Checking shared folders", sharedFolders.size());
+		monitor.beginTask("", sharedFolders.size());
+		monitor.subTask("Checking shared folders");
 		
 		boolean succeeded = true;
 		if (sharedFolders.size() == 0) {
@@ -228,7 +226,8 @@
 		IPath remote = share.getRemotePath();
 		
 		// check the shared folder
-		monitor.beginTask("Checking " + host + " -> " + remote, 5);
+		monitor.beginTask("", 5);
+		monitor.subTask("Checking " + host + " -> " + remote);
 		
 		IPath localFilePath = host.append("__testfile.txt");
 		IFileStore localStore = EFS.getLocalFileSystem().getStore(
@@ -259,7 +258,7 @@
 			os.write("Contents\n".getBytes());
 			Policy.close(os);
 		} catch (Exception e) {
-			fail("Could not create local test file ''{0}''.\n\nThis is a serious problem.",
+			fail("Could not create local test file ''{0}''.\n\nDoes this share''s folder really exist?  If so, this is a serious problem.",
 					localStore);
 			return false;
 		}
@@ -269,12 +268,14 @@
 		
 		// wait a little while for samba to notice, or else it looks like the file doesn't exist (:p !!!)
 		try {
-			Thread.sleep(1000);
+			Thread.sleep(2000);
 		} catch (InterruptedException e1) {
 		}
+		
 		remoteStore = machine.getFileSystemAccess().getFileStore(remoteFilePath);
-		if (!remoteStore.fetchInfo().exists()) {
-			fail("Could not access {0} over SSH filesystem.\n\nThis file should be visible since we created it locally and this location\nis assumed to be shared at {1}.\n\nPlease log in to the machine and invoke ''sh mount_share.sh''.\n",
+		IFileInfo info = remoteStore.fetchInfo();
+		if (!info.exists()) {
+			fail("Could not access {0} over SSH filesystem.\n\nThis file should be visible since we created it locally and this location\nis assumed to be shared at {1}.",
 					remoteStore, localStore);
 			return false;
 		}
@@ -282,11 +283,10 @@
 		if (monitor.isCanceled())
 			return false;
 		
-		if (!share.isAlias()) {
-			if (!testScratchboxTargets(remoteFilePath.toPortableString()))
+		if (!share.isManual()) {
+			if (!testScratchboxTargets(remoteFilePath.toPortableString(), new SubProgressMonitor(monitor, 1)))
 				return false;
 		}
-		monitor.worked(1);
 		if (monitor.isCanceled())
 			return false;
 		
@@ -302,16 +302,20 @@
 	}
 
 	/**
+	 * @param monitor 
 	 * 
 	 */
-	private boolean testScratchboxTargets(String path) {
+	private boolean testScratchboxTargets(String path, IProgressMonitor monitor) {
 		IFileStore remoteStore;
 		
-		SDKFactory.getInstance().waitForRefreshComplete(null);
-		ISDKTarget[] sdkTargets = SDKFactory.getInstance().getAllSDKTargets();
+		monitor.beginTask("", 2);
+		monitor.subTask("Testing visibility of shared folders in installed targets");
 		
+		SDKFactory.getInstance().waitForRefreshComplete(new SubProgressMonitor(monitor,  1));
+		ISDKTarget[] sdkTargets = getMachineProvidedTargets();
 		
-		if (countMachineProvidedTargets(sdkTargets) == 0) {
+		
+		if (sdkTargets.length == 0) {
 			info("Did not find any installed targets in build machine.\n\nRetrying ...");
 			
 			ProgressMonitorDialog dlg2 = new ProgressMonitorDialog(shell);
@@ -330,17 +334,24 @@
 				return false;
 			}
 
-			sdkTargets = SDKFactory.getInstance().getAllSDKTargets();
-			if (countMachineProvidedTargets(sdkTargets) == 0) {
+			sdkTargets = getMachineProvidedTargets();
+			if (sdkTargets.length == 0) {
 				fail("Failed to find any installed targets in this machine... it is probably misconfigured or broken.");
 				return false;
 			}
 		}
 
-		// make sure we can see the shared folder in all targets
+		// make sure we can see the shared folder in the target if it maps there
 		for (ISDKTarget target : sdkTargets) {
-			// now test the file
-			remoteStore = target.getTargetFileSystemAccess().getFileStore(new Path(path));
+			IPath remotePath;
+			try {
+				remotePath = target.convertHostToTargetPath(new Path(path));
+			} catch (MicaException e) {
+				// not visible there
+				continue;
+			}
+			
+			remoteStore = target.getTargetFileSystemAccess().getFileStore(remotePath);
 			if (!remoteStore.fetchInfo().exists()) {
 				fail("Could not access ''{0}'' inside build target ''{1}''.\n\nThis file should be visible since it is shared and accessible from the user''s home.\n\nEither there is a missing ''bind'' mount making this folder visible to scratchbox,\nor something else is broken.",
 						remoteStore, target);
@@ -351,12 +362,19 @@
 		return true;
 	}
 
-	private int countMachineProvidedTargets(ISDKTarget[] sdkTargets) {
-		int count = 0;
-		for (ISDKTarget sdkTarget : sdkTargets)
-			if (sdkTarget.getSDK().getMachine().equals(machine))
-				count++;
-		return count;
+	/**
+	 * Get the SDK targets that are purported to be available from the machine.
+	 * @return non-<code>null</code> array
+	 */
+	private ISDKTarget[] getMachineProvidedTargets() {
+		List<ISDKTarget> sdktargetsList = new ArrayList<ISDKTarget>(Arrays.asList(
+				SDKFactory.getInstance().getAllSDKTargets()));
+		for (Iterator<ISDKTarget> iter = sdktargetsList.iterator(); iter.hasNext(); ) {
+			if (!iter.next().getSDK().getMachine().equals(machine))
+				iter.remove();
+		}
+		return (ISDKTarget[]) sdktargetsList.toArray(new ISDKTarget[sdktargetsList
+				.size()]);
 	}
 
 }

Modified: branches/work_Ed/org.maemo.esbox.scratchbox.sb1/src/org/maemo/esbox/internal/scratchbox/sb1/launcher/Scratchbox1ProcessLauncher.java
===================================================================
--- branches/work_Ed/org.maemo.esbox.scratchbox.sb1/src/org/maemo/esbox/internal/scratchbox/sb1/launcher/Scratchbox1ProcessLauncher.java	2008-11-21 20:29:07 UTC (rev 975)
+++ branches/work_Ed/org.maemo.esbox.scratchbox.sb1/src/org/maemo/esbox/internal/scratchbox/sb1/launcher/Scratchbox1ProcessLauncher.java	2008-11-21 21:49:05 UTC (rev 976)
@@ -10,23 +10,16 @@
  *******************************************************************************/
 package org.maemo.esbox.internal.scratchbox.sb1.launcher;
 
-import org.eclipse.core.filesystem.EFS;
-import org.eclipse.core.filesystem.IFileStore;
-import org.eclipse.core.filesystem.provider.FileInfo;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.*;
 import org.maemo.esbox.internal.scratchbox.sb1.Activator;
 import org.maemo.esbox.internal.scratchbox.sb1.core.SB1PreferenceConstants;
-import org.maemo.esbox.scratchbox.core.scratchbox.ScratchboxException;
+import org.maemo.mica.common.core.GeneralUtils;
 import org.maemo.mica.common.core.MicaException;
-import org.maemo.mica.common.core.Policy;
 import org.maemo.mica.common.core.env.IEnvironmentModifierBlock;
 import org.maemo.mica.common.core.env.IEnvironmentOperation;
 import org.maemo.mica.common.core.process.*;
 import org.maemo.mica.common.core.sdk.ISDKTarget;
 
-import java.io.InputStream;
-import java.io.OutputStream;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -150,62 +143,22 @@
 		return mods;
 	}
 
-	/* A flag is the best way to do this -- see below */
-	private static boolean copiedRunScript;
-
 	@Override
 	protected void setupForLaunch() throws MicaException {
 		super.setupForLaunch();
 		
-		// Ensure the run script is available.
-		//
-		// It's a little fishy to check the timestamps, since the timestamp of the
-		// script from the plugin may be extracted from a JAR and always look newer!
-		//
-		// So, just be cautious and set it up once per Eclipse session.
-		// 
-		// We don't want to waste time checking contents or being "smart" since
-		// this will just slow things down.
+		// Ensure the run script is available.  This script is needed because
+		// /scratchbox/login doesn't pass environment variables the way we need to.
+		// Thus, we need to run under scratchbox a script which itself sets those
+		// variables.
 
-		if (!copiedRunScript) {
-			IFileStore runScriptLocation = sdkTarget
-					.getMachineFileSystemAccess()
-					.getFileStore(
-							new Path(
-									sdkTarget
-											.getPreferenceValue(SB1PreferenceConstants.RUN_SCRIPT_LOC)));
-			IFileStore runScript = runScriptLocation.getChild(RUN_SCRIPT_NAME);
-
-			try {
-				runScriptLocation.mkdir(EFS.NONE, null);
-
-				OutputStream os = null;
-				InputStream is = null;
-				try {
-					os = runScript.openOutputStream(EFS.OVERWRITE, null);
-					is = Activator.getPluginRelativeInputStream("./conf/"
-							+ RUN_SCRIPT_NAME);
-					byte[] content = new byte[8192];
-					int len;
-					while ((len = is.read(content)) > 0) {
-						os.write(content, 0, len);
-					}
-				} finally {
-					Policy.close(os);
-					Policy.close(is);
-				}
-
-				FileInfo info = new FileInfo();
-				info.setAttribute(EFS.ATTRIBUTE_EXECUTABLE, true);
-				runScript.putInfo(info, EFS.NONE, null);
-
-				copiedRunScript = true;
-
-			} catch (Exception e) {
-				throw (ScratchboxException) new ScratchboxException(
-						"Cannot copy run script to " + runScript).initCause(e);
-			}
-		}
+		GeneralUtils.cachedCopyScriptToMachine(
+				FileLocator.find(Activator.getDefault().getBundle(), 
+						new Path("conf/" + RUN_SCRIPT_NAME),
+						null),
+				sdkTarget.getMachine(),
+				new Path(sdkTarget.getPreferenceValue(SB1PreferenceConstants.RUN_SCRIPT_LOC)),
+				false);
 	}
 
 	/*

Modified: branches/work_Ed/org.maemo.esbox.vm/conf/vm_prefs.xml
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm/conf/vm_prefs.xml	2008-11-21 20:29:07 UTC (rev 975)
+++ branches/work_Ed/org.maemo.esbox.vm/conf/vm_prefs.xml	2008-11-21 21:49:05 UTC (rev 976)
@@ -12,7 +12,7 @@
 	<entry key="VM_SSH_HOST_ADDR">10.0.2.2</entry>
 	<entry key="VM_CIFS_TARGET_PORT">4445</entry>
 	
-	<entry key="VM_SHARED_FOLDERS_WIN32">c:\maemo\shared=/home/maemo/shared,c:\maemo\shared=/scratchbox/users/maemo/home/maemo/shared</entry>
+	<entry key="VM_SHARED_FOLDERS_WIN32">c:\maemo\shared|/home/maemo/shared,c:\maemo\shared|/scratchbox/users/maemo/home/maemo/shared</entry>
 	<entry key="VM_SHARED_FOLDERS_UNIX">/home/${USER}/maemo/shared=/home/maemo/shared,/home/${USER}/maemo/shared=/scratchbox/users/maemo/home/maemo/shared</entry>
 	
 </properties>
\ No newline at end of file

Modified: branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/core/BaseCustomVirtualMachineConfiguration.java
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/core/BaseCustomVirtualMachineConfiguration.java	2008-11-21 20:29:07 UTC (rev 975)
+++ branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/core/BaseCustomVirtualMachineConfiguration.java	2008-11-21 21:49:05 UTC (rev 976)
@@ -26,8 +26,8 @@
  */
 public abstract class BaseCustomVirtualMachineConfiguration implements IVirtualMachineConfiguration {
 	
-	private static final String HOST_ADDRESS = "hostAddress";
-	private static final String HOST_PORT = "hostPort";
+	private static final String SSH_HOST_ADDRESS = "sshHostAddress";
+	private static final String SSH_HOST_PORT = "sshHostPort";
 	private static final String TIMEOUT = "timeout";
 	private static final String CIFS_PORT = "cifsPort";
 	private static final String COMMAND_LAUNCH_PATTERN = "commandLaunchPattern";
@@ -74,9 +74,9 @@
 	 * @return true if handled, false if not
 	 */
 	protected boolean decodeQueryPart(String key, String value) {
-		if (key.equals(HOST_ADDRESS)) {
+		if (key.equals(SSH_HOST_ADDRESS)) {
 			sshConfiguration.setHostIPAddress(value);
-		} else if (key.equals(HOST_PORT)) {
+		} else if (key.equals(SSH_HOST_PORT)) {
 			sshConfiguration.setHostPort(Integer.parseInt(value));
 		} else if (key.equals(TIMEOUT)) {
 			sshConfiguration.setConnectionTimeout(Integer.parseInt(value));

Modified: branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/core/BasePreferenceVirtualMachineConfiguration.java
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/core/BasePreferenceVirtualMachineConfiguration.java	2008-11-21 20:29:07 UTC (rev 975)
+++ branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/core/BasePreferenceVirtualMachineConfiguration.java	2008-11-21 21:49:05 UTC (rev 976)
@@ -15,6 +15,7 @@
 import org.maemo.esbox.vm.core.IVirtualMachineConfiguration;
 import org.maemo.esbox.vm.core.VirtualMachinePreferenceConstants;
 import org.maemo.mica.common.core.CorePreferenceManager;
+import org.maemo.mica.common.core.PasswordStorage;
 import org.maemo.mica.common.core.machine.ISharedFilesystemProvider;
 import org.maemo.mica.common.core.machine.ISharedFolder;
 import org.maemo.mica.internal.api.common.core.machine.BaseSharedFilesystemProvider;
@@ -39,7 +40,9 @@
 	}
 
 	protected String getUserPassword() {
-		return getPreference(VirtualMachinePreferenceConstants.VM_USER_PASSWORD); 
+		String encoded = getPreference(VirtualMachinePreferenceConstants.VM_USER_PASSWORD);
+		String password = PasswordStorage.getInstance().decodePassword(VirtualMachinePreferenceConstants.VM_USER_PASSWORD, encoded);
+		return password;
 	}
 
 	protected String getTargetAddr() {

Modified: branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/core/BaseVirtualMachineController.java
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/core/BaseVirtualMachineController.java	2008-11-21 20:29:07 UTC (rev 975)
+++ branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/core/BaseVirtualMachineController.java	2008-11-21 21:49:05 UTC (rev 976)
@@ -421,7 +421,9 @@
 			return CANCEL_STATUS;
 		
 		// now, verify shared folders
-		status = SharedFilesystemMounter.validateSharedMounts(machine, new SubProgressMonitor(monitor, 1));
+		status = SharedFilesystemMounter.validateSharedMounts(
+				MachineRegistry.getInstance().getLocalMachine(), machine, 
+				new SubProgressMonitor(monitor, 1));
 
 		return status;
 	}
@@ -459,6 +461,7 @@
 					public void run() {
 						try {
 							IStatus status = SharedFilesystemMounter.validateSharedMounts(
+									MachineRegistry.getInstance().getLocalMachine(),
 									machine,
 									new SubProgressMonitor(monitor, 1));
 							if (!status.isOK()) {

Modified: branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/ui/preferences/CommonVirtualMachineSettingsPreferencePage.java
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/ui/preferences/CommonVirtualMachineSettingsPreferencePage.java	2008-11-21 20:29:07 UTC (rev 975)
+++ branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/ui/preferences/CommonVirtualMachineSettingsPreferencePage.java	2008-11-21 21:49:05 UTC (rev 976)
@@ -15,6 +15,7 @@
 import org.eclipse.jface.preference.StringFieldEditor;
 import org.eclipse.swt.widgets.Text;
 import org.maemo.esbox.vm.core.VirtualMachinePreferenceConstants;
+import org.maemo.mica.common.core.PasswordStorage;
 import org.maemo.mica.common.ui.preferences.BaseComposableFieldEditorPreferencePage;
 
 /**
@@ -58,11 +59,55 @@
 				VirtualMachinePreferenceConstants.VM_USER_PASSWORD,
 				"Password:",
 				32,
-				getFieldEditorParent());
+				getFieldEditorParent()) {
+			/* (non-Javadoc)
+			 * @see org.eclipse.jface.preference.StringFieldEditor#doLoad()
+			 */
+			@Override
+			protected void doLoad() {
+				 if (getTextControl() != null) {
+		            // the password is encoded in prefs and decoded through storage
+		            String value;
+		            
+		            String encoded = getPreferenceStore().getString(getPreferenceName());
+		            
+					value = PasswordStorage.getInstance().decodePassword(
+		            		getPreferenceName(), encoded);
+		            
+		            if (value == null)
+		            	value = getPreferenceStore().getDefaultString(getPreferenceName());
+		            
+		            getTextControl().setText(value);
+		            oldValue = value;
+				 }
+			}
+			
+			/* (non-Javadoc)
+			 * @see org.eclipse.jface.preference.StringFieldEditor#doLoadDefault()
+			 */
+			@Override
+			protected void doLoadDefault() {
+				super.doLoadDefault();
+			}
+					
+			/* (non-Javadoc)
+			 * @see org.eclipse.jface.preference.StringFieldEditor#doStore()
+			 */
+			@Override
+			protected void doStore() {
+				String password = getTextControl().getText();
+				
+				String encoded = PasswordStorage.getInstance().encodePassword(
+	            		getPreferenceName(), password);
+				
+				getPreferenceStore().setValue(getPreferenceName(), encoded);
+			}
+		
+		};
 		addField(feUserPassword);
 		text = feUserPassword.getTextControl(getFieldEditorParent());
 		text.setEchoChar('\u25CF'); // Black Circle
-		text.setToolTipText("Password for the user mentioned above.\nWARNING: this text is not encrypted in any way.");
+		text.setToolTipText("Password for the user mentioned above.\nNOTE: the password is encrypted for storage but can still show up in the UI.");
 
 		feSshTargetAddr = new StringFieldEditor(
 				VirtualMachinePreferenceConstants.VM_SSH_TARGET_ADDR,
@@ -110,5 +155,4 @@
 		text.setToolTipText("Specify the Samba/CIFS port used in the machine.\nThis may be different from the port seen outside the machine,\nespecially if the port is redirected to be visible to the host.");
 		
 	}
-
 }

Modified: branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/vm/core/VirtualMachinePreferenceConstants.java
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/vm/core/VirtualMachinePreferenceConstants.java	2008-11-21 20:29:07 UTC (rev 975)
+++ branches/work_Ed/org.maemo.esbox.vm/src/org/maemo/esbox/vm/core/VirtualMachinePreferenceConstants.java	2008-11-21 21:49:05 UTC (rev 976)
@@ -33,6 +33,7 @@
 	}
 	
 	public static final String VM_USER_NAME = "VM_USER_NAME";
+	/** XXX: fixme PLAINTEXT PASSWORD */
 	public static final String VM_USER_PASSWORD = "VM_USER_PASSWORD";
 	public static final String VM_SSH_TARGET_PORT = "VM_SSH_TARGET_PORT";
 	public static final String VM_SSH_TARGET_ADDR = "VM_SSH_TARGET_ADDR";

Added: branches/work_Ed/org.maemo.esbox.vm.vmware/about.html
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm.vmware/about.html	                        (rev 0)
+++ branches/work_Ed/org.maemo.esbox.vm.vmware/about.html	2008-11-21 21:49:05 UTC (rev 976)
@@ -0,0 +1,22 @@
+<h3>About This Content</h3>
+
+<h3>ESbox</h3>
+
+<p><a href="http://esbox.garage.maemo.org/" target="_blank">ESbox</a> 
+is a set of Eclipse plug-ins that helps programmers to develop applications for 
+maemo platform on Scratchbox Apophis. It supports C/C++ and Python programming 
+languages. Maemo 4.x SDKs (and later) will be supported.
+</p>
+
+<h3>License</h3>
+
+<p>See <a href="about_files/epl-v10.html">Eclipse Public License Version 1.0 (&quot;EPL&quot;)</a>.
+</p>
+
+<h3>Applicable Licenses</h3>   
+   
+<p>ESbox includes a set of open source icons and other graphics. Such graphics are distributed
+under the <a href="about_files/CC-sa3.0_License.txt">Creative Commons Attribution-ShareAlike 3.0 license</a>.</p>
+
+
+<address> &copy; Copyright 2007-2008 INdT, 2007-2008 Nokia. All rights reserved. </address>

Added: branches/work_Ed/org.maemo.esbox.vm.vmware/about_files/epl-v10.html
===================================================================
--- branches/work_Ed/org.maemo.esbox.vm.vmware/about_files/epl-v10.html	                        (rev 0)
+++ branches/work_Ed/org.maemo.esbox.vm.vmware/about_files/epl-v10.html	2008-11-21 21:49:05 UTC (rev 976)
@@ -0,0 +1,328 @@
+<html xmlns:o="urn:schemas-microsoft-com:office:office"
+xmlns:w="urn:schemas-microsoft-com:office:word"
+xmlns="http://www.w3.org/TR/REC-html40">
+
+<head>
+<meta http-equiv=Content-Type content="text/html; charset=windows-1252">
+<meta name=ProgId content=Word.Document>
+<meta name=Generator content="Microsoft Word 9">
+<meta name=Originator content="Microsoft Word 9">
+<link rel=File-List
+href="./Eclipse%20EPL%202003_11_10%20Final_files/filelist.xml">
+<title>Eclipse Public License - Version 1.0</title>
+<!--[if gte mso 9]><xml>
+ <o:DocumentProperties>
+  <o:Revision>2</o:Revision>
+  <o:TotalTime>3</o:TotalTime>
+  <o:Created>2004-03-05T23:03:00Z</o:Created>
+  <o:LastSaved>2004-03-05T23:03:00Z</o:LastSaved>
+  <o:Pages>4</o:Pages>
+  <o:Words>1626</o:Words>
+  <o:Characters>9270</o:Characters>
+   <o:Lines>77</o:Lines>
+  <o:Paragraphs>18</o:Paragraphs>
+  <o:CharactersWithSpaces>11384</o:CharactersWithSpaces>
+  <o:Version>9.4402</o:Version>
+ </o:DocumentProperties>
+</xml><![endif]--><!--[if gte mso 9]><xml>
+ <w:WordDocument>
+  <w:TrackRevisions/>
+ </w:WordDocument>
+</xml><![endif]-->
+<style>
+<!--
+ /* Font Definitions */
+ at font-face
+	{font-family:Tahoma;
+	panose-1:2 11 6 4 3 5 4 4 2 4;
+	mso-font-charset:0;
+	mso-generic-font-family:swiss;
+	mso-font-pitch:variable;
+	mso-font-signature:553679495 -2147483648 8 0 66047 0;}
+ /* Style Definitions */
+p.MsoNormal, li.MsoNormal, div.MsoNormal
+	{mso-style-parent:"";
+	margin:0in;
+	margin-bottom:.0001pt;
+	mso-pagination:widow-orphan;
+	font-size:12.0pt;
+	font-family:"Times New Roman";
+	mso-fareast-font-family:"Times New Roman";}
+p
+	{margin-right:0in;
+	mso-margin-top-alt:auto;
+	mso-margin-bottom-alt:auto;
+	margin-left:0in;
+	mso-pagination:widow-orphan;
+	font-size:12.0pt;
+	font-family:"Times New Roman";
+	mso-fareast-font-family:"Times New Roman";}
+p.BalloonText, li.BalloonText, div.BalloonText
+	{mso-style-name:"Balloon Text";
+	margin:0in;
+	margin-bottom:.0001pt;
+	mso-pagination:widow-orphan;
+	font-size:8.0pt;
+	font-family:Tahoma;
+	mso-fareast-font-family:"Times New Roman";}
+ at page Section1
+	{size:8.5in 11.0in;
+	margin:1.0in 1.25in 1.0in 1.25in;
+	mso-header-margin:.5in;
+	mso-footer-margin:.5in;
+	mso-paper-source:0;}
+div.Section1
+	{page:Section1;}
+-->
+</style>
+</head>
+
+<body lang=EN-US style='tab-interval:.5in'>
+
+<div class=Section1>
+
+<p align=center style='text-align:center'><b>Eclipse Public License - v 1.0</b>
+</p>
+
+<p><span style='font-size:10.0pt'>THE ACCOMPANYING PROGRAM IS PROVIDED UNDER
+THE TERMS OF THIS ECLIPSE PUBLIC LICENSE (&quot;AGREEMENT&quot;). ANY USE,
+REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE
+OF THIS AGREEMENT.</span> </p>
+
+<p><b><span style='font-size:10.0pt'>1. DEFINITIONS</span></b> </p>
+
+<p><span style='font-size:10.0pt'>&quot;Contribution&quot; means:</span> </p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
+in the case of the initial Contributor, the initial code and documentation
+distributed under this Agreement, and<br clear=left>
+b) in the case of each subsequent Contributor:</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>i)
+changes to the Program, and</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>ii)
+additions to the Program;</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>where
+such changes and/or additions to the Program originate from and are distributed
+by that particular Contributor. A Contribution 'originates' from a Contributor
+if it was added to the Program by such Contributor itself or anyone acting on
+such Contributor's behalf. Contributions do not include additions to the
+Program which: (i) are separate modules of software distributed in conjunction
+with the Program under their own license agreement, and (ii) are not derivative
+works of the Program. </span></p>
+
+<p><span style='font-size:10.0pt'>&quot;Contributor&quot; means any person or
+entity that distributes the Program.</span> </p>
+
+<p><span style='font-size:10.0pt'>&quot;Licensed Patents &quot; mean patent
+claims licensable by a Contributor which are necessarily infringed by the use
+or sale of its Contribution alone or when combined with the Program. </span></p>
+
+<p><span style='font-size:10.0pt'>&quot;Program&quot; means the Contributions
+distributed in accordance with this Agreement.</span> </p>
+
+<p><span style='font-size:10.0pt'>&quot;Recipient&quot; means anyone who
+receives the Program under this Agreement, including all Contributors.</span> </p>
+
+<p><b><span style='font-size:10.0pt'>2. GRANT OF RIGHTS</span></b> </p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
+Subject to the terms of this Agreement, each Contributor hereby grants Recipient
+a non-exclusive, worldwide, royalty-free copyright license to<span
+style='color:red'> </span>reproduce, prepare derivative works of, publicly
+display, publicly perform, distribute and sublicense the Contribution of such
+Contributor, if any, and such derivative works, in source code and object code
+form.</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b)
+Subject to the terms of this Agreement, each Contributor hereby grants
+Recipient a non-exclusive, worldwide,<span style='color:green'> </span>royalty-free
+patent license under Licensed Patents to make, use, sell, offer to sell, import
+and otherwise transfer the Contribution of such Contributor, if any, in source
+code and object code form. This patent license shall apply to the combination
+of the Contribution and the Program if, at the time the Contribution is added
+by the Contributor, such addition of the Contribution causes such combination
+to be covered by the Licensed Patents. The patent license shall not apply to
+any other combinations which include the Contribution. No hardware per se is
+licensed hereunder. </span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>c)
+Recipient understands that although each Contributor grants the licenses to its
+Contributions set forth herein, no assurances are provided by any Contributor
+that the Program does not infringe the patent or other intellectual property
+rights of any other entity. Each Contributor disclaims any liability to Recipient
+for claims brought by any other entity based on infringement of intellectual
+property rights or otherwise. As a condition to exercising the rights and
+licenses granted hereunder, each Recipient hereby assumes sole responsibility
+to secure any other intellectual property rights needed, if any. For example,
+if a third party patent license is required to allow Recipient to distribute
+the Program, it is Recipient's responsibility to acquire that license before
+distributing the Program.</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>d)
+Each Contributor represents that to its knowledge it has sufficient copyright
+rights in its Contribution, if any, to grant the copyright license set forth in
+this Agreement. </span></p>
+
+<p><b><span style='font-size:10.0pt'>3. REQUIREMENTS</span></b> </p>
+
+<p><span style='font-size:10.0pt'>A Contributor may choose to distribute the
+Program in object code form under its own license agreement, provided that:</span>
+</p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
+it complies with the terms and conditions of this Agreement; and</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b)
+its license agreement:</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>i)
+effectively disclaims on behalf of all Contributors all warranties and
+conditions, express and implied, including warranties or conditions of title
+and non-infringement, and implied warranties or conditions of merchantability
+and fitness for a particular purpose; </span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>ii)
+effectively excludes on behalf of all Contributors all liability for damages,
+including direct, indirect, special, incidental and consequential damages, such
+as lost profits; </span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>iii)
+states that any provisions which differ from this Agreement are offered by that
+Contributor alone and not by any other party; and</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>iv)
+states that source code for the Program is available from such Contributor, and
+informs licensees how to obtain it in a reasonable manner on or through a
+medium customarily used for software exchange.<span style='color:blue'> </span></span></p>
+
+<p><span style='font-size:10.0pt'>When the Program is made available in source
+code form:</span> </p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
+it must be made available under this Agreement; and </span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b) a
+copy of this Agreement must be included with each copy of the Program. </span></p>
+
+<p><span style='font-size:10.0pt'>Contributors may not remove or alter any
+copyright notices contained within the Program. </span></p>
+
+<p><span style='font-size:10.0pt'>Each Contributor must identify itself as the
+originator of its Contribution, if any, in a manner that reasonably allows
+subsequent Recipients to identify the originator of the Contribution. </span></p>
+
+<p><b><span style='font-size:10.0pt'>4. COMMERCIAL DISTRIBUTION</span></b> </p>
+
+<p><span style='font-size:10.0pt'>Commercial distributors of software may
+accept certain responsibilities with respect to end users, business partners
+and the like. While this license is intended to facilitate the commercial use
+of the Program, the Contributor who includes the Program in a commercial
+product offering should do so in a manner which does not create potential
+liability for other Contributors. Therefore, if a Contributor includes the
+Program in a commercial product offering, such Contributor (&quot;Commercial
+Contributor&quot;) hereby agrees to defend and indemnify every other
+Contributor (&quot;Indemnified Contributor&quot;) against any losses, damages and
+costs (collectively &quot;Losses&quot;) arising from claims, lawsuits and other
+legal actions brought by a third party against the Indemnified Contributor to
+the extent caused by the acts or omissions of such Commercial Contributor in
+connection with its distribution of the Program in a commercial product
+offering. The obligations in this section do not apply to any claims or Losses
+relating to any actual or alleged intellectual property infringement. In order
+to qualify, an Indemnified Contributor must: a) promptly notify the Commercial
+Contributor in writing of such claim, and b) allow the Commercial Contributor
+to control, and cooperate with the Commercial Contributor in, the defense and
+any related settlement negotiations. The Indemnified Contributor may participate
+in any such claim at its own expense.</span> </p>
+
+<p><span style='font-size:10.0pt'>For example, a Contributor might include the
+Program in a commercial product offering, Product X. That Contributor is then a
+Commercial Contributor. If that Commercial Contributor then makes performance
+claims, or offers warranties related to Product X, those performance claims and
+warranties are such Commercial Contributor's responsibility alone. Under this
+section, the Commercial Contributor would have to defend claims against the
+other Contributors related to those performance claims and warranties, and if a
+court requires any other Contributor to pay any damages as a result, the
+Commercial Contributor must pay those damages.</span> </p>
+
+<p><b><span style='font-size:10.0pt'>5. NO WARRANTY</span></b> </p>
+
+<p><span style='font-size:10.0pt'>EXCEPT AS EXPRESSLY SET FORTH IN THIS
+AGREEMENT, THE PROGRAM IS PROVIDED ON AN &quot;AS IS&quot; BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING,
+WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
+MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely
+responsible for determining the appropriateness of using and distributing the
+Program and assumes all risks associated with its exercise of rights under this
+Agreement , including but not limited to the risks and costs of program errors,
+compliance with applicable laws, damage to or loss of data, programs or
+equipment, and unavailability or interruption of operations. </span></p>
+
+<p><b><span style='font-size:10.0pt'>6. DISCLAIMER OF LIABILITY</span></b> </p>
+
+<p><span style='font-size:10.0pt'>EXCEPT AS EXPRESSLY SET FORTH IN THIS
+AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF
+THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGES.</span> </p>
+
+<p><b><span style='font-size:10.0pt'>7. GENERAL</span></b> </p>
+
+<p><span style='font-size:10.0pt'>If any provision of this Agreement is invalid
+or unenforceable under applicable law, it shall not affect the validity or
+enforceability of the remainder of the terms of this Agreement, and without
+further action by the parties hereto, such provision shall be reformed to the
+minimum extent necessary to make such provision valid and enforceable.</span> </p>
+
+<p><span style='font-size:10.0pt'>If Recipient institutes patent litigation
+against any entity (including a cross-claim or counterclaim in a lawsuit)
+alleging that the Program itself (excluding combinations of the Program with
+other software or hardware) infringes such Recipient's patent(s), then such
+Recipient's rights granted under Section 2(b) shall terminate as of the date
+such litigation is filed. </span></p>
+
+<p><span style='font-size:10.0pt'>All Recipient's rights under this Agreement
+shall terminate if it fails to comply with any of the material terms or
+conditions of this Agreement and does not cure such failure in a reasonable
+period of time after becoming aware of such noncompliance. If all Recipient's
+rights under this Agreement terminate, Recipient agrees to cease use and
+distribution of the Program as soon as reasonably practicable. However,
+Recipient's obligations under this Agreement and any licenses granted by
+Recipient relating to the Program shall continue and survive. </span></p>
+
+<p><span style='font-size:10.0pt'>Everyone is permitted to copy and distribute
+copies of this Agreement, but in order to avoid inconsistency the Agreement is
+copyrighted and may only be modified in the following manner. The Agreement
+Steward reserves the right to publish new versions (including revisions) of
+this Agreement from time to time. No one other than the Agreement Steward has
+the right to modify this Agreement. The Eclipse Foundation is the initial
+Agreement Steward. The Eclipse Foundation may assign the responsibility to
+serve as the Agreement Steward to a suitable separate entity. Each new version
+of the Agreement will be given a distinguishing version number. The Program
+(including Contributions) may always be distributed subject to the version of
+the Agreement under which it was received. In addition, after a new version of
+the Agreement is published, Contributor may elect to distribute the Program
+(including its Contributions) under the new version. Except as expressly stated
+in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to
+the intellectual property of any Contributor under this Agreement, whether
+expressly, by implication, estoppel or otherwise. All rights in the Program not
+expressly granted under this Agreement are reserved.</span> </p>
+
+<p><span style='font-size:10.0pt'>This Agreement is governed by the laws of the
+State of New York and the intellectual property laws of the United States of
+America. No party to this Agreement will bring a legal action under this
+Agreement more than one year after the cause of action arose. Each party waives
+its rights to a jury trial in any resulting litigation.</span> </p>
+
+<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+</div>
+
+</body>
+
+</html>
\ No newline at end of file



More information about the Esbox-commits mailing list