[Esbox-commits] r837 - in trunk: common/org.maemo.esbox.analysis.launch/src/org/maemo/esbox/analysis/launch common/org.maemo.esbox.core common/org.maemo.esbox.core/META-INF common/org.maemo.esbox.core/schema common/org.maemo.esbox.core/src/org/maemo/esbox/core common/org.maemo.esbox.core/src/org/maemo/esbox/core/env common/org.maemo.esbox.core/src/org/maemo/esbox/core/machine common/org.maemo.esbox.core/src/org/maemo/esbox/core/process common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core/env common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core/machine common/org.maemo.esbox.core/src/org/maemo/esbox/internal/core common/org.maemo.esbox.core.tests/src/org/maemo/esbox/core/tests common/org.maemo.esbox.core.tests/src/org/maemo/esbox/core/tests/core common/org.maemo.esbox.launch/META-INF common/org.maemo.esbox.launch/src/org/maemo/esbox/launch common/org.maemo.esbox.launch/src/org/maemo/esbox/launch/adapters common/org.maemo.esbox.launch/src/org/maemo/esbox/launch/core common/org.maemo.esbox.launch/src/org/maemo/esbox/launch/ui common/org.maemo.esbox.ssh/src/org/maemo/esbox/internal/api/ssh common/org.maemo.esbox.ssh/src/org/maemo/esbox/internal/ssh common/org.maemo.esbox.ui/src/org/maemo/esbox/ui/actions common/org.maemo.esbox.ui/src/org/maemo/esbox/ui/env common/org.maemo.esbox.ui/src/org/maemo/esbox/ui/preferences cpp/org.maemo.esbox.cpp.launch/src/org/maemo/esbox/cpp/launch cpp/org.maemo.esbox.cpp.launch/src/org/maemo/esbox/cpp/launch/local cpp/org.maemo.esbox.cpp.launch/src/org/maemo/esbox/cpp/launch/remote cpp/org.maemo.esbox.cpp.launch.analysis/src/org/maemo/esbox/cpp/launch/analysis/oprofile cpp/org.maemo.esbox.cpp.launch.analysis/src/org/maemo/esbox/cpp/launch/analysis/valgrind cpp/org.maemo.esbox.cpp.launch.cdi.gdb/src/org/maemo/esbox/cpp/launch/cdi/gdb cpp/org.maemo.esbox.cpp.launch.dsf.gdb/src/org/maemo/esbox/cpp/launch/dsf/gdb/ui cpp/org.maemo.esbox.cpp.project.core/src/org/maemo/esbox/cpp/project/core cpp/org.maemo.esbox.cpp.tests/src/org/maemo/esbox/cpp/tests device/org.maemo.esbox.device.core/src/org/maemo/esbox/internal/device/core/sbrsh device/org.maemo.esbox.device.tests/src/org/maemo/esbox/device/tests/sbrsh device/org.maemo.esbox.device.tests/src/org/maemo/esbox/device/tests/ssh linux/org.maemo.esbox.linux.packages.core/src/org/maemo/esbox/internal/linux/packages/core/aptpkgconfig linux/org.maemo.esbox.linux.packages.core/src/org/maemo/esbox/linux/packages/core/debian maemosdk/org.maemo.esbox.maemosdk.core maemosdk/org.maemo.esbox.maemosdk.core/conf maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/adapters maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/command/scratchbox maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/sdk maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/sdk/providers maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/maemosdk/core maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/maemosdk/core/scratchbox maemosdk/org.maemo.esbox.maemosdk.tests/src/org/maemo/esbox/maemosdk/tests maemosdk/org.maemo.esbox.maemosdk.tests/src/org/maemo/esbox/maemosdk/tests/commands maemosdk/org.maemo.esbox.maemosdk.ui/src/org/maemo/esbox/maemosdk/ui/preferences python/org.maemo.esbox.python.launch/src/org/maemo/esbox/python/launch python/org.maemo.esbox.python.launch/src/org/maemo/esbox/python/launch/debug python/org.maemo.esbox.python.launch/src/org/maemo/esbox/python/launch/local python/org.maemo.esbox.python.launch/src/org/maemo/esbox/python/launch/remote python/org.maemo.esbox.python.launch.analysis/src/org/maemo/esbox/python/launch/analysis/oprofile python/org.maemo.esbox.python.launch.analysis/src/org/maemo/esbox/python/launch/analysis/valgrind

eswartz at garage.maemo.org eswartz at garage.maemo.org
Tue Oct 7 21:56:07 EEST 2008


Author: eswartz
Date: 2008-10-07 21:56:06 +0300 (Tue, 07 Oct 2008)
New Revision: 837

Added:
   trunk/common/org.maemo.esbox.core.tests/src/org/maemo/esbox/core/tests/core/TestProcessLauncherUtils.java
   trunk/common/org.maemo.esbox.core/schema/environment_category.exsd
   trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/CorePreferenceMigrator.java
   trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/IPreferenceMigrator.java
   trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/ESboxCommonVariables.java
   trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/EnvironmentManager.java
   trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/IEnvironmentManager.java
   trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/IEnvironmentModifier.java
   trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/IEnvironmentModifierBlock.java
   trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/IEnvironmentModifierVisitor.java
   trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/IEnvironmentOperation.java
   trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/process/EnvironmentModifierUtils.java
   trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/process/StandardHostEnvironmentProvider.java
   trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/process/StandardMachineEnvironmentProvider.java
   trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core/IStandardEnvironmentProvider.java
   trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core/env/
   trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core/env/EnvironmentModifierBlock.java
   trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core/env/EnvironmentOperation.java
   trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core/env/EnvironmentXMLStorage.java
   trunk/common/org.maemo.esbox.launch/src/org/maemo/esbox/launch/adapters/ITargetEnvironmentModifierAdapter.java
   trunk/common/org.maemo.esbox.launch/src/org/maemo/esbox/launch/ui/ESboxEnvironmentTab.java
   trunk/common/org.maemo.esbox.ssh/src/org/maemo/esbox/internal/api/ssh/DeviceSSHLinuxMachine.java
   trunk/common/org.maemo.esbox.ssh/src/org/maemo/esbox/internal/ssh/SSHEnvironmentProvider.java
   trunk/common/org.maemo.esbox.ui/src/org/maemo/esbox/ui/env/EnvironmentTable.java
   trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/MaemoEnvironmentUtils.java
   trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/adapters/MaemoTargetEnvironmentModifierAdapter.java
   trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/adapters/MaemoTargetEnvironmentModifierAdapterFactory.java
   trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/sdk/Scratchbox1EnvironmentProvider.java
   trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/sdk/Scratchbox2EnvironmentProvider.java
   trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/maemosdk/core/MaemoPreferenceMigrator.java
Removed:
   trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/CorePreferenceMigrator.java
   trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/IPreferenceMigrator.java
   trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/ESboxCommonVariables.java
   trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/EnvironmentVariable.java
   trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/EnvironmentVariableBlock.java
   trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/EnvironmentVariableManager.java
   trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/EnvironmentXMLStorage.java
   trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/IEnvironmentVariable.java
   trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/IEnvironmentVariableBlock.java
   trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/IEnvironmentVariableManager.java
   trunk/common/org.maemo.esbox.ssh/src/org/maemo/esbox/internal/api/ssh/DeviceSSHLinuxMachine.java
   trunk/common/org.maemo.esbox.ui/src/org/maemo/esbox/ui/env/EnvironmentTab.java
   trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/MaemoPreferenceInitializer.java
   trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/SB1PreferenceInitializer.java
   trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/SB2PreferenceInitializer.java
   trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/maemosdk/core/MaemoPreferenceMigrator.java
Modified:
   trunk/common/org.maemo.esbox.analysis.launch/src/org/maemo/esbox/analysis/launch/ValgrindLocalLaunchProxy.java
   trunk/common/org.maemo.esbox.core.tests/src/org/maemo/esbox/core/tests/TestUtils.java
   trunk/common/org.maemo.esbox.core.tests/src/org/maemo/esbox/core/tests/core/TestEnvironmentProperties.java
   trunk/common/org.maemo.esbox.core.tests/src/org/maemo/esbox/core/tests/core/TestEnvironmentVariables.java
   trunk/common/org.maemo.esbox.core.tests/src/org/maemo/esbox/core/tests/core/TestPreferenceManager.java
   trunk/common/org.maemo.esbox.core.tests/src/org/maemo/esbox/core/tests/core/TestXMLStorage.java
   trunk/common/org.maemo.esbox.core/CHANGES-1.5.html
   trunk/common/org.maemo.esbox.core/ESboxRefactoringNotes.txt
   trunk/common/org.maemo.esbox.core/META-INF/MANIFEST.MF
   trunk/common/org.maemo.esbox.core/plugin.xml
   trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/CorePreferenceManager.java
   trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/machine/IMachine.java
   trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/process/BaseProcessLauncher.java
   trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/process/EnvironmentProperties.java
   trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/process/HostProcessLauncherFactory.java
   trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/process/IProcessLauncher.java
   trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/process/IProcessLauncherFactory.java
   trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/process/ProcessLauncherCreator.java
   trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/process/ProcessLauncherParameters.java
   trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/process/ProcessLauncherUtils.java
   trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/process/ProcessRunnerParameters.java
   trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core/BaseProcessLauncherFactory.java
   trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core/HostProcessLauncher.java
   trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core/OldESboxPreferenceMigrator.java
   trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core/machine/HostMachineBackend.java
   trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core/machine/HostUnixMachine.java
   trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core/machine/HostWindowsMachine.java
   trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core/machine/IMachineImpl.java
   trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core/machine/Machine.java
   trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/core/Activator.java
   trunk/common/org.maemo.esbox.launch/META-INF/MANIFEST.MF
   trunk/common/org.maemo.esbox.launch/src/org/maemo/esbox/launch/ESboxLaunchUtils.java
   trunk/common/org.maemo.esbox.launch/src/org/maemo/esbox/launch/ILaunchProtocol.java
   trunk/common/org.maemo.esbox.launch/src/org/maemo/esbox/launch/LaunchConfigurationData.java
   trunk/common/org.maemo.esbox.launch/src/org/maemo/esbox/launch/core/AbstractLaunchProxy.java
   trunk/common/org.maemo.esbox.launch/src/org/maemo/esbox/launch/core/AbstractLocalLaunchProxy.java
   trunk/common/org.maemo.esbox.launch/src/org/maemo/esbox/launch/core/AbstractRemoteLaunchProxy.java
   trunk/common/org.maemo.esbox.launch/src/org/maemo/esbox/launch/core/ILaunchParameterAccessor.java
   trunk/common/org.maemo.esbox.ssh/src/org/maemo/esbox/internal/ssh/SSHMachineBackend.java
   trunk/common/org.maemo.esbox.ssh/src/org/maemo/esbox/internal/ssh/SSHProcess.java
   trunk/common/org.maemo.esbox.ssh/src/org/maemo/esbox/internal/ssh/SSHProcessLauncher.java
   trunk/common/org.maemo.esbox.ssh/src/org/maemo/esbox/internal/ssh/SSHProcessLauncherFactory.java
   trunk/common/org.maemo.esbox.ssh/src/org/maemo/esbox/internal/ssh/UnixUserInformation.java
   trunk/common/org.maemo.esbox.ui/src/org/maemo/esbox/ui/actions/LaunchShellAction.java
   trunk/common/org.maemo.esbox.ui/src/org/maemo/esbox/ui/env/VariableInputDialog.java
   trunk/common/org.maemo.esbox.ui/src/org/maemo/esbox/ui/preferences/ESboxEnvPreferencePage.java
   trunk/cpp/org.maemo.esbox.cpp.launch.analysis/src/org/maemo/esbox/cpp/launch/analysis/oprofile/OProfileLaunchConfigurationTabGroup.java
   trunk/cpp/org.maemo.esbox.cpp.launch.analysis/src/org/maemo/esbox/cpp/launch/analysis/valgrind/ValgrindLaunchConfigurationTabGroup.java
   trunk/cpp/org.maemo.esbox.cpp.launch.cdi.gdb/src/org/maemo/esbox/cpp/launch/cdi/gdb/ESboxMICommandFactory.java
   trunk/cpp/org.maemo.esbox.cpp.launch.dsf.gdb/src/org/maemo/esbox/cpp/launch/dsf/gdb/ui/LocalLaunchConfigurationTabGroup.java
   trunk/cpp/org.maemo.esbox.cpp.launch.dsf.gdb/src/org/maemo/esbox/cpp/launch/dsf/gdb/ui/RemoteLaunchConfigurationTabGroup.java
   trunk/cpp/org.maemo.esbox.cpp.launch/src/org/maemo/esbox/cpp/launch/BaseCDTGDBParameterAccessor.java
   trunk/cpp/org.maemo.esbox.cpp.launch/src/org/maemo/esbox/cpp/launch/CPPLocalGDBParameterAccessor.java
   trunk/cpp/org.maemo.esbox.cpp.launch/src/org/maemo/esbox/cpp/launch/CPPRemoteLaunchProxy.java
   trunk/cpp/org.maemo.esbox.cpp.launch/src/org/maemo/esbox/cpp/launch/CppLaunchConfigurationData.java
   trunk/cpp/org.maemo.esbox.cpp.launch/src/org/maemo/esbox/cpp/launch/ESboxCppLaunchUtils.java
   trunk/cpp/org.maemo.esbox.cpp.launch/src/org/maemo/esbox/cpp/launch/local/ESboxLocalRunLaunchConfigurationTabGroup.java
   trunk/cpp/org.maemo.esbox.cpp.launch/src/org/maemo/esbox/cpp/launch/remote/ESboxRemoteRunLaunchConfigurationTabGroup.java
   trunk/cpp/org.maemo.esbox.cpp.project.core/src/org/maemo/esbox/cpp/project/core/ESboxOldMakeBuilder.java
   trunk/cpp/org.maemo.esbox.cpp.tests/src/org/maemo/esbox/cpp/tests/TestESboxProjectInfo.java
   trunk/device/org.maemo.esbox.device.core/src/org/maemo/esbox/internal/device/core/sbrsh/SBRSHMachine.java
   trunk/device/org.maemo.esbox.device.core/src/org/maemo/esbox/internal/device/core/sbrsh/SBRSHProcessLauncher.java
   trunk/device/org.maemo.esbox.device.core/src/org/maemo/esbox/internal/device/core/sbrsh/SBRSHProcessLauncherFactory.java
   trunk/device/org.maemo.esbox.device.tests/src/org/maemo/esbox/device/tests/sbrsh/ManualTestSBRSHMachine.java
   trunk/device/org.maemo.esbox.device.tests/src/org/maemo/esbox/device/tests/sbrsh/ManualTestSBRSHProcessLauncherFactory.java
   trunk/device/org.maemo.esbox.device.tests/src/org/maemo/esbox/device/tests/ssh/AllTests.java
   trunk/device/org.maemo.esbox.device.tests/src/org/maemo/esbox/device/tests/ssh/TestSSHProcess.java
   trunk/linux/org.maemo.esbox.linux.packages.core/src/org/maemo/esbox/internal/linux/packages/core/aptpkgconfig/AptSystemPackage.java
   trunk/linux/org.maemo.esbox.linux.packages.core/src/org/maemo/esbox/linux/packages/core/debian/DebianPackageInstaller.java
   trunk/maemosdk/org.maemo.esbox.maemosdk.core/conf/maemo_prefs.xml
   trunk/maemosdk/org.maemo.esbox.maemosdk.core/conf/run.sh
   trunk/maemosdk/org.maemo.esbox.maemosdk.core/conf/sb1_prefs.xml
   trunk/maemosdk/org.maemo.esbox.maemosdk.core/plugin.xml
   trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/command/scratchbox/CreateMaemoRootstrapSb2Command.java
   trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/command/scratchbox/ListAvailableMaemoRootstrapsSb2Command.java
   trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/command/scratchbox/ListCputranspSb2Command.java
   trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/command/scratchbox/MaemoCommand.java
   trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/command/scratchbox/MaemoRootstrapSb2Command.java
   trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/command/scratchbox/RemoveMaemoRootstrapSb2Command.java
   trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/command/scratchbox/ScratchboxCommand.java
   trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/sdk/IScratchboxSDKPlatformArchitectureProvider.java
   trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/sdk/Scratchbox1ProcessLauncher.java
   trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/sdk/Scratchbox1ProcessLauncherFactory.java
   trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/sdk/Scratchbox1SDK.java
   trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/sdk/Scratchbox1SDKTarget.java
   trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/sdk/Scratchbox2ProcessLauncher.java
   trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/sdk/Scratchbox2ProcessLauncherFactory.java
   trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/sdk/Scratchbox2SDK.java
   trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/sdk/ScratchboxSDK.java
   trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/sdk/providers/Scratchbox1SDKProvider.java
   trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/sdk/providers/Scratchbox2SDKProvider.java
   trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/maemosdk/core/MaemoPreferenceConstants.java
   trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/maemosdk/core/scratchbox/ScratchboxFacade.java
   trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/maemosdk/core/scratchbox/XLauncher.java
   trunk/maemosdk/org.maemo.esbox.maemosdk.tests/src/org/maemo/esbox/maemosdk/tests/TestProcessLauncher.java
   trunk/maemosdk/org.maemo.esbox.maemosdk.tests/src/org/maemo/esbox/maemosdk/tests/TestSB1ProcessLauncher.java
   trunk/maemosdk/org.maemo.esbox.maemosdk.tests/src/org/maemo/esbox/maemosdk/tests/TestSB2ProcessLauncher.java
   trunk/maemosdk/org.maemo.esbox.maemosdk.tests/src/org/maemo/esbox/maemosdk/tests/TestSB2SDKProvider.java
   trunk/maemosdk/org.maemo.esbox.maemosdk.tests/src/org/maemo/esbox/maemosdk/tests/commands/MockCommandAbstractor.java
   trunk/maemosdk/org.maemo.esbox.maemosdk.tests/src/org/maemo/esbox/maemosdk/tests/commands/MockProcessLauncher.java
   trunk/maemosdk/org.maemo.esbox.maemosdk.tests/src/org/maemo/esbox/maemosdk/tests/commands/MockProcessLauncherFactory.java
   trunk/maemosdk/org.maemo.esbox.maemosdk.tests/src/org/maemo/esbox/maemosdk/tests/commands/TestListSb2Commands.java
   trunk/maemosdk/org.maemo.esbox.maemosdk.ui/src/org/maemo/esbox/maemosdk/ui/preferences/ESboxXServerPreferencePage.java
   trunk/python/org.maemo.esbox.python.launch.analysis/src/org/maemo/esbox/python/launch/analysis/oprofile/OProfilePythonLaunchConfigurationTabGroup.java
   trunk/python/org.maemo.esbox.python.launch.analysis/src/org/maemo/esbox/python/launch/analysis/valgrind/ValgrindPythonLaunchConfigurationTabGroup.java
   trunk/python/org.maemo.esbox.python.launch/src/org/maemo/esbox/python/launch/BasePythonLaunchParameterAccessor.java
   trunk/python/org.maemo.esbox.python.launch/src/org/maemo/esbox/python/launch/PythonLaunchConfigurationData.java
   trunk/python/org.maemo.esbox.python.launch/src/org/maemo/esbox/python/launch/PythonLaunchUtils.java
   trunk/python/org.maemo.esbox.python.launch/src/org/maemo/esbox/python/launch/PythonLocalLaunchProxy.java
   trunk/python/org.maemo.esbox.python.launch/src/org/maemo/esbox/python/launch/PythonRemoteLaunchProxy.java
   trunk/python/org.maemo.esbox.python.launch/src/org/maemo/esbox/python/launch/debug/ESboxPythonDebugger.java
   trunk/python/org.maemo.esbox.python.launch/src/org/maemo/esbox/python/launch/debug/ESboxPythonRemoteDebugger.java
   trunk/python/org.maemo.esbox.python.launch/src/org/maemo/esbox/python/launch/debug/PythonDebugger.java
   trunk/python/org.maemo.esbox.python.launch/src/org/maemo/esbox/python/launch/local/ESboxPythonLocalRunConfigurationTabGroup.java
   trunk/python/org.maemo.esbox.python.launch/src/org/maemo/esbox/python/launch/remote/EsboxPythonRemoteRunConfigurationTabGroup.java
Log:
Rework environment variable APIs and UI
-- use IEnvironmentModifierBlock instead of Properties in IProcessLauncherFactory to express discrete changes to environment
-- allow SB1/SB2/SSH to delete env vars on launch
-- do not prepopulate UI with $-prefixed variables or launch configs with env vars (figure these out when needed)
-- move X display preferences into X Server preference page
-- use consistent UI in ESbox > Environment and launch config > Environment pane
-- allow ISDKTarget to provide ITargetEnvironmentModifierAdapter to provide platform-specific environment on launch
-- have IProcessLauncherFactory provide #getRawEnvironment() for the actual (cached) environment of a target
-- use IStandardEnvironmentProvider in IMachine and BaseProcessLauncherFactory to implement caching of target-side "raw" environment
-- rename IProcessLauncherFactory#createProcessLauncherHandler() to #createProcessLauncher()

Modified: trunk/common/org.maemo.esbox.analysis.launch/src/org/maemo/esbox/analysis/launch/ValgrindLocalLaunchProxy.java
===================================================================
--- trunk/common/org.maemo.esbox.analysis.launch/src/org/maemo/esbox/analysis/launch/ValgrindLocalLaunchProxy.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.analysis.launch/src/org/maemo/esbox/analysis/launch/ValgrindLocalLaunchProxy.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -81,7 +81,7 @@
 		
 		return valgrindSupportAdapter.preLaunchCheck(WorkbenchUtils.getActiveShell());
 	}
-
+	
 	@Override
 	public ProcessRunnerParameters createProgramLauncherParameters()
 			throws CoreException {

Modified: trunk/common/org.maemo.esbox.core/CHANGES-1.5.html
===================================================================
--- trunk/common/org.maemo.esbox.core/CHANGES-1.5.html	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.core/CHANGES-1.5.html	2008-10-07 18:56:06 UTC (rev 837)
@@ -44,7 +44,19 @@
 </li>
 </ul>
 
+<h2>DEBUG SUPPORT</h2>
 
+<ul>
+<li>Added DSF/DD support for running and debugging.  This requires a recent distribution (from CVS HEAD
+preferably) to use.</li>
+<li>Added RSE support for launching and debugging.  This exposes a new Download type in the remote
+run/debug launches.</li>
+<li>The Launch configurations expose the same UI as the ESbox > Environment pane, which
+allows unsetting variables.  This removes confusion about "append/replace" and "Select..." in the standard
+UI, which express operations and data sources that make little or no sense for cross targets.</li>
+
+</ul>
+
 <h2>INTERNALS</h2>
 
 <ul>
@@ -69,5 +81,22 @@
 <li>Added ProjectManager, IESboxProjectInfo, and IESboxBuildConfiguration as the primary means
 to access projects.  C/C++ and Python projects should both use these interfaces.  ESboxProjectProperties
 is no more, but similar functionality is maintained for convenience via ProjectManager#getProjectProperties().
+</li>
+<li>
+Added ISDKTarget#getAdapter() to allow platform-specific extensions to behavior keyed to an SDK target.
+See I*Adapter and org.eclipse.runtime.adapter extensions for possible adapters.
+</li>
+<li>IProcessLauncherFactory now exposes an IEnvironmentModifierBlock rather than Properties for setting
+environment variables.  This allows more clearly expressing the intent of a change.  Before, Properties
+loosely represented either "append" or "replace" due to implementation laxness.  Now, add/replace and
+remove operations are explicit, and implementations and clients have been updated to correctly do what
+they mean.
+<p>
+Global variable settings are automatically exposed to the environment modifier block for new process 
+launcher factories.  Clients can tweak these settings for their own particular launches.
+
+</li>
+ 
+
 </ul>  
 

Modified: trunk/common/org.maemo.esbox.core/ESboxRefactoringNotes.txt
===================================================================
--- trunk/common/org.maemo.esbox.core/ESboxRefactoringNotes.txt	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.core/ESboxRefactoringNotes.txt	2008-10-07 18:56:06 UTC (rev 837)
@@ -29,12 +29,21 @@
 the address of a host from the point of view of a device (SSHConfiguration has a start
 to this, but it must be pushed up into IMachine)
 
+//-- rename #createProcessLaunchHandler() to #createProcessLauncher
+
+//-- fix brokenness in passing Properties map to process launches (implying a rewrite of environment)
+when we just want to add or remove variables
+
+// -- remove $ prefixed variables from ESbox > Environment, and stop setting required Maemo
+DISPLAY / DBUS_SESSION_BUS_ADDRESS variables in launch configurations (these aren't user
+settings and shouldn't be stored/displayed as such)
+
 // FUTURE
 
 
 -- make common image cache for images, e.g., in the target/sdk icons used in the project wizard -- avoid copying these all over the plugin space
 
--- why does Python launch config have all the variables for sb2?
+//-- why does Python launch config have all the variables for sb2?
 
 -- Need to make IP-clean versions of icons for build targets/SDKs/etc.  Pretty much every icon
 except for the maemo-specific ones were copied from CDT or Eclipse.

Modified: trunk/common/org.maemo.esbox.core/META-INF/MANIFEST.MF
===================================================================
--- trunk/common/org.maemo.esbox.core/META-INF/MANIFEST.MF	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.core/META-INF/MANIFEST.MF	2008-10-07 18:56:06 UTC (rev 837)
@@ -28,6 +28,7 @@
  org.maemo.esbox.core.tool,
  org.maemo.esbox.core.xml,
  org.maemo.esbox.internal.api.core,
+ org.maemo.esbox.internal.api.core.env,
  org.maemo.esbox.internal.api.core.machine,
  org.maemo.esbox.internal.api.core.sdk,
  org.maemo.esbox.internal.core.cpp

Modified: trunk/common/org.maemo.esbox.core/plugin.xml
===================================================================
--- trunk/common/org.maemo.esbox.core/plugin.xml	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.core/plugin.xml	2008-10-07 18:56:06 UTC (rev 837)
@@ -6,6 +6,7 @@
    <extension-point id="execution_environment" name="Execution Environment" schema="schema/execution_environment.exsd"/>
    <extension-point id="build_machine_factory" name="Build Machine Factory" schema="schema/build_machine_factory.exsd"/>
    <extension-point id="preference_set_provider" name="Preference Set Provider" schema="schema/preference_set_provider.exsd"/>
+   <extension-point id="environment_category" name="Environment Category" schema="schema/environment_category.exsd"/>
    
  
   
@@ -39,6 +40,20 @@
              version="17">
        </preferenceSetProvider>
     </extension>
+    <extension
+          point="org.maemo.esbox.core.environment_category">
+       <environmentCategory
+             description="These variables are applied to any launch (local, remote, build, or on-device)."
+             id="org.maemo.esbox.core.environment_category.global"
+             initializer="org.maemo.esbox.internal.api.core.env.GlobalEnvironmentCategoryInitializer"
+             label="Global">
+       </environmentCategory>
+       <environmentCategory
+             description="These variables are applied when launching programs on the host."
+             id="org.maemo.esbox.core.environment_category.host"
+             label="Host">
+       </environmentCategory>
+    </extension>
 
 
 

Added: trunk/common/org.maemo.esbox.core/schema/environment_category.exsd
===================================================================
--- trunk/common/org.maemo.esbox.core/schema/environment_category.exsd	                        (rev 0)
+++ trunk/common/org.maemo.esbox.core/schema/environment_category.exsd	2008-10-07 18:56:06 UTC (rev 837)
@@ -0,0 +1,134 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.maemo.esbox.core" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+      <appinfo>
+         <meta.schema plugin="org.maemo.esbox.core" id="environment_category" name="Environment Category"/>
+      </appinfo>
+      <documentation>
+         This extension defines categories of environment variables that show up in the Window &gt; Preferences &gt; ESbox &gt; Environment pane.
+      </documentation>
+   </annotation>
+
+   <element name="extension">
+      <annotation>
+         <appinfo>
+            <meta.element />
+         </appinfo>
+      </annotation>
+      <complexType>
+         <sequence minOccurs="1" maxOccurs="unbounded">
+            <element ref="environmentCategory"/>
+         </sequence>
+         <attribute name="point" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="id" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="name" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+               <appinfo>
+                  <meta.attribute translatable="true"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="environmentCategory">
+      <annotation>
+         <documentation>
+            A category of variables.
+         </documentation>
+      </annotation>
+      <complexType>
+         <attribute name="id" type="string" use="required">
+            <annotation>
+               <documentation>
+                  The unique identifier of the category
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="label" type="string" use="required">
+            <annotation>
+               <documentation>
+                  The label to display in the UI for this category.
+               </documentation>
+               <appinfo>
+                  <meta.attribute translatable="true"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+         <attribute name="description" type="string" use="required">
+            <annotation>
+               <documentation>
+                  The description of the category for the UI.
+               </documentation>
+               <appinfo>
+                  <meta.attribute translatable="true"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+         <attribute name="initializer" type="string">
+            <annotation>
+               <documentation>
+                  A class which initializes the category, when it is first created or later reset to defaults.
+               </documentation>
+               <appinfo>
+                  <meta.attribute kind="java" basedOn=":org.maemo.esbox.core.env.IEnvironmentCategoryInitializer"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="since"/>
+      </appinfo>
+      <documentation>
+         [Enter the first release in which this extension point appears.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="examples"/>
+      </appinfo>
+      <documentation>
+         [Enter extension point usage example here.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="apiinfo"/>
+      </appinfo>
+      <documentation>
+         [Enter API information here.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="implementation"/>
+      </appinfo>
+      <documentation>
+         [Enter information about supplied implementation of this extension point.]
+      </documentation>
+   </annotation>
+
+
+</schema>

Modified: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/CorePreferenceManager.java
===================================================================
--- trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/CorePreferenceManager.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/CorePreferenceManager.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -67,15 +67,6 @@
  *
  */
 public class CorePreferenceManager {
-	/**
-	 * 
-	 */
-	/**
-	 * 
-	 */
-	/**
-	 * 
-	 */
 	private static final String PREFERENCE_SET_PROVIDER_EXTENSION_ID = Activator.PLUGIN_ID + ".preference_set_provider";
 	private static final String PREFERENCE_CONSTANTS_CLASS = "preferenceConstantsClass";
 	private static final String PREFERENCE_STORE_BUNDLE = "preferenceStoreBundle";
@@ -237,23 +228,14 @@
 			URL defaultPrefsFile, int major, int minor, IPreferenceMigrator migrator) {
 		String majorVersionKey = 
 			preferenceKeysClass.getName() + "." + BasePreferenceConstants.VERSION_PREFS_MAJOR;
-		String minorVersionKey = 
-			preferenceKeysClass.getName() + "." + BasePreferenceConstants.VERSION_PREFS_MINOR;
 		
 		String prefsMajorVersionStr = preferenceStore.getString(majorVersionKey);
-		String prefsMinorVersionStr = preferenceStore.getString(minorVersionKey);
 		int prefsMajorVersion = 0;
-		int prefsMinorVersion = 0;
 		try {
 			prefsMajorVersion = Integer.parseInt(prefsMajorVersionStr);
 		} catch (NumberFormatException e) {
 			// ooooold or new prefs without a version at all
 		}
-		try {
-			prefsMinorVersion = Integer.parseInt(prefsMinorVersionStr);
-		} catch (NumberFormatException e) {
-			// ooooold or new prefs without a version at all
-		}
 		
 		// read the default settings and adjust dynamically
 		Properties newPropertyDefaults = new Properties();
@@ -264,35 +246,20 @@
 		
 		// see if existing prefs need to be converted
 		Properties existingSettings = new Properties();
-		if (prefsMajorVersion == major && prefsMinorVersion == minor) {
+		if (prefsMajorVersion == major) {
 			// do nothing if we're up-to-date
 		} else {
-			if (prefsMajorVersion < major
-					|| prefsMinorVersion < minor) { 
+			if (prefsMajorVersion < major) { 
 				// the plug-in was not used before or is from an older version
 
 				// convert any settings from old keys known to the migrator
 				if (migrator != null) {
-					migrator.convertExistingPreferences(preferenceStore, prefsMajorVersion, prefsMinorVersion,
-							existingSettings, newPropertyDefaults);
+					migrator.convertExistingPreferences(preferenceStore, prefsMajorVersion, existingSettings,
+							newPropertyDefaults);
 				}
 				
-				/*
-				Preferences pluginPreferences = Activator.getDefault().getPluginPreferences();
-			
-				// retrieve existing settings if version didn't change
-				
-				if (prefsMajorVersion >= major) {
-					String[] names = pluginPreferences.propertyNames();
-					for (String name : names) {
-						existing.put(name, pluginPreferences.getString(name));
-					}
-				}
-				*/
-				
 				// update versions
 				existingSettings.setProperty(majorVersionKey, "" + major);
-				existingSettings.setProperty(minorVersionKey, "" + minor);
 				
 			} 
 		}
@@ -300,8 +267,7 @@
 		// now set defaults to match.  We leave any ${...} variables in place!
 		for (Map.Entry<Object, Object> entry : newPropertyDefaults.entrySet()) {
 			String key = entry.getKey().toString();
-			if (majorVersionKey.equals(key) || minorVersionKey.equals(key)
-					|| validateKey(key, preferenceKeysClass, registeredKeys, privateRegisteredKeys)) {
+			if (majorVersionKey.equals(key) || validateKey(key, preferenceKeysClass, registeredKeys, privateRegisteredKeys)) {
 				preferenceStore.setDefault(key, entry.getValue().toString());
 			}
 		}
@@ -309,8 +275,7 @@
 		// restore any customized settings
 		for (Map.Entry<Object, Object> entry : existingSettings.entrySet()) {
 			String key = entry.getKey().toString();
-			if (majorVersionKey.equals(key) || minorVersionKey.equals(key) 
-					|| validateKey(key, preferenceKeysClass, registeredKeys, privateRegisteredKeys)) {
+			if (majorVersionKey.equals(key) || validateKey(key, preferenceKeysClass, registeredKeys, privateRegisteredKeys)) {
 				preferenceStore.putValue(key, entry.getValue().toString());
 			}
 		}

Deleted: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/CorePreferenceMigrator.java
===================================================================
--- trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/CorePreferenceMigrator.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/CorePreferenceMigrator.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -1,41 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2008 Nokia Corporation
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *    Ed Swartz (Nokia) - initial API and implementation
- *******************************************************************************/
-
-package org.maemo.esbox.core;
-
-import org.maemo.esbox.internal.api.core.OldESboxPreferenceMigrator;
-
-import java.util.Properties;
-
-/**
- * To migrate preferences, we use the 1.4 -> newer conversion and also pick
- * an OS-specific initial value for the command log path.
- * @author eswartz
- *
- */
-public class CorePreferenceMigrator extends OldESboxPreferenceMigrator
-		implements IPreferenceMigrator {
-
-	/* (non-Javadoc)
-	 * @see org.maemo.esbox.core.IPreferenceMigrator#adjustDefaultSettings(java.util.Properties)
-	 */
-	public void adjustDefaultSettings(Properties newPropertyDefaults) {
-		// adjust any environment-dependent defaults
-		String hostEnvKey;
-		if (HostUtils.isWindows())
-			hostEnvKey = CorePreferenceConstants.LOG_COMMANDS_PATH_WIN32;
-		else
-			hostEnvKey = CorePreferenceConstants.LOG_COMMANDS_PATH_UNIX;
-		newPropertyDefaults.put(CorePreferenceConstants.LOG_COMMANDS_PATH,
-				newPropertyDefaults.getProperty(hostEnvKey));
-		newPropertyDefaults.remove(hostEnvKey);
-	}
-}

Added: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/CorePreferenceMigrator.java
===================================================================
--- trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/CorePreferenceMigrator.java	                        (rev 0)
+++ trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/CorePreferenceMigrator.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+
+package org.maemo.esbox.core;
+
+import org.maemo.esbox.internal.api.core.OldESboxPreferenceMigrator;
+
+import java.util.Properties;
+
+/**
+ * To initialize preferences, we use the 1.4 -> newer conversion and also pick
+ * an OS-specific initial value for the command log path.
+ * @author eswartz
+ *
+ */
+public class CorePreferenceMigrator extends OldESboxPreferenceMigrator
+		implements IPreferenceMigrator {
+
+	/* (non-Javadoc)
+	 * @see org.maemo.esbox.core.IPreferenceMigrator#adjustDefaultSettings(java.util.Properties)
+	 */
+	public void adjustDefaultSettings(Properties newPropertyDefaults) {
+		// adjust any environment-dependent defaults
+		String hostEnvKey;
+		if (HostUtils.isWindows())
+			hostEnvKey = CorePreferenceConstants.LOG_COMMANDS_PATH_WIN32;
+		else
+			hostEnvKey = CorePreferenceConstants.LOG_COMMANDS_PATH_UNIX;
+		newPropertyDefaults.put(CorePreferenceConstants.LOG_COMMANDS_PATH,
+				newPropertyDefaults.getProperty(hostEnvKey));
+	}
+}


Property changes on: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/CorePreferenceMigrator.java
___________________________________________________________________
Name: svn:mergeinfo
   + 

Deleted: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/IPreferenceMigrator.java
===================================================================
--- trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/IPreferenceMigrator.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/IPreferenceMigrator.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -1,45 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2008 Nokia Corporation
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *    Ed Swartz (Nokia) - initial API and implementation
- *******************************************************************************/
-
-package org.maemo.esbox.core;
-
-import org.eclipse.jface.preference.IPreferenceStore;
-
-import java.util.Properties;
-
-/**
- * Clients should implement this interface and pass it into {@link CorePreferenceManager}
- * when migrating their preference sets from old major versions.
- * @author eswartz
- *
- */
-public interface IPreferenceMigrator {
-	/**
-	 * Update the set of default settings dynamically.  This is used, e.g., when there are
-	 * OS-specific default values in XML and we want to select a specific setting.
-	 * @param newPropertyDefaults defaults from XML, updated in place
-	 */
-	void adjustDefaultSettings(Properties newPropertyDefaults);
-
-	/**
-	 * Convert an existing, possibly empty, set of non-default preference values to the current
-	 * format.  This allows the {@link CorePreferenceManager} to avoid resetting preferences
-	 * which the user has already edited.
-	 * @param preferences plugin preferences, ostensibly containing old preference values
-	 * @param oldMajor stored major version (or -1)
-	 * @param oldMinor stored minor version (or -1)
-	 * @param existingSettings settings to fill in  
-	 * @param newPropertyDefaults update any default values which might be adjusted
-	 * @return set of Properties containing any non-default values converted from preferences (must not be <code>null</code>)
-	 */
-	void convertExistingPreferences(IPreferenceStore preferences,
-			int oldMajor, int oldMinor, Properties existingSettings, Properties newPropertyDefaults);
-}

Added: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/IPreferenceMigrator.java
===================================================================
--- trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/IPreferenceMigrator.java	                        (rev 0)
+++ trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/IPreferenceMigrator.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+
+package org.maemo.esbox.core;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+
+import java.util.Properties;
+
+/**
+ * Clients should implement this interface and pass it into {@link CorePreferenceManager}
+ * when migrating their preference sets from old major versions or supplying defaults
+ * for newly created preference keys.
+ * @author eswartz
+ *
+ */
+public interface IPreferenceMigrator {
+	/**
+	 * Update the set of default settings dynamically.  This is used, e.g., when there are
+	 * OS-specific default values in XML and we want to select a specific setting.
+	 * @param newPropertyDefaults defaults from XML, updated in place
+	 */
+	void adjustDefaultSettings(Properties newPropertyDefaults);
+
+	/**
+	 * Convert an existing, possibly empty, set of non-default preference values to the current
+	 * format.  This allows the {@link CorePreferenceManager} to avoid resetting preferences
+	 * which the user has already edited.
+	 * @param preferences plugin preferences, ostensibly containing old preference values
+	 * @param oldMajor stored major version (or -1)
+	 * @param existingSettings settings to fill in  
+	 * @param newPropertyDefaults update any default values which might be adjusted
+	 * @return set of Properties containing any non-default values converted from preferences (must not be <code>null</code>)
+	 */
+	void convertExistingPreferences(IPreferenceStore preferences,
+			int oldMajor, Properties existingSettings, Properties newPropertyDefaults);
+}


Property changes on: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/IPreferenceMigrator.java
___________________________________________________________________
Name: svn:mergeinfo
   + 

Deleted: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/ESboxCommonVariables.java
===================================================================
--- trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/ESboxCommonVariables.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/ESboxCommonVariables.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -1,58 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2008 Nokia Corporation
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *    Ed Swartz (Nokia) - initial API and implementation
- *******************************************************************************/
-
-package org.maemo.esbox.core.env;
-
-import org.maemo.esbox.core.HostUtils;
-
-/**
- * This defines commonly used and referenced global variables that are passed
- * to launched processes.
- * @author eswartz
- *
- */
-public class ESboxCommonVariables {
-
-	public static final String XSERVER_PATH = "HOST$XSERVER_PATH";
-	public static final String DISPLAY = "HOST$DISPLAY";
-	public static final String DISPLAY_DEFAULT_VALUE = ":2";
-
-	/**
-	 * Iniitialize by adding missing variables
-	 * @param envBlock
-	 */
-	static void initialize(IEnvironmentVariableBlock envBlock) {
-		initVariable(envBlock, ESboxCommonVariables.DISPLAY, ESboxCommonVariables.DISPLAY_DEFAULT_VALUE);
-		// XXX: need a way to know the IP of the host from a remote machine
-		initVariable(envBlock, "SSH$DISPLAY", "10.0.2.2:2");
-		initVariable(envBlock, "REMOTE$DISPLAY", ":0");
-
-		initVariable(envBlock, "REMOTE$DBUS_SESSION_BUS_ADDRESS", "unix:path=/tmp/session_bus_socket");
-		initVariable(envBlock, "SSH$DBUS_SESSION_BUS_ADDRESS", "unix:path=/tmp/session_bus_socket");
-
-		if (HostUtils.isWindows()) {
-			initVariable(envBlock, XSERVER_PATH, "c:/cygwin/bin");
-		}
-
-	}
-
-	/**
-	 * Initialize a variable if it is not defined already
-	 * @param envBlock
-	 * @param name
-	 * @param value
-	 */
-	private static void initVariable(IEnvironmentVariableBlock envBlock,
-			String name, String value) {
-		if (envBlock.getVariable(name) == null)
-			envBlock.define(name, value);
-	}
-}

Added: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/ESboxCommonVariables.java
===================================================================
--- trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/ESboxCommonVariables.java	                        (rev 0)
+++ trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/ESboxCommonVariables.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+
+package org.maemo.esbox.core.env;
+
+import org.maemo.esbox.core.HostUtils;
+
+/**
+ * This defines commonly used and referenced global variables that are passed
+ * to launched processes.
+ * @author eswartz
+ *
+ */
+public class ESboxCommonVariables {
+
+	public static final String XSERVER_PATH = "HOST$XSERVER_PATH";
+	public static final String DISPLAY = "HOST$DISPLAY";
+	public static final String DISPLAY_DEFAULT_VALUE = ":2";
+
+	/**
+	 * Iniitialize by adding missing variables
+	 * @param envBlock
+	 */
+	static void initialize(IEnvironmentModifierBlock envBlock) {
+		initVariable(envBlock, ESboxCommonVariables.DISPLAY, ESboxCommonVariables.DISPLAY_DEFAULT_VALUE);
+		// XXX: need a way to know the IP of the host from a remote machine
+		initVariable(envBlock, "SSH$DISPLAY", "10.0.2.2:2");
+		initVariable(envBlock, "REMOTE$DISPLAY", ":0");
+
+		initVariable(envBlock, "REMOTE$DBUS_SESSION_BUS_ADDRESS", "unix:path=/tmp/session_bus_socket");
+		initVariable(envBlock, "SSH$DBUS_SESSION_BUS_ADDRESS", "unix:path=/tmp/session_bus_socket");
+
+		if (HostUtils.isWindows()) {
+			initVariable(envBlock, XSERVER_PATH, "c:/cygwin/bin");
+		}
+
+	}
+
+	/**
+	 * Initialize a variable if it is not defined already
+	 * @param envBlock
+	 * @param name
+	 * @param value
+	 */
+	private static void initVariable(IEnvironmentModifierBlock envBlock,
+			String name, String value) {
+		if (envBlock.findOperation(name) == null)
+			envBlock.define(name, value);
+	}
+}


Property changes on: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/ESboxCommonVariables.java
___________________________________________________________________
Name: svn:mergeinfo
   + 

Copied: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/EnvironmentManager.java (from rev 797, trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/EnvironmentVariableManager.java)
===================================================================
--- trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/EnvironmentManager.java	                        (rev 0)
+++ trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/EnvironmentManager.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -0,0 +1,136 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+
+package org.maemo.esbox.core.env;
+
+import com.nokia.cpp.internal.api.utils.core.IVariableLookupCallback;
+import com.nokia.cpp.internal.api.utils.core.VariableSubstitutionEngine;
+
+import org.eclipse.core.runtime.*;
+import org.maemo.esbox.internal.api.core.env.*;
+
+
+/**
+ * Singleton implementation of {@link IEnvironmentManager}.
+ * @author eswartz
+ *
+ */
+public class EnvironmentManager implements IEnvironmentManager {
+
+	private static EnvironmentManager instance;
+
+	public static IEnvironmentManager getInstance() {
+		if (instance == null) {
+			instance = new EnvironmentManager();
+		}
+		return instance;
+	}
+
+	private VariableSubstitutionEngine expansionEngine;
+	private IEnvironmentModifierBlock globalModifierBlock;
+	
+	protected EnvironmentManager() {
+		expansionEngine = new VariableSubstitutionEngine(null, null);
+		expansionEngine.allowRecursion(true);
+		expansionEngine.setVariableToken('{');
+
+		globalModifierBlock = createEnvironmentModifierBlock();
+		
+		try {
+			load();
+		} catch (CoreException e) {
+			resetToDefaults();
+		}
+		
+	}
+	
+	/**
+	 * Get the block for globally-visible environment variables.
+	 * @return {@link IEnvironmentModifierBlock}, never <code>null</code>
+	 */
+	public IEnvironmentModifierBlock getGlobalEnvironmentModifierBlock() {
+		return globalModifierBlock;
+	}
+	
+	/**
+	 * Create an empty environment variable block.  It must be still be registered
+	 * to be used.
+	 * @return new {@link IEnvironmentModifierBlock}
+	 */
+	public IEnvironmentModifierBlock createEnvironmentModifierBlock() {
+		return new EnvironmentModifierBlock();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.maemo.esbox.core.env.IEnvironmentVariableBlock#expandVariable(org.maemo.esbox.core.env.IEnvironmentVariable, org.maemo.esbox.core.env.IVariableLookupCallback)
+	 */
+	public String expandString(final IEnvironmentModifierBlock block,
+			String value,
+			final IVariableProvider variableProvider) {
+		if (value == null)
+			return null;
+		
+		IVariableLookupCallback variableLookupCallback = new IVariableLookupCallback() {
+
+			public Object getValue(String var) {
+				// environment itself trumps provider
+				IEnvironmentOperation existing = block.findOperation(var);
+				
+				// if the value is defined, return that
+				if (existing != null && existing.getValue() != null)
+					return existing.getValue();
+					
+				// else, ask the provider for its value
+				if (variableProvider != null) {
+					Object value = variableProvider.getValue(var);
+					if (value != null)
+						return value;
+				}
+				
+				// no one claimed it: if deleted, return blank, else it's an unknown variable
+				return existing != null ? "" : null;
+			}
+			
+		};
+		
+		return expansionEngine.substitute(variableLookupCallback, value);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.maemo.esbox.core.env.IEnvironmentManager#load()
+	 */
+	public void load() throws CoreException {
+		EnvironmentXMLStorage storage = new EnvironmentXMLStorage();
+		storage.load();
+		storage.readEnvironmentModifierBlock(globalModifierBlock, null);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.maemo.esbox.core.env.IEnvironmentManager#save()
+	 */
+	public void save() throws CoreException {
+		EnvironmentXMLStorage storage = new EnvironmentXMLStorage();
+		try {
+			storage.load();
+		} catch (CoreException e) {
+			storage.create();
+		}
+		storage.writeEnvironmentModifierBlock(globalModifierBlock, null);
+		storage.save();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.maemo.esbox.core.env.IEnvironmentManager#resetToDefaults()
+	 */
+	public void resetToDefaults() {
+		globalModifierBlock.clear();
+	}
+}


Property changes on: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/EnvironmentManager.java
___________________________________________________________________
Name: svn:mergeinfo
   + 

Deleted: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/EnvironmentVariable.java
===================================================================
--- trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/EnvironmentVariable.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/EnvironmentVariable.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -1,54 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2008 Nokia Corporation
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *    Ed Swartz (Nokia) - initial API and implementation
- *******************************************************************************/
-
-package org.maemo.esbox.core.env;
-
-/**
- * Standard implementation.
- * @author eswartz
- *
- */
-public class EnvironmentVariable implements IEnvironmentVariable {
-
-	private final String name;
-	private String value;
-
-	/**
-	 * @param name
-	 * @param value
-	 */
-	public EnvironmentVariable(String name, String value) {
-		this.name = name;
-		this.value = value;
-	}
-
-	/* (non-Javadoc)
-	 * @see org.maemo.esbox.core.env.IEnvironmentVariable#getName()
-	 */
-	public String getName() {
-		return name;
-	}
-
-	/* (non-Javadoc)
-	 * @see org.maemo.esbox.core.env.IEnvironmentVariable#getValue()
-	 */
-	public String getValue() {
-		return value;
-	}
-
-	/* (non-Javadoc)
-	 * @see org.maemo.esbox.core.env.IEnvironmentVariable#setValue(java.lang.String)
-	 */
-	public void setValue(String value) {
-		this.value = value;
-	}
-
-}

Deleted: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/EnvironmentVariableBlock.java
===================================================================
--- trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/EnvironmentVariableBlock.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/EnvironmentVariableBlock.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -1,154 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2008 Nokia Corporation
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *    Ed Swartz (Nokia) - initial API and implementation
- *******************************************************************************/
-
-package org.maemo.esbox.core.env;
-
-import com.nokia.cpp.internal.api.utils.core.IVariableLookupCallback;
-import com.nokia.cpp.internal.api.utils.core.VariableSubstitutionEngine;
-
-import java.util.*;
-
-
-/**
- * Standard implementation.
- * @author eswartz
- *
- */
-public class EnvironmentVariableBlock implements IEnvironmentVariableBlock {
-
-	private Map<String, IEnvironmentVariable> map;
-	private VariableSubstitutionEngine expansionEngine;
-	
-	public EnvironmentVariableBlock() {
-		map = new LinkedHashMap<String, IEnvironmentVariable>();
-		expansionEngine = new VariableSubstitutionEngine(null, null);
-		expansionEngine.allowRecursion(true);
-		expansionEngine.setVariableToken('{');
-
-	}
-	
-	/* (non-Javadoc)
-	 * @see org.maemo.esbox.core.env.IEnvironmentVariableBlock#define(java.lang.String, java.lang.String)
-	 */
-	public void define(String name, String value) {
-		synchronized (map) {
-			map.put(name, new EnvironmentVariable(name, value));
-		}
-	}
-
-	/* (non-Javadoc)
-	 * @see org.maemo.esbox.core.env.IEnvironmentVariableBlock#getVariable(java.lang.String)
-	 */
-	public IEnvironmentVariable getVariable(String name) {
-		synchronized (map) {
-			return map.get(name);
-		}
-	}
-
-	/* (non-Javadoc)
-	 * @see org.maemo.esbox.core.env.IEnvironmentVariableBlock#getVariables()
-	 */
-	public IEnvironmentVariable[] getVariables() {
-		synchronized (map) {
-			return (IEnvironmentVariable[]) map.values().toArray(new IEnvironmentVariable[map.values().size()]);
-		}
-	}
-
-	/* (non-Javadoc)
-	 * @see org.maemo.esbox.core.env.IEnvironmentVariableBlock#undefine(java.lang.String)
-	 */
-	public void undefine(String name) {
-		synchronized (map) {
-			map.put(name, new EnvironmentVariable(name, null));
-		}
-	}
-
-	/* (non-Javadoc)
-	 * @see org.maemo.esbox.core.env.IEnvironmentVariableBlock#expandVariable(org.maemo.esbox.core.env.IEnvironmentVariable, org.maemo.esbox.core.env.IVariableLookupCallback)
-	 */
-	public String expandString(String value,
-			final IVariableProvider variableProvider) {
-		if (value == null)
-			return null;
-		
-		IVariableLookupCallback variableLookupCallback = new IVariableLookupCallback() {
-
-			public Object getValue(String var) {
-				// environment itself trumps provider
-				IEnvironmentVariable existing = map.get(var);
-				if (existing != null)
-					return existing.getValue() != null ? existing.getValue() : "";
-					
-				if (variableProvider != null)
-					return variableProvider.getValue(var);
-				else
-					return null;
-			}
-			
-		};
-		
-		return expansionEngine.substitute(variableLookupCallback, value);
-	}
-	
-	/* (non-Javadoc)
-	 * @see org.maemo.esbox.core.env.IEnvironmentVariableBlock#expandVariable(org.maemo.esbox.core.env.IEnvironmentVariable, org.maemo.esbox.core.env.IVariableLookupCallback)
-	 */
-	public String expand(IEnvironmentVariable variable,
-			final IVariableProvider variableProvider) {
-		if (variable.getValue() == null)
-			return null;
-	
-		return expandString(variable.getValue(), variableProvider);
-	}
-
-	/* (non-Javadoc)
-	 * @see org.maemo.esbox.core.env.IEnvironmentVariableBlock#export(java.util.Properties, org.maemo.esbox.core.env.IVariableLookupCallback)
-	 */
-	public void export(Properties env, IVariableProvider variableProvider) {
-		IEnvironmentVariable[] variables = getVariables();
-		
-		for (IEnvironmentVariable variable : variables) {
-			if (variable.getValue() == null) {
-				env.remove(variable.getName());
-			} else {
-				env.put(variable.getName(), expand(variable, variableProvider));
-			}
-		}
-	}
-
-	/* (non-Javadoc)
-	 * @see org.maemo.esbox.core.env.IEnvironmentVariableBlock#clear()
-	 */
-	public void clear() {
-		synchronized (map) {
-			map.clear();
-		}
-	}
-	
-	/* (non-Javadoc)
-	 * @see org.maemo.esbox.core.env.IEnvironmentVariableBlock#remove(org.maemo.esbox.core.env.IEnvironmentVariable)
-	 */
-	public void remove(IEnvironmentVariable var) {
-		synchronized (map) {
-			map.remove(var.getName());
-		}
-	}
-	
-	/* (non-Javadoc)
-	 * @see org.maemo.esbox.core.env.IEnvironmentVariableBlock#copyTo(org.maemo.esbox.core.env.IEnvironmentVariableBlock)
-	 */
-	public void copyTo(IEnvironmentVariableBlock destination) {
-		destination.clear();
-		for (IEnvironmentVariable variable : map.values()) {
-			destination.define(variable.getName(), variable.getValue());
-		}
-	}
-}

Deleted: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/EnvironmentVariableManager.java
===================================================================
--- trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/EnvironmentVariableManager.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/EnvironmentVariableManager.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -1,98 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2008 Nokia Corporation
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *    Ed Swartz (Nokia) - initial API and implementation
- *******************************************************************************/
-
-package org.maemo.esbox.core.env;
-
-import org.eclipse.core.runtime.CoreException;
-import org.maemo.esbox.internal.core.Activator;
-
-
-/**
- * @author eswartz
- *
- */
-public class EnvironmentVariableManager {
-
-	
-	private static EnvironmentVariableManager instance;
-
-	public static EnvironmentVariableManager getInstance() {
-		if (instance == null) {
-			instance = new EnvironmentVariableManager();
-		}
-		return instance;
-	}
-
-	private EnvironmentVariableBlock envBlock;
-	
-	protected EnvironmentVariableManager() {
-		envBlock = new EnvironmentVariableBlock();
-	}
-
-	/**
-	 * Perform actions needed for workspace startup (e.g. 
-	 * reading variables from storage, propagating them to
-	 * language-specific backends, etc.)
-	 */
-	public void startup() {
-		boolean needsSave = false;
-		try {
-			load();
-		} catch (CoreException e) {
-			needsSave = true;
-		}
-		ESboxCommonVariables.initialize(envBlock);
-		
-		if (needsSave) {
-			try {
-				save();
-			} catch (CoreException e) {
-				Activator.getErrorLogger().logError("Unable to save global environment", e);
-			}
-		}
-	}
-
-	/**
-	 * Get the block for globally-visible environment variables.
-	 * @return
-	 */
-	public IEnvironmentVariableBlock getGlobalEnvironmentBlock() {
-		return envBlock;
-	}
-
-	/**
-	 * Get the standard provider for expanding variables.
-	 * @return
-	 */
-	public IVariableProvider getStandardVariableProvider() {
-		return null;
-	}
-
-	/**
-	 * Load contents from persistent storage.
-	 */
-	public void load() throws CoreException {
-		EnvironmentXMLStorage storage = new EnvironmentXMLStorage();
-		storage.load();
-		storage.readEnvironmentBlock(getGlobalEnvironmentBlock(), null);
-	}
-
-	/**
-	 * Save contents to persistent storage.
-	 */
-	public void save() throws CoreException {
-		EnvironmentXMLStorage storage = new EnvironmentXMLStorage();
-		storage.create();
-		storage.writeEnvironmentBlock(getGlobalEnvironmentBlock(), null);
-		storage.save();
-	}
-
-}

Deleted: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/EnvironmentXMLStorage.java
===================================================================
--- trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/EnvironmentXMLStorage.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/EnvironmentXMLStorage.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -1,134 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2008 Nokia Corporation
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *    Ed Swartz (Nokia) - initial API and implementation
- *******************************************************************************/
-
-package org.maemo.esbox.core.env;
-
-import org.eclipse.core.filesystem.URIUtil;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.maemo.esbox.core.HostUtils;
-import org.maemo.esbox.core.xml.EFSXMLFileStorage;
-import org.maemo.esbox.core.xml.XMLUtils;
-import org.maemo.esbox.internal.core.Activator;
-import org.w3c.dom.Element;
-
-import java.net.URI;
-
-/**
- * Storage for the environment block.
- * @author eswartz
- *
- */
-public class EnvironmentXMLStorage extends EFSXMLFileStorage {
-
-	private static final String ENVIRONMENT = "environment";
-	private static final String VARIABLE = "variable";
-	private static final String NAME = "name";
-	private static final String UNDEFINE = "undefine";
-	private static final String CATEGORY = "category";
-
-	public EnvironmentXMLStorage() {
-		super(URIUtil.toURI(getEnvironmentPath()));
-	}
-
-	public EnvironmentXMLStorage(URI uri) {
-		super(uri);
-	}
-
-	protected static IPath getEnvironmentPath() {
-		Activator plugin = Activator.getDefault();
-		IPath storePath;
-		if (plugin != null)
-			storePath = plugin.getStateLocation().append(".environment");
-		else
-			storePath = HostUtils.getTemporaryPath().append(".environment");
-		return storePath;
-	}
-
-	public void load() throws CoreException {
-		load(ENVIRONMENT);
-	}
-
-	/**
-	 * Find or create the element storing variables in a category.
-	 * @param category name of category or <code>null</code> for global
-	 * @return Element
-	 */
-	private Element getCategoryElement(String category) {
-		Element element = getDocumentElement();
-		if (category != null) {
-			element = XMLUtils.findOrCreateChildElement(getDocument(), element, CATEGORY); 
-			element.setAttribute(NAME, category);
-		}
-		return element;
-	}
-
-	/**
-	 * Read environment variables from the given category
-	 * @param envBlock
-	 * @param category or <code>null</code> for globals
-	 */
-	public void readEnvironmentBlock(
-			IEnvironmentVariableBlock envBlock, String category) {
-		envBlock.clear();
-
-		// create the category element
-		Element element = getCategoryElement(category);
-		
-		Element[] vars = XMLUtils.getChildElementsNamed(element, VARIABLE);
-		for (Element var : vars) {
-			String name = var.getAttribute(NAME);
-			if ("true".equals(var.getAttribute(UNDEFINE)))
-				envBlock.define(name, null);
-			else
-				envBlock.define(var.getAttribute(NAME), XMLUtils.getText(var));
-		}
-	}
-	
-	/**
-	 * Save an environment block to the given category
-	 * @param envBlock
-	 * @param category name of category or <code>null</code> for globals
-	 */
-	public void writeEnvironmentBlock(IEnvironmentVariableBlock envBlock, 
-			String category) {
-		Element element = getCategoryElement(category);
-		
-		// clear out existing elements
-		Element[] vars = XMLUtils.getChildElementsNamed(element, VARIABLE);
-		for (Element var : vars) {
-			element.removeChild(var);
-		}
-		
-		// add variables
-		for (IEnvironmentVariable variable : envBlock.getVariables()) {
-			Element var = getDocument().createElement(VARIABLE);
-			var.setAttribute(NAME, variable.getName());
-		
-			if (variable.getValue() == null) 
-				var.setAttribute(UNDEFINE, "true");
-			else
-				XMLUtils.setText(var, variable.getValue());
-			
-			element.appendChild(var);
-		}
-	}
-
-	/**
-	 * 
-	 */
-	public void create() throws CoreException {
-		create(ENVIRONMENT);
-	}
-
-
-	
-}

Copied: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/IEnvironmentManager.java (from rev 797, trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/IEnvironmentVariableManager.java)
===================================================================
--- trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/IEnvironmentManager.java	                        (rev 0)
+++ trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/IEnvironmentManager.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+
+package org.maemo.esbox.core.env;
+
+import org.eclipse.core.runtime.CoreException;
+
+/**
+ * This interface provides a means to manipulate the globally-accessible operations
+ * on environment variables which will be applied to various process launches in ESbox.
+ * @author eswartz
+ *
+ */
+public interface IEnvironmentManager {
+	/**
+	 * Get the block for globally-visible environment variables.
+	 * This is shorthand for {@link #findEnvironmentBlock(GLOBAL_CATEGORY_ID).getBlock()}
+	 * @return {@link IEnvironmentModifierBlock}, never <code>null</code>
+	 */
+	IEnvironmentModifierBlock getGlobalEnvironmentModifierBlock();
+
+	/**
+	 * Create an empty environment variable block.  
+	 * @return new {@link IEnvironmentModifierBlock}
+	 */
+	IEnvironmentModifierBlock createEnvironmentModifierBlock();
+
+	/**
+	 * Expand a single given string, which may contain references to variables
+	 * in the block via ${...} or to arbitrary other variables (handled by variableProvider).
+	 * The variableProvider is asked to supply a value only if the block does not define it.
+	 * @param block the block providing variable definitions and deletions
+	 * @param value a string 
+	 * @param variableProvider an implementation that provides values for ${...} sequences in variable values
+	 * @return String the expanded value
+	 */
+	String expandString(IEnvironmentModifierBlock block, String value, IVariableProvider variableProvider); 
+
+	
+	/**
+	 * Load contents for all registered categories from persistent storage.  
+	 * The storage is global to the workspace but unique for each category.  
+	 */
+	void load() throws CoreException;
+	
+	/**
+	 * Save contents for registered categories to persistent storage.  The storage is global 
+	 * to the workspace but unique for each category.  Only settings for registered 
+	 * categories are modified (values for unregistered categories are left alone).
+	 */
+	void save() throws CoreException;
+
+	/**
+	 * Reset all the registered categories to their default settings.
+	 * @see IEnvironmentCategory#resetToDefaults()
+	 */
+	void resetToDefaults();
+
+}


Property changes on: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/IEnvironmentManager.java
___________________________________________________________________
Name: svn:mergeinfo
   + 

Added: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/IEnvironmentModifier.java
===================================================================
--- trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/IEnvironmentModifier.java	                        (rev 0)
+++ trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/IEnvironmentModifier.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+
+package org.maemo.esbox.core.env;
+
+/**
+ * This interface represents a set of operations on environment variables in
+ * some context.  A client registers definitions and undefinitions of variables
+ * which a consumer later applies to a real environment.
+ * <p>
+ * This replaces the concept of a Properties map, which purports
+ * to represent the entire "replaced" environment, with a series of operations
+ * which is more germane to the needs of most clients as well as the implementation
+ * requirements of, e.g., sandboxed environments.
+ * @author eswartz
+ *
+ */
+public interface IEnvironmentModifier {
+	/**
+	 * Record a definition of a variable to a value.  When applied, any existing
+	 * variable with this name will be replaced, or else, the new defintion will
+	 * be added, to the target environment.
+	 * @param variable variable name, never <code>null</code>
+	 * @param value value, never <code>null</code>
+	 */
+	void define(String variable, String value);
+	
+	/**
+	 * Record an undefinition of a variable.  When applied, any existing
+	 * variable with this name will be removed.  Otherwise, nothing happens.
+	 * @param variable variable name, never <code>null</code>
+	 */
+	void undefine(String variable);
+	
+	/**
+	 * Clear all the operations in this modifier.
+	 */
+	void clear();
+	
+	/**
+	 * Catenate the given modifier to this one.  The receiver's modifications are
+	 * added to those in the argument.
+	 * @param modifier other modifications
+	 */
+	void catenate(IEnvironmentModifier modifier);
+	
+	/**
+	 * Copy the given modifier.  
+	 * @return new modifier with same operations as receiver
+	 */
+	IEnvironmentModifier copy();
+
+	/**
+	 * Visit the stored modifications
+	 * @param visitor an implementation which will receive each definition and undefinition in order
+	 */
+	void accept(IEnvironmentModifierVisitor visitor);
+}

Copied: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/IEnvironmentModifierBlock.java (from rev 797, trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/IEnvironmentVariableBlock.java)
===================================================================
--- trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/IEnvironmentModifierBlock.java	                        (rev 0)
+++ trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/IEnvironmentModifierBlock.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+
+package org.maemo.esbox.core.env;
+
+import java.util.Properties;
+
+/**
+ * This interface represents a set of modifications on environment variables in
+ * some context.  A client registers definitions and undefinitions of variables
+ * which a consumer later applies to a real environment.
+ * <p>
+ * The operations are collapsed -- a definition followed by a deletion of a 
+ * variable results in a no-op, overall.
+ * <p>
+ * This replaces the previous confusing use a Properties map, which purports
+ * to represent the entire "replaced" environment, with a series of operations
+ * which is more germane to the needs of most clients as well as the implementation
+ * requirements of, e.g., sandboxed environments.
+ * @author eswartz
+ *
+ */
+public interface IEnvironmentModifierBlock {
+	/**
+	 * Delete all the operations (nothing is defined or undefined).
+	 */
+	void clear();
+
+	/**
+	 * Copy the block.
+	 * @return new {@link IEnvironmentModifierBlock} 
+	 */
+	IEnvironmentModifierBlock copy();
+
+	/**
+	 * Define a variable.  This will replace any existing variable with the same name.
+	 * @param name
+	 * @param value value, never <code>null</code> 
+	 * @return the resulting operation
+	 */
+	IEnvironmentOperation define(String name, String value);
+
+	/**
+	 * Undefine a variable.  This will undefine any existing variable with the same name 
+	 * or remember that such a variable should be removed when exporting against a known
+	 * environment.
+	 * @param name
+	 * @return the resulting operation, or <code>null</code> if this cancels a definition
+	 */
+	IEnvironmentOperation undefine(String name);
+
+	/**
+	 * Remove an operation from the list (it is neither defined nor undefined).
+	 * Ignored if the operation is not in the modifier.
+	 * @param operation the operation, never <code>null</code>
+	 */
+	void remove(IEnvironmentOperation operation);
+
+	/**
+	 * Remove an operation for the given variable.  Ignored if the variable is not oeprated on.
+	 * @param name
+	 */
+	void remove(String name);
+	
+	/**
+	 * Get the resulting variable definitions or undefinitions, representing the 
+	 * collapsed state of the {@link #define(String, String)} and {@link #undefine(String)} operations
+	 * applied.
+	 * @return array, never <code>null</code>
+	 */
+	IEnvironmentOperation[] getOperations();
+	
+	/**
+	 * Find an operation that references a variable of the given name.
+	 * @return IEnvironmentOperation or <code>null</code>
+	 */
+	IEnvironmentOperation findOperation(String name);
+
+	/**
+	 * Apply an operation, modifying the receiver.
+	 * @param operation
+	 */
+	void apply(IEnvironmentOperation operation);
+	
+	/**
+	 * Apply the block of operations, modifying the receiver.
+	 * @param operation
+	 */
+	void apply(IEnvironmentModifierBlock block);
+
+	/**
+	 * Update the given properties from the operations in the receiver.
+	 * @param env
+	 */
+	void applyTo(Properties env);
+
+}


Property changes on: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/IEnvironmentModifierBlock.java
___________________________________________________________________
Name: svn:mergeinfo
   + 

Added: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/IEnvironmentModifierVisitor.java
===================================================================
--- trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/IEnvironmentModifierVisitor.java	                        (rev 0)
+++ trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/IEnvironmentModifierVisitor.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+
+package org.maemo.esbox.core.env;
+
+/**
+ * A client implements this interface and passes it to {@link IEnvironmentModifier#accept(IEnvironmentModifierVisitor)}
+ * to visit each modification in turn. 
+ * @author eswartz
+ *
+ */
+public interface IEnvironmentModifierVisitor {
+	void visitDefine(String variable, String value);
+	
+	void visitUndefine(String variable);
+}

Copied: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/IEnvironmentOperation.java (from rev 797, trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/IEnvironmentVariable.java)
===================================================================
--- trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/IEnvironmentOperation.java	                        (rev 0)
+++ trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/IEnvironmentOperation.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+
+package org.maemo.esbox.core.env;
+
+/**
+ * Abstraction for an environment variable operation -- either adding/replacing or deleting.
+ * The deleting operation is encoded by a <code>null</code> result for {@link #getValue()}.
+ * @author eswartz
+ *
+ */
+public interface IEnvironmentOperation {
+
+	/** 
+	 * Get the name of the variable.
+	 * @return String, never <code>null</code> 
+	 */
+	String getName();
+	
+	/** 
+	 * Get the value of the variable, which is either a non-<code>null</code> string that
+	 * is exported to the target environment, or <code>null</code> to undefine the variable
+	 * in the target environment. 
+	 * @return String or <code>null</code>
+	 */
+	String getValue();
+
+	/** 
+	 * Set the value of the variable, which is either a non-<code>null</code> string that
+	 * is exported to the target environment, or <code>null</code> to undefine the variable
+	 * in the target environment. 
+	 * @param value String or <code>null</code>  
+	 */
+	void setValue(String value);
+}


Property changes on: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/IEnvironmentOperation.java
___________________________________________________________________
Name: svn:mergeinfo
   + 

Deleted: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/IEnvironmentVariable.java
===================================================================
--- trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/IEnvironmentVariable.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/IEnvironmentVariable.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -1,42 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2008 Nokia Corporation
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *    Ed Swartz (Nokia) - initial API and implementation
- *******************************************************************************/
-
-package org.maemo.esbox.core.env;
-
-/**
- * Abstraction for an environment variable
- * @author eswartz
- *
- */
-public interface IEnvironmentVariable {
-
-	/** 
-	 * Get the name of the variable.
-	 * @return String, never <code>null</code> 
-	 */
-	String getName();
-	
-	/** 
-	 * Get the value of the variable, which is either a non-<code>null</code> string that
-	 * is exported to the target environment, or <code>null</code> to undefine the variable
-	 * in the target environment. 
-	 * @return String or <code>null</code>
-	 */
-	String getValue();
-	
-	/** 
-	 * Set the value of the variable, which is either a non-<code>null</code> string that
-	 * is exported to the target environment, or <code>null</code> to undefine the variable
-	 * in the target environment. 
-	 * @param value String or <code>null</code>  
-	 */
-	void setValue(String value);
-}

Deleted: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/IEnvironmentVariableBlock.java
===================================================================
--- trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/IEnvironmentVariableBlock.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/IEnvironmentVariableBlock.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -1,92 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2008 Nokia Corporation
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *    Ed Swartz (Nokia) - initial API and implementation
- *******************************************************************************/
-
-package org.maemo.esbox.core.env;
-
-import java.util.Properties;
-
-/**
- * This is an abstraction for a collection of environment variables.
- * These may be combined with other blocks and variable-expanded into a Properties map.
- * @author eswartz
- *
- */
-public interface IEnvironmentVariableBlock {
-	/**
-	 * Define a variable.  This will replace any existing variable with the same name.
-	 * @param name
-	 * @param value value, never <code>null</code> 
-	 */
-	void define(String name, String value);
-
-	/**
-	 * Undefine a variable.  This will undefine any existing variable with the same name 
-	 * or remember that such a variable should be removed when exporting against a known
-	 * environment.
-	 * @param name
-	 */
-	void undefine(String name);
-
-	/**
-	 * Get all the variables.
-	 * @return array, never <code>null</code>
-	 */
-	IEnvironmentVariable[] getVariables();
-	
-	/**
-	 * Find a variable with the given name.
-	 * @return IEnvironmentVariable or <code>null</code>
-	 */
-	IEnvironmentVariable getVariable(String name);
-	
-	/**
-	 * Expand a single given string, which may contain references to other variables via ${...} or
-	 * to arbitrary other variables (handled by variableProvider).
-	 * @param value a string 
-	 * @param variableProvider an implementation that provides values for ${...} sequences in variable values
-	 * @return String the expanded value
-	 */
-	String expandString(String value, IVariableProvider variableProvider);
-	
-	/**
-	 * Expand a single given variable, which may contain references to other variables via ${...} or
-	 * to arbitrary other variables (handled by variableProvider).
-	 * @param variable never <code>null</code> 
-	 * @param variableProvider an implementation that provides values for ${...} sequences in variable values
-	 * @return String the expanded value, or <code>null</code> if this is an "undefining" variable
-	 */
-	String expand(IEnvironmentVariable variable, IVariableProvider variableProvider);
-	
-	/**
-	 * Export the variables into the Properties map (incremental update; does not clear map).
-	 * This will override variables and undefine any for which {@link IEnvironmentVariable#getValue()} is <code>null</code>.
-	 * @param env environment to update
-	 * @param variableProvider an implementation that provides values for ${...} sequences in variable values
-	 */
-	void export(Properties env, IVariableProvider variableProvider);
-
-	/**
-	 * Delete all the variables (nothing is defined or undefined).
-	 */
-	void clear();
-
-	/**
-	 * Remove a variable from the list (it is neither defined nor undefined).
-	 * @param var
-	 */
-	void remove(IEnvironmentVariable var);
-	
-	/**
-	 * Copy the block into another.
-	 * @param destination 
-	 */
-	void copyTo(IEnvironmentVariableBlock destination);
-}

Deleted: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/IEnvironmentVariableManager.java
===================================================================
--- trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/IEnvironmentVariableManager.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/IEnvironmentVariableManager.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -1,22 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2008 Nokia Corporation
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *    Ed Swartz (Nokia) - initial API and implementation
- *******************************************************************************/
-
-package org.maemo.esbox.core.env;
-
-/**
- * This interface provides several blocks of environment variables for use in
- * the workspace.
- * @author eswartz
- *
- */
-public interface IEnvironmentVariableManager {
-	
-}

Modified: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/machine/IMachine.java
===================================================================
--- trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/machine/IMachine.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/machine/IMachine.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -12,7 +12,9 @@
 package org.maemo.esbox.core.machine;
 
 import org.eclipse.core.runtime.IPath;
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
 import org.maemo.esbox.core.process.IProcessLauncherFactory;
+import org.maemo.esbox.internal.api.core.IStandardEnvironmentProvider;
 
 import java.net.URI;
 import java.util.*;
@@ -50,16 +52,6 @@
 	 */
 	IPath getUserHome();
 
-	/**
-	 * Get the unique prefix -- before '$' -- for ESbox environment variables automatically
-	 * applied to launches for this machine.  Such variables' prefixes and '$'
-	 * are removed before being added to the launches for those machines.
-	 * Variables for other machines containing a prefix and '$' are stripped out.
-	 * <p>
-	 * @return a prefix, e.g. "HOST" or "BUILD" or "REMOTE"
-	 */
-	String getEnvironmentVariablePrefix();
-
 	/** 
 	 * Tell if the machine (appears to be) alive. 
 	 * This check is very fast but relies on cached information.
@@ -72,13 +64,12 @@
 	 * @param commandLine executable and arguments; for the executable, bare filename implies program on $PATH,
 	 * relative path with "./", etc., implies a script in the working directory, 
 	 * and a full path is an absolute path in the launch environment
-	 * @param environment the environment to pass (null to use the standard environment, else override the
-	 * environment)
+	 * @param environmentModifierBlock the environment to pass (or <code>null</code> to make no changes)
 	 * @param usePty the PTY to use or <code>null</code> for default
 	 * @return a new process 
 	 * @throws Exception 
 	 */
-	Process createProcess(IPath workingDirectory, List<String> commandLine, Properties environment, boolean usePty)
+	Process createProcess(IPath workingDirectory, List<String> commandLine, IEnvironmentModifierBlock environmentModifierBlock, boolean usePty)
 		throws Exception;
 
 	/**
@@ -88,16 +79,21 @@
 	IProcessLauncherFactory getProcessLauncherFactory();
 
 	/**
+	 * Get the standard environment for this user.
+	 * @return {@link IStandardEnvironmentProvider}, never <code>null</code>
+	 */
+	IStandardEnvironmentProvider getStandardEnvironmentProvider();
+	
+	/**
 	 * Read the user's default environment.
 	 * @return map of name to value, or <code>null</code>
 	 */
-	Map<String, String> getStandardEnvironment();
-
+	Properties getStandardEnvironment();
+	
 	/**
 	 * Get the URI identifying the machine.  This should only contain an authority.
 	 * @return URI, never <code>null</code>
 	 */
 	URI getURI();
 
-
 }

Modified: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/process/BaseProcessLauncher.java
===================================================================
--- trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/process/BaseProcessLauncher.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/process/BaseProcessLauncher.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -14,6 +14,8 @@
 import org.eclipse.core.runtime.*;
 import org.eclipse.ui.console.MessageConsole;
 import org.maemo.esbox.core.*;
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
+import org.maemo.esbox.core.env.IEnvironmentOperation;
 import org.maemo.esbox.core.sdk.IPreferenceProvider;
 import org.maemo.esbox.core.sdk.ISDKTarget;
 import org.maemo.esbox.internal.core.Activator;
@@ -30,7 +32,7 @@
 public abstract class BaseProcessLauncher implements IProcessLauncher {
 	
 	private List<String> commandArguments;
-	private Properties environment;
+	private IEnvironmentModifierBlock environmentModifierBlock;
 	private IPath cwdDir;
 	private String logToPath;
 	private Process process;
@@ -38,15 +40,15 @@
 	
 	public BaseProcessLauncher( 
 			List<String> commandArguments,
-			Properties environment,
-			IPath cwdDir,
-			IPreferenceProvider prefProvider
+			IEnvironmentModifierBlock environmentModifierBlock,
+			IPath cwdDir
 			) {
 		if (commandArguments == null)
 			throw new IllegalArgumentException();
 		this.commandArguments = commandArguments;
-		this.environment = environment;
+		this.environmentModifierBlock = environmentModifierBlock;
 		this.cwdDir = cwdDir;
+		IPreferenceProvider prefProvider = CorePreferenceManager.getInstance().getPreferenceProvider();
 		if (Boolean.parseBoolean(prefProvider.getPreferenceValue(
 				CorePreferenceConstants.LOG_COMMANDS))) {
 			this.logToPath = prefProvider.getPreferenceValue(
@@ -62,8 +64,8 @@
 		return commandArguments;
 	}
 	
-	public Properties getLaunchEnvironment() {
-		return this.environment;
+	public IEnvironmentModifierBlock getLaunchEnvironmentModifierBlock() {
+		return this.environmentModifierBlock;
 	}
 
 	/** 
@@ -109,10 +111,6 @@
 	/** Get the prefix for the dumped launch information (add a space at the end if needed) */
 	protected abstract String getLaunchInfoPrefix();
 
-	/** Get the standard environment to use as a delta for the dumped launch information
-	 * @return standard environment a process would use, or <code>null</code> */
-	protected abstract Map<String, String> getLaunchInfoStandardEnvironment();
-
 	private void dumpLaunchInfo(String cwd) {
 		File logFile = new File(logToPath);
 		try {
@@ -120,26 +118,14 @@
 			PrintWriter printWriter = new PrintWriter(fos);
 			printWriter.println(getLaunchInfoPrefix() +
 					"[" + cwd + "] " + CommandLineArguments.toString(commandArguments));
-			if (environment != null) {
-				Map<String, String> stdEnv = getLaunchInfoStandardEnvironment();
-				for (Map.Entry<Object, Object> entry : environment.entrySet()) {
+			if (environmentModifierBlock != null) {
+				for (IEnvironmentOperation operation : environmentModifierBlock.getOperations()) {
 					// report new or modified variables
-					if (stdEnv == null || !stdEnv.containsKey(entry.getKey())) {
-						printWriter.println("\tadded " + entry.getKey() + "=" + entry.getValue());
-					} else if (stdEnv != null && !stdEnv.get(entry.getKey()).equals(entry.getValue())) {
-						printWriter.println("\tchanged " + entry.getKey() + "=[-]"
-								+ stdEnv.get(entry.getKey()) + " [+]" 
-										+ entry.getValue());
-					}
+					if (operation.getValue() != null)
+						printWriter.println("\tadd/replace " + operation.getName() + "=" + operation.getValue());
+					else
+						printWriter.println("\tremoved " + operation.getName());
 				}
-				if (stdEnv != null) {
-					for (Map.Entry<String, String> entry : stdEnv.entrySet()) {
-						// report deleted new or modified variables
-						if (!environment.containsKey(entry.getKey())) {
-							printWriter.println("\tremoved " + entry.getKey());
-						}
-					}
-				}
 			}
 
 			printWriter.close();

Added: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/process/EnvironmentModifierUtils.java
===================================================================
--- trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/process/EnvironmentModifierUtils.java	                        (rev 0)
+++ trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/process/EnvironmentModifierUtils.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+package org.maemo.esbox.core.process;
+
+import org.maemo.esbox.core.env.*;
+
+import java.util.*;
+
+/**
+ * This class helps with converting environment arrays to and from {@link IEnvironmentModifierBlock}.
+ * @author eswartz
+ *
+ */
+public class EnvironmentModifierUtils {
+
+	/**
+	 * Create a property modifier block from an array of environment settings.
+	 * The entries are in the form "name[=value]".
+	 * @param envp array of strings or <code>null</code>
+	 * @return environment property modifiers, never <code>null</code>
+	 */
+	public static IEnvironmentModifierBlock createFromEnvp(String[] envp) {
+		IEnvironmentModifierBlock block = EnvironmentManager.getInstance().createEnvironmentModifierBlock();
+		if (envp == null)
+			return block;
+		
+		for (String entry : envp) {
+			int idx = entry.indexOf('=');
+			if (idx < 0)
+				block.define(entry, "");
+			else
+				block.define(entry.substring(0, idx), entry.substring(idx+1));
+		}
+
+		return block;
+	}
+
+	/** 
+	 * Create environment modifier block by copying the contents of an environment map.
+	 * 
+	 * @param env map, may be <code>null</code>
+	 * @return {@link IEnvironmentModifierBlock} or <code>null</code>
+	 */
+	public static IEnvironmentModifierBlock createFromMap(Map<String, String> env) {
+		if (env == null)
+			return null;
+		IEnvironmentModifierBlock block = EnvironmentManager.getInstance().createEnvironmentModifierBlock();
+		for (Map.Entry<String, String> entry : env.entrySet()) {
+			block.define(entry.getKey(), entry.getValue());
+		}
+		return block;
+	}
+
+	/**
+	 * Create environment modifier block by copying the contents of a property map.
+	 * @param env properties group, may be <code>null</code>
+	 * @return {@link IEnvironmentModifierBlock} or <code>null</code>
+	 */
+	public static IEnvironmentModifierBlock createFromProperties(Properties env) {
+		if (env == null)
+			return null;
+		IEnvironmentModifierBlock block = EnvironmentManager.getInstance().createEnvironmentModifierBlock();
+		for (Map.Entry<Object, Object> entry : env.entrySet()) {
+			block.define(entry.getKey().toString(), entry.getValue() != null ? entry.getValue().toString() : "");
+		}
+		return block;
+	}
+
+	/**
+	 * Create a map from an environment block.  Sets <code>null</code> values for deleted keys.
+	 * @param envBlock incoming block or <code>null</code>
+	 * @return new Map or <code>null</code> 
+	 */
+	public static Map<String, String> createMap(IEnvironmentModifierBlock envBlock) {
+		if (envBlock == null)
+			return null;
+		
+		Map<String, String> envMap = new LinkedHashMap<String, String>();
+		for (IEnvironmentOperation operation : envBlock.getOperations()) {
+			envMap.put(operation.getName(), operation.getValue());
+		}
+		return envMap;
+	}
+
+}

Modified: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/process/EnvironmentProperties.java
===================================================================
--- trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/process/EnvironmentProperties.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/process/EnvironmentProperties.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -23,6 +23,7 @@
 	/**
 	 * Create a property map from an array of environment settings.
 	 * The entries are in the form "name[=value]".
+	 * Blank lines are ignored.
 	 * @param envp array of strings or <code>null</code>
 	 * @return environment properties, never <code>null</code>
 	 */
@@ -43,6 +44,69 @@
 	}
 
 	/**
+	 * Create a property map from an array of environment settings as dumped by
+	 * "sh -c set".
+	 * The entries are in the form "name='value'".
+	 * @param envp array of strings or <code>null</code>
+	 * @return environment properties, never <code>null</code>
+	 */
+	public static Properties createFromShellEnvDump(String dump) {
+		Properties env = new Properties();
+		if (dump == null)
+			return env;
+		
+		int idx = 0;
+		while (idx < dump.length()) {
+			StringBuilder nameBuilder = new StringBuilder();
+			
+			// gather a name
+			while (idx < dump.length()) {
+				char ch = dump.charAt(idx++);
+				if (ch == '=')
+					break;
+				if (ch == '\r' || ch == '\n') {
+					nameBuilder.setLength(0);
+					break;
+				}
+				nameBuilder.append(ch);
+			}
+			
+			if (nameBuilder.length() == 0)
+				continue;
+			
+			String name = nameBuilder.toString();
+			
+			// gather a value
+			//
+			// apostrophes cannot be represented, so instead the string
+			// is broken into multiple catenated parts, using double-quoting
+			// to enclose the apostrophe.
+			
+			StringBuilder rawValue = new StringBuilder();
+			
+			char inString = 0;
+			while (idx < dump.length()) {
+				char ich = dump.charAt(idx++);
+				if (ich == inString) {
+					inString = 0;
+				} else if (inString == 0 && ich == '\'') {
+					inString = ich;
+				} else if (inString == 0 && ich == '"') {
+					inString = ich;
+				} else if (inString == 0 && (ich == '\r' || ich == '\n')) {
+					break;
+				} else {
+					rawValue.append(ich);
+				}
+			}
+			
+			env.setProperty(name, rawValue.toString());
+		}
+
+		return env;
+	}
+
+	/**
 	 * Create a list of environment settings from a property map.
 	 * @param env property map <code>null</code>
 	 * @param sort if true, sort map by variable name

Modified: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/process/HostProcessLauncherFactory.java
===================================================================
--- trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/process/HostProcessLauncherFactory.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/process/HostProcessLauncherFactory.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -12,44 +12,24 @@
 
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.Platform;
-import org.maemo.esbox.internal.api.core.BaseProcessLauncherFactory;
-import org.maemo.esbox.internal.api.core.HostProcessLauncher;
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
+import org.maemo.esbox.internal.api.core.*;
 
 import java.util.List;
-import java.util.Properties;
 
 /**
- * 
+ * This launcher factory creates processes running on the host.
  * @author eswartz
  *
  */
 public class HostProcessLauncherFactory extends BaseProcessLauncherFactory {
-
 	public HostProcessLauncherFactory() {
-		super(Platform.getOS().equals(Platform.OS_WIN32));
+		super(new StandardHostEnvironmentProvider(), Platform.getOS().equals(Platform.OS_WIN32));
 	}
 
-	private Properties standardEnv;
-	
-	@Override
-	protected Properties readStandardEnvironment() {
-		if (standardEnv == null) {
-			standardEnv = new Properties();
-			// This isn't valid.  User variables likely are intended for scratchbox
-			// environments, not the host's.
-			standardEnv.putAll(System.getenv());
-			//mergeOrSetUserVariables(standardEnv, System.getenv());
-		}
-		return standardEnv;
+	protected IProcessLauncher doCreateProcessLauncher(IPath workingDirectory,
+			List<String> cmdLine, IEnvironmentModifierBlock envBlock) {
+		return new HostProcessLauncher(workingDirectory, cmdLine, envBlock);
 	}
-	
-	/* (non-Javadoc)
-	 * @see org.maemo.esbox.core.IProcessLauncherFactory#createProcessLaunchHandler(org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath, org.maemo.esbox.core.sdk.List<String>, java.util.Properties)
-	 */
-	protected IProcessLauncher doCreateProcessLaunchHandler(IPath workingDirectory,
-			List<String> cmdLine, Properties environment) {
-		return new HostProcessLauncher(workingDirectory, cmdLine,
-				environment != null ? environment : readStandardEnvironment());
-	}
 
 }

Modified: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/process/IProcessLauncher.java
===================================================================
--- trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/process/IProcessLauncher.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/process/IProcessLauncher.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -14,11 +14,11 @@
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.ui.console.MessageConsole;
 import org.maemo.esbox.core.ESboxException;
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
 import org.maemo.esbox.core.sdk.ISDKTarget;
 
 import java.io.OutputStream;
 import java.util.List;
-import java.util.Properties;
 
 /**
  * This encapsulates the mechanics needed to launch a process in
@@ -27,28 +27,42 @@
  * target environment before launch.  It may be used for either
  * standalone or SDK-hosted launching.
  * @author eswartz
- * @see IProcessLauncherFactory#createProcessLaunchHandler
+ * @see IProcessLauncherFactory#createProcessLauncher(IPath, List, IEnvironmentModifierBlock)
  *
  */
 public interface IProcessLauncher {
-	/** Get the command line arguments which will invoke the process from the host
+	/**
+	 * Get the command line arguments which will invoke the process from the
+	 * host.
 	 * <p>
-	 * (useful for testing) 
-	 * @return argument list, never <code>null</code> (may be modified before launch)
+	 * Note that these may have been modified by the implementation from the
+	 * original command line arguments passed to the process launcher factory.
+	 * <p>
+	 * (useful for testing)
+	 * 
+	 * @return argument list, never <code>null</code> (may be modified before
+	 *         launch)
 	 */
 	List<String> getLaunchCommandArguments();
-	
-	/** 
-	 * Get the environment to set in the host before invoking the process.  Note
-	 * that environment variables may have been encoded in the launch command
-	 * arguments.
+
+	/**
+	 * Get the environment changes to make in the host before invoking the
+	 * process.
 	 * <p>
-	 * @return environment, may be empty or <code>null</code> (may be modified before launch)
+	 * Note that the implementation may have encoded environment variables into
+	 * the launch command arguments, meaning this returned block may be
+	 * different than originally passed to the proess launcher factory.
+	 * <p>
+	 * 
+	 * @return {@link IEnvironmentModifierBlock}, may be empty or
+	 *         <code>null</code> (and may be modified before launch)
 	 */
-	Properties getLaunchEnvironment();
+	IEnvironmentModifierBlock getLaunchEnvironmentModifierBlock();
 	
 	/**
 	 * Get the current working directory specified for the process.
+	 * <p>
+	 * Note: this may have been changed from the value passed to the process launcher factory.
 	 * @return IPath or <code>null</code>
 	 */
 	IPath getLaunchCurrentWorkingDirectory();

Modified: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/process/IProcessLauncherFactory.java
===================================================================
--- trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/process/IProcessLauncherFactory.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/process/IProcessLauncherFactory.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -11,6 +11,7 @@
 package org.maemo.esbox.core.process;
 
 import org.eclipse.core.runtime.IPath;
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
 
 import java.util.List;
 import java.util.Properties;
@@ -26,30 +27,44 @@
  */
 public interface IProcessLauncherFactory {
 	/**
-	 * Get a copy of the standard environment for launching processes.  This is implicitly used
-	 * when a process is launched passing a <code>null</code> environment.
+	 * Get a copy of the raw environment variables obtained by querying the launch environment.
 	 * <p>
-	 * Changes are not reflected in the standard environment.  You may pass a modified version to
-	 * to {@link #createProcessLaunchHandler(IPath, List, Properties)}.
+	 * NOTE: this is for reference purposes.  It may be cached and slightly different from what
+	 * is actually available for a future launch.  But it may be used, e.g., to check the 
+	 * values of variables like PATH in order to construct meaningful {@link IEnvironmentModifierBlock}s.
+	 * @return the environment block, may be empty if unknown
+	 */
+	Properties getRawEnvironment();
+
+	/**
+	 * Get the environment variable modifier block that represents the
+	 * implementation-defined set of environment modifications.
+	 * Currently, this is the global environment block from ESbox &gt; Environment.
 	 * <p>
-	 * This environment may contain ESbox Scratchbox environment overrides
-	 * @return the environment block, may be empty if unknown (launching on remote target)
+	 * Clients may modify the block as needed, and either pass it directly to
+	 * {@link #createProcessLauncher(IPath, List, IEnvironmentModifierBlock)} or
+	 * just pass <code>null</code> to that method.
+	 * 
+	 * @return non-null environment block
 	 */
-	Properties getStandardEnvironment();
-	
-	/**
-	 * Create a process launch handler for the given command whose input and output
-	 * are handled through the given PTY.
+	IEnvironmentModifierBlock defaultEnvironmentModifierBlock();
+
+	/** 
+ 	 * Create a process launcher for the given command.
 	 * @param workingDirectory the current working directory relative to the launch environment; may be null
 	 * @param commandLine executable and arguments; for the executable, bare filename implies program on $PATH,
 	 * relative path with "./", etc., implies a script in the working directory, 
 	 * and a full path is an absolute path in the launch environment
-	 * @param environment the environment to pass (null to use the standard environment, else override the
-	 * environment)
-	 * @return a new process launch handler
-	 */
-	IProcessLauncher createProcessLaunchHandler(
+     * @param environmentModifierBlock if not null, the set of modifications 
+	 * applied to the environment at process launch.  If null, the modifiers from
+	 * {@link #defaultEnvironmentModifierBlock()} are used instead.  
+	 * To avoid making any changes at all, pass an empty IEnvironmentModifierBlock.
+     * @see #defaultEnvironmentModifierBlock()
+     * @see EnvironmentVariableManager#createEnviromentModifierBlock()
+     */
+    IProcessLauncher createProcessLauncher(
 			IPath workingDirectory,
 			List<String> commandLine,
-			Properties environment);
+			IEnvironmentModifierBlock environmentModifierBlock);
+ 
 }

Modified: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/process/ProcessLauncherCreator.java
===================================================================
--- trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/process/ProcessLauncherCreator.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/process/ProcessLauncherCreator.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -11,6 +11,7 @@
 package org.maemo.esbox.core.process;
 
 import org.eclipse.core.runtime.IPath;
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
 
 import java.util.*;
 
@@ -28,24 +29,32 @@
 public abstract class ProcessLauncherCreator {
 
 	/**
-	 * Create a process launch handler for the given command whose input and output
-	 * are handled through the given PTY.
-	 * @param processLauncherFactory the factory
-	 * @param workingDirectory the current working directory relative to the launch environment; may be null
-	 * @param commandLine executable and arguments; for the executable, bare filename implies program on $PATH,
-	 * relative path with "./", etc., implies a script in the working directory, 
-	 * and a full path is an absolute path in the launch environment
-	 * @param environment the environment to pass (null to use the standard environment, else override the
-	 * environment)
-	 * @param usePTY whether to use a PTY (if available)
+	 * Create a process launch handler for the given command whose input and
+	 * output are handled through the given PTY.
+	 * 
+	 * @param processLauncherFactory
+	 *            the factory
+	 * @param workingDirectory
+	 *            the current working directory relative to the launch
+	 *            environment; may be null
+	 * @param commandLine
+	 *            executable and arguments; for the executable, bare filename
+	 *            implies program on $PATH, relative path with "./", etc.,
+	 *            implies a script in the working directory, and a full path is
+	 *            an absolute path in the launch environment
+	 * @param environmentModifierBlock
+	 *            the environment modifications to pass (null to use the
+	 *            standard environment modifications, else override those)
+	 * @param usePTY
+	 *            whether to use a PTY (if available)
 	 * @return a new process launch handler
 	 */
 	public static IProcessLauncher createProcessLauncher(
 			IProcessLauncherFactory processLauncherFactory,
 			IPath workingDirectory, List<String> commandLine,
-			Properties environment, boolean usePTY) {
-		IProcessLauncher launcher = processLauncherFactory.createProcessLaunchHandler(
-						workingDirectory, commandLine, environment);
+			IEnvironmentModifierBlock environmentModifierBlock, boolean usePTY) {
+		IProcessLauncher launcher = processLauncherFactory.createProcessLauncher(
+						workingDirectory, commandLine, environmentModifierBlock);
 		launcher.usePTY(usePTY);
 		return launcher;
 	}
@@ -57,16 +66,17 @@
 	 * @param commandLine executable and arguments; for the executable, bare filename implies program on $PATH,
 	 * relative path with "./", etc., implies a script in the working directory, 
 	 * and a full path is an absolute path in the launch environment
-	 * @param environment the environment to pass (null to use the standard environment, else override the
-	 * environment)
+	 * @param environmentModifierBlock
+	 *            the environment modifications to pass (null to use the
+	 *            standard environment modifications, else override those)
 	 * @return a new process launch handler
 	 */
 	public static IProcessLauncher createProcessLauncher(
 			IProcessLauncherFactory processLauncherFactory,
 			IPath workingDirectory, List<String> commandLine,
-			Properties environment) {
-		return processLauncherFactory.createProcessLaunchHandler(
-				workingDirectory, commandLine, environment);
+			IEnvironmentModifierBlock environmentModifierBlock) {
+		return processLauncherFactory.createProcessLauncher(
+				workingDirectory, commandLine, environmentModifierBlock);
 	}
 
 	/**
@@ -81,7 +91,7 @@
 	public static IProcessLauncher createProcessLauncher(
 			IProcessLauncherFactory processLauncherFactory,
 			IPath workingDirectory, List<String> commandLine) {
-		return processLauncherFactory.createProcessLaunchHandler( 
+		return processLauncherFactory.createProcessLauncher( 
 				workingDirectory,
 				commandLine,
 				null);
@@ -95,22 +105,23 @@
 	 * relative path with "./", etc., implies a script in the working directory, 
 	 * and a full path is an absolute path in the launch environment
 	 * @param args the arguments to pass to the program, may be null
-	 * @param environment the environment to pass (null to use the standard environment, else override the
-	 * environment)
+	 * @param environmentModifierBlock
+	 *            the environment modifications to pass (null to use the
+	 *            standard environment modifications, else override those)
 	 * @return a new process launch handler
 	 */
 	public static IProcessLauncher createProcessLauncher(
 			IProcessLauncherFactory processLauncherFactory,
 			IPath workingDirectory, String executable, List<String> args,
-			Properties environment) {
+			IEnvironmentModifierBlock environmentModifierBlock) {
 		List<String> cmdLine;
 		if (args != null)
 			cmdLine = new ArrayList<String>(args);
 		else
 			cmdLine = new ArrayList<String>();
 		cmdLine.add(0, executable);
-		return processLauncherFactory.createProcessLaunchHandler(
-				workingDirectory, cmdLine, environment);
+		return processLauncherFactory.createProcessLauncher(
+				workingDirectory, cmdLine, environmentModifierBlock);
 	}
 
 	/**
@@ -133,7 +144,7 @@
 		else
 			cmdLine = new ArrayList<String>();
 		cmdLine.add(0, executable);
-		return processLauncherFactory.createProcessLaunchHandler(
+		return processLauncherFactory.createProcessLauncher(
 				workingDirectory, cmdLine, null);
 	}
 
@@ -142,7 +153,7 @@
 	 * with the standard environment from this launcher.  
 	 * <p>
 	 * <b>Do not</b> use this if you are constructing a command line
-	 * from scratch.  Use {@link #createProcessLaunchHandler(IPath, IPath, List<String>)}
+	 * from scratch.  Use {@link #createProcessLauncher(IPath, IPath, List<String>)}
 	 * instead. 
 	 * @param processLauncherFactory the factory
 	 * @param workingDirectory the current working directory relative to the launch environment; may be null
@@ -154,7 +165,7 @@
 	public static IProcessLauncher createProcessLauncher(
 			IProcessLauncherFactory processLauncherFactory,
 			IPath workingDirectory, String commandLine) {
-		return processLauncherFactory.createProcessLaunchHandler(
+		return processLauncherFactory.createProcessLauncher(
 				workingDirectory,
 				CommandLineArguments.createFromCommandLine(commandLine),
 				null);
@@ -166,7 +177,7 @@
 	 * in an unspecified directory.  
 	 * <p>
 	 * <b>Do not</b> use this if you are constructing a command line
-	 * from scratch.  Use {@link #createProcessLaunchHandler(IPath, IPath, List<String>)}
+	 * from scratch.  Use {@link #createProcessLauncher(IPath, IPath, List<String>)}
 	 * instead. 
 	 * @param processLauncherFactory the factory
 	 * @param commandLine a string formatted for shell invocation
@@ -176,7 +187,7 @@
 	 */
 	public static IProcessLauncher createProcessLauncher(
 			IProcessLauncherFactory processLauncherFactory, String commandLine) {
-		return processLauncherFactory.createProcessLaunchHandler(
+		return processLauncherFactory.createProcessLauncher(
 				null,
 				CommandLineArguments.createFromCommandLine(commandLine),
 				null);
@@ -192,10 +203,10 @@
 	public static IProcessLauncher createProcessLauncher(
 			IProcessLauncherFactory 	processLauncherFactory, 
 			ProcessLauncherParameters	pars) {
-		return processLauncherFactory.createProcessLaunchHandler(
+		return processLauncherFactory.createProcessLauncher(
 				pars.getCwd(),
 				pars.getCommandLine(),
-				pars.getEnvVars());
+				pars.getEnvironmentModifierBlock());
 	}
 
 }

Modified: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/process/ProcessLauncherParameters.java
===================================================================
--- trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/process/ProcessLauncherParameters.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/process/ProcessLauncherParameters.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -13,8 +13,10 @@
 
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.Path;
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
 
-import java.util.*;
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * Record all parameters related to launching a process.
@@ -27,20 +29,20 @@
     private List<String> cmdLine;
 
     /** new environment variables, or null if nothing needed */
-    private Properties envVars;
+    private IEnvironmentModifierBlock envBlock;
 
     /** current directory to go to (host-relative, e.g. project path) */
     private IPath cwd;
 
-     public ProcessLauncherParameters(IPath workingDir, List<String> cmdArgs, Properties env) {
+     public ProcessLauncherParameters(IPath workingDir, List<String> cmdArgs, IEnvironmentModifierBlock environmentModifierBlock) {
     	cmdLine = cmdArgs;
-    	envVars = env;
+    	envBlock = environmentModifierBlock;
     	cwd = workingDir;
     }
     
     public ProcessLauncherParameters() {
     	setCommandLine(new ArrayList<String>());
-    	setEnvVars(new Properties());
+    	setEnvironmentModificationBlock(null);
     	setCwd(new Path("."));
     }
     
@@ -50,8 +52,8 @@
     	return cmdLine;
     }
     
-    public Properties getEnvVars() {
-    	return envVars;
+    public IEnvironmentModifierBlock getEnvironmentModifierBlock() {
+    	return envBlock;
     }
     
     public IPath getCwd() {
@@ -65,8 +67,8 @@
     	this.cmdLine = cmdLine;
     }
     
-    public void setEnvVars(Properties envVars) {
-    	this.envVars = envVars;
+    public void setEnvironmentModificationBlock(IEnvironmentModifierBlock environmentModifierBlock) {
+    	this.envBlock = environmentModifierBlock;
     }
     
     public void setCwd(IPath cwd) {

Modified: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/process/ProcessLauncherUtils.java
===================================================================
--- trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/process/ProcessLauncherUtils.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/process/ProcessLauncherUtils.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -13,9 +13,12 @@
 
 import org.eclipse.core.net.proxy.IProxyData;
 import org.eclipse.core.net.proxy.IProxyService;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.*;
 import org.maemo.esbox.core.ESboxException;
+import org.maemo.esbox.core.env.EnvironmentManager;
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
+import org.maemo.esbox.core.machine.IMachine;
+import org.maemo.esbox.core.machine.IPathCanonicalizer;
 
 import java.io.ByteArrayOutputStream;
 import java.util.List;
@@ -29,8 +32,9 @@
 public abstract class ProcessLauncherUtils {
 	private static final String LINE_ENDING_PATTERN_STRING = "(\r\n|\r|\n)";
 	private static final String NO_PROXY = "no_proxy"; //$NON-NLS-1$
-
 	private static final String HTTP_PROXY = "http_proxy"; //$NON-NLS-1$
+	
+	private static final String PATH = "PATH";
 
 
 	public static class Results {
@@ -57,7 +61,7 @@
 	 * @param monitor optional progress monitor, allowing cancellation
 	 * @param cwd the directory to run from, or <code>null</code>
 	 * @param cmdLine the command line, may not be <code>null</code>
-	 * @param env environment to set, or <code>null</code> for default
+	 * @param environmentModifierBlock environment modifications to apply, or <code>null</code> for default modifications
 	 * @return results of process launch (if launch succeeded)
 	 * @throws ESboxException if launch failed
 	 */
@@ -65,25 +69,14 @@
 			IProgressMonitor monitor,
 			IPath cwd,
 			List<String> cmdLine,
-			Properties env) throws ESboxException {
+			IEnvironmentModifierBlock environmentModifierBlock) throws ESboxException {
 		IProcessLauncher processLauncher = ProcessLauncherCreator.createProcessLauncher(
 				processLauncherFactory,
 				cwd,
 				cmdLine,
-				env);
+				environmentModifierBlock);
 		
-		try {
-			processLauncher.createProcess();
-		} catch (Exception e) {
-			throw new ESboxException("Failed to launch: " + CommandLineArguments.toCommandLine(cmdLine), e);
-		}
-		
-		ByteArrayOutputStream out = new ByteArrayOutputStream();
-		ByteArrayOutputStream err = new ByteArrayOutputStream();
-		
-		int exit = processLauncher.waitAndRead(out, err, monitor);
-		
-		return new Results(exit, out.toString(), err.toString());
+		return launchAndReadStandardStreams(processLauncher, monitor);
 	}
 	
 	/**
@@ -99,14 +92,40 @@
 	}
 	
 	/**
+	 * Create and launch a process, read its streams into memory, and wait for it to finish.
+	 * @param processLauncher launcher for the process
+	 * @param monitor optional progress monitor, allowing cancellation
+	 * @return results of process launch (if launch succeeded)
+	 * @throws ESboxException if launch failed
+	 */
+	public static Results launchAndReadStandardStreams(IProcessLauncher processLauncher,
+			IProgressMonitor monitor) throws ESboxException {
+		
+		try {
+			processLauncher.createProcess();
+		} catch (Exception e) {
+			throw new ESboxException("Failed to launch: " + CommandLineArguments.toCommandLine(processLauncher.getLaunchCommandArguments()), e);
+		}
+		
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		ByteArrayOutputStream err = new ByteArrayOutputStream();
+		
+		int exit = processLauncher.waitAndRead(out, err, monitor);
+		
+		return new Results(exit, out.toString(), err.toString());
+	}
+
+	/**
 	 * Add the http_proxy and no_proxy variables to an environment block, if necessary.
 	 * Use this when a command is known to need network access.
-	 * @param env incoming environment, or <code>null</code>
-	 * @return updated environment (possibly same as 'env' if not <code>null</code>), or <code>null</code> if
-	 * env was <code>null</code> and no changes were made
+	 * @param envBlock environment modifier block to update
 	 */
 	@SuppressWarnings("restriction")
-	public static Properties defineProxyVariables(Properties env) {
+	public static void defineProxyVariables(IEnvironmentModifierBlock envBlock) {
+		// don't make changes if user already defined this in Eclipse
+		if (envBlock.findOperation(HTTP_PROXY) != null)
+			return;
+		
 		// wow, completely internal information!
 		IProxyService proxyService = org.eclipse.ui.internal.net.Activator.getDefault().getProxyService();
 		if (proxyService != null && proxyService.isProxiesEnabled()) {
@@ -126,11 +145,9 @@
 				int port = data.getPort();
 				
 				String url = "http://" + address + ":" + port;
-				if (env == null)
-					env = new Properties();
-				env.put(HTTP_PROXY, url);
+				envBlock.define(HTTP_PROXY, url);
 				if (noProxy != null) {
-					env.put(NO_PROXY, noProxy.toString());
+					envBlock.define(NO_PROXY, noProxy.toString());
 				}
 			}			
 		} else {
@@ -138,7 +155,139 @@
 			// place in the environment, in case user manually defined it
 			//env.put(HTTP_PROXY, "");
 		}
-		return env;
+		
+		return;
 	}
 	
+	/**
+	 * Get the presumed environment that will be active for a given process launcher factory.
+	 * This combines the raw environment with any default environment modifiers provided by
+	 * the factory.
+	 * @param launcherFactory an IProcessLauncherFactory
+	 * @return environment map 
+	 */
+	public static Properties getSynthesizedEnvironment(IProcessLauncherFactory launcherFactory) {
+		Properties rawEnv = launcherFactory.getRawEnvironment();
+		IEnvironmentModifierBlock envBlock = launcherFactory.defaultEnvironmentModifierBlock();
+		envBlock.applyTo(rawEnv);
+		return rawEnv;
+	}
+
+	/**
+	 * Get the standard PATH separator.
+	 * @return separator for items in PATH
+	 */
+	public static char getPathEnvironmentVariableSeparator(IMachine machine) {
+		if (machine.getOS().equals(Platform.OS_WIN32))
+			return ';';
+		return ':';
+	}
+	
+	/**
+	 * Get an environment modifier block that defines PATH to include the given path.
+	 * This honors any default changes to PATH by the default environment modifier
+	 * and checks the launcher host environment.
+	 * @param machine the machine, which provides semantics for PATH construction and canonicalization
+	 * @param launcherFactory the process launcher factory
+	 * @param pathString the path to add
+	 * @param inFront if true, add to the beginning, else add to the end
+	 * @return {@link IEnvironmentModifierBlock} which contains the default modifier block plus
+	 * the PATH change or <code>null</code> if PATH already contains the path
+	 */
+	public static IEnvironmentModifierBlock addToPATH(
+			IMachine machine, 
+			IProcessLauncherFactory launcherFactory,
+			String pathString,
+			boolean inFront) {
+		return addToPATH(machine, 
+				launcherFactory.getRawEnvironment(),
+				launcherFactory.defaultEnvironmentModifierBlock(),
+				pathString,
+				inFront);
+	}
+	
+	/**
+	 * Get an environment modifier block that defines PATH to include the given path.
+	 * @param machine the machine, which provides semantics for PATH construction and canonicalization
+	 * @param env the original environment (not modified)
+	 * @param envBlock pending changes to the environment (updated)
+	 * @param pathString the path to add
+	 * @param inFront if true, add to the beginning, else add to the end
+	 * @return modified envBlock which contains the default modifier block plus
+	 * the PATH change or <code>null</code> if PATH already contains the path
+	 */
+	public static IEnvironmentModifierBlock addToPATH(
+			IMachine machine, 
+			Properties env,
+			IEnvironmentModifierBlock envBlock,
+			String pathString,
+			boolean inFront) {
+		
+		// apply pending changes to env block
+		if (envBlock != null) {
+			if (env != null)
+				env = EnvironmentProperties.copyProperties(env);
+			else
+				env = new Properties();
+			envBlock.applyTo(env);
+		}
+		
+		// find what PATH should be
+		String pathVar = env != null ? env.getProperty(PATH) : null;
+		
+		String newPathVar = addToPATH(machine, pathString, inFront, pathVar);
+		
+		if (newPathVar != null) {
+			// report PATH change into passed-in modifier block or make new one
+			if (envBlock == null) {
+				envBlock = EnvironmentManager.getInstance().createEnvironmentModifierBlock();
+			}
+			envBlock.define(PATH, newPathVar);
+			return envBlock;
+		} else {
+			return null;
+		}
+	}
+	
+	/**
+	 * Get an environment modifier block that defines PATH to include the given path.
+	 * @param machine the machine, which provides semantics for PATH construction and canonicalization
+	 * @param newPathString the path to add
+	 * @param inFront if true, add to the beginning, else add to the end
+	 * @param pathVar the current PATH value
+	 * TODO: we should allow variable substitution in an env block to make this code simpler
+	 * @return {@link IEnvironmentModifierBlock} or <code>null</code> if PATH already contains the path
+	 */
+	public static String addToPATH(
+			IMachine machine, 
+			String newPathString,
+			boolean inFront,
+			String pathVar) {
+		IPathCanonicalizer canonicalizer = machine.getFileSystemMapping().getHostPathCanonicalizer();
+		IPath newPath = canonicalizer.getCanonicalPath(new Path(newPathString));
+		
+		if (pathVar == null)
+			pathVar = "";
+		
+		String[] paths = pathVar.split("" + getPathEnvironmentVariableSeparator(machine));
+		
+		for (String path : paths) {
+			if (canonicalizer.getCanonicalPath(new Path(path)).equals(newPath)) {
+				return null;
+			}
+		}
+		
+		if (inFront) {
+			pathVar = newPathString 
+				+ (pathVar.length() > 0 ? getPathEnvironmentVariableSeparator(machine) + pathVar : "");
+		} else {
+			pathVar = 
+				(pathVar.length() > 0 ? pathVar + getPathEnvironmentVariableSeparator(machine) : "") 
+				+ newPathString;
+		}
+		
+		return pathVar;
+	}
 }
+
+ 
\ No newline at end of file

Modified: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/process/ProcessRunnerParameters.java
===================================================================
--- trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/process/ProcessRunnerParameters.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/process/ProcessRunnerParameters.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -14,9 +14,9 @@
 package org.maemo.esbox.core.process;
 
 import org.eclipse.core.runtime.IPath;
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
 
 import java.util.List;
-import java.util.Properties;
 
 
 /**
@@ -33,9 +33,9 @@
 	/** if sendToConsole==true, then create a new console */
 	private boolean brandNew = false;
 
-	public ProcessRunnerParameters(IPath wdInSb, List<String> cmdLine,
-			Properties env) {
-		super(wdInSb, cmdLine, env);
+	public ProcessRunnerParameters(IPath workingDirectory, List<String> cmdLine,
+			IEnvironmentModifierBlock environmentModifierBlock) {
+		super(workingDirectory, cmdLine, environmentModifierBlock);
 	}
 	
 	public ProcessRunnerParameters() {

Added: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/process/StandardHostEnvironmentProvider.java
===================================================================
--- trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/process/StandardHostEnvironmentProvider.java	                        (rev 0)
+++ trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/process/StandardHostEnvironmentProvider.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+
+package org.maemo.esbox.core.process;
+
+import org.maemo.esbox.internal.api.core.IStandardEnvironmentProvider;
+
+import java.util.Properties;
+
+/**
+ * This implementation will cache the host's environment values for as long as necessary,
+ * using a single copy for every instance  -- the environment won't change since it is 
+ * inherited at Eclipse launch.
+ * @author eswartz
+ *
+ */
+public class StandardHostEnvironmentProvider implements IStandardEnvironmentProvider {
+	private static Properties standardEnv;
+	
+	/* (non-Javadoc)
+	 * @see org.maemo.esbox.internal.api.core.IStandardEnvironmentProvider#getRawEnviroment()
+	 */
+	public Properties getRawEnvironment() {
+		if (standardEnv == null) {
+			standardEnv = new Properties();
+			standardEnv.putAll(System.getenv());
+		}
+		return standardEnv;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.maemo.esbox.internal.api.core.IStandardEnvironmentProvider#flushRawEnvironment()
+	 */
+	public void flushRawEnvironment() {
+		standardEnv = null;
+	}
+}
\ No newline at end of file

Added: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/process/StandardMachineEnvironmentProvider.java
===================================================================
--- trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/process/StandardMachineEnvironmentProvider.java	                        (rev 0)
+++ trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/process/StandardMachineEnvironmentProvider.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+
+package org.maemo.esbox.core.process;
+
+import org.maemo.esbox.core.machine.IMachine;
+import org.maemo.esbox.internal.api.core.IStandardEnvironmentProvider;
+
+import java.util.Properties;
+
+/**
+ * This provider will yield the environment from an IMachine.
+ * @author eswartz
+ *
+ */
+public class StandardMachineEnvironmentProvider implements IStandardEnvironmentProvider {
+	private Properties standardEnv;
+	private final IMachine machine;
+	
+	public StandardMachineEnvironmentProvider(IMachine machine) {
+		this.machine = machine;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.maemo.esbox.internal.api.core.IStandardEnvironmentProvider#getRawEnviroment()
+	 */
+	public Properties getRawEnvironment() {
+		if (standardEnv == null) {
+			standardEnv = machine.getStandardEnvironment();
+		}
+		return standardEnv;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.maemo.esbox.internal.api.core.IStandardEnvironmentProvider#flushRawEnvironment()
+	 */
+	public void flushRawEnvironment() {
+		standardEnv = null;
+	}
+}

Modified: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core/BaseProcessLauncherFactory.java
===================================================================
--- trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core/BaseProcessLauncherFactory.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core/BaseProcessLauncherFactory.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -19,20 +19,18 @@
 public abstract class BaseProcessLauncherFactory implements IProcessLauncherFactory {
 
 	private boolean isWin32;
+	private IEnvironmentModifierBlock defaultEnvironmentModifierBlock;
+	private final IStandardEnvironmentProvider envProvider;
 
-	public BaseProcessLauncherFactory(boolean isWin32) {
+	public BaseProcessLauncherFactory(IStandardEnvironmentProvider envProvider, boolean isWin32) {
+		this.envProvider = envProvider;
 		this.isWin32 = isWin32;
+		defaultEnvironmentModifierBlock = EnvironmentManager.getInstance().getGlobalEnvironmentModifierBlock().copy();
 	}
 	
-	/** Implement to provide the standard environment.
-	 * @return property map (may be null or singleton) */
-	abstract protected Properties readStandardEnvironment();
-
-	public Properties getStandardEnvironment() {
-		Properties standardEnv = readStandardEnvironment();
-		Properties copy = new Properties();
-		if (standardEnv != null)
-			copy.putAll(standardEnv);
+	public Properties getRawEnvironment() {
+		Properties standardEnv = envProvider.getRawEnvironment();
+		Properties copy = EnvironmentProperties.copyProperties(standardEnv);
 		return copy;
 	}
 	
@@ -40,67 +38,40 @@
 	 * Implement for the actual process launcher implementation 
 	 * @param workingDirectory
 	 * @param cmdLine cmdline array, may be modified
-	 * @param environment environment, may be modified
+	 * @param environmentModifierBlock environment, never <code>null</code>, may be modified
 	 */
-	protected abstract IProcessLauncher doCreateProcessLaunchHandler(IPath workingDirectory,
-			List<String> cmdLine, Properties environment);
+	protected abstract IProcessLauncher doCreateProcessLauncher(IPath workingDirectory,
+			List<String> cmdLine, IEnvironmentModifierBlock environmentModifierBlock);
 
 	/* (non-Javadoc)
-	 * @see org.maemo.esbox.core.IProcessLauncherFactory#createProcessLaunchHandler(org.eclipse.core.runtime.IPath, java.util.List, java.util.Properties, org.eclipse.cdt.utils.pty.PTY)
+	 * @see org.maemo.esbox.core.process.IProcessLauncherFactory#createProcessLauncher(org.eclipse.core.runtime.IPath, java.util.List, org.maemo.esbox.core.env.IEnvironmentModifierBlock)
 	 */
-	public IProcessLauncher createProcessLaunchHandler(IPath workingDirectory,
-			List<String> cmdLine, Properties environment) {
+	public IProcessLauncher createProcessLauncher(IPath workingDirectory,
+			List<String> cmdLine, IEnvironmentModifierBlock environmentModifierBlock) {
 		// if PATH is changed, we must wrap the command in a shell so the new PATH
 		// will be used to search for any binaries referenced in the command
 		
 		// XXX: move logic out
 		List<String> cmdLineCopy;
-		if (environment != null && environment.containsKey("PATH") && !isWin32) {
+		if (environmentModifierBlock != null && environmentModifierBlock.findOperation("PATH") != null && !isWin32) {
 			cmdLineCopy = CommandLineArguments.wrapScriptCommandLineForShell(cmdLine);
 		} else {
 			cmdLineCopy = new ArrayList<String>(cmdLine);
 		}
-		return doCreateProcessLaunchHandler(workingDirectory, 
+		
+		if (environmentModifierBlock == null)
+			environmentModifierBlock = defaultEnvironmentModifierBlock();
+		
+		return doCreateProcessLauncher(workingDirectory, 
 				cmdLineCopy,
-				EnvironmentProperties.copyProperties(environment));
+				environmentModifierBlock);
 	}
 
 	/**
-	 * Either merge user supplied variables into standardEnv, or set the
-	 * contents of standardEnv from those variables, based on the disposition
-	 * of the ESbox environment preferences.
-	 * <p>
-	 * Pick variables only slated for a particular machine based on a prefix.
-	 * 
-	 * @param standardEnv environment block updated
-	 * @param systemEnv environment for system
+	 * The default implementation applies values from the Global environment category.
+	 * Subclasses may not override -- modify the contents instead.
 	 */
-	public void mergeOrSetUserVariables(String machinePrefix, Properties standardEnv, Map<String, String> systemEnv) {
-		EnvironmentVariableManager manager = EnvironmentVariableManager.getInstance();
-		IEnvironmentVariableBlock envBlock = manager.getGlobalEnvironmentBlock();
-		
-		if (/* TODO: append? && */ systemEnv != null) {
-			standardEnv.putAll(systemEnv);
-		}
-		
-		for (IEnvironmentVariable variable : envBlock.getVariables()) {
-			String name = variable.getName();
-			int idx = name.indexOf('$');
-			if (idx >= 0) {
-				if (machinePrefix == null || !name.substring(0, idx).equals(machinePrefix))
-					continue;
-				else
-					name = name.substring(machinePrefix.length() + 1);
-			}
-			
-			if (variable.getValue() != null) {
-				standardEnv.put(name, envBlock.expandString(variable.getValue(), 
-						manager.getStandardVariableProvider()));
-			} else {
-				standardEnv.remove(name);
-			}
-		}
+	public final IEnvironmentModifierBlock defaultEnvironmentModifierBlock() {
+		return defaultEnvironmentModifierBlock;
 	}
-	
-
 }

Modified: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core/HostProcessLauncher.java
===================================================================
--- trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core/HostProcessLauncher.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core/HostProcessLauncher.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -12,6 +12,8 @@
 
 import org.eclipse.core.runtime.IPath;
 import org.maemo.esbox.core.*;
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
+import org.maemo.esbox.core.env.IEnvironmentOperation;
 import org.maemo.esbox.core.process.BaseProcessLauncher;
 
 import java.util.*;
@@ -24,11 +26,10 @@
 public class HostProcessLauncher extends BaseProcessLauncher {
 
 	public HostProcessLauncher(IPath workingDirectory,
-			List<String> cmdLine, Properties environment) {
+			List<String> cmdLine, IEnvironmentModifierBlock envBlock) {
 		super(cmdLine, 
-				environment,
-				workingDirectory,
-				CorePreferenceManager.getInstance().getPreferenceProvider());
+				envBlock,
+				workingDirectory);
 	}
 
 	/* (non-Javadoc)
@@ -39,15 +40,7 @@
 		return "";
 	}
 	
-	/* (non-Javadoc)
-	 * @see org.maemo.esbox.internal.core.BaseProcessLauncher#getLaunchInfoStandardEnvironment()
-	 */
 	@Override
-	protected Map<String, String> getLaunchInfoStandardEnvironment() {
-		return System.getenv();
-	}
-	
-	@Override
 	protected void setupForLaunch() throws ESboxException {
 		// nothing special
 	}
@@ -57,13 +50,16 @@
 	 */
 	@Override
 	protected Process doCreateProcess() throws Exception {
+		// XXX: use an IMachine
 		Process process;
 		
 		ProcessBuilder builder = new ProcessBuilder(getLaunchCommandArguments());
-		if (getLaunchEnvironment() != null) {
-			builder.environment().clear();
-			for (Map.Entry<Object, Object> entry : getLaunchEnvironment().entrySet()) {
-				builder.environment().put(entry.getKey().toString(), entry.getValue().toString());
+		if (getLaunchEnvironmentModifierBlock() != null) {
+			for (IEnvironmentOperation operation : getLaunchEnvironmentModifierBlock().getOperations()) {
+				if (operation.getValue() == null)
+					builder.environment().remove(operation.getName());
+				else
+					builder.environment().put(operation.getName(), operation.getValue());
 			}
 		}
 		if (getLaunchCurrentWorkingDirectory() != null) {

Added: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core/IStandardEnvironmentProvider.java
===================================================================
--- trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core/IStandardEnvironmentProvider.java	                        (rev 0)
+++ trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core/IStandardEnvironmentProvider.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+
+package org.maemo.esbox.internal.api.core;
+
+import java.util.Properties;
+
+/**
+ * Creators of IProcessLauncherFactory may implement this interface to cache the
+ * standard environment for a given target.
+ * @author eswartz
+ *
+ */
+public interface IStandardEnvironmentProvider {
+
+	/**
+	 * Read the (possibly cached) raw environment from the target.
+	 * @return Properties, never <code>null</code>
+	 */
+	Properties getRawEnvironment();
+	
+	/** 
+	 * Flush the cached raw environment.
+	 */
+	void flushRawEnvironment();
+}

Modified: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core/OldESboxPreferenceMigrator.java
===================================================================
--- trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core/OldESboxPreferenceMigrator.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core/OldESboxPreferenceMigrator.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -17,7 +17,9 @@
 import java.util.Properties;
 
 /**
- * This class migrates ESbox 1.4 settings to the new framework.
+ * This class migrates ESbox 1.4 settings to the new framework (previous settings
+ * were all in one block, and now we redistribute them to categories using the
+ * CorePreferenceManager).
  * @author eswartz
  *
  */
@@ -59,8 +61,7 @@
 	 * @see org.maemo.esbox.core.IPreferenceMigrator#convertExistingPreferences(org.eclipse.jface.preference.IPreferenceStore, int, int, java.util.Properties, java.util.Properties)
 	 */
 	public void convertExistingPreferences(IPreferenceStore preferences,
-			int oldMajor, int oldMinor, Properties existingSettings,
-			Properties newPropertyDefaults) {
+			int oldMajor, Properties existingSettings, Properties newPropertyDefaults) {
 		if (oldMajor <= LAST_ESBOX_VERSION_MAJOR) {
 			for (String key : userPrefKeys) {
 				if (!preferences.isDefault(key) && newPropertyDefaults.containsKey(key)) {

Copied: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core/env/EnvironmentModifierBlock.java (from rev 797, trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/EnvironmentVariableBlock.java)
===================================================================
--- trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core/env/EnvironmentModifierBlock.java	                        (rev 0)
+++ trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core/env/EnvironmentModifierBlock.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -0,0 +1,174 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+
+package org.maemo.esbox.internal.api.core.env;
+
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
+import org.maemo.esbox.core.env.IEnvironmentOperation;
+
+import java.util.*;
+
+
+/**
+ * Standard implementation.
+ * @author eswartz
+ *
+ */
+public class EnvironmentModifierBlock implements IEnvironmentModifierBlock {
+
+	private Map<String, IEnvironmentOperation> map;
+	
+	public EnvironmentModifierBlock() {
+		map = new LinkedHashMap<String, IEnvironmentOperation>();
+	}
+	
+	/* (non-Javadoc)
+	 * @see java.lang.Object#hashCode()
+	 */
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((map == null) ? 0 : map.hashCode());
+		return result;
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.Object#equals(java.lang.Object)
+	 */
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		EnvironmentModifierBlock other = (EnvironmentModifierBlock) obj;
+		if (map == null) {
+			if (other.map != null)
+				return false;
+		} else if (!map.equals(other.map))
+			return false;
+		return true;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.maemo.esbox.core.env.IEnvironmentVariableBlock#define(java.lang.String, java.lang.String)
+	 */
+	public IEnvironmentOperation define(String name, String value) {
+		IEnvironmentOperation var = new EnvironmentOperation(name, value);
+		synchronized (map) {
+			map.put(name, var);
+		}
+		return var;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.maemo.esbox.core.env.IEnvironmentVariableBlock#getVariable(java.lang.String)
+	 */
+	public IEnvironmentOperation findOperation(String name) {
+		synchronized (map) {
+			return map.get(name);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.maemo.esbox.core.env.IEnvironmentVariableBlock#getVariables()
+	 */
+	public IEnvironmentOperation[] getOperations() {
+		synchronized (map) {
+			return (IEnvironmentOperation[]) map.values().toArray(new IEnvironmentOperation[map.values().size()]);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.maemo.esbox.core.env.IEnvironmentVariableBlock#undefine(java.lang.String)
+	 */
+	public IEnvironmentOperation undefine(String name) {
+		IEnvironmentOperation var = new EnvironmentOperation(name, null);
+		synchronized (map) {
+			map.put(name, var);
+		}
+		return var;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.maemo.esbox.core.env.IEnvironmentVariableBlock#clear()
+	 */
+	public void clear() {
+		synchronized (map) {
+			map.clear();
+		}
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.maemo.esbox.core.env.IEnvironmentVariableBlock#remove(org.maemo.esbox.core.env.IEnvironmentVariable)
+	 */
+	public void remove(IEnvironmentOperation var) {
+		synchronized (map) {
+			map.remove(var.getName());
+		}
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.maemo.esbox.core.env.IEnvironmentModifierBlock#remove(java.lang.String)
+	 */
+	public void remove(String name) {
+		synchronized (map) {
+			map.remove(name);
+		}
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.maemo.esbox.core.env.IEnvironmentModifierBlock#copy()
+	 */
+	public IEnvironmentModifierBlock copy() {
+		IEnvironmentModifierBlock destination = new EnvironmentModifierBlock();
+		for (IEnvironmentOperation variable : map.values()) {
+			if (variable.getValue() != null)
+				destination.define(variable.getName(), variable.getValue());
+			else
+				destination.undefine(variable.getName());
+		}
+		return destination;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.maemo.esbox.core.env.IEnvironmentModifierBlock#apply(org.maemo.esbox.core.env.IEnvironmentOperation)
+	 */
+	public void apply(IEnvironmentOperation operation) {
+		synchronized (map) {
+			map.put(operation.getName(), operation);
+		}
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.maemo.esbox.core.env.IEnvironmentModifierBlock#apply(org.maemo.esbox.core.env.IEnvironmentModifierBlock)
+	 */
+	public void apply(IEnvironmentModifierBlock block) {
+		for (IEnvironmentOperation operation : block.getOperations()) {
+			apply(operation);
+		}
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.maemo.esbox.core.env.IEnvironmentModifierBlock#applyTo(java.util.Properties)
+	 */
+	public void applyTo(Properties env) {
+		for (IEnvironmentOperation operation : getOperations()) {
+			if (operation.getValue() == null)
+				env.remove(operation.getName());
+			else
+				env.put(operation.getName(), operation.getValue());
+		}
+	}
+}


Property changes on: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core/env/EnvironmentModifierBlock.java
___________________________________________________________________
Name: svn:mergeinfo
   + 

Copied: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core/env/EnvironmentOperation.java (from rev 797, trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/EnvironmentVariable.java)
===================================================================
--- trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core/env/EnvironmentOperation.java	                        (rev 0)
+++ trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core/env/EnvironmentOperation.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+
+package org.maemo.esbox.internal.api.core.env;
+
+import org.maemo.esbox.core.env.IEnvironmentOperation;
+
+/**
+ * Standard implementation.
+ * @author eswartz
+ *
+ */
+public class EnvironmentOperation implements IEnvironmentOperation {
+
+	private final String name;
+	private String value;
+
+	/**
+	 * @param name
+	 * @param value
+	 */
+	public EnvironmentOperation(String name, String value) {
+		this.name = name;
+		this.value = value;
+	}
+
+	
+	/* (non-Javadoc)
+	 * @see java.lang.Object#hashCode()
+	 */
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((name == null) ? 0 : name.hashCode());
+		result = prime * result + ((value == null) ? 0 : value.hashCode());
+		return result;
+	}
+
+
+	/* (non-Javadoc)
+	 * @see java.lang.Object#equals(java.lang.Object)
+	 */
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		EnvironmentOperation other = (EnvironmentOperation) obj;
+		if (name == null) {
+			if (other.name != null)
+				return false;
+		} else if (!name.equals(other.name))
+			return false;
+		if (value == null) {
+			if (other.value != null)
+				return false;
+		} else if (!value.equals(other.value))
+			return false;
+		return true;
+	}
+
+
+	/* (non-Javadoc)
+	 * @see org.maemo.esbox.core.env.IEnvironmentVariable#getName()
+	 */
+	public String getName() {
+		return name;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.maemo.esbox.core.env.IEnvironmentVariable#getValue()
+	 */
+	public String getValue() {
+		return value;
+	}
+
+	public void setValue(String value) {
+		this.value = value;
+	}
+}


Property changes on: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core/env/EnvironmentOperation.java
___________________________________________________________________
Name: svn:mergeinfo
   + 

Copied: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core/env/EnvironmentXMLStorage.java (from rev 797, trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/core/env/EnvironmentXMLStorage.java)
===================================================================
--- trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core/env/EnvironmentXMLStorage.java	                        (rev 0)
+++ trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core/env/EnvironmentXMLStorage.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -0,0 +1,156 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+
+package org.maemo.esbox.internal.api.core.env;
+
+import org.eclipse.core.filesystem.URIUtil;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.maemo.esbox.core.HostUtils;
+import org.maemo.esbox.core.env.IEnvironmentOperation;
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
+import org.maemo.esbox.core.xml.EFSXMLFileStorage;
+import org.maemo.esbox.core.xml.XMLUtils;
+import org.maemo.esbox.internal.core.Activator;
+import org.w3c.dom.Element;
+
+import java.net.URI;
+
+/**
+ * Storage for the environment block.
+ * @author eswartz
+ *
+ */
+public class EnvironmentXMLStorage extends EFSXMLFileStorage {
+
+	private static final String ENVIRONMENT = "environment";
+	private static final String VARIABLE = "variable";
+	private static final String NAME = "name";
+	private static final String UNDEFINE = "undefine";
+	private static final String CATEGORY = "category";
+
+	public EnvironmentXMLStorage() {
+		super(URIUtil.toURI(getEnvironmentPath()));
+	}
+
+	public EnvironmentXMLStorage(URI uri) {
+		super(uri);
+	}
+
+	protected static IPath getEnvironmentPath() {
+		Activator plugin = Activator.getDefault();
+		IPath storePath;
+		if (plugin != null)
+			storePath = plugin.getStateLocation().append(".environment");
+		else
+			storePath = HostUtils.getTemporaryPath().append(".environment");
+		return storePath;
+	}
+
+	/**
+	 * Reload the document and initialize the root.
+	 */
+	public void load() throws CoreException {
+		load(ENVIRONMENT);
+	}
+
+	/**
+	 * Find or create the element storing variables in a category.
+	 * @param category name of category or <code>null</code> for global
+	 * @return Element
+	 */
+	private Element getCategoryElement(String category) {
+		Element element = getDocumentElement();
+		if (category == null) {
+			return element;
+		}
+		
+		Element[] categories = XMLUtils.getChildElementsNamed(element, CATEGORY);
+		for (Element categoryElement : categories) {
+			if (category.equals(categoryElement.getAttribute(NAME))) {
+				return categoryElement;
+			}
+		}
+		
+		Element categoryElement = getDocument().createElement(CATEGORY);
+		element.appendChild(categoryElement);
+		categoryElement.setAttribute(NAME, category);
+		return categoryElement;
+	}
+
+	/**
+	 * Read environment variables from the given category
+	 * @param envBlock
+	 * @param category or <code>null</code> for globals
+	 * @return boolean true if the block is defined, false otherwise
+	 */
+	public boolean readEnvironmentModifierBlock(
+			IEnvironmentModifierBlock envBlock, String category) {
+		envBlock.clear();
+
+		// create the category element
+		Element element = getCategoryElement(category);
+		if (element == null)
+			return false;
+		
+		Element[] vars = XMLUtils.getChildElementsNamed(element, VARIABLE);
+		for (Element var : vars) {
+			String name = var.getAttribute(NAME);
+			if ("true".equals(var.getAttribute(UNDEFINE))) {
+				envBlock.define(name, null);
+			} else {
+				String value = XMLUtils.getText(var);
+				if (value == null) value = "";
+				envBlock.define(var.getAttribute(NAME), value);
+			}
+		}
+		return true;
+	}
+	
+	/**
+	 * Save an environment block to the given category
+	 * @param envBlock
+	 * @param category name of category or <code>null</code> for globals
+	 */
+	public void writeEnvironmentModifierBlock(IEnvironmentModifierBlock envBlock, 
+			String category) {
+		Element element = getCategoryElement(category);
+		
+		// clear out existing elements
+		Element[] vars = XMLUtils.getChildElementsNamed(element, VARIABLE);
+		for (Element var : vars) {
+			element.removeChild(var);
+		}
+		
+		// add variables
+		for (IEnvironmentOperation variable : envBlock.getOperations()) {
+			Element var = getDocument().createElement(VARIABLE);
+			var.setAttribute(NAME, variable.getName());
+		
+			if (variable.getValue() == null) 
+				var.setAttribute(UNDEFINE, "true");
+			else
+				XMLUtils.setText(var, variable.getValue());
+			
+			element.appendChild(var);
+		}
+	}
+
+	/**
+	 * Clear the document and create the &lt;environment&gt; node.
+	 */
+	public void create() throws CoreException {
+		create(ENVIRONMENT);
+	}
+
+
+	
+}


Property changes on: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core/env/EnvironmentXMLStorage.java
___________________________________________________________________
Name: svn:mergeinfo
   + 

Modified: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core/machine/HostMachineBackend.java
===================================================================
--- trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core/machine/HostMachineBackend.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core/machine/HostMachineBackend.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -13,9 +13,11 @@
 
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.Path;
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
+import org.maemo.esbox.core.env.IEnvironmentOperation;
 import org.maemo.esbox.core.machine.*;
-import org.maemo.esbox.core.process.HostProcessLauncherFactory;
-import org.maemo.esbox.core.process.IProcessLauncherFactory;
+import org.maemo.esbox.core.process.*;
+import org.maemo.esbox.internal.api.core.IStandardEnvironmentProvider;
 
 import java.net.URI;
 import java.util.*;
@@ -97,15 +99,17 @@
 	 * @see org.maemo.esbox.core.machine.IMachine#createProcess(org.eclipse.core.runtime.IPath, java.util.List, java.util.Properties, org.eclipse.cdt.utils.pty.PTY)
 	 */
 	public Process createProcess(IPath workingDirectory,
-			List<String> commandLine, Properties environment, boolean usePty)
+			List<String> commandLine, IEnvironmentModifierBlock environmentModifierBlock, boolean usePty)
 			throws Exception {
 		Process process;
 		
 		ProcessBuilder builder = new ProcessBuilder(commandLine);
-		if (environment != null) {
-			builder.environment().clear();
-			for (Map.Entry<Object, Object> entry : environment.entrySet()) {
-				builder.environment().put(entry.getKey().toString(), entry.getValue().toString());
+		if (environmentModifierBlock != null) {
+			for (IEnvironmentOperation operation : environmentModifierBlock.getOperations()) {
+				if (operation.getValue() == null)
+					builder.environment().remove(operation.getName());
+				else
+					builder.environment().put(operation.getName(), operation.getValue());
 			}
 		}
 		if (workingDirectory != null) {
@@ -120,8 +124,14 @@
 	/* (non-Javadoc)
 	 * @see org.maemo.esbox.core.machine.IMachine#getStandardEnvironment()
 	 */
-	public Map<String, String> getStandardEnvironment() {
-		return System.getenv();
+	public Properties getStandardEnvironment() {
+		return getStandardEnvironmentProvider().getRawEnvironment();
 	}
 
+	/* (non-Javadoc)
+	 * @see org.maemo.esbox.core.machine.IMachine#getStandardEnvironmentProvider()
+	 */
+	public IStandardEnvironmentProvider getStandardEnvironmentProvider() {
+		return new StandardHostEnvironmentProvider();
+	}
 }

Modified: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core/machine/HostUnixMachine.java
===================================================================
--- trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core/machine/HostUnixMachine.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core/machine/HostUnixMachine.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -29,6 +29,14 @@
 		super(Platform.getOS(), new AlwaysOnMachineController());
 	}
 
+
+	/**
+	 * 
+	 */
+	public HostUnixMachine(String os) {
+		super(os, new AlwaysOnMachineController());
+	}
+
 	/* (non-Javadoc)
 	 * @see org.maemo.esbox.core.machine.IBuildMachine#canBuildFor(java.lang.String)
 	 */

Modified: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core/machine/HostWindowsMachine.java
===================================================================
--- trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core/machine/HostWindowsMachine.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core/machine/HostWindowsMachine.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -21,16 +21,15 @@
 public class HostWindowsMachine extends HostMachineBackend implements
 		IMachineImpl {
 
-	/**
-	 * @param id
-	 * @param name
-	 * @param os
-	 * @param machineController
-	 */
+	
 	public HostWindowsMachine() {
 		super(Platform.OS_WIN32, new AlwaysOnMachineController());
 	}
 
+	public HostWindowsMachine(String os) {
+		super(os, new AlwaysOnMachineController());
+	}
+
 	/* (non-Javadoc)
 	 * @see org.maemo.esbox.core.machine.IMachineBackend#getProcessLister()
 	 */

Modified: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core/machine/IMachineImpl.java
===================================================================
--- trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core/machine/IMachineImpl.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core/machine/IMachineImpl.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -11,14 +11,16 @@
 
 package org.maemo.esbox.internal.api.core.machine;
 
-import org.maemo.esbox.core.machine.IMachine;
-import org.maemo.esbox.core.machine.IMachineController;
+import org.maemo.esbox.core.machine.*;
 
 /**
+ * The implementation side of an IMachine, usually hidden from clients, who should
+ * use {@link MachineManager} instead.
  * @author eswartz
  *
  */
 public interface IMachineImpl extends IMachine {
 	
+	/** Get the controller managing the state of the machine. */
 	IMachineController getMachineController();
 }

Modified: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core/machine/Machine.java
===================================================================
--- trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core/machine/Machine.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/api/core/machine/Machine.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -63,5 +63,4 @@
 	public String getName() {
 		return name;
 	}
-
 }

Modified: trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/core/Activator.java
===================================================================
--- trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/core/Activator.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.core/src/org/maemo/esbox/internal/core/Activator.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -17,7 +17,6 @@
 import org.eclipse.ui.console.ConsolePlugin;
 import org.eclipse.ui.plugin.AbstractUIPlugin;
 import org.maemo.esbox.core.*;
-import org.maemo.esbox.core.env.EnvironmentVariableManager;
 import org.maemo.esbox.core.sdk.ISDKTarget;
 import org.osgi.framework.BundleContext;
 
@@ -53,8 +52,10 @@
 		super.start(context);
 		plugin = this;
 		CorePlugin.getDefault().setContext(context);
-		// initialize common environment early 
-		EnvironmentVariableManager.getInstance().startup();
+		
+		// ensure pref defaults are loaded and active, in case IPreferenceStore 
+		// for any plugin is referenced before the IPreferenceProvider.
+		CorePreferenceManager.getInstance();
 	}
 	
 	/*

Modified: trunk/common/org.maemo.esbox.core.tests/src/org/maemo/esbox/core/tests/TestUtils.java
===================================================================
--- trunk/common/org.maemo.esbox.core.tests/src/org/maemo/esbox/core/tests/TestUtils.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.core.tests/src/org/maemo/esbox/core/tests/TestUtils.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -72,7 +72,7 @@
 		cmdLine.add("-d");
 		cmdLine.add(targetPath);
 		
-		IProcessLauncher processLauncher = processLauncherFactory.createProcessLaunchHandler(
+		IProcessLauncher processLauncher = processLauncherFactory.createProcessLauncher(
 				null, // workingDir
 				cmdLine,
 				null // env

Modified: trunk/common/org.maemo.esbox.core.tests/src/org/maemo/esbox/core/tests/core/TestEnvironmentProperties.java
===================================================================
--- trunk/common/org.maemo.esbox.core.tests/src/org/maemo/esbox/core/tests/core/TestEnvironmentProperties.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.core.tests/src/org/maemo/esbox/core/tests/core/TestEnvironmentProperties.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -135,4 +135,40 @@
 		assertTrue(envp.get(1).equals("FOO"));
 	}
 
+	@Test
+	public void testFromShellDump() throws Exception {
+		String text =  "FOO='my '\"'\"'dad'\"'\"\n" + 
+				"HISTCONTROL='ignoreboth'\n" + 
+				"HOME='/home/devel'\n" + 
+				"HUSHLOGIN='FALSE'\n" + 
+				"IFS=' \t\n'\n" + 
+				"LANG='en_US.UTF-8'\n" + 
+				"LESSCLOSE='/usr/bin/lesspipe %s %s'\n" + 
+				"LESSOPEN='| /usr/bin/lesspipe %s'\n" + 
+				"LOGNAME='devel'\n" + 
+				"LS_COLORS='no=00:fi=00:di=01;34:ln=01;36:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.bz2=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.avi=01;35:*.fli=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.flac=01;35:*.mp3=01;35:*.mpc=01;35:*.ogg=01;35:*.wav=01;35:'\n" + 
+				"MAIL='/var/mail/devel'\n" + 
+				"OPTIND='1'\n" + 
+				"PATH='/scratchbox:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games'\n" + 
+				"PPID='9523'\n" + 
+				"PS1='$ '\n" + 
+				"PS2='> '\n" + 
+				"PS4='+ '\n" + 
+				"PWD='/home/devel'\n" + 
+				"SHELL='/bin/bash'\n" + 
+				"SHLVL='1'\n" + 
+				"TERM='linux'\n" + 
+				"USER='devel'\n" + 
+				"_='/bin/sh'\n" + 
+				"";
+		Properties env = EnvironmentProperties.createFromShellEnvDump(text);
+		
+		assertEquals("/bin/bash", env.get("SHELL"));
+		assertEquals("/home/devel", env.get("PWD"));
+		assertEquals("> ", env.get("PS2"));
+		assertEquals(" \t\n", env.get("IFS"));
+		assertEquals("my 'dad'", env.get("FOO"));
+		assertEquals("no=00:fi=00:di=01;34:ln=01;36:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.bz2=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.avi=01;35:*.fli=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.flac=01;35:*.mp3=01;35:*.mpc=01;35:*.ogg=01;35:*.wav=01;35:",
+				env.get("LS_COLORS"));
+	}
 }

Modified: trunk/common/org.maemo.esbox.core.tests/src/org/maemo/esbox/core/tests/core/TestEnvironmentVariables.java
===================================================================
--- trunk/common/org.maemo.esbox.core.tests/src/org/maemo/esbox/core/tests/core/TestEnvironmentVariables.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.core.tests/src/org/maemo/esbox/core/tests/core/TestEnvironmentVariables.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -13,56 +13,209 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
 
 import org.junit.Test;
 import org.maemo.esbox.core.env.*;
 
 /**
- * Test the environment manager and implementations
+ * Test the environment manager, operations, and implementations
  * @author eswartz
  *
  */
 public class TestEnvironmentVariables {
 	
-	private EnvironmentVariableManager manager = EnvironmentVariableManager.getInstance();
+	private IEnvironmentManager manager = EnvironmentManager.getInstance();
+	private IVariableProvider nullVariableProvider;
+	private IEnvironmentModifierBlock hostBlock;
+	private IEnvironmentModifierBlock deviceBlock;
+	private IEnvironmentModifierBlock globalBlock;
 	
 	@Test
-	public void testBasic() throws Exception {
-		manager.startup();
-		assertNotNull(manager.getGlobalEnvironmentBlock());
-		assertTrue(manager.getGlobalEnvironmentBlock().getVariables().length > 0);
+	public void testGlobal() throws Exception {
+		assertNotNull(manager.getGlobalEnvironmentModifierBlock());
 	}
 	
 	@Test
-	public void testExpand() throws Exception {
-		IEnvironmentVariableBlock block = new EnvironmentVariableBlock();
-		manager.getGlobalEnvironmentBlock().copyTo(block);
-		IEnvironmentVariable var = block.getVariable("HOST$DISPLAY");
+	public void testExpansion() throws Exception {
+		IEnvironmentModifierBlock block = manager.createEnvironmentModifierBlock();
+		IEnvironmentOperation var = block.define("DISPLAY", ":2");
 		assertNotNull(var);
 		String val = var.getValue();
-		if (val == null) {
-			var = new EnvironmentVariable("HOST$DISPLAY", ":2");
-		}
-		String exp = block.expand(var, manager.getStandardVariableProvider());
-		assertEquals(exp, block.expandString(val, manager.getStandardVariableProvider()));
+		assertEquals(":2", val);
+		assertEquals(":2", manager.expandString(block, val, nullVariableProvider));
 		
 		// test recursive expansion
 		block.define("EXTRA", "123");
 		block.define("BAZZ", "--${EXTRA}--");
 		
-		exp = block.expandString("My ${BAZZ} stuff", manager.getStandardVariableProvider());
+		String exp = manager.expandString(block, "My ${BAZZ} stuff", nullVariableProvider);
 		assertEquals("My --123-- stuff", exp);
 		
-		// null values
+		// env overrides provider
+		IVariableProvider myVariableProvider = new IVariableProvider() {
+
+			public Object getValue(String var) {
+				if ("BAZZ".equals(var))
+					return "baz!";
+				if ("VAL".equals(var))
+					return "val!";
+				return null;
+			}
+			
+		};
+		exp = manager.expandString(block, "My ${BAZZ} stuff", myVariableProvider);
+		assertEquals("My --123-- stuff", exp);
+		
+		// deleted values 1
 		block.define("VAL", null);
-		exp = block.expandString("12${VAL}34", manager.getStandardVariableProvider());
+		exp = manager.expandString(block, "12${VAL}34", nullVariableProvider);
 		assertEquals("1234", exp);
 		
+		// deleted replaced values
+		exp = manager.expandString(block, "12${VAL}34", myVariableProvider);
+		assertEquals("12val!34", exp);
+
+		// deleted values
+		block.define("VAL", "something");
+		block.undefine("VAL");
+		exp = manager.expandString(block, "12${VAL}34", nullVariableProvider);
+		assertEquals("1234", exp);
+		exp = manager.expandString(block, "12${VAL}34", myVariableProvider);
+		assertEquals("12val!34", exp);
+
 		// non infinite!
 		block.define("VAL", "2");
 		block.define("EXTRA", "${EXTRA}${EXTRA} ${VAL}...");
-		exp = block.expandString("${EXTRA}...", manager.getStandardVariableProvider());
+		exp = manager.expandString(block, "${EXTRA}...", nullVariableProvider);
 		assertEquals("${EXTRA}${EXTRA} 2......", exp);
 	}
+	
+	
+	
+	/**
+	 * 
+	 */
+	private void defineTestBlocks() {
+		
+		globalBlock = manager.getGlobalEnvironmentModifierBlock();
+		
+		hostBlock = manager.createEnvironmentModifierBlock();
+		
+		deviceBlock = manager.createEnvironmentModifierBlock();
+		
+		globalBlock.define("SHARED", "shared");
+		hostBlock.define("Host1", "host1");
+		deviceBlock.define("Device1", "device1");		
+	}
+
+	@Test
+	public void testAppliedBlocks() throws Exception {
+		defineTestBlocks();
+		
+		IEnvironmentModifierBlock block = globalBlock.copy();
+		block.apply(hostBlock);
+			
+		IEnvironmentOperation[] ops = block.getOperations();
+		assertEquals(2, ops.length);
+		if (!("Host1".equals(ops[0].getName()) || "SHARED".equals(ops[1].getName()))
+			&& !("Host1".equals(ops[1].getName()) || "SHARED".equals(ops[0].getName()))) {
+			fail("Did not get expected host variables");
+		}
+		
+		block = globalBlock.copy();
+		block.apply(deviceBlock);
+		
+		ops = block.getOperations();
+		assertEquals(2, ops.length);
+		if (!("Device1".equals(ops[0].getName()) || "SHARED".equals(ops[1].getName()))
+				&& !("Device1".equals(ops[1].getName()) || "SHARED".equals(ops[0].getName()))) {
+			fail("Did not get expected device variables");
+		}
+		
+		////////
+		
+		// host value overrides global
+		hostBlock.define("SHARED", "host-shared");
+		
+		block = globalBlock.copy();
+		block.apply(hostBlock);
+		
+		ops = block.getOperations();
+		assertEquals(2, ops.length);
+		if (!("Host1".equals(ops[0].getName()) || "SHARED".equals(ops[1].getName()))
+				&& !("Host1".equals(ops[1].getName()) || "SHARED".equals(ops[0].getName()))) {
+			fail("Did not get expected host variables");
+		}
+		assertEquals("host-shared", block.findOperation("SHARED").getValue());
+		
+		///////
+
+		// the host deletes it, it trumps the global
+		hostBlock.undefine("SHARED");
+		
+		block = globalBlock.copy();
+		block.apply(hostBlock);
+		
+		ops = block.getOperations();
+		assertEquals(2, ops.length);
+		if (!("Host1".equals(ops[0].getName()) || "SHARED".equals(ops[1].getName()))
+				&& !("Host1".equals(ops[1].getName()) || "SHARED".equals(ops[0].getName()))) {
+			fail("Did not get expected host variables");
+		}
+		assertNull(block.findOperation("SHARED").getValue());
+		
+		///////
+
+		// if the host doesn't define or undefine it, the global does
+		hostBlock.remove("SHARED");
+		
+		block = globalBlock.copy();
+		block.apply(hostBlock);
+		
+		ops = block.getOperations();
+		assertEquals(2, ops.length);
+		if (!("Host1".equals(ops[0].getName()) || "SHARED".equals(ops[1].getName()))
+				&& !("Host1".equals(ops[1].getName()) || "SHARED".equals(ops[0].getName()))) {
+			fail("Did not get expected host variables");
+		}
+		assertEquals("shared", block.findOperation("SHARED").getValue());
+
+		////////
+		
+		// if no one defines it, it's not exposed at all
+		globalBlock.remove("SHARED");
+		
+		block = globalBlock.copy();
+		block.apply(hostBlock);
+		
+		ops = block.getOperations();
+		assertEquals(1, ops.length);
+		assertEquals("Host1", ops[0].getName());
+		assertEquals("host1", ops[0].getValue());
+	}
+	
+	@Test
+	public void testStorage() throws Exception {
+		defineTestBlocks();
+		
+		globalBlock.define("FOO", "bar");
+		
+		manager.save();
+		
+		///
+		
+		// make some changes
+		globalBlock.define("DELETEME", "");
+		
+		// restore the changes
+		manager.load();
+
+		// be sure they are stored distinctly and correctly
+		assertEquals("bar", globalBlock.findOperation("FOO").getValue());
+		
+		assertNull(globalBlock.findOperation("DELETEME"));
+	}
+	
 }

Modified: trunk/common/org.maemo.esbox.core.tests/src/org/maemo/esbox/core/tests/core/TestPreferenceManager.java
===================================================================
--- trunk/common/org.maemo.esbox.core.tests/src/org/maemo/esbox/core/tests/core/TestPreferenceManager.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.core.tests/src/org/maemo/esbox/core/tests/core/TestPreferenceManager.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -282,8 +282,7 @@
 		 * @see org.maemo.esbox.core.IPreferenceMigrator#convertExistingPreferences(org.eclipse.jface.preference.IPreferenceStore, int, int, java.util.Properties, java.util.Properties)
 		 */
 		public void convertExistingPreferences(IPreferenceStore preferences,
-				int oldMajor, int oldMinor, Properties existingSettings,
-				Properties newPropertyDefaults) {
+				int oldMajor, Properties existingSettings, Properties newPropertyDefaults) {
 			
 		}
 		
@@ -301,8 +300,7 @@
 		 * @see org.maemo.esbox.core.IPreferenceMigrator#convertExistingPreferences(org.eclipse.jface.preference.IPreferenceStore, int, int, java.util.Properties, java.util.Properties)
 		 */
 		public void convertExistingPreferences(IPreferenceStore preferences,
-				int oldMajor, int oldMinor, Properties existingSettings,
-				Properties newPropertyDefaults) {
+				int oldMajor, Properties existingSettings, Properties newPropertyDefaults) {
 			if (oldMajor < 1) {
 				existingSettings.put("MOOKIE", "123");
 			}
@@ -366,8 +364,7 @@
 		 * @see org.maemo.esbox.core.IPreferenceMigrator#convertExistingPreferences(org.eclipse.jface.preference.IPreferenceStore, int, int, java.util.Properties, java.util.Properties)
 		 */
 		public void convertExistingPreferences(IPreferenceStore preferences,
-				int oldMajor, int oldMinor, Properties existingSettings,
-				Properties newPropertyDefaults) {
+				int oldMajor, Properties existingSettings, Properties newPropertyDefaults) {
 			
 		}
 	}

Added: trunk/common/org.maemo.esbox.core.tests/src/org/maemo/esbox/core/tests/core/TestProcessLauncherUtils.java
===================================================================
--- trunk/common/org.maemo.esbox.core.tests/src/org/maemo/esbox/core/tests/core/TestProcessLauncherUtils.java	                        (rev 0)
+++ trunk/common/org.maemo.esbox.core.tests/src/org/maemo/esbox/core/tests/core/TestProcessLauncherUtils.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -0,0 +1,167 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+
+package org.maemo.esbox.core.tests.core;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+
+import org.eclipse.core.runtime.Platform;
+import org.junit.Test;
+import org.maemo.esbox.core.env.EnvironmentManager;
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
+import org.maemo.esbox.core.machine.IMachine;
+import org.maemo.esbox.core.process.ProcessLauncherUtils;
+import org.maemo.esbox.internal.api.core.machine.HostUnixMachine;
+import org.maemo.esbox.internal.api.core.machine.HostWindowsMachine;
+
+import java.util.Properties;
+
+/**
+ * Test the environment manager, operations, and implementations
+ * @author eswartz
+ *
+ */
+public class TestProcessLauncherUtils {
+	
+	@Test
+	public void testAddToPATHUnix() throws Exception {
+		IMachine unixMachine = new HostUnixMachine(Platform.OS_LINUX);
+		String newPath = ProcessLauncherUtils.addToPATH(
+				unixMachine,
+				"/scratchbox/tools/bin",
+				true,
+				"/usr/bin:/bin:/sbin");
+		assertEquals("/scratchbox/tools/bin:/usr/bin:/bin:/sbin", newPath);
+
+		newPath = ProcessLauncherUtils.addToPATH(
+				unixMachine,
+				"/scratchbox/tools/bin",
+				false,
+				"/usr/bin:/bin:/sbin");
+		assertEquals("/usr/bin:/bin:/sbin:/scratchbox/tools/bin", newPath);
+
+		newPath = ProcessLauncherUtils.addToPATH(
+				unixMachine,
+				"/scratchbox/tools/bin",
+				true,
+				"/usr/bin:/scratchbox/tools/bin:/bin:/sbin");
+		assertNull(newPath);
+		
+		newPath = ProcessLauncherUtils.addToPATH(
+				unixMachine,
+				"/scratchbox/tools/bin",
+				true,
+				null);
+		assertEquals("/scratchbox/tools/bin", newPath);
+
+	}
+	
+	/** Test the interaction with Properties and IEnvironmentModifierBlock */
+	@Test
+	public void testAddToPATHEnvBlock() throws Exception {
+		IMachine unixMachine = new HostUnixMachine(Platform.OS_LINUX);
+		Properties env = new Properties();
+		env.put("FOO", "bar");
+		env.put("PATH", "/usr/bin:/bin:/sbin");
+		
+		IEnvironmentModifierBlock envBlock = ProcessLauncherUtils.addToPATH(
+				unixMachine,
+				env,
+				null,
+				"/scratchbox/tools/bin",
+				true);
+		assertNotNull(envBlock);
+		assertEquals("/scratchbox/tools/bin:/usr/bin:/bin:/sbin", envBlock.findOperation("PATH").getValue());
+		
+		// don't modify env
+		assertEquals("bar", env.get("FOO"));
+		assertEquals("/usr/bin:/bin:/sbin", env.get("PATH"));
+		
+		///////////
+		
+		IEnvironmentModifierBlock envChanges = EnvironmentManager.getInstance().createEnvironmentModifierBlock();
+		envChanges.define("PATH", "/tmp");
+		envChanges.define("FOO", null);
+		
+		envBlock = ProcessLauncherUtils.addToPATH(
+				unixMachine,
+				env,
+				envChanges,
+				"/scratchbox/tools/bin",
+				true);
+		assertNotNull(envBlock);
+		assertSame(envBlock, envChanges);
+		assertEquals("/scratchbox/tools/bin:/tmp", envBlock.findOperation("PATH").getValue());
+		// don't remove other ops
+		assertNull(envBlock.findOperation("FOO").getValue());
+		
+		// don't modify env
+		assertEquals("bar", env.get("FOO"));
+		assertEquals("/usr/bin:/bin:/sbin", env.get("PATH"));
+
+		/////////////
+		
+		envChanges = EnvironmentManager.getInstance().createEnvironmentModifierBlock();
+		envChanges.define("PATH", "/tmp");
+		envChanges.define("FOO", null);
+
+		envBlock = ProcessLauncherUtils.addToPATH(
+				unixMachine,
+				null,
+				envChanges,
+				"/scratchbox/tools/bin",
+				true);
+		assertNotNull(envBlock);
+		assertSame(envBlock, envChanges);
+		assertEquals("/scratchbox/tools/bin:/tmp", envBlock.findOperation("PATH").getValue());
+		// don't remove other ops
+		assertNull(envBlock.findOperation("FOO").getValue());
+
+	}
+	
+	
+	@Test
+	public void testAddToPATHWindows() throws Exception {
+		IMachine win32Machine = new HostWindowsMachine(Platform.OS_WIN32);
+		String newPath = ProcessLauncherUtils.addToPATH(
+				win32Machine,
+				"c:/cygwin/bin",
+				true,
+				"c:\\winnt;c:\\winnt\\system32");
+		assertEquals("c:/cygwin/bin;c:\\winnt;c:\\winnt\\system32", newPath);
+
+		newPath = ProcessLauncherUtils.addToPATH(
+				win32Machine,
+				"c:\\cygwin\\bin",
+				false,
+				"c:\\winnt;c:\\winnt\\system32");
+		assertEquals("c:\\winnt;c:\\winnt\\system32;c:\\cygwin\\bin", newPath);
+
+		newPath = ProcessLauncherUtils.addToPATH(
+				win32Machine,
+				"c:\\cygwin\\bin",
+				true,
+				"c:\\winnt;c:\\cygwin\\bin;c:\\winnt\\system32");
+		assertNull(newPath);
+
+		newPath = ProcessLauncherUtils.addToPATH(
+				win32Machine,
+				"c:\\cygwin\\bin",
+				false,
+				null);
+		assertEquals("c:\\cygwin\\bin", newPath);
+
+	}
+
+}

Modified: trunk/common/org.maemo.esbox.core.tests/src/org/maemo/esbox/core/tests/core/TestXMLStorage.java
===================================================================
--- trunk/common/org.maemo.esbox.core.tests/src/org/maemo/esbox/core/tests/core/TestXMLStorage.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.core.tests/src/org/maemo/esbox/core/tests/core/TestXMLStorage.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -26,6 +26,8 @@
 import org.maemo.esbox.core.env.*;
 import org.maemo.esbox.core.xml.EFSXMLFileStorage;
 import org.maemo.esbox.core.xml.XMLUtils;
+import org.maemo.esbox.internal.api.core.env.EnvironmentModifierBlock;
+import org.maemo.esbox.internal.api.core.env.EnvironmentXMLStorage;
 import org.w3c.dom.Element;
 
 import java.net.URI;
@@ -146,25 +148,25 @@
 		}
 		storage.create();
 		
-		IEnvironmentVariableBlock block = new EnvironmentVariableBlock();
-		storage.readEnvironmentBlock(block, null);
-		IEnvironmentVariable[] vars = block.getVariables();
+		IEnvironmentModifierBlock block = new EnvironmentModifierBlock();
+		storage.readEnvironmentModifierBlock(block, null);
+		IEnvironmentOperation[] vars = block.getOperations();
 		assertEquals(0, vars.length);
 		
 		block.define("FOO", "bar");
 		block.define("BAR", null);
 		
-		storage.writeEnvironmentBlock(block, null);
+		storage.writeEnvironmentModifierBlock(block, null);
 		
-		IEnvironmentVariableBlock catblock = new EnvironmentVariableBlock();
-		storage.readEnvironmentBlock(block, "mycat");
-		IEnvironmentVariable[] catvars = catblock.getVariables();
+		IEnvironmentModifierBlock catblock = new EnvironmentModifierBlock();
+		storage.readEnvironmentModifierBlock(block, "mycat");
+		IEnvironmentOperation[] catvars = catblock.getOperations();
 		assertEquals(0, vars.length);
 		
 		catblock.define("SUB1", "bzzzzt");
 		catblock.define("SUB2", null);
 		
-		storage.writeEnvironmentBlock(catblock, "mycat");
+		storage.writeEnvironmentModifierBlock(catblock, "mycat");
 		
 		storage.save();
 		
@@ -185,18 +187,18 @@
 				
 		storage.load();
 		
-		block = new EnvironmentVariableBlock();
-		storage.readEnvironmentBlock(block, null);
-		vars = block.getVariables();
+		block = new EnvironmentModifierBlock();
+		storage.readEnvironmentModifierBlock(block, null);
+		vars = block.getOperations();
 		assertEquals(2, vars.length);	// don't get sub-nodes called 'variable'!
 		assertEquals("FOO",vars[0].getName());
 		assertEquals("bar", vars[0].getValue());
 		assertEquals("BAR", vars[1].getName());
 		assertEquals(null, vars[1].getValue());
 		
-		catblock = new EnvironmentVariableBlock();
-		storage.readEnvironmentBlock(catblock, "mycat");
-		catvars = catblock.getVariables();
+		catblock = new EnvironmentModifierBlock();
+		storage.readEnvironmentModifierBlock(catblock, "mycat");
+		catvars = catblock.getOperations();
 		assertEquals(2, catvars.length);
 		assertEquals("SUB1",catvars[0].getName());
 		assertEquals("bzzzzt", catvars[0].getValue());

Modified: trunk/common/org.maemo.esbox.launch/META-INF/MANIFEST.MF
===================================================================
--- trunk/common/org.maemo.esbox.launch/META-INF/MANIFEST.MF	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.launch/META-INF/MANIFEST.MF	2008-10-07 18:56:06 UTC (rev 837)
@@ -9,7 +9,8 @@
  org.eclipse.debug.ui;bundle-version="3.4.0",
  org.maemo.esbox.core;bundle-version="1.5.0",
  org.maemo.esbox.project.core;bundle-version="1.5.0",
- org.maemo.esbox.ui;bundle-version="1.5.0"
+ org.maemo.esbox.ui;bundle-version="1.5.0";visibility:=reexport,
+ org.eclipse.core.variables;bundle-version="3.2.100"
 Bundle-RequiredExecutionEnvironment: J2SE-1.5
 Bundle-ActivationPolicy: lazy
 Export-Package: org.maemo.esbox.launch,

Modified: trunk/common/org.maemo.esbox.launch/src/org/maemo/esbox/launch/ESboxLaunchUtils.java
===================================================================
--- trunk/common/org.maemo.esbox.launch/src/org/maemo/esbox/launch/ESboxLaunchUtils.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.launch/src/org/maemo/esbox/launch/ESboxLaunchUtils.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -27,10 +27,10 @@
 import org.eclipse.ui.console.*;
 import org.maemo.esbox.core.*;
 import org.maemo.esbox.core.adapters.IDefaultExecutionEnvironmentAdapter;
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
 import org.maemo.esbox.core.execEnv.IExecutionEnvironment;
 import org.maemo.esbox.core.machine.*;
-import org.maemo.esbox.core.process.EnvironmentProperties;
-import org.maemo.esbox.core.process.ProcessLauncherParameters;
+import org.maemo.esbox.core.process.*;
 import org.maemo.esbox.core.sdk.ISDKTarget;
 import org.maemo.esbox.internal.launch.Activator;
 import org.maemo.esbox.launch.adapters.IRunStandaloneAdapter;
@@ -55,6 +55,9 @@
 	private static final IStatus CANCEL_STATUS = Policy.getCancelStatus(Activator.getDefault());
 	static public final String sboxMappingsContainerName = "Scratchbox Path Mappings"; //$NON-NLS-1$
 	static public final int SSH_PORT = 22;
+	
+	/** this is the value of an environment variable intended for deletion */ 
+	private static final String DELETE_ENV_VAR_TOKEN = " <<delete>> ";
 
 	static public		int debugSessionCounter = 1;
 
@@ -529,29 +532,52 @@
 	}
 
 	/**
-	 * Get the environment from the launch configuration.
+	 * Get the environment modifier block for the configuration from the environment map
+	 * in the configuration.  This does not expand any variables or apply the Replace/Append
+	 * setting.
 	 * <p>
 	 * Note: this does not migrate old environment settings -- see ESboxCppLaunchUtils for that (with
 	 * C/C++ launch configs).
-	 * @return environment array[n] name=value
+	 * @param config
+	 * @return the modifier block, never <code>null</code>
 	 * @throws CoreException
 	 */
-	public static String[] getEnvironment(ILaunchConfiguration config) throws CoreException {
-		String[] array = DebugPlugin.getDefault().getLaunchManager().getEnvironment(config);
-		if (array == null) {
-			return new String[0];
+	public static IEnvironmentModifierBlock getEnvironmentModifierBlock(ILaunchConfiguration config) throws CoreException {
+		Map<String, String> envMap = config.getAttribute(ILaunchManager.ATTR_ENVIRONMENT_VARIABLES, (Map)null);
+		if (envMap == null) 
+			envMap = Collections.emptyMap();
+		
+		IEnvironmentModifierBlock envBlock = EnvironmentModifierUtils.createFromMap(envMap);
+		
+		// convert deletions back
+		for (Map.Entry<String, String> entry : envMap.entrySet()) {
+			if (DELETE_ENV_VAR_TOKEN.equals(entry.getValue()))
+				envBlock.undefine(entry.getKey());
 		}
-		return array;
+		
+		return envBlock;
 	}
 
 	/**
-	 * Get the environment settings from the launch configuration.
-	 * @param launchConfiguration
-	 * @return
+	 * Get the environment modifier block for the configuration from the environment map
+	 * in the configuration.  This does not expand any variables or apply the Replace/Append
+	 * setting.
+	 * <p>
+	 * Note: this does not migrate old environment settings -- see ESboxCppLaunchUtils for that (with
+	 * C/C++ launch configs).
+	 * @param config
+	 * @return the modifier block, never <code>null</code>
+	 * @throws CoreException
 	 */
-	public static Properties getEnvironmentAsProperty(
-			ILaunchConfiguration launchConfiguration) throws CoreException {
-		String[] envp = getEnvironment(launchConfiguration);
-		return EnvironmentProperties.createFromEnvp(envp);
+	public static void setEnvironmentModifierBlockToMap(ILaunchConfigurationWorkingCopy config, IEnvironmentModifierBlock envBlock) throws CoreException {
+		Map<String, String> envMap = EnvironmentModifierUtils.createMap(envBlock);
+		
+		// convert deletions back
+		for (Map.Entry<String, String> entry : envMap.entrySet()) {
+			if (entry.getValue() == null)
+				entry.setValue(DELETE_ENV_VAR_TOKEN);
+		}
+		
+		config.setAttribute(ILaunchManager.ATTR_ENVIRONMENT_VARIABLES, envMap);
 	}
 }

Modified: trunk/common/org.maemo.esbox.launch/src/org/maemo/esbox/launch/ILaunchProtocol.java
===================================================================
--- trunk/common/org.maemo.esbox.launch/src/org/maemo/esbox/launch/ILaunchProtocol.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.launch/src/org/maemo/esbox/launch/ILaunchProtocol.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -15,8 +15,7 @@
 import org.eclipse.ui.console.MessageConsole;
 import org.maemo.esbox.core.ESboxException;
 import org.maemo.esbox.core.machine.IMachine;
-import org.maemo.esbox.core.process.IProcessLauncher;
-import org.maemo.esbox.core.process.ProcessLauncherParameters;
+import org.maemo.esbox.core.process.*;
 
 import java.io.File;
 import java.util.*;
@@ -150,5 +149,4 @@
 	 * @throws CoreException 
 	 */
 	public void requireRunAsRoot() throws CoreException;
-
 }

Modified: trunk/common/org.maemo.esbox.launch/src/org/maemo/esbox/launch/LaunchConfigurationData.java
===================================================================
--- trunk/common/org.maemo.esbox.launch/src/org/maemo/esbox/launch/LaunchConfigurationData.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.launch/src/org/maemo/esbox/launch/LaunchConfigurationData.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -133,5 +133,4 @@
 		
 		return path.append(configFileName);
 	}
-
 }

Added: trunk/common/org.maemo.esbox.launch/src/org/maemo/esbox/launch/adapters/ITargetEnvironmentModifierAdapter.java
===================================================================
--- trunk/common/org.maemo.esbox.launch/src/org/maemo/esbox/launch/adapters/ITargetEnvironmentModifierAdapter.java	                        (rev 0)
+++ trunk/common/org.maemo.esbox.launch/src/org/maemo/esbox/launch/adapters/ITargetEnvironmentModifierAdapter.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+
+package org.maemo.esbox.launch.adapters;
+
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
+import org.maemo.esbox.launch.core.*;
+
+/**
+ * This adapter provides environment variable overrides needed for specific SDK targets.
+ * These are applied in launch configurations after the process launcher factory's
+ * default environment block and before the user's environment modifiers.
+ * 
+ * @author eswartz
+ *
+ */
+public interface ITargetEnvironmentModifierAdapter {
+
+	/**
+	 * Apply the environment to the given environment modifier block, using any
+	 * data from the launch proxy for guidance.
+	 * @param launchProxy
+	 * @return new environment modifier block or <code>null</code>
+	 */
+	IEnvironmentModifierBlock getTargetEnvironmentModifierBlock(ILaunchProxy launchProxy);
+
+}

Modified: trunk/common/org.maemo.esbox.launch/src/org/maemo/esbox/launch/core/AbstractLaunchProxy.java
===================================================================
--- trunk/common/org.maemo.esbox.launch/src/org/maemo/esbox/launch/core/AbstractLaunchProxy.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.launch/src/org/maemo/esbox/launch/core/AbstractLaunchProxy.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -11,11 +11,14 @@
 package org.maemo.esbox.launch.core;
 
 import org.eclipse.core.runtime.*;
+import org.eclipse.core.variables.VariablesPlugin;
 import org.eclipse.debug.core.*;
+import org.maemo.esbox.core.env.*;
 import org.maemo.esbox.core.process.*;
 import org.maemo.esbox.core.sdk.ISDKTarget;
 import org.maemo.esbox.launch.ESboxLaunchUtils;
 import org.maemo.esbox.launch.IESboxCDTLaunchConfigurationConstants;
+import org.maemo.esbox.launch.adapters.ITargetEnvironmentModifierAdapter;
 
 import java.text.DateFormat;
 import java.text.MessageFormat;
@@ -80,7 +83,7 @@
 	 * @throws CoreException on error.
 	 */
 	protected Process doRunApplication(IProgressMonitor monitor) throws CoreException {
-		monitor.beginTask("", 5);
+		monitor.beginTask("", 6);
 		
 		ProcessLauncherParameters rInfo = createProgramLauncherParameters();
 		monitor.worked(1);
@@ -153,10 +156,22 @@
 	}
 	
 	/**
+	 * Get the process launcher factory this proxy will eventually use.
+	 * <p>
+	 * Currently, this is primarily used to expand the environment modifier block.
+	 * @return {@link IProcessLauncherFactory}
+	 * @throws CoreException if something prevents creating the factory
+	 */
+	abstract protected IProcessLauncherFactory getProcessLauncherFactory();
+	
+	/**
 	 * Create ProcessLauncherParameters that records how to run the program (the working 
 	 * directory in runtime file system, environment vars, command line with arguments 
-	 * in runtime file system, etc) of the underlying launch configuration.<br>
-	 * <br> 
+	 * in runtime file system, etc) of the underlying launch configuration.
+	 * <p>
+	 * The environment modifier block is expanded proxy must take care of finalizing the parameters for its particular type of
+	 * launch.  
+	 * <p> 
 	 * This is independent of whether to launch the process locally or remotely. 
 	 * 
 	 * @return new ProcessLauncherParameters
@@ -164,7 +179,7 @@
 	 */
 	public ProcessRunnerParameters createProgramLauncherParameters() throws CoreException {
 		IPath exeInSb = getLaunchParameterAccessor().getProgramPathInRuntimeFileSystem();
-		Properties env = getLaunchParameterAccessor().getEnvironmentAsProperty();
+		IEnvironmentModifierBlock baseEnvBlock = getLaunchParameterAccessor().getEnvironmentModifierBlock();
 		String arguments[] = getLaunchParameterAccessor().getProgramArguments();
 
 		IPath wdInSb = getLaunchParameterAccessor().getWorkingDirectory();
@@ -172,10 +187,81 @@
 		List<String> cmdLine = CommandLineArguments.createFromArray(arguments);
 		cmdLine.add(0, exeInSb.toPortableString());
 		
-		ProcessRunnerParameters parameters = new ProcessRunnerParameters(wdInSb, cmdLine, env);
+		IEnvironmentModifierBlock envBlock = expandEnvironmentBlock(baseEnvBlock, getProcessLauncherFactory());
 		
+		ProcessRunnerParameters parameters = new ProcessRunnerParameters(wdInSb, cmdLine, envBlock);
+		
 		return parameters;
 	}
 	
+	/**
+	 * Expand the environment block by applying the standard "Replace" or "Append" options
+	 * from the launch configuration to the standard environment provided by the process launcher
+	 * factory and expanding the string substitutions to establish a meaningful set of values
+	 * for the target.
+	 * @param baseEnvBlock
+	 * @param processLauncherFactory
+	 * @return updated expanded modifier block
+	 */
+	private IEnvironmentModifierBlock expandEnvironmentBlock(
+			IEnvironmentModifierBlock baseEnvBlock,
+			IProcessLauncherFactory processLauncherFactory) throws CoreException {
+		
+		IEnvironmentModifierBlock envBlock;
+		
+		// combine with "native" (target) environment
+		
+		// We don't bother with the Replace/Append setting anymore. 
+		// The UI doesn't show it, and it is meaningless in most cases.
+		// The user can undefine variables in the Environment tab if he wishes.
+		boolean append = true;  //getLaunchConfiguration().getAttribute(ILaunchManager.ATTR_APPEND_ENVIRONMENT_VARIABLES, true);
+		
+		// ignore "replace" when env block is empty -- the UI doesn't allow even setting
+		// the option in this case
+		if (!append && baseEnvBlock.getOperations().length > 0) {
+			// replace: we must retrieve the raw environment and delete all its variables first
+			Properties rawEnv = processLauncherFactory.getRawEnvironment();
+			envBlock = EnvironmentManager.getInstance().createEnvironmentModifierBlock();
+			for (Object key : rawEnv.keySet()) {
+				envBlock.undefine(key.toString());
+			}
+			envBlock.apply(baseEnvBlock);
+		} else {
+			// append: apply to target environment's default changes
+			envBlock = processLauncherFactory.defaultEnvironmentModifierBlock();
+			
+			// apply any vars the SDK target needs
+			ISDKTarget sdkTarget = null;
+			if (getLaunchParameterAccessor() instanceof IESboxLaunchParameterAccessor) { 
+				sdkTarget = ((IESboxLaunchParameterAccessor) getLaunchParameterAccessor()).getSDKTarget();
+				if (sdkTarget != null) {
+					ITargetEnvironmentModifierAdapter adapter =
+						(ITargetEnvironmentModifierAdapter) sdkTarget.getAdapter(ITargetEnvironmentModifierAdapter.class);
+					if (adapter != null) {
+						IEnvironmentModifierBlock targetEnvBlock = adapter.getTargetEnvironmentModifierBlock(
+								this);
+						if (targetEnvBlock != null) {
+							envBlock.apply(targetEnvBlock);
+						}
+					}
+				}
+			}
+		}
+		
+		// now, expand and merge all the variables 
+		for (IEnvironmentOperation operation : baseEnvBlock.getOperations()) {
+			if (operation != null) {
+				String value = operation.getValue();
+				if (value != null) {
+					value = VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(value);
+					operation.setValue(value);
+				}
+			}
+			envBlock.apply(operation);
+		}
+		
+		return envBlock;
+	}
+
 	abstract protected Process doRun(ProcessLauncherParameters info) throws CoreException;
 }

Modified: trunk/common/org.maemo.esbox.launch/src/org/maemo/esbox/launch/core/AbstractLocalLaunchProxy.java
===================================================================
--- trunk/common/org.maemo.esbox.launch/src/org/maemo/esbox/launch/core/AbstractLocalLaunchProxy.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.launch/src/org/maemo/esbox/launch/core/AbstractLocalLaunchProxy.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -38,6 +38,15 @@
 		return ESboxLaunchUtils.validateLocalConnection(getLaunchConfiguration());
 	}
 
+	/* (non-Javadoc)
+	 * @see org.maemo.esbox.launch.core.AbstractLaunchProxy#getProcessLauncherFactory()
+	 */
+	@Override
+	protected IProcessLauncherFactory getProcessLauncherFactory() {
+		IESboxLaunchParameterAccessor eLPA = (IESboxLaunchParameterAccessor)getLaunchParameterAccessor();
+		return eLPA.getSDKTarget().getProcessLauncherFactory();
+	}
+
 	protected Process doRun(ProcessLauncherParameters info) throws CoreException {
 		try {
 			IESboxLaunchParameterAccessor eLPA = (IESboxLaunchParameterAccessor)getLaunchParameterAccessor();

Modified: trunk/common/org.maemo.esbox.launch/src/org/maemo/esbox/launch/core/AbstractRemoteLaunchProxy.java
===================================================================
--- trunk/common/org.maemo.esbox.launch/src/org/maemo/esbox/launch/core/AbstractRemoteLaunchProxy.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.launch/src/org/maemo/esbox/launch/core/AbstractRemoteLaunchProxy.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -39,6 +39,15 @@
 		return ESboxLaunchUtils.validateRemoteConnection(lpa.getLaunchProtocol());
 	}
 
+	/* (non-Javadoc)
+	 * @see org.maemo.esbox.launch.core.AbstractLaunchProxy#getProcessLauncherFactory()
+	 */
+	@Override
+	protected IProcessLauncherFactory getProcessLauncherFactory() {
+		IRemoteLaunchParameterAccessor lpa = (IRemoteLaunchParameterAccessor)getLaunchParameterAccessor();
+		return lpa.getLaunchProtocol().getDeviceMachine().getProcessLauncherFactory();
+	}
+
 	// Special for remote run: downloading files.
 	@Override
 	protected Process doRunApplication(IProgressMonitor monitor)
@@ -59,7 +68,7 @@
 			
 			// Launch the process on the DeviceMachine.
 			return ProcessRunnerCreator.createAndLaunchProcess(
-						lpa.getLaunchProtocol().getDeviceMachine().getProcessLauncherFactory(),
+						getProcessLauncherFactory(),	
 						lpa.getSDKTarget(), 
 						info);
 		} catch (ESboxException e) {

Modified: trunk/common/org.maemo.esbox.launch/src/org/maemo/esbox/launch/core/ILaunchParameterAccessor.java
===================================================================
--- trunk/common/org.maemo.esbox.launch/src/org/maemo/esbox/launch/core/ILaunchParameterAccessor.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.launch/src/org/maemo/esbox/launch/core/ILaunchParameterAccessor.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -14,8 +14,8 @@
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.debug.core.ILaunchConfiguration;
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
 
-import java.util.Properties;
 
 /**
  * Interface for accessing parameters/options related to run and debug. The parameters here
@@ -122,5 +122,17 @@
 	 */
 	public IPath getWorkingDirectory() throws CoreException;
 	
-	public Properties getEnvironmentAsProperty() throws CoreException;
+	/**
+	 * Get the modifications to the target environment for the launched program.
+	 * This returns a set of add/replace or remove operations for the environment.
+	 * <p>
+	 * These are the literal changes spelled out in the launch configuration.
+	 * Any string substitutions ${...} are still present.
+	 * It is up to the launch proxy to handle the "Replace" or "Append" option in
+	 * the configuration, apply the default global environment preferences for
+	 * the target, and to expand the variables. 
+	 * @return IEnvironmentModifierBlock, never <code>null</code>
+	 * @throws CoreException
+	 */
+	public IEnvironmentModifierBlock getEnvironmentModifierBlock() throws CoreException;
 }

Added: trunk/common/org.maemo.esbox.launch/src/org/maemo/esbox/launch/ui/ESboxEnvironmentTab.java
===================================================================
--- trunk/common/org.maemo.esbox.launch/src/org/maemo/esbox/launch/ui/ESboxEnvironmentTab.java	                        (rev 0)
+++ trunk/common/org.maemo.esbox.launch/src/org/maemo/esbox/launch/ui/ESboxEnvironmentTab.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+
+package org.maemo.esbox.launch.ui;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.*;
+import org.eclipse.debug.internal.ui.DebugPluginImages;
+import org.eclipse.debug.ui.AbstractLaunchConfigurationTab;
+import org.eclipse.debug.ui.IDebugUIConstants;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.maemo.esbox.core.env.EnvironmentManager;
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
+import org.maemo.esbox.internal.launch.Activator;
+import org.maemo.esbox.launch.ESboxLaunchUtils;
+import org.maemo.esbox.ui.env.EnvironmentTable;
+import org.maemo.esbox.ui.env.EnvironmentTable.IListener;
+
+/**
+ * Reimplement this from the debugger UI... 
+ * We don't want the Append/Replace radio button or the Select button, 
+ * since these are meaningless with the default implementation that
+ * reads host variables... and it doesn't let us override the class anyway :(
+ * @author eswartz
+ *
+ */
+ at SuppressWarnings("restriction")
+public class ESboxEnvironmentTab extends AbstractLaunchConfigurationTab implements IListener {
+
+	private EnvironmentTable envTable;
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#getName()
+	 */
+	public String getName() {
+		return "Environment";
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#getImage()
+	 */
+	public Image getImage() {
+		return DebugPluginImages.getImage(IDebugUIConstants.IMG_OBJS_ENVIRONMENT);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#createControl(org.eclipse.swt.widgets.Composite)
+	 */
+	public void createControl(Composite parent) {
+		envTable = new EnvironmentTable(parent, "Specify the environment changes to make for this launch:");
+		envTable.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+		envTable.setListener(this);
+		setControl(envTable);
+	}
+	
+	
+
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#initializeFrom(org.eclipse.debug.core.ILaunchConfiguration)
+	 */
+	public void initializeFrom(ILaunchConfiguration configuration) {
+		IEnvironmentModifierBlock envBlock;
+		try {
+			envBlock = ESboxLaunchUtils.getEnvironmentModifierBlock(configuration);
+		} catch (CoreException e) {
+			Activator.getErrorLogger().logError("Failed to read existing environment", e);
+			envBlock = EnvironmentManager.getInstance().createEnvironmentModifierBlock();
+		}
+		envTable.initializeFrom(envBlock);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#performApply(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy)
+	 */
+	public void performApply(ILaunchConfigurationWorkingCopy configuration) {
+		IEnvironmentModifierBlock envBlock = EnvironmentManager.getInstance().createEnvironmentModifierBlock();
+		envTable.performApply(envBlock);
+		try {
+			ESboxLaunchUtils.setEnvironmentModifierBlockToMap(configuration, envBlock);
+		} catch (CoreException e) {
+			Activator.getErrorLogger().logAndShowError("Failed to store environment", e);
+		} 
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#setDefaults(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy)
+	 */
+	public void setDefaults(ILaunchConfigurationWorkingCopy configuration) {
+		IEnvironmentModifierBlock envBlock = EnvironmentManager.getInstance().createEnvironmentModifierBlock();
+		try {
+			ESboxLaunchUtils.setEnvironmentModifierBlockToMap(configuration, envBlock);
+		} catch (CoreException e) {
+			Activator.getErrorLogger().logAndShowError("Failed to store environment", e);
+		} 
+	}
+
+	/* (non-Javadoc)
+	 * @see org.maemo.esbox.ui.env.EnvironmentTab.IListener#changed(org.maemo.esbox.ui.env.EnvironmentTab)
+	 */
+	public void changed(EnvironmentTable environmentTable) {
+		updateLaunchConfigurationDialog();
+	}
+
+	
+}

Deleted: trunk/common/org.maemo.esbox.ssh/src/org/maemo/esbox/internal/api/ssh/DeviceSSHLinuxMachine.java
===================================================================
--- trunk/common/org.maemo.esbox.ssh/src/org/maemo/esbox/internal/api/ssh/DeviceSSHLinuxMachine.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.ssh/src/org/maemo/esbox/internal/api/ssh/DeviceSSHLinuxMachine.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -1,39 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2008 Nokia Corporation
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *    Ed Swartz (Nokia) - initial API and implementation
- *******************************************************************************/
-package org.maemo.esbox.internal.api.ssh;
-
-import org.eclipse.core.runtime.Platform;
-import org.maemo.esbox.core.machine.IDeviceMachine;
-import org.maemo.esbox.core.machine.ISharedFilesystemProvider;
-import org.maemo.esbox.internal.ssh.*;
-import org.maemo.esbox.ssh.SSHConfiguration;
-
-
-/**
- * This machine is a remote Linux device.
- * @author eswartz
- *
- */
-public class DeviceSSHLinuxMachine extends SSHMachineBackend implements IDeviceMachine {
-	public final static String ID = Activator.PLUGIN_ID + ".device_machine";
-
-	/**
-	 * @param configuration
-	 * @param sharedFilesystemProvider 
-	 */
-	public DeviceSSHLinuxMachine(String name,
-			SSHConfiguration configuration, ISharedFilesystemProvider sharedFilesystemProvider) {
-		super(ID, name, Platform.OS_LINUX,
-				new SSHDeviceMachineController(configuration, name),
-				configuration,
-				sharedFilesystemProvider);
-	}
-}

Added: trunk/common/org.maemo.esbox.ssh/src/org/maemo/esbox/internal/api/ssh/DeviceSSHLinuxMachine.java
===================================================================
--- trunk/common/org.maemo.esbox.ssh/src/org/maemo/esbox/internal/api/ssh/DeviceSSHLinuxMachine.java	                        (rev 0)
+++ trunk/common/org.maemo.esbox.ssh/src/org/maemo/esbox/internal/api/ssh/DeviceSSHLinuxMachine.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+package org.maemo.esbox.internal.api.ssh;
+
+import org.eclipse.core.runtime.Platform;
+import org.maemo.esbox.core.machine.IDeviceMachine;
+import org.maemo.esbox.core.machine.ISharedFilesystemProvider;
+import org.maemo.esbox.internal.ssh.Activator;
+import org.maemo.esbox.internal.ssh.SSHMachineBackend;
+import org.maemo.esbox.ssh.SSHConfiguration;
+
+
+/**
+ * This machine is a generic Linux device.
+ * @author eswartz
+ *
+ */
+public class DeviceSSHLinuxMachine extends SSHMachineBackend implements IDeviceMachine {
+	public final static String ID = Activator.PLUGIN_ID + ".device_machine";
+
+	/**
+	 * @param configuration
+	 * @param sharedFilesystemProvider 
+	 */
+	public DeviceSSHLinuxMachine(String name,
+			SSHConfiguration configuration, ISharedFilesystemProvider sharedFilesystemProvider) {
+		super(ID, name, Platform.OS_LINUX,
+				new SSHDeviceMachineController(configuration, name),
+				configuration,
+				sharedFilesystemProvider);
+	}
+}


Property changes on: trunk/common/org.maemo.esbox.ssh/src/org/maemo/esbox/internal/api/ssh/DeviceSSHLinuxMachine.java
___________________________________________________________________
Name: svn:mergeinfo
   + 

Added: trunk/common/org.maemo.esbox.ssh/src/org/maemo/esbox/internal/ssh/SSHEnvironmentProvider.java
===================================================================
--- trunk/common/org.maemo.esbox.ssh/src/org/maemo/esbox/internal/ssh/SSHEnvironmentProvider.java	                        (rev 0)
+++ trunk/common/org.maemo.esbox.ssh/src/org/maemo/esbox/internal/ssh/SSHEnvironmentProvider.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+
+package org.maemo.esbox.internal.ssh;
+
+import com.nokia.cpp.internal.api.utils.core.FileUtils;
+
+import org.maemo.esbox.core.process.CommandLineArguments;
+import org.maemo.esbox.core.process.EnvironmentProperties;
+import org.maemo.esbox.internal.api.core.IStandardEnvironmentProvider;
+import org.maemo.esbox.ssh.SSHConfiguration;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.net.URI;
+import java.util.*;
+
+/**
+ * This provider caches the standard environment for a given user and machine.
+ * @author eswartz
+ *
+ */
+public class SSHEnvironmentProvider implements IStandardEnvironmentProvider {
+
+	private static Map<URI, Properties> cachedStdEnvMap = new HashMap<URI, Properties>();
+	
+	private final SSHConfiguration config;
+
+	/**
+	 * @param config
+	 */
+	public SSHEnvironmentProvider(SSHConfiguration config) {
+		this.config = config;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.maemo.esbox.internal.api.core.IStandardEnvironmentProvider#getRawEnvironment()
+	 */
+	public Properties getRawEnvironment() {
+		Properties env = cachedStdEnvMap.get(config.getURI());
+		if (env == null) {
+			try {
+				// once per session, find out what the standard environment is
+				SSHProcessLauncher launcher = new SSHProcessLauncher(
+						config, null, 
+						CommandLineArguments.createFromVarArgs("sh" ,"-c", "set"),
+						null);
+				
+				Process process = launcher.createProcess();
+				BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
+				
+				// ignore variables specific to the SSH session that is retrieving the variables 
+				String dump = new String(FileUtils.readReaderContents(reader));
+				
+				env = EnvironmentProperties.createFromShellEnvDump(dump);
+			} catch (Exception e) {
+				Activator.getErrorLogger().logError("Cannot read standard environment", e);
+				env = new Properties();
+			}
+			cachedStdEnvMap.put(config.getURI(), env);
+		}
+		return env;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.maemo.esbox.internal.api.core.IStandardEnvironmentProvider#flushRawEnvironment()
+	 */
+	public void flushRawEnvironment() {
+		cachedStdEnvMap.remove(config.getURI());
+	}
+
+}

Modified: trunk/common/org.maemo.esbox.ssh/src/org/maemo/esbox/internal/ssh/SSHMachineBackend.java
===================================================================
--- trunk/common/org.maemo.esbox.ssh/src/org/maemo/esbox/internal/ssh/SSHMachineBackend.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.ssh/src/org/maemo/esbox/internal/ssh/SSHMachineBackend.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -15,9 +15,10 @@
 import org.eclipse.core.filesystem.*;
 import org.eclipse.core.runtime.*;
 import org.maemo.esbox.core.Policy;
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
 import org.maemo.esbox.core.machine.*;
-import org.maemo.esbox.core.process.CommandLineArguments;
-import org.maemo.esbox.core.process.IProcessLauncherFactory;
+import org.maemo.esbox.core.process.*;
+import org.maemo.esbox.internal.api.core.IStandardEnvironmentProvider;
 import org.maemo.esbox.internal.api.core.machine.*;
 import org.maemo.esbox.ssh.*;
 
@@ -38,9 +39,9 @@
 	private IFileSystemAccess sshFileSystemAccess;
 	private SSHConfiguration sshConfiguration;
 	private IProcessLister processLister;
-	private Map<String,String> gatheredEnv;
 	protected final ISharedFilesystemProvider sharedFilesystemProvider;
 	private String userName;
+	private SSHEnvironmentProvider environmentProvider;
 	
 	public SSHMachineBackend(String id, String name, String os,
 			IMachineController controller,
@@ -57,7 +58,7 @@
 		}
 		
 		this.userName = sshConfiguration.getUserName();
-
+		this.environmentProvider = new SSHEnvironmentProvider(sshConfiguration);
 	}
 	
 	/* (non-Javadoc)
@@ -166,51 +167,32 @@
 	 * @see org.maemo.esbox.core.machine.IMachine#getProcessLauncherFactory()
 	 */
 	public IProcessLauncherFactory getProcessLauncherFactory() {
-		return new SSHProcessLauncherFactory(sshConfiguration);
+		return new SSHProcessLauncherFactory(sshConfiguration, 
+				new StandardMachineEnvironmentProvider(this));
 	}
 	
 	/* (non-Javadoc)
 	 * @see org.maemo.esbox.core.machine.IMachine#createProcess(org.eclipse.core.runtime.IPath, java.util.List, java.util.Properties, org.eclipse.cdt.utils.pty.PTY)
 	 */
 	public Process createProcess(IPath workingDirectory,
-			List<String> commandLine, Properties environment, boolean usePty)
+			List<String> commandLine, IEnvironmentModifierBlock environmentModifierBlock, boolean usePty)
 			throws Exception {
-		return new SSHProcess(sshConfiguration, commandLine, environment, workingDirectory);
+		return new SSHProcess(sshConfiguration, commandLine, environmentModifierBlock, workingDirectory);
 	}
 	
 	/* (non-Javadoc)
+	 * @see org.maemo.esbox.core.machine.IMachine#getStandardEnvironmentProvider()
+	 */
+	public IStandardEnvironmentProvider getStandardEnvironmentProvider() {
+		return environmentProvider;
+	}
+	
+	/* (non-Javadoc)
 	 * @see org.maemo.esbox.core.machine.IMachine#getStandardEnvironment()
 	 */
-	public Map<String, String> getStandardEnvironment() {
-		if (gatheredEnv == null) {
-			gatheredEnv = new HashMap<String, String>();
-			try {
-				// once per session, find out what the standard environment is
-				Process process = createProcess(null, CommandLineArguments.createFromCommandLine("sh -c set"), null, false);
-				BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
-				String line;
-				while ((line = reader.readLine()) != null) {
-					String[] parts = line.split("=", 2);
-					if (parts.length == 2) {
-						String name = parts[0];
-						// ignore variables specific to the SSH session that is retrieving the variables 
-						if (!name.startsWith("SSH_")) {
-							// value is quoted
-							String value = parts[1];
-							if (value.length() >= 2 && value.startsWith("'") && value.endsWith("'")) {
-								value = value.substring(1, value.length() - 1).replace("\\'", "'");
-							}
-									
-							gatheredEnv.put(parts[0], value);
-						}
-					}
-				}
-				process.waitFor();
-			} catch (Exception e) {
-				Activator.getErrorLogger().logError("Cannot read standard environment", e);
-			}
-		}
-		return gatheredEnv;
+	public Properties getStandardEnvironment() {
+		return getStandardEnvironmentProvider().getRawEnvironment();
+
 	}
 	
 	/* (non-Javadoc)

Modified: trunk/common/org.maemo.esbox.ssh/src/org/maemo/esbox/internal/ssh/SSHProcess.java
===================================================================
--- trunk/common/org.maemo.esbox.ssh/src/org/maemo/esbox/internal/ssh/SSHProcess.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.ssh/src/org/maemo/esbox/internal/ssh/SSHProcess.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -15,6 +15,8 @@
 import com.jcraft.jsch.Session;
 
 import org.eclipse.core.runtime.IPath;
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
+import org.maemo.esbox.core.env.IEnvironmentOperation;
 import org.maemo.esbox.core.process.CommandLineArguments;
 import org.maemo.esbox.internal.api.core.machine.IStreamWrapper;
 import org.maemo.esbox.internal.api.core.machine.IStreamWrapperFactory;
@@ -44,13 +46,14 @@
 	
 	public SSHProcess(final SSHConfiguration configuration,
 			List<String> cmdLine,
-			Properties env,
+			IEnvironmentModifierBlock envBlock,
 			IPath cwd) throws Exception {
-		this(configuration, cmdLine, env, cwd, injectSSHProcessWrapper());
+		this(configuration, cmdLine, envBlock, cwd, injectSSHProcessWrapper());
 	}
 	
 	/**
-	 * XXX FIXME HACK TODO: until the official sb2-qemu-arm with the bugfix is in the repository, use this hack to ensure processes terminate 
+	 * XXX FIXME HACK TODO: until the official sb2-qemu-arm with the bugfix is in the 
+	 * repository, use this hack to ensure processes terminate 
 	 * @return
 	 */
 	private static IStreamWrapperFactory injectSSHProcessWrapper() {
@@ -64,7 +67,7 @@
 
 	public SSHProcess(final SSHConfiguration configuration,
 			List<String> cmdLine,
-			Properties env,
+			IEnvironmentModifierBlock envBlock,
 			IPath cwd,
 			IStreamWrapperFactory wrapperFactory) throws Exception {
 		session = JSchSessionFactory.createSessionAndConnect(configuration);
@@ -88,17 +91,47 @@
 		
 		String commandLine = CommandLineArguments.toCommandLine(cmdLine);
 		
-		if (env != null) {
-			String envCmdLine = "";
+		if (envBlock != null) {
+			StringBuilder envCmdLine = new StringBuilder();
 			boolean needShell = false;
-			for (Map.Entry<Object, Object> entry : env.entrySet()) {
+			
+			// To handle undefines, run "unset" with all the variables listed,
+			// and then use '&&' to start a new shell (which 'inherits' the undefinitions).
+			//
+			// Defines must be defined on the same line as the following command like this:
+			//
+			//		FOO=bar BAR=baz BAZ=foo ./command
+			//
+			// or else they will not be visible (and we don't want to waste space exporting them
+			// nor start a new shell).
+			
+			// put all undefines first
+			boolean anyUndef = false;
+			for (IEnvironmentOperation operation : envBlock.getOperations()) {
 				needShell = true;
-				envCmdLine += entry.getKey() + "=" +
-						//'"' + entry.getValue() + "\";"
-						"\"" + CommandLineArguments.escape(entry.getValue().toString(), false) +  "\""
-						//"'" + entry.getValue().toString().replaceAll("'", "\\\\'") +  "'"
-						+ " ";
+				if (operation.getValue() == null) {
+					if (!anyUndef) {
+						envCmdLine.append("unset ");
+						anyUndef = true;
+					}
+					envCmdLine.append(operation.getName());
+					envCmdLine.append(' ');
+				}
 			}
+			if (anyUndef) {
+				envCmdLine.append("&& ");
+			}
+
+			// now define variables
+			for (IEnvironmentOperation operation : envBlock.getOperations()) {
+				needShell = true;
+				if (operation.getValue() != null) {
+					envCmdLine.append(operation.getName());
+					envCmdLine.append('=');
+					envCmdLine.append("\"" + CommandLineArguments.escape(operation.getValue(), false) +  "\"");
+					envCmdLine.append(' ');
+				}
+			}
 			
 			if (needShell) {
 				commandLine = "/bin/sh -c \"" + CommandLineArguments.escape(envCmdLine + commandLine, false) + "\"";

Modified: trunk/common/org.maemo.esbox.ssh/src/org/maemo/esbox/internal/ssh/SSHProcessLauncher.java
===================================================================
--- trunk/common/org.maemo.esbox.ssh/src/org/maemo/esbox/internal/ssh/SSHProcessLauncher.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.ssh/src/org/maemo/esbox/internal/ssh/SSHProcessLauncher.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -15,8 +15,8 @@
 
 import org.eclipse.core.runtime.IPath;
 import org.maemo.esbox.core.ESboxException;
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
 import org.maemo.esbox.core.process.BaseProcessLauncher;
-import org.maemo.esbox.core.sdk.IPreferenceProvider;
 import org.maemo.esbox.internal.api.core.machine.IStreamWrapperFactory;
 import org.maemo.esbox.ssh.SSHConfiguration;
 
@@ -35,17 +35,23 @@
 
 	public SSHProcessLauncher(
 					SSHConfiguration configuration,
-					List<String> cmdLine,
-					Properties environment,
 					IPath workingDirectory,
-					IPreferenceProvider prefProvider) {
+					List<String> cmdLine,
+					IEnvironmentModifierBlock environmentBlock) {
 		super(cmdLine, 
-				environment,
-				workingDirectory,
-				prefProvider);
+				environmentBlock,
+				workingDirectory);
 		this.configuration = configuration;
 	}
 	
+	/**
+	 * If necessary, provide a stream wrapper factory which will provide
+	 * custom wrappers for the launched SSH process and handle its
+	 * input and output streams.
+	 * <p>
+	 * Currently this is used for working around an obscure SB2 bug.
+	 * @param factory
+	 */
 	public void setStreamWrapperFactory(IStreamWrapperFactory factory) {
 		this.streamWrapperFactory = factory;
 	}
@@ -59,14 +65,6 @@
 	}
 	
 	/* (non-Javadoc)
-	 * @see org.maemo.esbox.internal.core.BaseProcessLauncher#getLaunchInfoStandardEnvironment()
-	 */
-	@Override
-	protected Map<String, String> getLaunchInfoStandardEnvironment() {
-		return null;
-	}
-	
-	/* (non-Javadoc)
 	 * @see org.maemo.esbox.internal.core.BaseProcessLauncher#setupForLaunch()
 	 */
 	@Override
@@ -81,7 +79,7 @@
 	public Process doCreateProcess() throws Exception {
 		try {
 			return new SSHProcess(configuration, getLaunchCommandArguments(),
-						getLaunchEnvironment(), getLaunchCurrentWorkingDirectory(),
+						getLaunchEnvironmentModifierBlock(), getLaunchCurrentWorkingDirectory(),
 						streamWrapperFactory);
 		} catch (JSchException e) {
 			throw new ESboxException("Cannot launch program over SSH", e);

Modified: trunk/common/org.maemo.esbox.ssh/src/org/maemo/esbox/internal/ssh/SSHProcessLauncherFactory.java
===================================================================
--- trunk/common/org.maemo.esbox.ssh/src/org/maemo/esbox/internal/ssh/SSHProcessLauncherFactory.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.ssh/src/org/maemo/esbox/internal/ssh/SSHProcessLauncherFactory.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -12,13 +12,13 @@
 package org.maemo.esbox.internal.ssh;
 
 import org.eclipse.core.runtime.IPath;
-import org.maemo.esbox.core.CorePreferenceManager;
-import org.maemo.esbox.core.process.IProcessLauncher;
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
+import org.maemo.esbox.core.process.*;
 import org.maemo.esbox.internal.api.core.BaseProcessLauncherFactory;
+import org.maemo.esbox.internal.api.core.IStandardEnvironmentProvider;
 import org.maemo.esbox.ssh.SSHConfiguration;
 
 import java.util.List;
-import java.util.Properties;
 
 /**
  * Launch processes over SSH.
@@ -29,41 +29,41 @@
 public class SSHProcessLauncherFactory extends BaseProcessLauncherFactory {
 
 	private SSHConfiguration configuration;
-	private Properties standardEnv;
 	
-	public SSHProcessLauncherFactory(SSHConfiguration config) {
-		super(false);
+	/**
+	 * Create a process launcher factory with the given configuration and 
+	 * environment provider.
+	 * @param config
+	 * @param envProvider
+	 */
+	public SSHProcessLauncherFactory(SSHConfiguration config, IStandardEnvironmentProvider envProvider) {
+		super(envProvider, false);
 		configuration = config;
 	}
 
+	/**
+	 * Create a process launcher factory with the given configuration and 
+	 * a default environment provider.
+	 * @param config
+	 */
+	public SSHProcessLauncherFactory(SSHConfiguration config) {
+		this(config, new SSHEnvironmentProvider(config));
+	}
+
 	/* (non-Javadoc)
-	 * @see org.maemo.esbox.internal.core.BaseProcessLauncherFactory#doCreateProcessLaunchHandler(org.eclipse.core.runtime.IPath, java.util.List, java.util.Properties, org.eclipse.cdt.utils.pty.PTY)
+	 * @see org.maemo.esbox.internal.core.BaseProcessLauncherFactory#docreateProcessLauncher(org.eclipse.core.runtime.IPath, java.util.List, java.util.Properties, org.eclipse.cdt.utils.pty.PTY)
 	 */
 	@Override
-	protected IProcessLauncher doCreateProcessLaunchHandler(
+	protected IProcessLauncher doCreateProcessLauncher(
 			IPath workingDirectory, List<String> cmdLine,
-			Properties environment) {
+			IEnvironmentModifierBlock environmentBlock) {
 		return new SSHProcessLauncher(
 					configuration, 
+					workingDirectory, 
 					cmdLine, 
-					environment != null ? environment : readStandardEnvironment(), 
-					workingDirectory,
-					CorePreferenceManager.getInstance().getPreferenceProvider());
+					environmentBlock);
 	}
 
-	/* (non-Javadoc)
-	 * @see org.maemo.esbox.internal.core.BaseProcessLauncherFactory#readStandardEnvironment()
-	 */
-	@Override
-	protected Properties readStandardEnvironment() {
-		if (standardEnv == null) {
-			standardEnv = new Properties();
-			
-			mergeOrSetUserVariables("SSH", standardEnv, null);
-		}
-		return standardEnv;
-	}
-
 	public SSHConfiguration getConfiguration() {
 		return configuration;
 	}

Modified: trunk/common/org.maemo.esbox.ssh/src/org/maemo/esbox/internal/ssh/UnixUserInformation.java
===================================================================
--- trunk/common/org.maemo.esbox.ssh/src/org/maemo/esbox/internal/ssh/UnixUserInformation.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.ssh/src/org/maemo/esbox/internal/ssh/UnixUserInformation.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -36,7 +36,7 @@
 		"(\\d+)\\(.*\\)");
 	
 	public static UnixUserInformation create(IProcessLauncherFactory processLauncherFactory, String userName) throws ESboxException {
-		IProcessLauncher processLaunchHandler = processLauncherFactory.createProcessLaunchHandler(
+		IProcessLauncher processLaunchHandler = processLauncherFactory.createProcessLauncher(
 				null,
 				CommandLineArguments.createFromCommandLine("/usr/bin/id"),
 				null);

Modified: trunk/common/org.maemo.esbox.ui/src/org/maemo/esbox/ui/actions/LaunchShellAction.java
===================================================================
--- trunk/common/org.maemo.esbox.ui/src/org/maemo/esbox/ui/actions/LaunchShellAction.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.ui/src/org/maemo/esbox/ui/actions/LaunchShellAction.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -16,14 +16,15 @@
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.jface.action.IAction;
 import org.maemo.esbox.core.*;
-
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
 import org.maemo.esbox.core.process.*;
 import org.maemo.esbox.core.sdk.IPreferenceProvider;
 import org.maemo.esbox.core.sdk.ISDKTarget;
 import org.maemo.esbox.internal.ui.UIActivator;
 import org.maemo.esbox.project.core.ProjectManager;
 
-import java.util.*;
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * Launch a scratchbox shell in the selected directory
@@ -77,12 +78,12 @@
 		List<String> targetCmdLine = new ArrayList<String>();
 		targetCmdLine.add("/bin/bash");
 		
-		Properties targetEnv = launcherFactory.getStandardEnvironment();
-		targetEnv.put("PWD", targetWd.toOSString());
+		IEnvironmentModifierBlock targetEnvBlock = launcherFactory.defaultEnvironmentModifierBlock();
+		targetEnvBlock.define("PWD", targetWd.toOSString());
 		if (sdkTarget != null)
-			targetEnv.put("PS1", "[" + sdkTarget.getName() + "] \\w$ ");
+			targetEnvBlock.define("PS1", "[" + sdkTarget.getName() + "] \\w$ ");
 		
-		IProcessLauncher launchHandler = launcherFactory.createProcessLaunchHandler(targetWd, targetCmdLine, targetEnv);
+		IProcessLauncher launchHandler = launcherFactory.createProcessLauncher(targetWd, targetCmdLine, targetEnvBlock);
 		String sandboxCmdLine = CommandLineArguments.toCommandLine(launchHandler.getLaunchCommandArguments());
 		
 		terminalPattern = prefProvider.getPreferenceValue(CorePreferenceConstants.TERMINAL_COMMAND);
@@ -94,14 +95,13 @@
 		
 		String terminalCommand = substitutor.substitute(terminalPattern);
 		
-		// don't use ESbox-enhanced environment for terminal launch
-		Properties hostEnv = EnvironmentProperties.createFromMap(System.getenv());
-		hostEnv.put("PWD", targetWd.toOSString());
+		IEnvironmentModifierBlock hostEnvBlock = hostLauncherFactory.defaultEnvironmentModifierBlock();
+		hostEnvBlock.define("PWD", targetWd.toOSString());
 		
 		IProcessLauncher launcher = ProcessLauncherCreator.createProcessLauncher(hostLauncherFactory,
 				hostWd,
 				CommandLineArguments.createFromCommandLine(terminalCommand),
-				hostEnv);
+				hostEnvBlock);
 		launcher.usePTY(true);
 		
 		try {

Deleted: trunk/common/org.maemo.esbox.ui/src/org/maemo/esbox/ui/env/EnvironmentTab.java
===================================================================
--- trunk/common/org.maemo.esbox.ui/src/org/maemo/esbox/ui/env/EnvironmentTab.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.ui/src/org/maemo/esbox/ui/env/EnvironmentTab.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -1,484 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2000, 2007, 2008 Keith Seitz and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * 
- * Contributors:
- *     Keith Seitz (keiths at redhat.com) - initial implementation
- *     IBM Corporation - integration and code cleanup
- *     Ed Swartz (Nokia) - adapted for ESbox and for proper use of content provider
- *******************************************************************************/
-package org.maemo.esbox.ui.env;
-
-import org.eclipse.core.runtime.Assert;
-import org.eclipse.jface.dialogs.*;
-import org.eclipse.jface.dialogs.Dialog;
-import org.eclipse.jface.resource.JFaceResources;
-import org.eclipse.jface.viewers.*;
-import org.eclipse.jface.window.Window;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.*;
-import org.eclipse.swt.graphics.*;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.*;
-import org.maemo.esbox.core.env.*;
-
-import java.text.MessageFormat;
-
-/**
- * Launch configuration tab for configuring an environment block
- */
-public class EnvironmentTab extends Composite {
-
-	/**
-	 * @param parent
-	 * @param description
-	 */
-	public EnvironmentTab(Composite parent, String description) {
-		super(parent, SWT.NONE);
-		
-		GridLayout layout = new GridLayout(2, false);
-		setLayout(layout);
-		
-		// Create main composite
-		Composite mainComposite = new Composite(this, SWT.NONE);
-		mainComposite.setLayout(new GridLayout(2, false));
-		mainComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
-		
-		//PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(), IDebugHelpContextIds.LAUNCH_CONFIGURATION_DIALOG_ENVIRONMENT_TAB);
-		
-		// Create label, add it to the parent to align the right side buttons with the top of the table
-		createLabel(mainComposite, description, 2);
-
-		createEnvironmentTable(mainComposite);
-		createTableButtons(mainComposite);
-		
-		Dialog.applyDialogFont(mainComposite);
-	}
-
-	protected TableViewer environmentTable;
-	protected String[] envTableColumnHeaders = {
-			"Variable",
-			"Value"
-	};
-	protected static final String P_VARIABLE = "variable"; //$NON-NLS-1$
-	protected static final String P_VALUE = "value"; //$NON-NLS-1$
-	protected Button envAddButton;
-	protected Button envEditButton;
-	protected Button envRemoveButton;
-	private Button envUndefButton;
-	
-	/**
-	 * Content provider for the environment table
-	 */
-	protected class IEnvironmentVariableContentProvider implements IStructuredContentProvider {
-		public Object[] getElements(Object inputElement) {
-			IEnvironmentVariableBlock block = (IEnvironmentVariableBlock) inputElement;
-			return block.getVariables();
-		}
-		public void dispose() {
-		}
-		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
-			if (newInput == null){
-				return;
-			}
-			if (viewer instanceof TableViewer){
-				TableViewer tableViewer = (TableViewer) viewer;
-				if (tableViewer.getTable().isDisposed()) {
-					return;
-				}
-				tableViewer.setComparator(new ViewerComparator() {
-					public int compare(Viewer iviewer, Object e1, Object e2) {
-						if (e1 == null) {
-							return -1;
-						} else if (e2 == null) {
-							return 1;
-						} else {
-							return ((IEnvironmentVariable)e1).getName().compareToIgnoreCase(((IEnvironmentVariable)e2).getName());
-						}
-					}
-				});
-			}
-		}
-	}
-	
-	/**
-	 * Label provider for the environment table
-	 */
-	public class IEnvironmentVariableLabelProvider extends LabelProvider implements ITableLabelProvider, ITableFontProvider {
-		public String getColumnText(Object element, int columnIndex) 	{
-			String result = null;
-			if (element != null) {
-				IEnvironmentVariable var = (IEnvironmentVariable) element;
-				switch (columnIndex) {
-					case 0: // variable
-						result = var.getName();
-						break;
-					case 1: // value
-						result = var.getValue();
-						if (result == null)
-							return "<undefined>";
-						break;
-				}
-			}
-			return result;
-		}
-		public Image getColumnImage(Object element, int columnIndex) {
-			if (columnIndex == 0) {
-				return null; // TODO
-			}
-			return null;
-		}
-		/* (non-Javadoc)
-		 * @see org.eclipse.jface.viewers.IFontProvider#getFont(java.lang.Object)
-		 */
-		public Font getFont(Object element, int columnIndex) {
-			if (element != null) {
-				IEnvironmentVariable var = (IEnvironmentVariable) element;
-				switch (columnIndex) {
-					case 1: // value
-						if (var.getValue() == null) {
-							return JFaceResources.getFontRegistry().getItalic(
-									JFaceResources.DIALOG_FONT);
-						}
-						break;
-				}
-			}
-			return null;
-		}
-	}
-
-	private Label createLabel(Composite parent, String text, int hspan) {
-		Label l = new Label(parent, SWT.NONE);
-		l.setFont(parent.getFont());
-		l.setText(text);
-		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
-		gd.horizontalSpan = hspan;
-		gd.grabExcessHorizontalSpace = false;
-		l.setLayoutData(gd);
-		return l;
-	}
-	
-	/**
-	 * Creates a Composite widget
-	 * @param parent the parent composite to add this composite to
-	 * @param font the font to set on the control
-	 * @param columns the number of columns within the composite
-	 * @param hspan the horizontal span the composite should take up on the parent
-	 * @param fill the style for how this composite should fill into its parent
-	 * @param marginwidth the width of the margin to place on the sides of the composite (default is 5, specified by GridLayout)
-	 * @param marginheight the height of the margin to place o the top and bottom of the composite
-	 * @return the new composite
-	 * @since 3.3
-	 */
-	private Composite createComposite(Composite parent, Font font, int columns, int hspan, int fill, int marginwidth, int marginheight) {
-		Composite g = new Composite(parent, SWT.NONE);
-		GridLayout layout = new GridLayout(columns, false);
-		layout.marginWidth = marginwidth;
-		layout.marginHeight = marginheight;
-    	g.setLayout(layout);
-    	g.setFont(font);
-    	GridData gd = new GridData(fill);
-		gd.horizontalSpan = hspan;
-    	g.setLayoutData(gd);
-    	return g;
-	}
-	
-	/**
-	 * Creates and returns a new push button with the given
-	 * label and/or image.
-	 * 
-	 * @param parent parent control
-	 * @param label button label or <code>null</code>
-	 * @param image image of <code>null</code>
-	 * 
-	 * @return a new push button
-	 */
-	private Button createPushButton(Composite parent, String label, Image image) {
-		Button button = new Button(parent, SWT.PUSH);
-		button.setFont(parent.getFont());
-		if (image != null) {
-			button.setImage(image);
-		}
-		if (label != null) {
-			button.setText(label);
-		}
-		GridData gd = new GridData();
-		button.setLayoutData(gd);	
-		setButtonDimensionHint(button);
-		return button;	
-	}	
-
-	/**
-	 * Returns a width hint for a button control.
-	 */
-	private int getButtonWidthHint(Button button) {
-		button.setFont(JFaceResources.getDialogFont());
-		PixelConverter converter = new PixelConverter(button);
-		int widthHint = converter.convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
-		return Math.max(widthHint, button.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x);
-	}
-	
-	/**
-	 * Sets width and height hint for the button control.
-	 * <b>Note:</b> This is a NOP if the button's layout data is not
-	 * an instance of <code>GridData</code>.
-	 * 
-	 * @param	the button for which to set the dimension hint
-	 */		
-	private void setButtonDimensionHint(Button button) {
-		Assert.isNotNull(button);
-		Object gd = button.getLayoutData();
-		if (gd instanceof GridData) {
-			((GridData)gd).widthHint = getButtonWidthHint(button);	
-			((GridData)gd).horizontalAlignment = GridData.FILL;	 
-		}
-	}		
-	
-	/**
-	 * Creates and configures the table that displayed the key/value
-	 * pairs that comprise the environment.
-	 * @param parent the composite in which the table should be created
-	 */
-	protected void createEnvironmentTable(Composite parent) {
-		Font font = parent.getFont();
-		// Create table composite
-		Composite tableComposite = createComposite(parent, font, 1, 1, GridData.FILL_BOTH, 0, 0);
-		// Create table
-		environmentTable = new TableViewer(tableComposite, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI | SWT.FULL_SELECTION);
-		Table table = environmentTable.getTable();
-		table.setLayout(new GridLayout());
-		table.setLayoutData(new GridData(GridData.FILL_BOTH));
-		table.setHeaderVisible(true);
-		table.setLinesVisible(true);
-		table.setFont(font);
-		environmentTable.setContentProvider(new IEnvironmentVariableContentProvider());
-		environmentTable.setLabelProvider(new IEnvironmentVariableLabelProvider());
-		environmentTable.setColumnProperties(new String[] {P_VARIABLE, P_VALUE});
-		environmentTable.addSelectionChangedListener(new ISelectionChangedListener() {
-			public void selectionChanged(SelectionChangedEvent event) {
-				handleTableSelectionChanged(event);
-			}
-		});
-		environmentTable.addDoubleClickListener(new IDoubleClickListener() {
-			public void doubleClick(DoubleClickEvent event) {
-				if (!environmentTable.getSelection().isEmpty()) {
-					handleEnvEditButtonSelected();
-				}
-			}
-		});
-		// Create columns
-		final TableColumn tc1 = new TableColumn(table, SWT.NONE, 0);
-		tc1.setText(envTableColumnHeaders[0]);
-		final TableColumn tc2 = new TableColumn(table, SWT.NONE, 1);
-		tc2.setText(envTableColumnHeaders[1]);
-		final Table tref = table;
-		final Composite comp = tableComposite;
-		tableComposite.addControlListener(new ControlAdapter() {
-			public void controlResized(ControlEvent e) {
-				Rectangle area = comp.getClientArea();
-				Point size = tref.computeSize(SWT.DEFAULT, SWT.DEFAULT);
-				ScrollBar vBar = tref.getVerticalBar();
-				int width = area.width - tref.computeTrim(0,0,0,0).width - 2;
-				if (size.y > area.height + tref.getHeaderHeight()) {
-					Point vBarSize = vBar.getSize();
-					width -= vBarSize.x;
-				}
-				Point oldSize = tref.getSize();
-				if (oldSize.x > area.width) {
-					tc1.setWidth(width/2-1);
-					tc2.setWidth(width - tc1.getWidth());
-					tref.setSize(area.width, area.height);
-				} else {
-					tref.setSize(area.width, area.height);
-					tc1.setWidth(width/2-1);
-					tc2.setWidth(width - tc1.getWidth());
-				}
-			}
-		});
-	}
-	
-	/**
-	 * Responds to a selection changed event in the environment table
-	 * @param event the selection change event
-	 */
-	protected void handleTableSelectionChanged(SelectionChangedEvent event) {
-		int size = ((IStructuredSelection)event.getSelection()).size();
-		envEditButton.setEnabled(size == 1);
-		envRemoveButton.setEnabled(size > 0);
-		envUndefButton.setEnabled(size > 0);
-	}
-	
-	/**
-	 * Creates the add/edit/remove buttons for the environment table
-	 * @param parent the composite in which the buttons should be created
-	 */
-	protected void createTableButtons(Composite parent) {
-		// Create button composite
-		Composite buttonComposite = createComposite(parent, parent.getFont(), 1, 1, GridData.VERTICAL_ALIGN_BEGINNING | GridData.HORIZONTAL_ALIGN_END, 0, 0);
-
-		// Create buttons
-		envAddButton = createPushButton(buttonComposite, "New", null); 
-		envAddButton.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent event) {
-				handleEnvAddButtonSelected();
-			}
-		});
-		envEditButton = createPushButton(buttonComposite, "Edit", null); 
-		envEditButton.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent event) {
-				handleEnvEditButtonSelected();
-			}
-		});
-		envEditButton.setEnabled(false);
-		envUndefButton = createPushButton(buttonComposite, "Undefine", null); 
-		envUndefButton.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent event) {
-				handleEnvUndefineButtonSelected();
-			}
-		});
-		envUndefButton.setEnabled(false);
-		envRemoveButton = createPushButton(buttonComposite, "Remove", null); 
-		envRemoveButton.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent event) {
-				handleEnvRemoveButtonSelected();
-			}
-		});
-		envRemoveButton.setEnabled(false);
-	}
-	
-	/**
-	 * Adds a new environment variable to the table.
-	 */
-	protected void handleEnvAddButtonSelected() {
-		VariableInputDialog dialog = new VariableInputDialog(getShell(), 
-				"Add variable",
-				"Name",
-				"",
-				"");
-		
-		if (dialog.open() != Window.OK) {
-			return;
-		}
-		
-		String name = dialog.getName();
-		String value = dialog.getValue();
-		
-		if (name != null && value != null && name.length() > 0) {
-			addVariable(new EnvironmentVariable(name.trim(), value.trim()));
-		}
-	}
-	
-	/**
-	 * Attempts to add the given variable. Returns whether the variable
-	 * was added or not (as when the user answers not to overwrite an
-	 * existing variable).
-	 * @param variable the variable to add
-	 * @return whether the variable was added
-	 */
-	protected boolean addVariable(IEnvironmentVariable variable) {
-		String name = variable.getName();
-		
-		IEnvironmentVariableBlock block = (IEnvironmentVariableBlock) environmentTable.getInput();
-		
-		IEnvironmentVariable existing = block.getVariable(name);
-		if (existing != null) {
-			boolean overWrite = MessageDialog.openQuestion(getShell(), 
-					"Overwrite variable?",
-					MessageFormat.format("Variable ''{0}'' already exists; overwrite?", name)); 
-			if (!overWrite) {
-				return false;
-			}
-		}
-		block.define(variable.getName(), variable.getValue());
-		updatePane();
-		return true;
-	}
-	
-	/**
-	 * Creates an editor for the value of the selected environment variable.
-	 */
-	private void handleEnvEditButtonSelected() {
-		IStructuredSelection sel = (IStructuredSelection) environmentTable.getSelection();
-		IEnvironmentVariable var = (IEnvironmentVariable) sel.getFirstElement();
-		if (var == null) {
-			return;
-		}
-		String originalName = var.getName();
-		String value = var.getValue();
-		if (value == null)
-			value = "";
-		
-		VariableInputDialog dialog = new VariableInputDialog(getShell(), "Edit variable",
-				"Name", originalName, value);
-		
-		dialog.focusOnValue();
-		
-		if (dialog.open() != Window.OK) {
-			return;
-		}
-		String name = dialog.getName();
-		value = dialog.getValue();
-		if (!originalName.equals(name)) {
-			if (addVariable(new EnvironmentVariable(name, value))) {
-				environmentTable.remove(var);
-			}
-		} else {
-			var.setValue(value);
-			environmentTable.update(var, null);
-			updatePane();
-		}
-	}
-
-	/**
-	 * Removes the selected environment variable from the table.
-	 */
-	private void handleEnvRemoveButtonSelected() {
-		IStructuredSelection sel = (IStructuredSelection) environmentTable.getSelection();
-		IEnvironmentVariableBlock block = (IEnvironmentVariableBlock) environmentTable.getInput();
-		for (Object obj : sel.toList()) {
-			IEnvironmentVariable var = (IEnvironmentVariable) obj;
-			block.remove(var);
-		}
-		updatePane();
-	}
-
-	/**
-	 * Undefines the selected environment variables in the table.
-	 */
-	private void handleEnvUndefineButtonSelected() {
-		IStructuredSelection sel = (IStructuredSelection) environmentTable.getSelection();
-		environmentTable.getControl().setRedraw(false);
-		for (Object obj : sel.toList()) {
-			IEnvironmentVariable var = (IEnvironmentVariable) obj;
-			var.setValue(null);
-		}
-		environmentTable.getControl().setRedraw(true);
-		updatePane();
-	}
-
-	public void initializeFrom(IEnvironmentVariableBlock envBlock) {
-		// make a copy for the input
-		IEnvironmentVariableBlock copy = new EnvironmentVariableBlock();
-		for (IEnvironmentVariable variable : envBlock.getVariables()) {
-			copy.define(variable.getName(), variable.getValue());
-		}
-		environmentTable.setInput(copy);
-	}
-	
-	public void performApply(IEnvironmentVariableBlock envBlock) {	
-		envBlock.clear();
-		
-		IEnvironmentVariableBlock copy = (IEnvironmentVariableBlock) environmentTable.getInput();
-		for (IEnvironmentVariable variable : copy.getVariables()) {
-			envBlock.define(variable.getName(), variable.getValue());
-		}
-	}
-
-	protected void updatePane() {
-		environmentTable.refresh();
-	}
-}

Copied: trunk/common/org.maemo.esbox.ui/src/org/maemo/esbox/ui/env/EnvironmentTable.java (from rev 833, trunk/common/org.maemo.esbox.ui/src/org/maemo/esbox/ui/env/EnvironmentTab.java)
===================================================================
--- trunk/common/org.maemo.esbox.ui/src/org/maemo/esbox/ui/env/EnvironmentTable.java	                        (rev 0)
+++ trunk/common/org.maemo.esbox.ui/src/org/maemo/esbox/ui/env/EnvironmentTable.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -0,0 +1,502 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007, 2008 Keith Seitz and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     Keith Seitz (keiths at redhat.com) - initial implementation
+ *     IBM Corporation - integration and code cleanup
+ *     Ed Swartz (Nokia) - adapted for ESbox and for proper use of content provider
+ *******************************************************************************/
+package org.maemo.esbox.ui.env;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.dialogs.*;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.viewers.*;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.*;
+import org.maemo.esbox.core.env.*;
+
+import java.text.MessageFormat;
+
+/**
+ * Generic UI for configuring an environment block.
+ * This may be used in a preference page or a launch configuration or
+ * anything else... unlike the stock Eclipse UI.
+ */
+public class EnvironmentTable extends Composite {
+
+	public interface IListener {
+		void changed(EnvironmentTable environmentTable);
+	}
+
+	private IListener listener;
+	
+	/**
+	 * @param parent
+	 * @param description
+	 */
+	public EnvironmentTable(Composite parent, String description) {
+		super(parent, SWT.NONE);
+		
+		GridLayout layout = new GridLayout(2, false);
+		setLayout(layout);
+		
+		// Create main composite
+		Composite mainComposite = new Composite(this, SWT.NONE);
+		mainComposite.setLayout(new GridLayout(2, false));
+		mainComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+		
+		//PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(), IDebugHelpContextIds.LAUNCH_CONFIGURATION_DIALOG_ENVIRONMENT_TAB);
+		
+		// Create label, add it to the parent to align the right side buttons with the top of the table
+		createLabel(mainComposite, description, 2);
+
+		createEnvironmentTable(mainComposite);
+		createTableButtons(mainComposite);
+		
+		Dialog.applyDialogFont(mainComposite);
+		
+		listener = null;
+	}
+
+	public void setListener(IListener listener) {
+		this.listener = listener;
+	}
+	
+	protected TableViewer environmentTable;
+	protected String[] envTableColumnHeaders = {
+			"Variable",
+			"Value"
+	};
+	protected static final String P_VARIABLE = "variable"; //$NON-NLS-1$
+	protected static final String P_VALUE = "value"; //$NON-NLS-1$
+	protected Button envAddButton;
+	protected Button envEditButton;
+	protected Button envRemoveButton;
+	private Button envUndefButton;
+	private IEnvironmentModifierBlock envBlockModel;
+	
+	/**
+	 * Content provider for the environment table
+	 */
+	protected class IEnvironmentOperationContentProvider implements IStructuredContentProvider {
+		public Object[] getElements(Object inputElement) {
+			IEnvironmentModifierBlock block = (IEnvironmentModifierBlock) inputElement;
+			return block.getOperations();
+		}
+		public void dispose() {
+		}
+		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+			if (newInput == null){
+				return;
+			}
+			if (viewer instanceof TableViewer){
+				TableViewer tableViewer = (TableViewer) viewer;
+				if (tableViewer.getTable().isDisposed()) {
+					return;
+				}
+				tableViewer.setComparator(new ViewerComparator() {
+					public int compare(Viewer iviewer, Object e1, Object e2) {
+						if (e1 == null) {
+							return -1;
+						} else if (e2 == null) {
+							return 1;
+						} else {
+							return ((IEnvironmentOperation)e1).getName().compareToIgnoreCase(((IEnvironmentOperation)e2).getName());
+						}
+					}
+				});
+			}
+		}
+	}
+	
+	/**
+	 * Label provider for the environment table
+	 */
+	public class IEnvironmentOperationLabelProvider extends LabelProvider implements ITableLabelProvider, ITableFontProvider {
+		/**
+		 * 
+		 */
+		private static final String UNDEFINED_LABEL = "<unset at launch>";
+		public String getColumnText(Object element, int columnIndex) 	{
+			String result = null;
+			if (element != null) {
+				IEnvironmentOperation var = (IEnvironmentOperation) element;
+				switch (columnIndex) {
+					case 0: // variable
+						result = var.getName();
+						break;
+					case 1: // value
+						result = var.getValue();
+						if (result == null)
+							return UNDEFINED_LABEL;
+						break;
+				}
+			}
+			return result;
+		}
+		public Image getColumnImage(Object element, int columnIndex) {
+			if (columnIndex == 0) {
+				return null; // TODO
+			}
+			return null;
+		}
+		/* (non-Javadoc)
+		 * @see org.eclipse.jface.viewers.IFontProvider#getFont(java.lang.Object)
+		 */
+		public Font getFont(Object element, int columnIndex) {
+			if (element != null) {
+				IEnvironmentOperation var = (IEnvironmentOperation) element;
+				switch (columnIndex) {
+					case 1: // value
+						if (var.getValue() == null) {
+							return JFaceResources.getFontRegistry().getItalic(
+									JFaceResources.DIALOG_FONT);
+						}
+						break;
+				}
+			}
+			return null;
+		}
+	}
+
+	private Label createLabel(Composite parent, String text, int hspan) {
+		Label l = new Label(parent, SWT.NONE);
+		l.setFont(parent.getFont());
+		l.setText(text);
+		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+		gd.horizontalSpan = hspan;
+		gd.grabExcessHorizontalSpace = false;
+		l.setLayoutData(gd);
+		return l;
+	}
+	
+	/**
+	 * Creates a Composite widget
+	 * @param parent the parent composite to add this composite to
+	 * @param font the font to set on the control
+	 * @param columns the number of columns within the composite
+	 * @param hspan the horizontal span the composite should take up on the parent
+	 * @param fill the style for how this composite should fill into its parent
+	 * @param marginwidth the width of the margin to place on the sides of the composite (default is 5, specified by GridLayout)
+	 * @param marginheight the height of the margin to place o the top and bottom of the composite
+	 * @return the new composite
+	 * @since 3.3
+	 */
+	private Composite createComposite(Composite parent, Font font, int columns, int hspan, int fill, int marginwidth, int marginheight) {
+		Composite g = new Composite(parent, SWT.NONE);
+		GridLayout layout = new GridLayout(columns, false);
+		layout.marginWidth = marginwidth;
+		layout.marginHeight = marginheight;
+    	g.setLayout(layout);
+    	g.setFont(font);
+    	GridData gd = new GridData(fill);
+		gd.horizontalSpan = hspan;
+    	g.setLayoutData(gd);
+    	return g;
+	}
+	
+	/**
+	 * Creates and returns a new push button with the given
+	 * label and/or image.
+	 * 
+	 * @param parent parent control
+	 * @param label button label or <code>null</code>
+	 * @param image image of <code>null</code>
+	 * 
+	 * @return a new push button
+	 */
+	private Button createPushButton(Composite parent, String label, Image image) {
+		Button button = new Button(parent, SWT.PUSH);
+		button.setFont(parent.getFont());
+		if (image != null) {
+			button.setImage(image);
+		}
+		if (label != null) {
+			button.setText(label);
+		}
+		GridData gd = new GridData();
+		button.setLayoutData(gd);	
+		setButtonDimensionHint(button);
+		return button;	
+	}	
+
+	/**
+	 * Returns a width hint for a button control.
+	 */
+	private int getButtonWidthHint(Button button) {
+		button.setFont(JFaceResources.getDialogFont());
+		PixelConverter converter = new PixelConverter(button);
+		int widthHint = converter.convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
+		return Math.max(widthHint, button.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x);
+	}
+	
+	/**
+	 * Sets width and height hint for the button control.
+	 * <b>Note:</b> This is a NOP if the button's layout data is not
+	 * an instance of <code>GridData</code>.
+	 * 
+	 * @param	the button for which to set the dimension hint
+	 */		
+	private void setButtonDimensionHint(Button button) {
+		Assert.isNotNull(button);
+		Object gd = button.getLayoutData();
+		if (gd instanceof GridData) {
+			((GridData)gd).widthHint = getButtonWidthHint(button);	
+			((GridData)gd).horizontalAlignment = GridData.FILL;	 
+		}
+	}		
+	
+	/**
+	 * Creates and configures the table that displayed the key/value
+	 * pairs that comprise the environment.
+	 * @param parent the composite in which the table should be created
+	 */
+	protected void createEnvironmentTable(Composite parent) {
+		Font font = parent.getFont();
+		// Create table composite
+		Composite tableComposite = createComposite(parent, font, 1, 1, GridData.FILL_BOTH, 0, 0);
+		// Create table
+		environmentTable = new TableViewer(tableComposite, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI | SWT.FULL_SELECTION);
+		Table table = environmentTable.getTable();
+		table.setLayout(new GridLayout());
+		table.setLayoutData(new GridData(GridData.FILL_BOTH));
+		table.setHeaderVisible(true);
+		table.setLinesVisible(true);
+		table.setFont(font);
+		environmentTable.setContentProvider(new IEnvironmentOperationContentProvider());
+		environmentTable.setLabelProvider(new IEnvironmentOperationLabelProvider());
+		environmentTable.setColumnProperties(new String[] {P_VARIABLE, P_VALUE});
+		environmentTable.addSelectionChangedListener(new ISelectionChangedListener() {
+			public void selectionChanged(SelectionChangedEvent event) {
+				handleTableSelectionChanged(event);
+			}
+		});
+		environmentTable.addDoubleClickListener(new IDoubleClickListener() {
+			public void doubleClick(DoubleClickEvent event) {
+				if (!environmentTable.getSelection().isEmpty()) {
+					handleEnvEditButtonSelected();
+				}
+			}
+		});
+		// Create columns
+		final TableColumn tc1 = new TableColumn(table, SWT.NONE, 0);
+		tc1.setText(envTableColumnHeaders[0]);
+		final TableColumn tc2 = new TableColumn(table, SWT.NONE, 1);
+		tc2.setText(envTableColumnHeaders[1]);
+		final Table tref = table;
+		final Composite comp = tableComposite;
+		tableComposite.addControlListener(new ControlAdapter() {
+			public void controlResized(ControlEvent e) {
+				Rectangle area = comp.getClientArea();
+				Point size = tref.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+				ScrollBar vBar = tref.getVerticalBar();
+				int width = area.width - tref.computeTrim(0,0,0,0).width - 2;
+				if (size.y > area.height + tref.getHeaderHeight()) {
+					Point vBarSize = vBar.getSize();
+					width -= vBarSize.x;
+				}
+				Point oldSize = tref.getSize();
+				if (oldSize.x > area.width) {
+					tc1.setWidth(width/2-1);
+					tc2.setWidth(width - tc1.getWidth());
+					tref.setSize(area.width, area.height);
+				} else {
+					tref.setSize(area.width, area.height);
+					tc1.setWidth(width/2-1);
+					tc2.setWidth(width - tc1.getWidth());
+				}
+			}
+		});
+	}
+	
+	/**
+	 * Responds to a selection changed event in the environment table
+	 * @param event the selection change event
+	 */
+	protected void handleTableSelectionChanged(SelectionChangedEvent event) {
+		int size = ((IStructuredSelection)event.getSelection()).size();
+		envEditButton.setEnabled(size == 1);
+		envRemoveButton.setEnabled(size > 0);
+		envUndefButton.setEnabled(size > 0);
+	}
+	
+	/**
+	 * Creates the add/edit/remove buttons for the environment table
+	 * @param parent the composite in which the buttons should be created
+	 */
+	protected void createTableButtons(Composite parent) {
+		// Create button composite
+		Composite buttonComposite = createComposite(parent, parent.getFont(), 1, 1, GridData.VERTICAL_ALIGN_BEGINNING | GridData.HORIZONTAL_ALIGN_END, 0, 0);
+
+		// Create buttons
+		envAddButton = createPushButton(buttonComposite, "New", null); 
+		envAddButton.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent event) {
+				handleEnvAddButtonSelected();
+			}
+		});
+		envEditButton = createPushButton(buttonComposite, "Edit", null); 
+		envEditButton.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent event) {
+				handleEnvEditButtonSelected();
+			}
+		});
+		envEditButton.setEnabled(false);
+		envUndefButton = createPushButton(buttonComposite, "Unset", null); 
+		envUndefButton.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent event) {
+				handleEnvUndefineButtonSelected();
+			}
+		});
+		envUndefButton.setEnabled(false);
+		envRemoveButton = createPushButton(buttonComposite, "Remove", null); 
+		envRemoveButton.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent event) {
+				handleEnvRemoveButtonSelected();
+			}
+		});
+		envRemoveButton.setEnabled(false);
+	}
+	
+	/**
+	 * Adds a new environment variable to the table.
+	 */
+	protected void handleEnvAddButtonSelected() {
+		VariableInputDialog dialog = new VariableInputDialog(getShell(), 
+				"Add variable",
+				"Name",
+				"",
+				"");
+		
+		if (dialog.open() != Window.OK) {
+			return;
+		}
+		
+		String name = dialog.getName();
+		String value = dialog.getValue();
+		
+		if (name != null && name.length() > 0) {
+			addVariable(name, value);
+		}
+	}
+	
+	/**
+	 * Attempts to add the given variable. Returns whether the variable
+	 * was added or not (as when the user answers not to overwrite an
+	 * existing variable).
+	 * @param name
+	 * @param value
+	 * @return whether the variable was added
+	 */
+	protected boolean addVariable(String name, String value) {
+		IEnvironmentOperation existing = envBlockModel.findOperation(name);
+		if (existing != null && value != null && existing.getValue() != null) {
+			boolean overWrite = MessageDialog.openQuestion(getShell(), 
+					"Overwrite variable?",
+					MessageFormat.format("Variable ''{0}'' already exists; overwrite?", name)); 
+			if (!overWrite) {
+				return false;
+			}
+		}
+		envBlockModel.define(name, value);
+		updatePane();
+		fireListener();
+		return true;
+	}
+	
+	/**
+	 * Creates an editor for the value of the selected environment variable.
+	 */
+	protected void handleEnvEditButtonSelected() {
+		IStructuredSelection sel = (IStructuredSelection) environmentTable.getSelection();
+		IEnvironmentOperation var = (IEnvironmentOperation) sel.getFirstElement();
+		if (var == null) {
+			return;
+		}
+		String originalName = var.getName();
+		String value = var.getValue();
+		
+		VariableInputDialog dialog = new VariableInputDialog(getShell(), "Edit variable",
+				"Name", originalName, value);
+		
+		dialog.focusOnValue();
+		
+		if (dialog.open() != Window.OK) {
+			return;
+		}
+		String name = dialog.getName();
+		value = dialog.getValue();
+		if (!originalName.equals(name)) {
+			// renamed
+			if (addVariable(name, value)) {
+				envBlockModel.remove(var);
+				environmentTable.refresh();
+			}
+		} else {
+			var.setValue(value);
+			environmentTable.update(var, null);
+			updatePane();
+		}
+		fireListener();
+	}
+
+	/**
+	 * Removes the selected environment variable from the table.
+	 */
+	protected void handleEnvRemoveButtonSelected() {
+		IStructuredSelection sel = (IStructuredSelection) environmentTable.getSelection();
+		for (Object obj : sel.toList()) {
+			IEnvironmentOperation var = (IEnvironmentOperation) obj;
+			envBlockModel.remove(var);
+		}
+		updatePane();
+		fireListener();
+	}
+
+	/**
+	 * Undefines the selected environment variables in the table.
+	 */
+	protected void handleEnvUndefineButtonSelected() {
+		IStructuredSelection sel = (IStructuredSelection) environmentTable.getSelection();
+		environmentTable.getControl().setRedraw(false);
+		for (Object obj : sel.toList()) {
+			IEnvironmentOperation var = (IEnvironmentOperation) obj;
+			var.setValue(null);
+		}
+		environmentTable.getControl().setRedraw(true);
+		updatePane();
+		fireListener();
+	}
+
+	protected void fireListener() {
+		if (listener != null) {
+			listener.changed(this);
+		}
+	}
+	public void initializeFrom(IEnvironmentModifierBlock envBlock) {
+		// make a copy for the input
+		this.envBlockModel = envBlock.copy();
+		environmentTable.setInput(envBlockModel);
+	}
+	
+	public void performApply(IEnvironmentModifierBlock envBlock) {	
+		envBlock.clear();
+		envBlock.apply(envBlockModel);
+	}
+
+	protected void updatePane() {
+		environmentTable.refresh();
+	}
+	
+}


Property changes on: trunk/common/org.maemo.esbox.ui/src/org/maemo/esbox/ui/env/EnvironmentTable.java
___________________________________________________________________
Name: svn:mergeinfo
   + 

Modified: trunk/common/org.maemo.esbox.ui/src/org/maemo/esbox/ui/env/VariableInputDialog.java
===================================================================
--- trunk/common/org.maemo.esbox.ui/src/org/maemo/esbox/ui/env/VariableInputDialog.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.ui/src/org/maemo/esbox/ui/env/VariableInputDialog.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -27,6 +27,8 @@
 	private Text valueText;
 	protected String value;
 	private boolean doFocusOnValue;
+	private boolean unsetValue;
+	private Button unsetValueButton;
 
 	/**
 	 * @param parentShell
@@ -45,6 +47,7 @@
 		
 		doFocusOnValue = false;
 		value = initialValue;
+		unsetValue = (initialValue == null);
 	}
 	
 	/* (non-Javadoc)
@@ -67,14 +70,36 @@
 		valueText = new Text(composite, getInputTextStyle());
 		valueText.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL
                 | GridData.HORIZONTAL_ALIGN_FILL));
-		valueText.setText(value);
+		valueText.setText(value != null ? value : "");
+		if (value == null)
+			valueText.setEnabled(false);
+		
 		valueText.addModifyListener(new ModifyListener() {
 
 			public void modifyText(ModifyEvent e) {
-				value = valueText.getText();
+				if (!unsetValue)
+					value = valueText.getText();
 			}
 			
 		});
+		
+		unsetValueButton = new Button(composite, SWT.CHECK);
+		unsetValueButton.setText("Unset (delete) variable on launch");
+		unsetValueButton.setSelection(value == null);
+		
+		unsetValueButton.addSelectionListener(new SelectionAdapter() {
+			/* (non-Javadoc)
+			 * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+			 */
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				unsetValue = unsetValueButton.getSelection();
+				valueText.setEnabled(!unsetValue);
+			}
+		});
+		
+		if (value == null)
+			value = "";	// have it non-null as an invariant from now on
 
 		getShell().addShellListener(new ShellAdapter() {
 			/* (non-Javadoc)
@@ -83,9 +108,11 @@
 			@Override
 			public void shellActivated(ShellEvent e) {
 				if (doFocusOnValue) {
-					getText().setSelection(0, 0);
-					valueText.forceFocus();
-					valueText.setSelection(0, -1);
+					if (!unsetValue) {
+						getText().setSelection(0, 0);
+						valueText.forceFocus();
+						valueText.setSelection(0, -1);
+					}
 				}
 				doFocusOnValue = false;
 			}
@@ -99,7 +126,7 @@
 	}
 	
 	public String getValue() {
-		return value;
+		return unsetValue ? null : value;
 	}
 
 	/**

Modified: trunk/common/org.maemo.esbox.ui/src/org/maemo/esbox/ui/preferences/ESboxEnvPreferencePage.java
===================================================================
--- trunk/common/org.maemo.esbox.ui/src/org/maemo/esbox/ui/preferences/ESboxEnvPreferencePage.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/common/org.maemo.esbox.ui/src/org/maemo/esbox/ui/preferences/ESboxEnvPreferencePage.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -18,10 +18,9 @@
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.ui.IWorkbench;
 import org.eclipse.ui.IWorkbenchPreferencePage;
-import org.maemo.esbox.core.env.EnvironmentVariableManager;
-import org.maemo.esbox.core.env.IEnvironmentVariableBlock;
+import org.maemo.esbox.core.env.*;
 import org.maemo.esbox.internal.ui.UIActivator;
-import org.maemo.esbox.ui.env.EnvironmentTab;
+import org.maemo.esbox.ui.env.EnvironmentTable;
 
 /**
  * 
@@ -29,21 +28,21 @@
 public class ESboxEnvPreferencePage extends PreferencePage implements
 IWorkbenchPreferencePage {
 
-	private EnvironmentTab envPane;
-	private EnvironmentVariableManager envManager = EnvironmentVariableManager.getInstance();
+	private EnvironmentTable envPane;
+	private IEnvironmentManager envManager = EnvironmentManager.getInstance();
 	
 	/* (non-Javadoc)
 	 * @see org.eclipse.jface.preference.PreferencePage#createContents(org.eclipse.swt.widgets.Composite)
 	 */
 	@Override
 	protected Control createContents(Composite parent) {
-		envPane = new EnvironmentTab(parent, "Edit the environment variables passed to programs launched by ESbox.");
+		envPane = new EnvironmentTable(parent, "Edit the environment variables passed to programs launched by ESbox.");
 		
 		GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
 		gridData.minimumWidth = 600;
 		envPane.setLayoutData(gridData);
 		
-		envPane.initializeFrom(envManager.getGlobalEnvironmentBlock());
+		envPane.initializeFrom(envManager.getGlobalEnvironmentModifierBlock());
 		return envPane;
 	}
 	
@@ -60,8 +59,7 @@
 	 */
 	@Override
 	protected void performDefaults() {
-		envManager.startup();
-		envPane.initializeFrom(envManager.getGlobalEnvironmentBlock());
+		envPane.initializeFrom(envManager.getGlobalEnvironmentModifierBlock());
 		super.performDefaults();
 	}
 	
@@ -70,7 +68,7 @@
 	 */
 	@Override
 	public boolean performOk() {
-		IEnvironmentVariableBlock envBlock = envManager.getGlobalEnvironmentBlock();
+		IEnvironmentModifierBlock envBlock = envManager.getGlobalEnvironmentModifierBlock();
 		envPane.performApply(envBlock);
 		try {
 			envManager.save();

Modified: trunk/cpp/org.maemo.esbox.cpp.launch/src/org/maemo/esbox/cpp/launch/BaseCDTGDBParameterAccessor.java
===================================================================
--- trunk/cpp/org.maemo.esbox.cpp.launch/src/org/maemo/esbox/cpp/launch/BaseCDTGDBParameterAccessor.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/cpp/org.maemo.esbox.cpp.launch/src/org/maemo/esbox/cpp/launch/BaseCDTGDBParameterAccessor.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -18,6 +18,7 @@
 import org.eclipse.core.runtime.*;
 import org.eclipse.core.variables.VariablesPlugin;
 import org.eclipse.debug.core.ILaunchConfiguration;
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
 import org.maemo.esbox.internal.cpp.launch.Activator;
 import org.maemo.esbox.launch.*;
 import org.maemo.esbox.launch.core.AbstractLaunchParameterAccessor;
@@ -273,8 +274,8 @@
 		return proc;
 	}
 
-	public Properties getEnvironmentAsProperty() throws CoreException {
-		return ESboxCppLaunchUtils.getEnvironmentAsProperty(getLaunchConfiguration());
+	public IEnvironmentModifierBlock getEnvironmentModifierBlock() throws CoreException {
+		return ESboxCppLaunchUtils.getEnvironmentModifierBlock(getLaunchConfiguration());
 	}
 
 	@Override

Modified: trunk/cpp/org.maemo.esbox.cpp.launch/src/org/maemo/esbox/cpp/launch/CPPLocalGDBParameterAccessor.java
===================================================================
--- trunk/cpp/org.maemo.esbox.cpp.launch/src/org/maemo/esbox/cpp/launch/CPPLocalGDBParameterAccessor.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/cpp/org.maemo.esbox.cpp.launch/src/org/maemo/esbox/cpp/launch/CPPLocalGDBParameterAccessor.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -15,6 +15,7 @@
 import org.eclipse.core.runtime.*;
 import org.eclipse.debug.core.ILaunchConfiguration;
 import org.maemo.esbox.core.ESboxException;
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
 import org.maemo.esbox.core.machine.IMachine;
 import org.maemo.esbox.core.process.*;
 import org.maemo.esbox.core.sdk.ISDKTarget;
@@ -275,8 +276,8 @@
 		return getOriginal().autoLoadSharedLibrary();
 	}
 
-	public Properties getEnvironmentAsProperty() throws CoreException {
-		return getOriginal().getEnvironmentAsProperty();
+	public IEnvironmentModifierBlock getEnvironmentModifierBlock() throws CoreException {
+		return getOriginal().getEnvironmentModifierBlock();
 	}
 
 	public String[] getProgramArguments() throws CoreException {

Modified: trunk/cpp/org.maemo.esbox.cpp.launch/src/org/maemo/esbox/cpp/launch/CPPRemoteLaunchProxy.java
===================================================================
--- trunk/cpp/org.maemo.esbox.cpp.launch/src/org/maemo/esbox/cpp/launch/CPPRemoteLaunchProxy.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/cpp/org.maemo.esbox.cpp.launch/src/org/maemo/esbox/cpp/launch/CPPRemoteLaunchProxy.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -50,7 +50,7 @@
 
 		fLPA = new CPPRemoteGDBParameterAccessor(launchConfiguration, original);
 	}
-
+	
 	public ILaunchParameterAccessor getLaunchParameterAccessor() {
 		return fLPA;
 	}

Modified: trunk/cpp/org.maemo.esbox.cpp.launch/src/org/maemo/esbox/cpp/launch/CppLaunchConfigurationData.java
===================================================================
--- trunk/cpp/org.maemo.esbox.cpp.launch/src/org/maemo/esbox/cpp/launch/CppLaunchConfigurationData.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/cpp/org.maemo.esbox.cpp.launch/src/org/maemo/esbox/cpp/launch/CppLaunchConfigurationData.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -15,13 +15,11 @@
 import org.eclipse.cdt.debug.mi.core.*;
 import org.eclipse.core.runtime.*;
 import org.eclipse.debug.core.*;
-import org.maemo.esbox.core.process.EnvironmentProperties;
 import org.maemo.esbox.core.sdk.ISDKTarget;
 import org.maemo.esbox.internal.cpp.launch.Activator;
 import org.maemo.esbox.launch.*;
 
-import java.util.Map;
-import java.util.Properties;
+import java.util.*;
 
 /**
  * Encapsulation of operations on launch configuration data, especially
@@ -56,7 +54,14 @@
 		//
 		configuration.setAttribute(ATTR_SDK_NAME, LaunchConfigurationData.getUniqueSDKName(sdkTarget.getSDK()));
 		configuration.setAttribute(ATTR_SDK_TARGET_NAME, sdkTarget.getName());
-		
+
+		// Pass the environment modifier for the process launcher by default, and let
+		// user add variables.  The user can choose to replace variables -- meaning no
+		// global settings are used -- but it's up the process launcher to honor this.
+		//
+		configuration.setAttribute(ILaunchManager.ATTR_APPEND_ENVIRONMENT_VARIABLES, true);
+		configuration.setAttribute(ILaunchManager.ATTR_ENVIRONMENT_VARIABLES, new HashMap<Object, Object>());			
+
 		//-------- Common defaults ----------------
 		// 
 		if (configTypeID.equals(CONFIG_TYPE_MAEMOLOCAL) || 
@@ -97,8 +102,6 @@
 			*/
 		}
 		
-		Properties defaultEnv = sdkTarget.getProcessLauncherFactory().getStandardEnvironment();
-
 		//---------- Maemo Local debug specific --------------------------------
 		//
 		if (configTypeID.equals(CONFIG_TYPE_MAEMOLOCAL) ||
@@ -121,20 +124,6 @@
 			configuration.setAttribute(IGDBServerMILaunchConfigurationConstants.ATTR_REMOTE_TCP, true );
 			configuration.setAttribute(IGDBServerMILaunchConfigurationConstants.ATTR_HOST, DEFAULT_LOCAL_HOST);
 			configuration.setAttribute(IGDBServerMILaunchConfigurationConstants.ATTR_PORT, DEFAULT_GDBSERVER_PORT_NUMBER);
-
-			// Replace native env.
-			configuration.setAttribute(ILaunchManager.ATTR_APPEND_ENVIRONMENT_VARIABLES, false);
-
-			// For applications using D-Bus, this env variable must be set. 
-			// 
-			/*
-			String[] envStrs = {
-					"DISPLAY=:2.0", 
-					"DBUS_SESSION_BUS_ADDRESS=unix:path=/tmp/session_bus_socket"
-					};
-			defaultEnv = EnvironmentProperties.createFromEnvp(envStrs);
-			*/
-			configuration.setAttribute(ILaunchManager.ATTR_ENVIRONMENT_VARIABLES, (Map<Object, Object>) defaultEnv);
 		}
 		
 		//---------- Maemo Remote debug specific --------------------------------
@@ -158,19 +147,6 @@
 			configuration.setAttribute(IGDBServerMILaunchConfigurationConstants.ATTR_HOST, DEFAULT_TARGET_NAME);
 			configuration.setAttribute(IGDBServerMILaunchConfigurationConstants.ATTR_PORT, DEFAULT_GDBSERVER_PORT_NUMBER);
 
-			// For our remote debug, don't pass any host env vars to device program/command.
-			// Instead, add those required by default.
-			configuration.setAttribute(ILaunchManager.ATTR_APPEND_ENVIRONMENT_VARIABLES, false);
-			
-			//XXX: remove once we add IMachine for remote machines
-			String[] envStrs = {
-					"DISPLAY=:0.0", 
-					"DBUS_SESSION_BUS_ADDRESS=unix:path=/tmp/session_bus_socket"
-					};
-			defaultEnv = EnvironmentProperties.createFromEnvp(envStrs);
-			
-			configuration.setAttribute(ILaunchManager.ATTR_ENVIRONMENT_VARIABLES, (Map<Object, Object>) defaultEnv);
-			
 	    	// Set defaults for download method (i.e. launch protocols) related attributes.
 	    	LaunchProtocolFactory.getInstance().setDefaults(configuration);
 		}
@@ -181,19 +157,6 @@
 
 			configuration.setAttribute(ATTR_RUN_STANDALONE, runStandaloneDefault);
 
-			// For our remote debug, don't pass any host env vars to device program/command.
-			// Instead, add those required by default.
-			configuration.setAttribute(ILaunchManager.ATTR_APPEND_ENVIRONMENT_VARIABLES, false);
-			
-			//XXX: remove once we add IMachine for remote machines
-			String[] envStrs = {
-					"DISPLAY=:0.0", 
-					"DBUS_SESSION_BUS_ADDRESS=unix:path=/tmp/session_bus_socket"
-					};
-			defaultEnv = EnvironmentProperties.createFromEnvp(envStrs);
-			
-			configuration.setAttribute(ILaunchManager.ATTR_ENVIRONMENT_VARIABLES, (Map<Object, Object>) defaultEnv);
-			
 	    	// Set defaults for download method (i.e. launch protocols) related attributes.
 	    	LaunchProtocolFactory.getInstance().setDefaults(configuration);
 		}

Modified: trunk/cpp/org.maemo.esbox.cpp.launch/src/org/maemo/esbox/cpp/launch/ESboxCppLaunchUtils.java
===================================================================
--- trunk/cpp/org.maemo.esbox.cpp.launch/src/org/maemo/esbox/cpp/launch/ESboxCppLaunchUtils.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/cpp/org.maemo.esbox.cpp.launch/src/org/maemo/esbox/cpp/launch/ESboxCppLaunchUtils.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -30,7 +30,7 @@
 import org.eclipse.debug.core.sourcelookup.AbstractSourceLookupDirector;
 import org.eclipse.debug.core.sourcelookup.ISourceContainer;
 import org.maemo.esbox.core.ESboxException;
-import org.maemo.esbox.core.process.EnvironmentProperties;
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
 import org.maemo.esbox.core.sdk.ISDKTarget;
 import org.maemo.esbox.internal.api.core.machine.IFileSystemMappingImpl;
 import org.maemo.esbox.internal.cpp.launch.Activator;
@@ -46,16 +46,18 @@
 public class ESboxCppLaunchUtils extends LaunchUtils {
 
 	/**
-	 * Copied from org.eclipse.cdt.launch.AbstractCLaunchDelegate.
+	 * Get the environment modifier block for the configuration from the environment map
+	 * in the configuration.  This does not expand any variables or apply the Replace/Append
+	 * setting.
+	 * <p>
+	 * Copied from org.eclipse.cdt.launch.AbstractCLaunchDelegate to
+	 * handle migrating old variables.
 	 * Don't know why CDT does not put it as public API... LWang. 02/18/08
-	 * 
-	 * Return the save environment variables in the configuration. The array
-	 * does not include the default environment of the target. array[n] :
-	 * name=value
+	 * @return the modifier block, never <code>null</code>
 	 * @throws CoreException
 	 */
 	@SuppressWarnings({ "unchecked", "deprecation" })
-	public static String[] getEnvironment(ILaunchConfiguration config) throws CoreException {
+	public static IEnvironmentModifierBlock getEnvironmentModifierBlock(ILaunchConfiguration config) throws CoreException {
 		try {
 			// Migrate old env settings to new.
 			Map map = config.getAttribute(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_ENVIROMENT_MAP, (Map)null);
@@ -69,23 +71,10 @@
 			wc.setAttribute(ILaunchManager.ATTR_APPEND_ENVIRONMENT_VARIABLES, append);
 		} catch (CoreException e) {
 		}		
-		String[] array = DebugPlugin.getDefault().getLaunchManager().getEnvironment(config);
-		if (array == null) {
-			return new String[0];
-		}
-		return array;
+		
+		return ESboxLaunchUtils.getEnvironmentModifierBlock(config);
 	}
 
-	/**
-	 * @param config
-	 * @return
-	 * @throws CoreException
-	 */
-	public static Properties getEnvironmentAsProperty(ILaunchConfiguration config) throws CoreException {
-		String[] envp = getEnvironment(config);
-		return EnvironmentProperties.createFromEnvp(envp);
-	}
-
 	static public void addSourceMappingToLaunch(
 			IPath sdkTargetPath,
 			IPath hostPath, 

Modified: trunk/cpp/org.maemo.esbox.cpp.launch/src/org/maemo/esbox/cpp/launch/local/ESboxLocalRunLaunchConfigurationTabGroup.java
===================================================================
--- trunk/cpp/org.maemo.esbox.cpp.launch/src/org/maemo/esbox/cpp/launch/local/ESboxLocalRunLaunchConfigurationTabGroup.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/cpp/org.maemo.esbox.cpp.launch/src/org/maemo/esbox/cpp/launch/local/ESboxLocalRunLaunchConfigurationTabGroup.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -13,16 +13,13 @@
 
 import org.eclipse.cdt.launch.ui.CArgumentsTab;
 import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
-import org.eclipse.debug.ui.AbstractLaunchConfigurationTabGroup;
-import org.eclipse.debug.ui.CommonTab;
-import org.eclipse.debug.ui.EnvironmentTab;
-import org.eclipse.debug.ui.ILaunchConfigurationDialog;
-import org.eclipse.debug.ui.ILaunchConfigurationTab;
+import org.eclipse.debug.ui.*;
 import org.eclipse.debug.ui.sourcelookup.SourceLookupTab;
 import org.maemo.esbox.cpp.launch.CppLaunchConfigurationData;
 import org.maemo.esbox.cpp.launch.ui.ESboxCDebuggerTab;
 import org.maemo.esbox.cpp.launch.ui.ESboxCMainTab;
 import org.maemo.esbox.launch.IESboxCDTLaunchConfigurationConstants;
+import org.maemo.esbox.launch.ui.ESboxEnvironmentTab;
 
 /**
  * 
@@ -37,7 +34,7 @@
 		ILaunchConfigurationTab[] tabs = new ILaunchConfigurationTab[] {
 				new ESboxCMainTab(), 
 				new CArgumentsTab(), 
-				new EnvironmentTab(),
+				new ESboxEnvironmentTab(),
 				new ESboxCDebuggerTab(false), 
 				new SourceLookupTab(), 
 				new CommonTab() };

Modified: trunk/cpp/org.maemo.esbox.cpp.launch/src/org/maemo/esbox/cpp/launch/remote/ESboxRemoteRunLaunchConfigurationTabGroup.java
===================================================================
--- trunk/cpp/org.maemo.esbox.cpp.launch/src/org/maemo/esbox/cpp/launch/remote/ESboxRemoteRunLaunchConfigurationTabGroup.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/cpp/org.maemo.esbox.cpp.launch/src/org/maemo/esbox/cpp/launch/remote/ESboxRemoteRunLaunchConfigurationTabGroup.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -15,7 +15,6 @@
 import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
 import org.eclipse.debug.ui.AbstractLaunchConfigurationTabGroup;
 import org.eclipse.debug.ui.CommonTab;
-import org.eclipse.debug.ui.EnvironmentTab;
 import org.eclipse.debug.ui.ILaunchConfigurationDialog;
 import org.eclipse.debug.ui.ILaunchConfigurationTab;
 import org.eclipse.debug.ui.sourcelookup.SourceLookupTab;
@@ -23,6 +22,7 @@
 import org.maemo.esbox.cpp.launch.ui.ESboxRemoteCMainTab;
 import org.maemo.esbox.launch.IESboxCDTLaunchConfigurationConstants;
 import org.maemo.esbox.launch.ui.ESboxDownloadTab;
+import org.maemo.esbox.launch.ui.ESboxEnvironmentTab;
 
 /**
  * 
@@ -37,7 +37,7 @@
 		ILaunchConfigurationTab[] tabs = new ILaunchConfigurationTab[] {
 				new ESboxRemoteCMainTab(),
 				new CArgumentsTab(), 
-				new EnvironmentTab(),
+				new ESboxEnvironmentTab(),
 				new CDebuggerTab(false), 
 				new ESboxDownloadTab(),
 				new SourceLookupTab(), 

Modified: trunk/cpp/org.maemo.esbox.cpp.launch.analysis/src/org/maemo/esbox/cpp/launch/analysis/oprofile/OProfileLaunchConfigurationTabGroup.java
===================================================================
--- trunk/cpp/org.maemo.esbox.cpp.launch.analysis/src/org/maemo/esbox/cpp/launch/analysis/oprofile/OProfileLaunchConfigurationTabGroup.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/cpp/org.maemo.esbox.cpp.launch.analysis/src/org/maemo/esbox/cpp/launch/analysis/oprofile/OProfileLaunchConfigurationTabGroup.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -13,13 +13,13 @@
 import org.eclipse.cdt.launch.ui.CArgumentsTab;
 import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
 import org.eclipse.debug.ui.AbstractLaunchConfigurationTabGroup;
-import org.eclipse.debug.ui.EnvironmentTab;
 import org.eclipse.debug.ui.ILaunchConfigurationDialog;
 import org.eclipse.debug.ui.ILaunchConfigurationTab;
 import org.maemo.esbox.cpp.launch.CppLaunchConfigurationData;
 import org.maemo.esbox.cpp.launch.ui.ESboxCMainTab;
 import org.maemo.esbox.launch.IESboxCDTLaunchConfigurationConstants;
 import org.maemo.esbox.launch.ui.ESboxDownloadTab;
+import org.maemo.esbox.launch.ui.ESboxEnvironmentTab;
 
 /**
  *
@@ -34,7 +34,7 @@
 		ILaunchConfigurationTab[] tabs = new ILaunchConfigurationTab[] {
 				new ESboxCMainTab(),
 				new CArgumentsTab(), 
-				new EnvironmentTab(),
+				new ESboxEnvironmentTab(),
 				new ESboxDownloadTab()
 		};
 		

Modified: trunk/cpp/org.maemo.esbox.cpp.launch.analysis/src/org/maemo/esbox/cpp/launch/analysis/valgrind/ValgrindLaunchConfigurationTabGroup.java
===================================================================
--- trunk/cpp/org.maemo.esbox.cpp.launch.analysis/src/org/maemo/esbox/cpp/launch/analysis/valgrind/ValgrindLaunchConfigurationTabGroup.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/cpp/org.maemo.esbox.cpp.launch.analysis/src/org/maemo/esbox/cpp/launch/analysis/valgrind/ValgrindLaunchConfigurationTabGroup.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -12,10 +12,10 @@
 
 import org.eclipse.cdt.launch.ui.CArgumentsTab;
 import org.eclipse.debug.ui.AbstractLaunchConfigurationTabGroup;
-import org.eclipse.debug.ui.EnvironmentTab;
 import org.eclipse.debug.ui.ILaunchConfigurationDialog;
 import org.eclipse.debug.ui.ILaunchConfigurationTab;
 import org.maemo.esbox.cpp.launch.ui.ESboxCMainTab;
+import org.maemo.esbox.launch.ui.ESboxEnvironmentTab;
 
 /**
  *
@@ -30,7 +30,7 @@
 		ILaunchConfigurationTab[] tabs = new ILaunchConfigurationTab[] {
 				new ESboxCMainTab(),
 				new CArgumentsTab(), 
-				new EnvironmentTab()
+				new ESboxEnvironmentTab()
 		};
 		setTabs(tabs);
 	}

Modified: trunk/cpp/org.maemo.esbox.cpp.launch.cdi.gdb/src/org/maemo/esbox/cpp/launch/cdi/gdb/ESboxMICommandFactory.java
===================================================================
--- trunk/cpp/org.maemo.esbox.cpp.launch.cdi.gdb/src/org/maemo/esbox/cpp/launch/cdi/gdb/ESboxMICommandFactory.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/cpp/org.maemo.esbox.cpp.launch.cdi.gdb/src/org/maemo/esbox/cpp/launch/cdi/gdb/ESboxMICommandFactory.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -56,7 +56,7 @@
 			 * @throws IOException
 			 */
 			protected Process getGDBProcess(String[] args, int launchTimeout, IProgressMonitor monitor) throws IOException {
-				IProcessLauncher launcher = fSDKTarget.getProcessLauncherFactory().createProcessLaunchHandler(
+				IProcessLauncher launcher = fSDKTarget.getProcessLauncherFactory().createProcessLauncher(
 						null, CommandLineArguments.createFromArray(args),
 						null);
 				Process process;

Modified: trunk/cpp/org.maemo.esbox.cpp.launch.dsf.gdb/src/org/maemo/esbox/cpp/launch/dsf/gdb/ui/LocalLaunchConfigurationTabGroup.java
===================================================================
--- trunk/cpp/org.maemo.esbox.cpp.launch.dsf.gdb/src/org/maemo/esbox/cpp/launch/dsf/gdb/ui/LocalLaunchConfigurationTabGroup.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/cpp/org.maemo.esbox.cpp.launch.dsf.gdb/src/org/maemo/esbox/cpp/launch/dsf/gdb/ui/LocalLaunchConfigurationTabGroup.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -18,13 +18,13 @@
 import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
 import org.eclipse.debug.ui.AbstractLaunchConfigurationTabGroup;
 import org.eclipse.debug.ui.CommonTab;
-import org.eclipse.debug.ui.EnvironmentTab;
 import org.eclipse.debug.ui.ILaunchConfigurationDialog;
 import org.eclipse.debug.ui.ILaunchConfigurationTab;
 import org.eclipse.debug.ui.sourcelookup.SourceLookupTab;
 import org.maemo.esbox.cpp.launch.dsf.gdb.DsfLaunchConfigurationData;
 import org.maemo.esbox.cpp.launch.ui.ESboxCMainTab;
 import org.maemo.esbox.launch.IESboxCDTLaunchConfigurationConstants;
+import org.maemo.esbox.launch.ui.ESboxEnvironmentTab;
 
 
 /**
@@ -41,7 +41,7 @@
 		ILaunchConfigurationTab[] tabs = new ILaunchConfigurationTab[] {
 				new ESboxCMainTab(), 
 				new CArgumentsTab(), 
-				new EnvironmentTab(),
+				new ESboxEnvironmentTab(),
 	            new CDebuggerTab(SessionType.REMOTE, false), // note this is from org.eclipse.dd.gdb.ui, not the CDT one.
 				new SourceLookupTab(),
 				new CommonTab() 

Modified: trunk/cpp/org.maemo.esbox.cpp.launch.dsf.gdb/src/org/maemo/esbox/cpp/launch/dsf/gdb/ui/RemoteLaunchConfigurationTabGroup.java
===================================================================
--- trunk/cpp/org.maemo.esbox.cpp.launch.dsf.gdb/src/org/maemo/esbox/cpp/launch/dsf/gdb/ui/RemoteLaunchConfigurationTabGroup.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/cpp/org.maemo.esbox.cpp.launch.dsf.gdb/src/org/maemo/esbox/cpp/launch/dsf/gdb/ui/RemoteLaunchConfigurationTabGroup.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -18,7 +18,6 @@
 import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
 import org.eclipse.debug.ui.AbstractLaunchConfigurationTabGroup;
 import org.eclipse.debug.ui.CommonTab;
-import org.eclipse.debug.ui.EnvironmentTab;
 import org.eclipse.debug.ui.ILaunchConfigurationDialog;
 import org.eclipse.debug.ui.ILaunchConfigurationTab;
 import org.eclipse.debug.ui.sourcelookup.SourceLookupTab;
@@ -26,6 +25,7 @@
 import org.maemo.esbox.cpp.launch.ui.ESboxCMainTab;
 import org.maemo.esbox.launch.IESboxCDTLaunchConfigurationConstants;
 import org.maemo.esbox.launch.ui.ESboxDownloadTab;
+import org.maemo.esbox.launch.ui.ESboxEnvironmentTab;
 
 
 /**
@@ -42,7 +42,7 @@
 		ILaunchConfigurationTab[] tabs = new ILaunchConfigurationTab[] {
 				new ESboxCMainTab(), 
 				new CArgumentsTab(), 
-				new EnvironmentTab(),
+				new ESboxEnvironmentTab(),
 	            new CDebuggerTab(SessionType.REMOTE, false), // note this is from org.eclipse.dd.gdb.ui, not the CDT one.
 	            new ESboxDownloadTab(),
 				new SourceLookupTab(),

Modified: trunk/cpp/org.maemo.esbox.cpp.project.core/src/org/maemo/esbox/cpp/project/core/ESboxOldMakeBuilder.java
===================================================================
--- trunk/cpp/org.maemo.esbox.cpp.project.core/src/org/maemo/esbox/cpp/project/core/ESboxOldMakeBuilder.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/cpp/org.maemo.esbox.cpp.project.core/src/org/maemo/esbox/cpp/project/core/ESboxOldMakeBuilder.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -25,6 +25,8 @@
 import org.eclipse.core.runtime.jobs.ISchedulingRule;
 import org.eclipse.core.runtime.jobs.Job;
 import org.maemo.esbox.core.*;
+import org.maemo.esbox.core.env.EnvironmentManager;
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
 import org.maemo.esbox.core.process.*;
 import org.maemo.esbox.core.sdk.ISDKTarget;
 import org.maemo.esbox.internal.cpp.project.core.Activator;
@@ -172,20 +174,21 @@
 				IProcessLauncherFactory processLauncherFactory = sdkTarget.getProcessLauncherFactory();
 				
 				// Set the environment
-				Properties envMap = new Properties();
+				IEnvironmentModifierBlock envBlock;
 				if (info.appendEnvironment()) {
-					Properties environment = processLauncherFactory.getStandardEnvironment();
-					if (environment != null)
-						envMap.putAll(environment);
+					envBlock = processLauncherFactory.defaultEnvironmentModifierBlock();
+				} else {
+					// don't "replace" the environment
+					envBlock = EnvironmentManager.getInstance().createEnvironmentModifierBlock();
 				}
 				// Add variables from build info
-				envMap.putAll(info.getExpandedEnvironment());
+				envBlock.apply(EnvironmentModifierUtils.createFromMap(info.getExpandedEnvironment()));
 				
 				IPath wdInSb = sdkTarget.convertHostToTargetPath(workingDirectory);
 				
 				// add CWD and PWD since subprocesses may need it
-				envMap.put("CWD", wdInSb.toPortableString()); 
-				envMap.put("PWD", wdInSb.toPortableString()); 
+				envBlock.define("CWD", wdInSb.toPortableString()); 
+				envBlock.define("PWD", wdInSb.toPortableString()); 
 				
 				String[] buildArguments = targets;
 				if (info.isDefaultBuildCmd()) {
@@ -229,7 +232,7 @@
 				List<String> cmdLine = CommandLineArguments.createFromCommandLine(buildCommand.toString());
 				CommandLineArguments.append(cmdLine, buildArguments);
 				IProcessLauncher processLauncher = ProcessLauncherCreator.createProcessLauncher(processLauncherFactory,
-						wdInSb, cmdLine, envMap);
+						wdInSb, cmdLine, envBlock);
 				
 				Process process = processLauncher.createProcess();
 				try {

Modified: trunk/cpp/org.maemo.esbox.cpp.tests/src/org/maemo/esbox/cpp/tests/TestESboxProjectInfo.java
===================================================================
--- trunk/cpp/org.maemo.esbox.cpp.tests/src/org/maemo/esbox/cpp/tests/TestESboxProjectInfo.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/cpp/org.maemo.esbox.cpp.tests/src/org/maemo/esbox/cpp/tests/TestESboxProjectInfo.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -48,6 +48,10 @@
 	@Before
 	public void setUp() throws Exception {
 		TestUtils.disableAutobuild();
+		
+		TestUtils.deleteProject(project1);
+		TestUtils.deleteProject(project2);
+		
 		File proj1Dir = HostUtils.getTemporaryPath().append(PROJ1_GOOD).toFile();
 		TestUtils.copyTreeNoParent(TestUtils.projectRelativeFile(
 				TestActivator.PLUGIN_ID, 

Modified: trunk/device/org.maemo.esbox.device.core/src/org/maemo/esbox/internal/device/core/sbrsh/SBRSHMachine.java
===================================================================
--- trunk/device/org.maemo.esbox.device.core/src/org/maemo/esbox/internal/device/core/sbrsh/SBRSHMachine.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/device/org.maemo.esbox.device.core/src/org/maemo/esbox/internal/device/core/sbrsh/SBRSHMachine.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -13,9 +13,12 @@
 
 import org.eclipse.core.runtime.*;
 import org.maemo.esbox.core.*;
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
 import org.maemo.esbox.core.machine.*;
 import org.maemo.esbox.core.process.IProcessLauncherFactory;
+import org.maemo.esbox.core.process.StandardMachineEnvironmentProvider;
 import org.maemo.esbox.device.core.sbrsh.*;
+import org.maemo.esbox.internal.api.core.IStandardEnvironmentProvider;
 import org.maemo.esbox.internal.api.core.machine.Machine;
 import org.maemo.esbox.internal.api.core.machine.UnixProcessLister;
 import org.maemo.esbox.internal.api.ssh.SSHDeviceMachineController;
@@ -43,6 +46,7 @@
 	private SBRSHConfigurationFile sbrshFile;
 	private SBRSHTarget sbrshTarget;
 	private ISSHMachine deviceMachine;
+	private IStandardEnvironmentProvider environmentProvider;
 
 	/**
 	 * @param hostMachine
@@ -67,6 +71,7 @@
 		
 		parseConfiguration();
 		this.uri = URI.create("sbrsh://" + deviceMachine.getUserName() + "@" + configuration.getTargetName() + "@" + deviceMachine.getURI().getHost());
+		this.environmentProvider = new StandardMachineEnvironmentProvider(hostMachine);
 	}
 
 	/* (non-Javadoc)
@@ -164,7 +169,7 @@
 		return processLister;
 	}
 
-	public Process createProcess(IPath workingDirectory, List<String> commandLine, Properties environment,
+	public Process createProcess(IPath workingDirectory, List<String> commandLine, IEnvironmentModifierBlock environmentModifierBlock,
 			boolean usePty) throws Exception {
 		// check early if the device is inaccessible, otherwise the launch hangs forever
 		// (esp. or only under a VM environment?)
@@ -173,7 +178,7 @@
 			throw new CoreException(status);
 		}
 		
-		return hostMachine.createProcess(workingDirectory, commandLine, environment, usePty);
+		return hostMachine.createProcess(workingDirectory, commandLine, environmentModifierBlock, usePty);
 	}
 
 	public String getEnvironmentVariablePrefix() {
@@ -184,10 +189,16 @@
 		return new SBRSHProcessLauncherFactory(configuration, this);
 	}
 
-	public Map<String, String> getStandardEnvironment() {
-		// it will be the host's environment
-		return hostMachine.getStandardEnvironment();
+	/* (non-Javadoc)
+	 * @see org.maemo.esbox.core.machine.IMachine#getStandardEnvironmentProvider()
+	 */
+	public IStandardEnvironmentProvider getStandardEnvironmentProvider() {
+		return environmentProvider;
 	}
+	
+	public Properties getStandardEnvironment() {
+		return environmentProvider.getRawEnvironment();
+	}
 
 	/* (non-Javadoc)
 	 * @see org.maemo.esbox.core.machine.ISBRSHMachine#getBuildMachine()

Modified: trunk/device/org.maemo.esbox.device.core/src/org/maemo/esbox/internal/device/core/sbrsh/SBRSHProcessLauncher.java
===================================================================
--- trunk/device/org.maemo.esbox.device.core/src/org/maemo/esbox/internal/device/core/sbrsh/SBRSHProcessLauncher.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/device/org.maemo.esbox.device.core/src/org/maemo/esbox/internal/device/core/sbrsh/SBRSHProcessLauncher.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -14,9 +14,9 @@
 
 import org.eclipse.core.runtime.IPath;
 import org.maemo.esbox.core.ESboxException;
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
 import org.maemo.esbox.core.machine.IMachine;
 import org.maemo.esbox.core.process.BaseProcessLauncher;
-import org.maemo.esbox.core.sdk.IPreferenceProvider;
 import org.maemo.esbox.device.core.sbrsh.SBRSHCommandConfiguration;
 
 /**
@@ -32,14 +32,12 @@
 	public SBRSHProcessLauncher(
 			SBRSHCommandConfiguration configuration,
 			IMachine machine, List<String> cmdLine,
-			Properties environment,
-			IPath workingDirectory,
-			IPreferenceProvider prefProvider)
+			IEnvironmentModifierBlock environmentModifierBlock,
+			IPath workingDirectory)
 	{
 		super(encodeArgumentArray(configuration, cmdLine, workingDirectory), 
-				environment,	// "sbrsh" copies all env on host to target. So just set the env on host.
-				null,
-				prefProvider); // needed for logging command. See super class.
+				environmentModifierBlock, 
+				null);
 		this.machine = machine;
 	}
 
@@ -52,14 +50,6 @@
 	}
 	
 	/* (non-Javadoc)
-	 * @see org.maemo.esbox.internal.core.BaseProcessLauncher#getLaunchInfoStandardEnvironment()
-	 */
-	@Override
-	protected Map<String, String> getLaunchInfoStandardEnvironment() {
-		return machine.getStandardEnvironment();
-	}
-	
-	/* (non-Javadoc)
 	 * @see org.maemo.esbox.internal.core.BaseProcessLauncher#setupForLaunch()
 	 */
 	@Override
@@ -105,8 +95,6 @@
 			hostCmdLine.add(configuration.getTargetName());
 		}
 		
-		//String targetWD = workingDirectory == null ? 
-		//		configuration.getTargetBinPath() : workingDirectory.toPortableString();
 		String targetWD = workingDirectory == null ? null : workingDirectory.toPortableString();
 		
 		if (targetWD != null) {
@@ -126,6 +114,6 @@
 	@Override
 	protected Process doCreateProcess() throws Exception {
 		return machine.createProcess(getLaunchCurrentWorkingDirectory(), getLaunchCommandArguments(), 
-				getLaunchEnvironment(), isUsePTY());
+				getLaunchEnvironmentModifierBlock(), isUsePTY());
 	}
 }

Modified: trunk/device/org.maemo.esbox.device.core/src/org/maemo/esbox/internal/device/core/sbrsh/SBRSHProcessLauncherFactory.java
===================================================================
--- trunk/device/org.maemo.esbox.device.core/src/org/maemo/esbox/internal/device/core/sbrsh/SBRSHProcessLauncherFactory.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/device/org.maemo.esbox.device.core/src/org/maemo/esbox/internal/device/core/sbrsh/SBRSHProcessLauncherFactory.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -12,14 +12,13 @@
 package org.maemo.esbox.internal.device.core.sbrsh;
 
 import org.eclipse.core.runtime.IPath;
-import org.maemo.esbox.core.CorePreferenceManager;
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
 import org.maemo.esbox.core.machine.IMachine;
 import org.maemo.esbox.core.process.IProcessLauncher;
 import org.maemo.esbox.device.core.sbrsh.SBRSHCommandConfiguration;
 import org.maemo.esbox.internal.api.core.BaseProcessLauncherFactory;
 
 import java.util.List;
-import java.util.Properties;
 
 /**
  * @author LWang.
@@ -37,36 +36,26 @@
 	 * @param sbrshHostMachine
 	 */
 	public SBRSHProcessLauncherFactory(SBRSHCommandConfiguration config, IMachine sbrshHostMachine) {
-		super(false);
+		super(sbrshHostMachine.getStandardEnvironmentProvider(), false);
 		configuration = config;
 		this.machine = sbrshHostMachine; 
 	}
 
 	/* (non-Javadoc)
-	 * @see org.maemo.esbox.internal.core.BaseProcessLauncherFactory#doCreateProcessLaunchHandler(org.eclipse.core.runtime.IPath, java.util.List, java.util.Properties, org.eclipse.cdt.utils.pty.PTY)
+	 * @see org.maemo.esbox.internal.core.BaseProcessLauncherFactory#docreateProcessLauncher(org.eclipse.core.runtime.IPath, java.util.List, java.util.Properties, org.eclipse.cdt.utils.pty.PTY)
 	 */
 	@Override
-	protected IProcessLauncher doCreateProcessLaunchHandler(
+	protected IProcessLauncher doCreateProcessLauncher(
 			IPath workingDirectory, List<String> cmdLine,
-			Properties environment) {
+			IEnvironmentModifierBlock environmentModifierBlock) {
 		return new SBRSHProcessLauncher(
 					configuration, 
 					machine,
 					cmdLine, 
-					environment != null ? environment : readStandardEnvironment(), 
-					workingDirectory,
-					CorePreferenceManager.getInstance().getPreferenceProvider());
+					environmentModifierBlock, 
+					workingDirectory);
 	}
 
-	/* (non-Javadoc)
-	 * @see org.maemo.esbox.internal.core.BaseProcessLauncherFactory#readStandardEnvironment()
-	 */
-	@Override
-	protected Properties readStandardEnvironment() {
-		// Do nothing. "sbrsh" will just use default host environment.
-		return null;
-	}
-
 	/**
 	 * Get reference to underlying configuration. You can change the
 	 * configuration if needed before creating a process launcher from this

Modified: trunk/device/org.maemo.esbox.device.tests/src/org/maemo/esbox/device/tests/sbrsh/ManualTestSBRSHMachine.java
===================================================================
--- trunk/device/org.maemo.esbox.device.tests/src/org/maemo/esbox/device/tests/sbrsh/ManualTestSBRSHMachine.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/device/org.maemo.esbox.device.tests/src/org/maemo/esbox/device/tests/sbrsh/ManualTestSBRSHMachine.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -6,6 +6,8 @@
 import org.eclipse.core.filesystem.IFileStore;
 import org.eclipse.core.runtime.*;
 import org.maemo.esbox.core.*;
+import org.maemo.esbox.core.env.EnvironmentManager;
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
 import org.maemo.esbox.core.machine.*;
 import org.maemo.esbox.core.process.*;
 import org.maemo.esbox.core.sdk.ISDKTarget;
@@ -95,7 +97,7 @@
 		if (!validateMachine(sbrshMachine)) return;
 		List<String> cmdLine = CommandLineArguments.createFromCommandLine("ls -m");
 		IProcessLauncherFactory factory = sbrshMachine.getProcessLauncherFactory();
-		IProcessLauncher launcher = factory.createProcessLaunchHandler(null, cmdLine, null);
+		IProcessLauncher launcher = factory.createProcessLauncher(null, cmdLine, null);
 		Process process = launcher.createProcess();
 		
 		// this variant waits for the process to finish before consuming output
@@ -122,12 +124,12 @@
 		if (!validateMachine(sbrshMachine)) return;
 		List<String> cmdLine = CommandLineArguments.wrapScriptCommandLineForShell(
 				CommandLineArguments.createFromCommandLine("echo $CC,$LD/"));
-		Properties env = new Properties();
-		env.put("CC", "gcc");
-		env.put("LD", "1 2 3");
+		IEnvironmentModifierBlock envBlock = EnvironmentManager.getInstance().createEnvironmentModifierBlock();
+		envBlock.define("CC", "gcc");
+		envBlock.define("LD", "1 2 3");
 		
 		IProcessLauncherFactory factory = sbrshMachine.getProcessLauncherFactory();
-		IProcessLauncher launcher = factory.createProcessLaunchHandler(null, cmdLine, env);
+		IProcessLauncher launcher = factory.createProcessLauncher(null, cmdLine, envBlock);
 		Process process = launcher.createProcess();
 		int exit = process.waitFor();
 		

Modified: trunk/device/org.maemo.esbox.device.tests/src/org/maemo/esbox/device/tests/sbrsh/ManualTestSBRSHProcessLauncherFactory.java
===================================================================
--- trunk/device/org.maemo.esbox.device.tests/src/org/maemo/esbox/device/tests/sbrsh/ManualTestSBRSHProcessLauncherFactory.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/device/org.maemo.esbox.device.tests/src/org/maemo/esbox/device/tests/sbrsh/ManualTestSBRSHProcessLauncherFactory.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -5,6 +5,7 @@
 
 import org.eclipse.core.runtime.IPath;
 import org.maemo.esbox.core.*;
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
 import org.maemo.esbox.core.machine.*;
 import org.maemo.esbox.core.process.*;
 import org.maemo.esbox.core.sdk.ISDKTarget;
@@ -85,7 +86,7 @@
 		if (!validateMachine(machine)) return;
 		List<String> cmdLine = CommandLineArguments.createFromCommandLine("ls -m");
 		IProcessLauncherFactory factory = new SBRSHProcessLauncherFactory(sbrshConfiguration, machine);
-		IProcessLauncher launcher = factory.createProcessLaunchHandler(null, cmdLine, null);
+		IProcessLauncher launcher = factory.createProcessLauncher(null, cmdLine, null);
 		Process process = launcher.createProcess();
 		
 		// this variant waits for the process to finish before consuming output
@@ -112,12 +113,13 @@
 		if (!validateMachine(machine)) return;
 		List<String> cmdLine = CommandLineArguments.wrapScriptCommandLineForShell(
 				CommandLineArguments.createFromCommandLine("echo $CC,$LD/"));
-		Properties env = new Properties();
-		env.put("CC", "gcc");
-		env.put("LD", "1 2 3");
+		IProcessLauncherFactory factory = new SBRSHProcessLauncherFactory(sbrshConfiguration, machine);
 		
-		IProcessLauncherFactory factory = new SBRSHProcessLauncherFactory(sbrshConfiguration, machine);
-		IProcessLauncher launcher = factory.createProcessLaunchHandler(null, cmdLine, env);
+		IEnvironmentModifierBlock envBlock = factory.defaultEnvironmentModifierBlock();
+		envBlock.define("CC", "gcc");
+		envBlock.define("LD", "1 2 3");
+		
+		IProcessLauncher launcher = factory.createProcessLauncher(null, cmdLine, envBlock);
 		Process process = launcher.createProcess();
 		int exit = process.waitFor();
 		

Modified: trunk/device/org.maemo.esbox.device.tests/src/org/maemo/esbox/device/tests/ssh/AllTests.java
===================================================================
--- trunk/device/org.maemo.esbox.device.tests/src/org/maemo/esbox/device/tests/ssh/AllTests.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/device/org.maemo.esbox.device.tests/src/org/maemo/esbox/device/tests/ssh/AllTests.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -24,6 +24,9 @@
 		TestSuite suite = new TestSuite(
 				"Test for org.maemo.esbox.device.tests.sbrsh");
 		//$JUnit-BEGIN$
+		suite.addTestSuite(TestMountWalker.class);
+		suite.addTestSuite(TestSSHProcess.class);
+		suite.addTestSuite(TestSSHFileSystem.class);
 		//$JUnit-END$
 		return suite;
 	}

Modified: trunk/device/org.maemo.esbox.device.tests/src/org/maemo/esbox/device/tests/ssh/TestSSHProcess.java
===================================================================
--- trunk/device/org.maemo.esbox.device.tests/src/org/maemo/esbox/device/tests/ssh/TestSSHProcess.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/device/org.maemo.esbox.device.tests/src/org/maemo/esbox/device/tests/ssh/TestSSHProcess.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -4,6 +4,8 @@
 package org.maemo.esbox.device.tests.ssh;
 
 import org.maemo.esbox.core.*;
+import org.maemo.esbox.core.env.EnvironmentManager;
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
 import org.maemo.esbox.core.machine.MachineManager;
 import org.maemo.esbox.core.process.CommandLineArguments;
 import org.maemo.esbox.core.tests.core.BaseTest;
@@ -12,7 +14,6 @@
 
 import java.io.*;
 import java.util.List;
-import java.util.Properties;
 
 
 /**
@@ -69,15 +70,21 @@
 	
 	public void testEnvVars() throws Exception {
 		if (!validateMachine(machine)) return;
+		
+		// this purposely includes a string similar to a gdb/mi bogus token that
+		// a buggy qemu emits -- just making sure the SSH process isn't tainted 
+		// by seeing this string here
+		
 		List<String> cmdLine = CommandLineArguments.wrapScriptCommandLineForShell(
-				CommandLineArguments.createFromCommandLine("echo $CC,$LD/ '\\\\$'W00#b= la"));
-		Properties env = new Properties();
-		env.put("CC", "gcc");
-		env.put("LD", "1 2 3");
+				CommandLineArguments.createFromCommandLine("echo $CC,$TERM,$LD/ '\\\\$'W00#b= la"));
+		IEnvironmentModifierBlock envBlock = EnvironmentManager.getInstance().createEnvironmentModifierBlock();
+		envBlock.define("CC", "gcc");
+		envBlock.define("LD", "1 2 3");
+		envBlock.undefine("TERM");
 		
 		Process process = new SSHProcess(sshConfiguration,
 				cmdLine,
-				env,
+				envBlock,
 				null,
 				null);
 		int exit = process.waitFor();
@@ -93,7 +100,7 @@
 		is = process.getInputStream();
 		while ((ch = is.read()) != -1)
 			out.write(ch);
-		assertStdTextEquals("gcc,1 2 3/ $W00#b= la\n", out.toString());
+		assertStdTextEquals("gcc,,1 2 3/ $W00#b= la\n", out.toString());
 
 		assertEquals(0, exit);
 
@@ -191,10 +198,9 @@
 		// this uses an arm binary, which invokes qemu and reveals the bug
 		List<String> cmdLine = CommandLineArguments.createFromCommandLine("sb2 -Qx -m emulate -t chinook40_armel ls / . /not/here");
 		SSHProcessLauncher launcher = new SSHProcessLauncher(sshConfiguration, 
+				null,
 				cmdLine,
-				null,
-				null,
-				CorePreferenceManager.getInstance().getPreferenceProvider());
+				null);
 		launcher.setStreamWrapperFactory(new BuggySB2QEMUStreamWrapperFactory());
 
 		launcher.createProcess();

Modified: trunk/linux/org.maemo.esbox.linux.packages.core/src/org/maemo/esbox/internal/linux/packages/core/aptpkgconfig/AptSystemPackage.java
===================================================================
--- trunk/linux/org.maemo.esbox.linux.packages.core/src/org/maemo/esbox/internal/linux/packages/core/aptpkgconfig/AptSystemPackage.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/linux/org.maemo.esbox.linux.packages.core/src/org/maemo/esbox/internal/linux/packages/core/aptpkgconfig/AptSystemPackage.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -11,6 +11,7 @@
 package org.maemo.esbox.internal.linux.packages.core.aptpkgconfig;
 
 import org.eclipse.core.runtime.*;
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
 import org.maemo.esbox.core.process.*;
 import org.maemo.esbox.internal.linux.packages.core.Activator;
 import org.maemo.esbox.linux.packages.core.*;
@@ -18,7 +19,6 @@
 
 import java.text.MessageFormat;
 import java.util.List;
-import java.util.Properties;
 import java.util.regex.Matcher;
 
 /**
@@ -84,13 +84,13 @@
 			List<String> cmdLine = CommandLineArguments.createFromVarArgs(
 					"apt-get", "--force-yes", "-y", "install", getName());
 			
-			Properties env = launcherFactory.getStandardEnvironment();
-			env = ProcessLauncherUtils.defineProxyVariables(env);
+			IEnvironmentModifierBlock envBlock = launcherFactory.defaultEnvironmentModifierBlock(); 
+			ProcessLauncherUtils.defineProxyVariables(envBlock);
 			
 			IProcessLauncher processLauncher = ProcessLauncherCreator.createProcessLauncher(launcherFactory,
 					null,
 					cmdLine,
-					env);
+					envBlock);
 			
 			Process process = processLauncher.createProcess();
 			processLauncher.redirectToConsole(false, getPackageManager().getSDKTarget(), "Installing apt package(s)");

Modified: trunk/linux/org.maemo.esbox.linux.packages.core/src/org/maemo/esbox/linux/packages/core/debian/DebianPackageInstaller.java
===================================================================
--- trunk/linux/org.maemo.esbox.linux.packages.core/src/org/maemo/esbox/linux/packages/core/debian/DebianPackageInstaller.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/linux/org.maemo.esbox.linux.packages.core/src/org/maemo/esbox/linux/packages/core/debian/DebianPackageInstaller.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -177,7 +177,7 @@
 
 		List<String> cmdLine = CommandLineArguments.createFromVarArgs("dpkg", "-i", targetPackageLocation);
 		
-		IProcessLauncher processLauncher = deviceMachine.getProcessLauncherFactory().createProcessLaunchHandler(
+		IProcessLauncher processLauncher = deviceMachine.getProcessLauncherFactory().createProcessLauncher(
 				null,
 				cmdLine,
 				null);

Modified: trunk/maemosdk/org.maemo.esbox.maemosdk.core/conf/maemo_prefs.xml
===================================================================
--- trunk/maemosdk/org.maemo.esbox.maemosdk.core/conf/maemo_prefs.xml	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/maemosdk/org.maemo.esbox.maemosdk.core/conf/maemo_prefs.xml	2008-10-07 18:56:06 UTC (rev 837)
@@ -9,6 +9,13 @@
 	<entry key="DISPLAY_X_COMMAND_UNIX">Xephyr ${DISPLAY} -host-cursor -screen 800x480x16 -dpi 96 -ac -extension Composite</entry>
 	<entry key="DISPLAY_X_COMMAND_WIN32">c:/cygwin/usr/X11R6/bin/Xwin ${DISPLAY} -lesspointer -swcursor -screen 0 800x480x16 -dpi 96 -ac -extension Composite</entry>
 	<!-- this is initialized dynamically <entry key="DISPLAY_X_COMMAND"></entry> -->
+	
+	<!-- others commands -->	
+	<entry key="X_DISPLAY">:2</entry>
+	<entry key="X_PATH_WIN32">c:/cygwin/bin</entry>
+	<entry key="X_PATH_UNIX"></entry>
+	<!-- this is initialized dynamically <entry key="X_PATH"></entry> -->
+	
 	<entry key="MAEMO_COMMAND">af-sb-init.sh ${ACTIONS}</entry>
 	<entry key="MAEMO_START_ACTION">start</entry>
 	<entry key="MAEMO_RESTART_ACTION">restart</entry>

Modified: trunk/maemosdk/org.maemo.esbox.maemosdk.core/conf/run.sh
===================================================================
--- trunk/maemosdk/org.maemo.esbox.maemosdk.core/conf/run.sh	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/maemosdk/org.maemo.esbox.maemosdk.core/conf/run.sh	2008-10-07 18:56:06 UTC (rev 837)
@@ -9,7 +9,7 @@
 # *
 # * Contributors:
 # *    Raul Herbster (raul at embedded.ufcg.edu.br) (UFCG) - initial API and implementation
-# *    Ed Swartz (Nokia)
+# *    Ed Swartz (Nokia) - additions and changes
 # *******************************************************************************/
 
 __version=0.5
@@ -27,13 +27,17 @@
 
 cd $__location
 
-# gather exports
-IFS=,; for __export in $__export_list; do
-	export $__export
-done
-IFS=" "
+# apply exports and unsets
+if [ "$__export_list" != "-" ] ; then
+	IFS=,; for __export in $__export_list; do
+		case $__export in 
+			-* ) 	unset `echo $__export | sed s/-//` ;;
+			* ) 	export $__export ;;
+		esac
+	done
+	IFS=" "
+fi
 
-
 # Run command
 $__command
 

Modified: trunk/maemosdk/org.maemo.esbox.maemosdk.core/conf/sb1_prefs.xml
===================================================================
--- trunk/maemosdk/org.maemo.esbox.maemosdk.core/conf/sb1_prefs.xml	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/maemosdk/org.maemo.esbox.maemosdk.core/conf/sb1_prefs.xml	2008-10-07 18:56:06 UTC (rev 837)
@@ -10,7 +10,7 @@
 		WHEN ANYTHING ELSE CHANGED which can be merged into existing prefs, 
 		adjust ESboxPreferenceInitializer#RPEFS_VERSION_MINOR -->
 		
-	<entry key="SB1_LOGIN_COMMAND">/scratchbox/login -d ${RUN_SCRIPT_DIRECTORY} "./run.sh ${{DIRECTORY}} \\\"${{{EXPORTS}}}\\\" \\\"${{{COMMAND}}} ${{{ARGS}}}\\\""</entry>
+	<entry key="SB1_LOGIN_COMMAND">/scratchbox/login -d ${RUN_SCRIPT_DIRECTORY} "./${RUN_SCRIPT} ${{DIRECTORY}} \\\"${{{EXPORTS}}}\\\" \\\"${{{COMMAND}}} ${{{ARGS}}}\\\""</entry>
 	<entry key="SB1_SBOX_COMMAND">sb-conf ${ACTIONS} ${OPTIONS}</entry>	
 
 	<entry key="RUN_SCRIPT_LOC">/scratchbox/users/${USER}/home/${USER}/.esbox/</entry>

Modified: trunk/maemosdk/org.maemo.esbox.maemosdk.core/plugin.xml
===================================================================
--- trunk/maemosdk/org.maemo.esbox.maemosdk.core/plugin.xml	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/maemosdk/org.maemo.esbox.maemosdk.core/plugin.xml	2008-10-07 18:56:06 UTC (rev 837)
@@ -346,6 +346,13 @@
                type="org.maemo.esbox.core.adapters.IDefaultExecutionEnvironmentAdapter">
          </adapter>
       </factory>
+       <factory
+            adaptableType="org.maemo.esbox.core.sdk.ISDKTarget"
+            class="org.maemo.esbox.internal.maemosdk.core.adapters.MaemoTargetEnvironmentModifierAdapterFactory">
+         <adapter
+               type="org.maemo.esbox.launch.adapters.ITargetEnvironmentModifierAdapter">
+         </adapter>
+      </factory>
    </extension>
  
   <extension

Added: trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/MaemoEnvironmentUtils.java
===================================================================
--- trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/MaemoEnvironmentUtils.java	                        (rev 0)
+++ trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/MaemoEnvironmentUtils.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+
+package org.maemo.esbox.internal.maemosdk.core;
+
+import org.maemo.esbox.core.CorePreferenceManager;
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
+import org.maemo.esbox.core.machine.IMachine;
+import org.maemo.esbox.core.machine.IVirtualMachine;
+import org.maemo.esbox.maemosdk.core.MaemoPreferenceConstants;
+
+/**
+ * @author eswartz
+ *
+ */
+public class MaemoEnvironmentUtils {
+	/**
+	 * Define DISPLAY for launches under the emulator that need a connection to the X server.
+	 * <p>
+	 * This uses the setting from the X Server preferences.
+	 * @param serverMachine the machine that hosts X
+	 * @param envBlock
+	 */
+	public static void defineEmulatorXDisplayVariable(IMachine serverMachine, IEnvironmentModifierBlock envBlock) {
+		// local launches need DISPLAY that points back to the host machine
+		String display = CorePreferenceManager.getInstance().getRegisteredKeyValue(
+				MaemoPreferenceConstants.X_DISPLAY);
+		if (display != null && display.length() > 0) {
+			String host = "";
+			
+			// XXX: provide an accessor from IMachine
+			if (serverMachine instanceof IVirtualMachine) {
+				host = "10.0.2.2";
+			}
+			
+			envBlock.define("DISPLAY", host + display);
+		}
+	}
+}

Deleted: trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/MaemoPreferenceInitializer.java
===================================================================
--- trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/MaemoPreferenceInitializer.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/MaemoPreferenceInitializer.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -1,41 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007-2008 INdT, (c) 2008 Nokia Corporation
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *    Raul Herbster (UFCG) - initial API and implementation
- *    Ed Swartz (Nokia)
- *******************************************************************************/
-package org.maemo.esbox.internal.maemosdk.core;
-
-import org.eclipse.core.runtime.FileLocator;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
-import org.maemo.esbox.core.*;
-import org.maemo.esbox.maemosdk.core.MaemoPreferenceConstants;
-import org.maemo.esbox.maemosdk.core.MaemoPreferenceMigrator;
-
-/**
- * Initialize maemo preferences.
- */
-public class MaemoPreferenceInitializer extends AbstractPreferenceInitializer {
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer#initializeDefaultPreferences()
-	 */
-	public void initializeDefaultPreferences() {
-		CorePreferenceManager.getInstance().registerAndUpdatePreferences(
-				MaemoPreferenceConstants.class,
-				MaemoPreferenceConstants.getPreferenceStore(),
-				FileLocator.find(Activator.getDefault().getBundle(), 
-						new Path("conf/maemo_prefs.xml"),
-						null),
-				MaemoPreferenceConstants.VERSION_MAJOR,
-				MaemoPreferenceConstants.VERSION_MINOR,
-				new MaemoPreferenceMigrator());
-	}
-}

Deleted: trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/SB1PreferenceInitializer.java
===================================================================
--- trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/SB1PreferenceInitializer.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/SB1PreferenceInitializer.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -1,41 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007-2008 INdT, (c) 2008 Nokia Corporation
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *    Raul Herbster (UFCG) - initial API and implementation
- *    Ed Swartz (Nokia)
- *******************************************************************************/
-package org.maemo.esbox.internal.maemosdk.core;
-
-import org.eclipse.core.runtime.FileLocator;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
-import org.maemo.esbox.core.*;
-import org.maemo.esbox.internal.api.core.OldESboxPreferenceMigrator;
-import org.maemo.esbox.maemosdk.core.SB1PreferenceConstants;
-
-/**
- * Initialize SB1 preferences.
- */
-public class SB1PreferenceInitializer extends AbstractPreferenceInitializer {
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer#initializeDefaultPreferences()
-	 */
-	public void initializeDefaultPreferences() {
-		CorePreferenceManager.getInstance().registerAndUpdatePreferences(
-				SB1PreferenceConstants.class,
-				SB1PreferenceConstants.getPreferenceStore(),
-				FileLocator.find(Activator.getDefault().getBundle(), 
-						new Path("conf/sb1_prefs.xml"),
-						null),
-				SB1PreferenceConstants.VERSION_MAJOR,
-				SB1PreferenceConstants.VERSION_MINOR,
-				new OldESboxPreferenceMigrator());
-	}
-}

Deleted: trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/SB2PreferenceInitializer.java
===================================================================
--- trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/SB2PreferenceInitializer.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/SB2PreferenceInitializer.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -1,41 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007-2008 INdT, (c) 2008 Nokia Corporation
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *    Raul Herbster (UFCG) - initial API and implementation
- *    Ed Swartz (Nokia)
- *******************************************************************************/
-package org.maemo.esbox.internal.maemosdk.core;
-
-import org.eclipse.core.runtime.FileLocator;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
-import org.maemo.esbox.core.*;
-import org.maemo.esbox.internal.api.core.OldESboxPreferenceMigrator;
-import org.maemo.esbox.maemosdk.core.SB2PreferenceConstants;
-
-/**
- * Initialize SB1 preferences.
- */
-public class SB2PreferenceInitializer extends AbstractPreferenceInitializer {
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer#initializeDefaultPreferences()
-	 */
-	public void initializeDefaultPreferences() {
-		CorePreferenceManager.getInstance().registerAndUpdatePreferences(
-				SB2PreferenceConstants.class,
-				SB2PreferenceConstants.getPreferenceStore(),
-				FileLocator.find(Activator.getDefault().getBundle(), 
-						new Path("conf/sb2_prefs.xml"),
-						null),
-				SB2PreferenceConstants.VERSION_MAJOR,
-				SB2PreferenceConstants.VERSION_MINOR,
-				new OldESboxPreferenceMigrator());
-	}
-}

Added: trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/adapters/MaemoTargetEnvironmentModifierAdapter.java
===================================================================
--- trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/adapters/MaemoTargetEnvironmentModifierAdapter.java	                        (rev 0)
+++ trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/adapters/MaemoTargetEnvironmentModifierAdapter.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+
+package org.maemo.esbox.internal.maemosdk.core.adapters;
+
+import org.maemo.esbox.core.env.EnvironmentManager;
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
+import org.maemo.esbox.core.sdk.ISDKTarget;
+import org.maemo.esbox.internal.maemosdk.core.MaemoEnvironmentUtils;
+import org.maemo.esbox.launch.adapters.ITargetEnvironmentModifierAdapter;
+import org.maemo.esbox.launch.core.AbstractLocalLaunchProxy;
+import org.maemo.esbox.launch.core.ILaunchProxy;
+
+/**
+ * Provide the necessary variables for maemo launches.
+ * @author eswartz
+ *
+ */
+public class MaemoTargetEnvironmentModifierAdapter implements ITargetEnvironmentModifierAdapter {
+
+	private final ISDKTarget sdkTarget;
+
+	/**
+	 * @param sdkTarget
+	 */
+	public MaemoTargetEnvironmentModifierAdapter(ISDKTarget sdkTarget) {
+		this.sdkTarget = sdkTarget;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.maemo.esbox.launch.adapters.ITargetEnvironmentModifierAdapter#getTargetEnvironmentModifierBlock(org.maemo.esbox.launch.core.ILaunchProxy)
+	 */
+	public IEnvironmentModifierBlock getTargetEnvironmentModifierBlock(ILaunchProxy launchProxy) {
+		IEnvironmentModifierBlock envBlock = EnvironmentManager.getInstance().createEnvironmentModifierBlock();
+		
+		// first, all launches need proper DBUS access
+		envBlock.define("DBUS_SESSION_BUS_ADDRESS", "unix:path=/tmp/session_bus_socket");
+		
+		if (launchProxy instanceof AbstractLocalLaunchProxy) {
+			MaemoEnvironmentUtils.defineEmulatorXDisplayVariable(sdkTarget.getSDK().getMachine(), envBlock);
+			
+		} else {
+			// remote launches need DISPLAY for its own machine
+			
+			envBlock.define("DISPLAY", ":0");
+			
+		}
+		
+		return envBlock;
+	}
+
+}

Added: trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/adapters/MaemoTargetEnvironmentModifierAdapterFactory.java
===================================================================
--- trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/adapters/MaemoTargetEnvironmentModifierAdapterFactory.java	                        (rev 0)
+++ trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/adapters/MaemoTargetEnvironmentModifierAdapterFactory.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+
+package org.maemo.esbox.internal.maemosdk.core.adapters;
+
+import org.eclipse.core.runtime.IAdapterFactory;
+import org.maemo.esbox.core.sdk.ISDKTarget;
+import org.maemo.esbox.launch.adapters.ITargetEnvironmentModifierAdapter;
+
+/**
+ * 
+ * @author eswartz
+ *
+ */
+public class MaemoTargetEnvironmentModifierAdapterFactory implements IAdapterFactory {
+
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.runtime.IAdapterFactory#getAdapter(java.lang.Object, java.lang.Class)
+	 */
+	public Object getAdapter(Object adaptableObject, Class adapterType) {
+		if (adapterType.equals(ITargetEnvironmentModifierAdapter.class)) {
+			if (adaptableObject instanceof ISDKTarget) {
+				ISDKTarget sdkTarget = (ISDKTarget) adaptableObject;
+				return new MaemoTargetEnvironmentModifierAdapter(sdkTarget);
+			}
+		}
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.runtime.IAdapterFactory#getAdapterList()
+	 */
+	public Class[] getAdapterList() {
+		return new Class[] { ITargetEnvironmentModifierAdapter.class };
+	}
+
+}

Modified: trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/command/scratchbox/CreateMaemoRootstrapSb2Command.java
===================================================================
--- trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/command/scratchbox/CreateMaemoRootstrapSb2Command.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/command/scratchbox/CreateMaemoRootstrapSb2Command.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -13,6 +13,7 @@
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.maemo.esbox.core.*;
 
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
 import org.maemo.esbox.core.process.ProcessLauncherUtils;
 import org.maemo.esbox.core.sdk.ISDK;
 import org.maemo.esbox.internal.maemosdk.core.command.ICommandAbstractor;
@@ -71,13 +72,13 @@
 				SB2PreferenceConstants.SB2_MAEMO_ROOTSTRAP_INSTALL_ACT));
 		params.add(targetName);
 		
-		Properties env = commandAbstractor.getProcessLauncherFactory().getStandardEnvironment();
-		env = ProcessLauncherUtils.defineProxyVariables(env);
+		IEnvironmentModifierBlock envBlock = commandAbstractor.getProcessLauncherFactory().defaultEnvironmentModifierBlock();
+		ProcessLauncherUtils.defineProxyVariables(envBlock);
 		
 		setMonitorAndConsole(
 				monitor,
 				CorePlugin.getDefault().getConsole(true, null, "Installing rootstrap " + targetName));
-		doPerformCommand(params, env, 0);
+		doPerformCommand(params, envBlock, 0);
 		
 		sdk.refresh();
 		

Modified: trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/command/scratchbox/ListAvailableMaemoRootstrapsSb2Command.java
===================================================================
--- trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/command/scratchbox/ListAvailableMaemoRootstrapsSb2Command.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/command/scratchbox/ListAvailableMaemoRootstrapsSb2Command.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -11,6 +11,7 @@
 package org.maemo.esbox.internal.maemosdk.core.command.scratchbox;
 
 import org.maemo.esbox.core.*;
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
 import org.maemo.esbox.core.process.ProcessLauncherUtils;
 import org.maemo.esbox.internal.maemosdk.core.command.ICommandAbstractor;
 import org.maemo.esbox.maemosdk.core.SB2PreferenceConstants;
@@ -50,11 +51,11 @@
 				SB2PreferenceConstants.SB2_MAEMO_ROOTSTRAP_AVAILABLE_ACT);
 		
 		// ensure the proxy is established
-		Properties proxyEnv = commandAbstractor.getProcessLauncherFactory().getStandardEnvironment();
-		proxyEnv = ProcessLauncherUtils.defineProxyVariables(proxyEnv);
+		IEnvironmentModifierBlock proxyEnvBlock = commandAbstractor.getProcessLauncherFactory().defaultEnvironmentModifierBlock();
+		ProcessLauncherUtils.defineProxyVariables(proxyEnvBlock);
 		
 		List<String> available = doPerformCommand(
-				Collections.singletonList(availableAction), proxyEnv, LIST_TIMEOUT);
+				Collections.singletonList(availableAction), proxyEnvBlock, LIST_TIMEOUT);
 
 		// this output has a few header lines
 		List<MaemoRootstrap> targetsAvailable = new ArrayList<MaemoRootstrap>();

Modified: trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/command/scratchbox/ListCputranspSb2Command.java
===================================================================
--- trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/command/scratchbox/ListCputranspSb2Command.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/command/scratchbox/ListCputranspSb2Command.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -13,6 +13,7 @@
 import org.eclipse.core.filesystem.IFileStore;
 import org.eclipse.core.runtime.Path;
 import org.maemo.esbox.core.ESboxException;
+import org.maemo.esbox.core.process.ProcessLauncherUtils;
 import org.maemo.esbox.internal.maemosdk.core.command.ICommandAbstractor;
 import org.maemo.esbox.maemosdk.core.scratchbox.ScratchboxException;
 
@@ -46,8 +47,8 @@
 		expected.add("sb2-qemu-arm");
 		expected.add("sbrsh");
 		
-		Properties properties = commandAbstractor.getProcessLauncherFactory().getStandardEnvironment();
-		String pathenv = (String) properties.get("PATH");
+		Properties env = ProcessLauncherUtils.getSynthesizedEnvironment(commandAbstractor.getProcessLauncherFactory());
+		String pathenv = env.getProperty("PATH");
 		if (pathenv == null) {
 			pathenv = "/usr/bin:/bin";	// XXX
 		}

Modified: trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/command/scratchbox/MaemoCommand.java
===================================================================
--- trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/command/scratchbox/MaemoCommand.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/command/scratchbox/MaemoCommand.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -14,9 +14,11 @@
 import org.eclipse.ui.console.MessageConsole;
 import org.maemo.esbox.core.*;
 
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
 import org.maemo.esbox.core.process.*;
 import org.maemo.esbox.core.sdk.ISDKTarget;
 import org.maemo.esbox.internal.maemosdk.core.Activator;
+import org.maemo.esbox.internal.maemosdk.core.MaemoEnvironmentUtils;
 import org.maemo.esbox.internal.maemosdk.core.command.ICommandAbstractor;
 import org.maemo.esbox.maemosdk.core.MaemoPreferenceConstants;
 import org.maemo.esbox.maemosdk.core.scratchbox.ScratchboxException;
@@ -77,8 +79,12 @@
 		maemoCommand = this.replaceActions(maemoCommand,params.get(0));
 		
 		IProcessLauncherFactory processLauncherFactory = commandAbstractor.getProcessLauncherFactory();
+		
+		IEnvironmentModifierBlock envBlock = processLauncherFactory.defaultEnvironmentModifierBlock();
+		MaemoEnvironmentUtils.defineEmulatorXDisplayVariable(sdkTarget.getSDK().getMachine(), envBlock);
+		
 		IProcessLauncher processLauncher = ProcessLauncherCreator.createProcessLauncher(processLauncherFactory, null,
-				Collections.singletonList(maemoCommand), null);
+				Collections.singletonList(maemoCommand), envBlock);
 		
 		Process process = processLauncher.createProcess();
 		

Modified: trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/command/scratchbox/MaemoRootstrapSb2Command.java
===================================================================
--- trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/command/scratchbox/MaemoRootstrapSb2Command.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/command/scratchbox/MaemoRootstrapSb2Command.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -11,6 +11,7 @@
 package org.maemo.esbox.internal.maemosdk.core.command.scratchbox;
 
 import org.maemo.esbox.core.*;
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
 import org.maemo.esbox.core.process.CommandLineArguments;
 import org.maemo.esbox.core.process.ShellTemplateSubstitutor;
 import org.maemo.esbox.internal.maemosdk.core.command.ICommandAbstractor;
@@ -46,13 +47,13 @@
 	 * Perform the command with the given params as command line arguments,
 	 * with an optional timeout (triggering ScratchboxException if reached)
 	 * @param params command line parameters to maemo-rootstrap
-	 * @param env any environment needed or <code>null</code>
+	 * @param envBlock any environment needed or <code>null</code>
 	 * @param timeout if not 0, timeout in milliseconds
 	 * @return lines from stdout
 	 * @throws ScratchboxException if command execution fails or if timeout reached
 	 */
 	@SuppressWarnings("unchecked")
-	protected List<String> doPerformCommand(List<String> params, Properties env, long timeout)
+	protected List<String> doPerformCommand(List<String> params, IEnvironmentModifierBlock envBlock, long timeout)
 			throws ESboxException {
 		String rootstrapCommand = commandAbstractor.getPreferenceValue(
 					SB2PreferenceConstants.SB2_MAEMO_ROOTSTRAP_COMMAND);
@@ -65,11 +66,11 @@
 		rootstrapCommand = substitutor.substitute(rootstrapCommand);
 		
 		if (console == null) {
-			Process process = createProcess(rootstrapCommand, env);
+			Process process = createProcess(rootstrapCommand, envBlock);
 			List<String> results = getLineInputFromProcessAndWait(process, allowErrors(), timeout);
 			return results;
 		} else {
-			runAndWaitForProcess("Running " + rootstrapCommand, rootstrapCommand, env, timeout);
+			runAndWaitForProcess("Running " + rootstrapCommand, rootstrapCommand, envBlock, timeout);
 			return Collections.EMPTY_LIST;
 		}
 	}

Modified: trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/command/scratchbox/RemoveMaemoRootstrapSb2Command.java
===================================================================
--- trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/command/scratchbox/RemoveMaemoRootstrapSb2Command.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/command/scratchbox/RemoveMaemoRootstrapSb2Command.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -13,6 +13,7 @@
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.maemo.esbox.core.*;
 
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
 import org.maemo.esbox.core.process.ProcessLauncherUtils;
 import org.maemo.esbox.internal.maemosdk.core.command.ICommandAbstractor;
 import org.maemo.esbox.maemosdk.core.SB2PreferenceConstants;
@@ -64,14 +65,14 @@
 		commands.add(action);
 		commands.add(targetName);
 		
-		Properties env = commandAbstractor.getProcessLauncherFactory().getStandardEnvironment();
-		env = ProcessLauncherUtils.defineProxyVariables(env);
+		IEnvironmentModifierBlock envBlock = commandAbstractor.getProcessLauncherFactory().defaultEnvironmentModifierBlock();
+		ProcessLauncherUtils.defineProxyVariables(envBlock);
 		
 		setMonitorAndConsole(
 				monitor,
 				CorePlugin.getDefault().getConsole(true, null, "Removing rootstrap " + targetName));
 
-		doPerformCommand(commands, env, 0);
+		doPerformCommand(commands, envBlock, 0);
 		
 		return Boolean.TRUE;
 	}

Modified: trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/command/scratchbox/ScratchboxCommand.java
===================================================================
--- trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/command/scratchbox/ScratchboxCommand.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/command/scratchbox/ScratchboxCommand.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -15,6 +15,7 @@
 import org.eclipse.core.runtime.jobs.Job;
 import org.eclipse.ui.console.MessageConsole;
 import org.maemo.esbox.core.*;
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
 import org.maemo.esbox.core.process.*;
 import org.maemo.esbox.internal.maemosdk.core.Activator;
 import org.maemo.esbox.internal.maemosdk.core.command.ICommand;
@@ -226,16 +227,16 @@
 	 * Create a process from the given process launch handler factory and 
 	 * the given command line.
 	 * @param commandLine the command line string
-	 * @param env prperties
+	 * @param envBlock prperties
 	 * @throws ScratchboxException failure to launch process
 	 */
-	public Process createProcess(String commandline, Properties env) throws ESboxException {
+	public Process createProcess(String commandline, IEnvironmentModifierBlock envBlock) throws ESboxException {
 		List<String> cmdLine = CommandLineArguments.createFromCommandLine(commandline);
 		IProcessLauncher processLauncher = ProcessLauncherCreator.createProcessLauncher(
 				commandAbstractor.getProcessLauncherFactory(), 
 				null,
 				cmdLine,
-				env);
+				envBlock);
 		Process process = processLauncher.createProcess();
 		if (console != null) {
 			new PrintStream(console.newMessageStream()).println(commandline);
@@ -259,12 +260,12 @@
 	}
 
 	protected IStatus runAndWaitForProcess(String jobName, final String commandline,
-			Properties env, long timeout) throws ESboxException {
+			IEnvironmentModifierBlock envBlock, long timeout) throws ESboxException {
 		final IProcessLauncher processLauncher = ProcessLauncherCreator.createProcessLauncher(
 				commandAbstractor.getProcessLauncherFactory(), 
 				null,
 				CommandLineArguments.createFromCommandLine(commandline),
-				env);
+				envBlock);
 		processLauncher.usePTY(true);
 		
 		final Process process = processLauncher.createProcess();

Modified: trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/sdk/IScratchboxSDKPlatformArchitectureProvider.java
===================================================================
--- trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/sdk/IScratchboxSDKPlatformArchitectureProvider.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/sdk/IScratchboxSDKPlatformArchitectureProvider.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -10,9 +10,7 @@
  *******************************************************************************/
 package org.maemo.esbox.internal.maemosdk.core.sdk;
 
-import org.eclipse.core.runtime.IPath;
 import org.maemo.esbox.core.sdk.ISDKPlatform;
-import org.maemo.esbox.maemosdk.core.sdk.IScratchboxSDK;
 
 /**
  * Helper interface to identify the platform and architecture

Added: trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/sdk/Scratchbox1EnvironmentProvider.java
===================================================================
--- trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/sdk/Scratchbox1EnvironmentProvider.java	                        (rev 0)
+++ trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/sdk/Scratchbox1EnvironmentProvider.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+
+package org.maemo.esbox.internal.maemosdk.core.sdk;
+
+import org.maemo.esbox.core.ESboxException;
+import org.maemo.esbox.core.process.*;
+import org.maemo.esbox.core.process.ProcessLauncherUtils.Results;
+import org.maemo.esbox.core.sdk.ISDKTarget;
+import org.maemo.esbox.internal.api.core.IStandardEnvironmentProvider;
+import org.maemo.esbox.internal.maemosdk.core.Activator;
+
+import java.util.*;
+
+/**
+ * The standard environment provider for scratchbox caches the environment once
+ * per SDK target.
+ * @author eswartz
+ *
+ */
+public class Scratchbox1EnvironmentProvider implements
+		IStandardEnvironmentProvider {
+	public static Map<ISDKTarget, Properties> cachedStdEnvMap = new HashMap<ISDKTarget, Properties>();
+	private final ISDKTarget sdkTarget;
+	
+
+	/**
+	 * @param sdkTarget
+	 */
+	public Scratchbox1EnvironmentProvider(ISDKTarget sdkTarget) {
+		this.sdkTarget = sdkTarget;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.maemo.esbox.internal.api.core.IStandardEnvironmentProvider#getRawEnvironment()
+	 */
+	public Properties getRawEnvironment() {
+		Properties standardEnv = cachedStdEnvMap.get(sdkTarget);
+		if (standardEnv == null) {
+			// gather arguments by querying a typical shell launched in POSIX mode (sh instead of bash)
+			Scratchbox1ProcessLauncher launcher = new Scratchbox1ProcessLauncher(
+					sdkTarget, null, 
+					CommandLineArguments.createFromVarArgs("sh", "-c", "set"),
+					null);
+			
+			try {
+				Results results = ProcessLauncherUtils.launchAndReadStandardStreams(launcher, null);
+				standardEnv = EnvironmentProperties.createFromShellEnvDump(results.stdout);
+			} catch (ESboxException e) {
+				Activator.getErrorLogger().logError("Failed to read scratchbox environment; using system environment", e);
+				standardEnv = sdkTarget.getSDK().getMachine().getStandardEnvironment();
+			}
+			
+			cachedStdEnvMap.put(sdkTarget, standardEnv);
+		}
+		return standardEnv;
+	}
+	
+	
+	/* (non-Javadoc)
+	 * @see org.maemo.esbox.internal.api.core.IStandardEnvironmentProvider#flushRawEnvironment()
+	 */
+	public void flushRawEnvironment() {
+		cachedStdEnvMap.remove(sdkTarget);
+	}
+
+}

Modified: trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/sdk/Scratchbox1ProcessLauncher.java
===================================================================
--- trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/sdk/Scratchbox1ProcessLauncher.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/sdk/Scratchbox1ProcessLauncher.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -10,12 +10,12 @@
  *******************************************************************************/
 package org.maemo.esbox.internal.maemosdk.core.sdk;
 
-import org.eclipse.core.filesystem.EFS;
-import org.eclipse.core.filesystem.IFileStore;
+import org.eclipse.core.filesystem.*;
 import org.eclipse.core.filesystem.provider.FileInfo;
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.Path;
 import org.maemo.esbox.core.*;
+import org.maemo.esbox.core.env.*;
 import org.maemo.esbox.core.process.*;
 import org.maemo.esbox.core.sdk.ISDKTarget;
 import org.maemo.esbox.internal.maemosdk.core.Activator;
@@ -38,21 +38,26 @@
 public class Scratchbox1ProcessLauncher extends BaseProcessLauncher implements
 		IProcessLauncher {
 
+	/**
+	 * The name of a file copied from the plugin to the sb environment and
+	 * used to ensure environment variables can be passed.  
+	 */
+	private static final String RUN_SCRIPT_NAME = "run.sh";
+	
 	private ISDKTarget sdkTarget;
 	private List<String> originalArguments;
 
 	public Scratchbox1ProcessLauncher(
 			ISDKTarget sdkTarget, 
 			IPath workingDirectory,
-			List<String> cmdLine, Properties environment) {
+			List<String> cmdLine, IEnvironmentModifierBlock environmentModifierBlock) {
 		// in SB 1, the working directory, executable, args, and environment
 		// are encoded in a single command to a wrapper script
 		super(encodeArgumentArray(sdkTarget, workingDirectory, 
 						cmdLine,
-						environment), 
+						environmentModifierBlock), 
 				null,
-				null,
-				sdkTarget);
+				null);
 		if (sdkTarget == null)
 			throw new IllegalArgumentException();
 		this.sdkTarget = sdkTarget;
@@ -67,15 +72,7 @@
 		return sdkTarget + " ";
 	}
 	
-	/* (non-Javadoc)
-	 * @see org.maemo.esbox.internal.core.BaseProcessLauncher#getLaunchInfoStandardEnvironment()
-	 */
 	@Override
-	protected Map<String, String> getLaunchInfoStandardEnvironment() {
-		return sdkTarget.getSDK().getMachine().getStandardEnvironment();
-	}
-	
-	@Override
 	public String getCommandLineString() {
 		return CommandLineArguments.toCommandLine(originalArguments);
 	}
@@ -83,7 +80,7 @@
 	private static List<String> encodeArgumentArray(ISDKTarget sdkTarget, 
 			IPath workingDirectory,  
 			List<String> cmdLine,
-			Properties environment) {
+			IEnvironmentModifierBlock environmentModifierBlock) {
 				
 		// get the location where the launcher script will be copied on the target
 		String runScriptLocation = sdkTarget.getPreferenceValue(SB1PreferenceConstants.RUN_SCRIPT_LOC);
@@ -93,26 +90,15 @@
 			workingDirectory = new Path("/");
 		}
 		
-		// get complete environment to play with
-		Properties fullEnv = new Properties();
-		if (environment != null) {
-			fullEnv.putAll(environment);
-		}
+		List<String> envArgs = encodeEnvironmentModifier(environmentModifierBlock);
 		
-		// sort environment variables, since no longer done in run.sh
-		List<String> envArgs = EnvironmentProperties.createEnvpList(fullEnv, true);
-		
-		// ensure SOMETHING is exported, or else run.sh fails
-		if (envArgs.isEmpty()) {
-			envArgs.add("_DUMMY="); //$NON-NLS-1$
-		}
-		
 		// Encode the launch command by replacing the arguments
 		// representing template arguments with the actual values.
 		//
 		ShellTemplateSubstitutor substitutor = new ShellTemplateSubstitutor();
 		
 		substitutor.define("RUN_SCRIPT_DIRECTORY", runScriptLocation);
+		substitutor.define("RUN_SCRIPT", RUN_SCRIPT_NAME);
 		substitutor.define("DIRECTORY", workingDirectory.toPortableString());
 		
 		String exportsString = CommandLineArguments.toString(envArgs, ",", false); //$NON-NLS-1$
@@ -132,16 +118,50 @@
 	}
 
 
+	/**
+	 * Encode the add/replace and delete operations to run.sh
+	 * @param environmentModifierBlock
+	 * @return list of modifier flags
+	 */
+	private static List<String> encodeEnvironmentModifier(
+			IEnvironmentModifierBlock environmentModifierBlock) {
+		List<String> mods = new ArrayList<String>();
+		if (environmentModifierBlock != null) {
+			for (IEnvironmentOperation operation : environmentModifierBlock.getOperations()) {
+				if (operation.getValue() == null)
+					mods.add("-" + operation.getName());
+				else
+					mods.add(operation.getName() + "=" + operation.getValue());
+			}
+		}
+		if (mods.isEmpty()) {
+			mods.add("-");		// must have something for the argument to be detected by run.sh
+		}
+		return mods;
+	}
+
+	/* A flag is the best way to do this -- see below */
+	private static boolean copiedRunScript;
+	
 	@Override
 	protected void setupForLaunch() throws ESboxException {
-		// first, be sure we're running under the current target
+		// First, be sure we're running under the current target
 		ScratchboxTargetSwitcher.ensureCurrentTarget(sdkTarget);
 
-		IFileStore runScriptLocation = sdkTarget.getMachineFileSystemAccess().getFileStore(new Path(
-				sdkTarget.getPreferenceValue(SB1PreferenceConstants.RUN_SCRIPT_LOC)));
-		IFileStore runScript = runScriptLocation.getChild("run.sh");
+		// 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.
 		
-		if (!runScript.fetchInfo().exists()) {
+		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);
 				
@@ -149,7 +169,7 @@
 				InputStream is = null;
 				try {
 					os = runScript.openOutputStream(EFS.OVERWRITE, null);
-					is = Activator.getPluginRelativeInputStream("./conf/run.sh");
+					is = Activator.getPluginRelativeInputStream("./conf/" + RUN_SCRIPT_NAME);
 					byte[] content = new byte[8192];
 					int len;
 					while ((len = is.read(content)) > 0) {
@@ -164,6 +184,8 @@
 				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);
 			}
@@ -178,7 +200,7 @@
 	protected Process doCreateProcess() throws Exception {
 		return sdkTarget.getSDK().getMachine().createProcess(
 				getLaunchCurrentWorkingDirectory(), getLaunchCommandArguments(), 
-				getLaunchEnvironment(), isUsePTY());
+				getLaunchEnvironmentModifierBlock(), isUsePTY());
 	}
 	
 

Modified: trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/sdk/Scratchbox1ProcessLauncherFactory.java
===================================================================
--- trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/sdk/Scratchbox1ProcessLauncherFactory.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/sdk/Scratchbox1ProcessLauncherFactory.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -11,7 +11,8 @@
 package org.maemo.esbox.internal.maemosdk.core.sdk;
 
 import org.eclipse.core.runtime.IPath;
-import org.maemo.esbox.core.process.IProcessLauncher;
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
+import org.maemo.esbox.core.process.*;
 import org.maemo.esbox.core.sdk.ISDKTarget;
 import org.maemo.esbox.internal.api.core.BaseProcessLauncherFactory;
 
@@ -25,43 +26,20 @@
 		BaseProcessLauncherFactory {
 
 	protected ISDKTarget sdkTarget;
-	private Properties standardEnv;
 	private final boolean runAsRoot;
 
 	public Scratchbox1ProcessLauncherFactory(ISDKTarget sdkTarget, boolean runAsRoot) {
-		super(false);
+		super(new Scratchbox1EnvironmentProvider(sdkTarget), false);
 		this.sdkTarget = sdkTarget;
 		this.runAsRoot = runAsRoot;
 	}
 
-	/**
-	 * The standard environment *should* include the host environment if the Esbox
-	 * environment setting is 'Append', but we don't want to pass these to sb1,
-	 * ever.
-	 */
-	protected Properties readStandardEnvironment() {
-		if (standardEnv == null) {
-			standardEnv = new Properties();
-
-			// ensure that DBUS is visible, if available
-			// XXX: do this more cleanly
-			String value = System.getenv("DBUS_SESSION_BUS_ADDRESS");
-			if (value != null) {
-				standardEnv.put("DBUS_SESSION_BUS_ADDRESS", value);
-			}
-			// don't use system environment; sb1 wants its own isolated context
-			mergeOrSetUserVariables(sdkTarget.getSDK().getMachine().getEnvironmentVariablePrefix(),  
-					standardEnv, null);
-		}
-		return standardEnv;
-	}
-	
 	/* (non-Javadoc)
-	 * @see org.maemo.esbox.core.IProcessLauncherFactory#createProcessLaunchHandler(org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath, org.maemo.esbox.core.List<String>, java.util.Properties)
+	 * @see org.maemo.esbox.core.IProcessLauncherFactory#createProcessLauncher(org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath, org.maemo.esbox.core.List<String>, java.util.Properties)
 	 */
-	protected IProcessLauncher doCreateProcessLaunchHandler(
+	protected IProcessLauncher doCreateProcessLauncher(
 			IPath workingDirectory, List<String> cmdLine,
-			Properties environment) {
+			IEnvironmentModifierBlock envBlock) {
 
 		if (runAsRoot) {
 			cmdLine = new ArrayList<String>(cmdLine);
@@ -70,6 +48,6 @@
 		return new Scratchbox1ProcessLauncher(
 				sdkTarget,
 				workingDirectory, cmdLine,
-				environment != null ? environment : readStandardEnvironment()); 
+				envBlock); 
 	}
 }

Modified: trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/sdk/Scratchbox1SDK.java
===================================================================
--- trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/sdk/Scratchbox1SDK.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/sdk/Scratchbox1SDK.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -21,8 +21,7 @@
 import org.maemo.esbox.maemosdk.core.scratchbox.ScratchboxFacade;
 import org.maemo.esbox.maemosdk.core.sdk.IScratchbox1SDK;
 
-import java.util.ArrayList;
-import java.util.List;
+import java.util.*;
 
 /**
  * SDK for a Scratchbox 1.x environment
@@ -32,7 +31,6 @@
 public class Scratchbox1SDK extends ScratchboxSDK implements IScratchbox1SDK {
 
 	private IPath sdkRoot;
-//	private IPreferenceProvider prefProvider;
 	private final IScratchboxSDKPlatformArchitectureProvider platformArchitectureProvider;
 	
 	/**
@@ -44,10 +42,9 @@
 			IScratchboxSDKPlatformArchitectureProvider platformArchitectureProvider,
 			String version, 
 			IPreferenceProvider prefProvider) {
-		super(machine, version, NAME);
+		super(machine, version, NAME, prefProvider);
 		this.sdkRoot = null;
 		this.platformArchitectureProvider = platformArchitectureProvider;
-		this.prefProvider = prefProvider;
 	}
 
 	public void refresh() {

Modified: trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/sdk/Scratchbox1SDKTarget.java
===================================================================
--- trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/sdk/Scratchbox1SDKTarget.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/sdk/Scratchbox1SDKTarget.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -12,6 +12,8 @@
 
 import org.eclipse.core.runtime.IPath;
 import org.maemo.esbox.core.CorePreferenceConstants;
+import org.maemo.esbox.core.machine.IVirtualMachine;
+import org.maemo.esbox.core.process.EnvironmentModifierUtils;
 import org.maemo.esbox.core.process.IProcessLauncherFactory;
 import org.maemo.esbox.core.sdk.ISDKPlatform;
 import org.maemo.esbox.maemosdk.core.sdk.IScratchbox1SDKTarget;
@@ -52,14 +54,23 @@
 	 * @see org.maemo.esbox.core.ISDKTarget#createProcessLauncher()
 	 */
 	public IProcessLauncherFactory getProcessLauncherFactory() {
-		return new Scratchbox1ProcessLauncherFactory(this, false); 
+		return getProcessLauncherFactory(false);
 	}
 
+	/**
+	 * @param b
+	 * @return
+	 */
+	private IProcessLauncherFactory getProcessLauncherFactory(boolean runAsRoot) {
+		Scratchbox1ProcessLauncherFactory launcherFactory = new Scratchbox1ProcessLauncherFactory(this, runAsRoot);
+		return launcherFactory; 
+	}
+
 	/* (non-Javadoc)
 	 * @see org.maemo.esbox.core.scratchbox.sdk.IScratchboxSDKTarget#getProcessLauncherFactoryForInstall()
 	 */
 	public IProcessLauncherFactory getProcessLauncherFactoryForInstall() {
-		return new Scratchbox1ProcessLauncherFactory(this, true); 
+		return getProcessLauncherFactory(true);
 	}
 	
 

Added: trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/sdk/Scratchbox2EnvironmentProvider.java
===================================================================
--- trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/sdk/Scratchbox2EnvironmentProvider.java	                        (rev 0)
+++ trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/sdk/Scratchbox2EnvironmentProvider.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+
+package org.maemo.esbox.internal.maemosdk.core.sdk;
+
+import org.maemo.esbox.core.ESboxException;
+import org.maemo.esbox.core.process.*;
+import org.maemo.esbox.core.process.ProcessLauncherUtils.Results;
+import org.maemo.esbox.core.sdk.ISDKTarget;
+import org.maemo.esbox.internal.api.core.IStandardEnvironmentProvider;
+import org.maemo.esbox.internal.maemosdk.core.Activator;
+import org.maemo.esbox.maemosdk.core.SB2PreferenceConstants;
+
+import java.util.*;
+
+/**
+ * @author eswartz
+ *
+ */
+public class Scratchbox2EnvironmentProvider implements
+		IStandardEnvironmentProvider {
+	public static Map<ISDKTarget, Properties> cachedStdEnvMap = new HashMap<ISDKTarget, Properties>();
+	private final ISDKTarget sdkTarget;
+	
+
+	/**
+	 * @param sdkTarget
+	 */
+	public Scratchbox2EnvironmentProvider(ISDKTarget sdkTarget) {
+		this.sdkTarget = sdkTarget;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.maemo.esbox.internal.api.core.IStandardEnvironmentProvider#flushRawEnvironment()
+	 */
+	public void flushRawEnvironment() {
+		cachedStdEnvMap.remove(sdkTarget);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.maemo.esbox.internal.api.core.IStandardEnvironmentProvider#getRawEnvironment()
+	 */
+	public Properties getRawEnvironment() {
+		Properties standardEnv = cachedStdEnvMap.get(sdkTarget);
+		if (standardEnv == null) {
+			// gather arguments by querying a typical shell launched in POSIX mode (sh instead of bash)
+			Scratchbox2ProcessLauncher launcher = new Scratchbox2ProcessLauncher(
+					sdkTarget, null, 
+					CommandLineArguments.createFromVarArgs("sh", "-c", "set"),
+					null, 
+					SB2PreferenceConstants.SB2_MAPPING_MODE,
+					false);
+			
+			try {
+				Results results = ProcessLauncherUtils.launchAndReadStandardStreams(launcher, null);
+				standardEnv = EnvironmentProperties.createFromShellEnvDump(results.stdout);
+			} catch (ESboxException e) {
+				Activator.getErrorLogger().logError("Failed to read scratchbox environment; using system environment", e);
+				standardEnv = sdkTarget.getSDK().getMachine().getStandardEnvironment();
+			}
+			
+			cachedStdEnvMap.put(sdkTarget, standardEnv);
+		}
+		return standardEnv;
+	}
+
+}

Modified: trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/sdk/Scratchbox2ProcessLauncher.java
===================================================================
--- trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/sdk/Scratchbox2ProcessLauncher.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/sdk/Scratchbox2ProcessLauncher.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -11,6 +11,7 @@
 package org.maemo.esbox.internal.maemosdk.core.sdk;
 
 import org.eclipse.core.runtime.IPath;
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
 import org.maemo.esbox.core.process.*;
 import org.maemo.esbox.core.sdk.ISDKTarget;
 import org.maemo.esbox.maemosdk.core.SB2PreferenceConstants;
@@ -33,10 +34,10 @@
 			ISDKTarget sdkTarget, 
 			IPath workingDirectory,
 			List<String> cmdLine, 
-			Properties environment,
+			IEnvironmentModifierBlock environmentModifierBlock,
 			String modeKey, boolean runAsRoot) {
-		super(encodeArgumentArray(sdkTarget, cmdLine, modeKey), environment, workingDirectory,
-				sdkTarget);
+		super(encodeArgumentArray(sdkTarget, cmdLine, modeKey), 
+				environmentModifierBlock, workingDirectory);
 		if (runAsRoot) {
 			getLaunchCommandArguments().add(0, "sudo");
 		}
@@ -53,14 +54,6 @@
 		return sdkTarget + " ";
 	}
 	
-	/* (non-Javadoc)
-	 * @see org.maemo.esbox.internal.core.BaseProcessLauncher#getLaunchInfoStandardEnvironment()
-	 */
-	@Override
-	protected Map<String, String> getLaunchInfoStandardEnvironment() {
-		return sdkTarget.getSDK().getMachine().getStandardEnvironment();
-	}
-	
 	private static List<String> encodeArgumentArray(
 			ISDKTarget sdkTarget,
 			List<String> cmdLine,
@@ -107,6 +100,6 @@
 	protected Process doCreateProcess() throws Exception {
 		return sdkTarget.getSDK().getMachine().createProcess(
 				getLaunchCurrentWorkingDirectory(), getLaunchCommandArguments(),
-				getLaunchEnvironment(), isUsePTY());
+				getLaunchEnvironmentModifierBlock(), isUsePTY());
 	}
 }

Modified: trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/sdk/Scratchbox2ProcessLauncherFactory.java
===================================================================
--- trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/sdk/Scratchbox2ProcessLauncherFactory.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/sdk/Scratchbox2ProcessLauncherFactory.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -12,10 +12,12 @@
 
 import org.eclipse.core.runtime.IPath;
 import org.maemo.esbox.core.*;
-import org.maemo.esbox.core.process.EnvironmentProperties;
-import org.maemo.esbox.core.process.IProcessLauncher;
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
+import org.maemo.esbox.core.process.*;
+import org.maemo.esbox.core.process.ProcessLauncherUtils.Results;
 import org.maemo.esbox.core.sdk.ISDKTarget;
 import org.maemo.esbox.internal.api.core.BaseProcessLauncherFactory;
+import org.maemo.esbox.internal.maemosdk.core.Activator;
 
 import java.util.*;
 
@@ -27,7 +29,6 @@
 		BaseProcessLauncherFactory {
 
 	protected ISDKTarget sdkTarget;
-	private Properties standardEnv;
 	private String mappingModeKey;
 	private final boolean runAsRoot;
 	
@@ -35,10 +36,11 @@
 	 * Create a factory and specify whether it is creating commands in build
 	 * mode (sb2 -m maemo) or installation mode (sb2 -e)
 	 * @param sdkTarget
+	 * @param mappingModeKey one of SB2PreferenceConstants.MAPPING_MODE or SB2PreferenceConstants.INSTALL_MAPPING_MODE
 	 * @param isBuildMode true: build mode, false: installation mode
 	 */
 	public Scratchbox2ProcessLauncherFactory(ISDKTarget sdkTarget, String mappingModeKey, boolean runAsRoot) {
-		super(false);
+		super(new Scratchbox2EnvironmentProvider(sdkTarget), false);
 		if (sdkTarget == null)
 			throw new IllegalArgumentException();
 		this.sdkTarget = sdkTarget;
@@ -46,60 +48,19 @@
 		this.runAsRoot = runAsRoot;
 	}
 
-	protected Properties readStandardEnvironment() {
-		if (standardEnv == null) {
-			standardEnv = new Properties();
-			
-			Map<String, String> env = sdkTarget.getSDK().getMachine().getStandardEnvironment();
-			mergeOrSetUserVariables(sdkTarget.getSDK().getMachine().getEnvironmentVariablePrefix(), 
-					standardEnv, env);
-		}
-		return standardEnv;
-	}
-
 	/* (non-Javadoc)
-	 * @see org.maemo.esbox.core.IProcessLauncherFactory#createProcessLaunchHandler(org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath, org.maemo.esbox.core.List<String>, java.util.Properties)
+	 * @see org.maemo.esbox.core.IProcessLauncherFactory#createProcessLauncher(org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath, org.maemo.esbox.core.List<String>, java.util.Properties)
 	 */
-	protected IProcessLauncher doCreateProcessLaunchHandler(
+	protected IProcessLauncher doCreateProcessLauncher(
 			IPath workingDirectory, List<String> cmdLine,
-			Properties environment) {
+			IEnvironmentModifierBlock environmentModifierBlock) {
 
 		return new Scratchbox2ProcessLauncher(
 				sdkTarget,
 				workingDirectory, cmdLine,
-				augmentEnvironment(environment),
+				environmentModifierBlock,
 				mappingModeKey,
 				runAsRoot); 
 	}
 
-	/**
-	 * sbox2 depends on some variables always existing, so avoid attempts
-	 * to run without them.
-	 * @param environment
-	 * @return possibly modified environment
-	 */
-	private Properties augmentEnvironment(Properties environment) {
-		// if no env, then default is used anyway
-		if (environment == null)
-			return null; //readStandardEnvironment();
-		
-		if (environment.containsKey("HOME") && environment.containsKey("SBOX_DIR"))
-			return environment;
-		
-		Properties augmented = EnvironmentProperties.copyProperties(environment);
-		
-		// avoid spurious nil dereferences
-		Object homeDir = getStandardEnvironment().get("HOME");
-		if (homeDir != null)
-			augmented.put("HOME", homeDir);
-		else
-			augmented.put("HOME", "/home/" + sdkTarget.getPreferenceValue(CorePreferenceConstants.USER));
-		Object sboxDir = getStandardEnvironment().get("SBOX_DIR");
-		if (sboxDir != null)
-			augmented.put("SBOX_DIR", sboxDir.toString());
-		else
-			augmented.put("SBOX_DIR", "");
-
-		return augmented;
-	}
 }

Modified: trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/sdk/Scratchbox2SDK.java
===================================================================
--- trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/sdk/Scratchbox2SDK.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/sdk/Scratchbox2SDK.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -42,9 +42,8 @@
 			IMachine machine,
 			IScratchboxSDKPlatformArchitectureProvider platformArchitectureProvider,
 			String version, IPreferenceProvider prefProvider) {
-		super(machine, version, NAME);
+		super(machine, version, NAME, prefProvider);
 		this.platformArchitectureProvider = platformArchitectureProvider;
-		this.prefProvider = prefProvider;
 	}
 
 	public void refresh() {
@@ -105,5 +104,4 @@
 			userName = "ubuntu";
 		return new Path("home").append(userName).append(".scratchbox2").makeAbsolute();
 	}
-	
 }

Modified: trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/sdk/ScratchboxSDK.java
===================================================================
--- trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/sdk/ScratchboxSDK.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/sdk/ScratchboxSDK.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -24,14 +24,15 @@
  */
 public abstract class ScratchboxSDK extends BaseSDK implements IScratchboxSDK {
 
-	protected IPreferenceProvider prefProvider=null;
+	private String cachedCurrentTarget;
+
+	protected IPreferenceProvider prefProvider;
 	
-	
-	public ScratchboxSDK(IMachine machine, String version, String name) {
+	public ScratchboxSDK(IMachine machine, String version, String name, IPreferenceProvider prefProvider) {
 		super(machine, version, name);
+		this.prefProvider = prefProvider;
 	}
 
-	private String cachedCurrentTarget;
 
 	/* (non-Javadoc)
 	 * @see org.maemo.esbox.core.sdk.ISDK#refresh()

Modified: trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/sdk/providers/Scratchbox1SDKProvider.java
===================================================================
--- trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/sdk/providers/Scratchbox1SDKProvider.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/sdk/providers/Scratchbox1SDKProvider.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -19,13 +19,11 @@
 import org.maemo.esbox.internal.api.core.sdk.BaseSDKPlatform;
 import org.maemo.esbox.internal.api.core.sdk.UserAwarePreferenceProviderWrapper;
 import org.maemo.esbox.internal.maemosdk.core.Activator;
-import org.maemo.esbox.internal.maemosdk.core.sdk.IScratchboxSDKPlatformArchitectureProvider;
-import org.maemo.esbox.internal.maemosdk.core.sdk.Scratchbox1SDK;
+import org.maemo.esbox.internal.maemosdk.core.sdk.*;
 import org.maemo.esbox.maemosdk.core.MaemoSDKEngine;
 import org.maemo.esbox.maemosdk.core.MaemoSDKInfo;
 import org.maemo.esbox.maemosdk.core.scratchbox.ScratchboxException;
 import org.maemo.esbox.maemosdk.core.scratchbox.ScratchboxFacade;
-import org.maemo.esbox.maemosdk.core.sdk.IScratchboxSDK;
 import org.maemo.esbox.maemosdk.core.sdk.IScratchboxSDKTarget;
 
 import java.text.MessageFormat;
@@ -57,6 +55,9 @@
 	public List<ISDK> createSDKs() throws ESboxException {
 		ErrorLogger logger = Activator.getErrorLogger();
 		
+		// reset any cached info stored in launchers
+		Scratchbox1EnvironmentProvider.cachedStdEnvMap.clear();
+		
 		List<ISDK> sdks = new ArrayList<ISDK>();
 		for (IMachine machine : MachineRegistry.getInstance().getBuildMachines()) {
 			try {

Modified: trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/sdk/providers/Scratchbox2SDKProvider.java
===================================================================
--- trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/sdk/providers/Scratchbox2SDKProvider.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/internal/maemosdk/core/sdk/providers/Scratchbox2SDKProvider.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -19,11 +19,9 @@
 import org.maemo.esbox.internal.api.core.sdk.BaseSDKPlatform;
 import org.maemo.esbox.internal.api.core.sdk.UserAwarePreferenceProviderWrapper;
 import org.maemo.esbox.internal.maemosdk.core.Activator;
-import org.maemo.esbox.internal.maemosdk.core.sdk.IScratchboxSDKPlatformArchitectureProvider;
-import org.maemo.esbox.internal.maemosdk.core.sdk.Scratchbox2SDK;
+import org.maemo.esbox.internal.maemosdk.core.sdk.*;
 import org.maemo.esbox.maemosdk.core.scratchbox.ScratchboxException;
 import org.maemo.esbox.maemosdk.core.scratchbox.ScratchboxFacade;
-import org.maemo.esbox.maemosdk.core.sdk.IScratchboxSDK;
 import org.maemo.esbox.maemosdk.core.sdk.IScratchboxSDKTarget;
 
 import java.text.MessageFormat;
@@ -57,7 +55,9 @@
 	public List<ISDK> createSDKs() throws ESboxException {
 		ErrorLogger logger = Activator.getErrorLogger();
 
-		
+		// clear any cached info
+		Scratchbox2EnvironmentProvider.cachedStdEnvMap.clear();
+
 		List<ISDK> sdks = new ArrayList<ISDK>();
 		for (IMachine machine : MachineRegistry.getInstance().getBuildMachines()) {
 			// will never find sbox on host (right?!)

Modified: trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/maemosdk/core/MaemoPreferenceConstants.java
===================================================================
--- trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/maemosdk/core/MaemoPreferenceConstants.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/maemosdk/core/MaemoPreferenceConstants.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -48,9 +48,13 @@
 	public static final String START_GDB_SERVER = "START_GDB_SERVER";
 	public static final String USE_X_HOST = "USE_X_HOST";
 	public static final String X_HOST_CMD = "X_HOST_CMD";
+	public static final String X_DISPLAY = "X_DISPLAY";
+	public static final String X_PATH = "X_PATH";
 
 	/* OS-specific defaults */
 	static final String DISPLAY_X_COMMAND_WIN32 = "DISPLAY_X_COMMAND_WIN32";
 	static final String DISPLAY_X_COMMAND_UNIX = "DISPLAY_X_COMMAND_UNIX";
+	static final String X_PATH_WIN32 = "X_PATH_WIN32";
+	static final String X_PATH_UNIX = "X_PATH_UNIX";
 
 }

Deleted: trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/maemosdk/core/MaemoPreferenceMigrator.java
===================================================================
--- trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/maemosdk/core/MaemoPreferenceMigrator.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/maemosdk/core/MaemoPreferenceMigrator.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -1,46 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2008 Nokia Corporation
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *    Ed Swartz (Nokia) - initial API and implementation
- *******************************************************************************/
-
-package org.maemo.esbox.maemosdk.core;
-
-import org.maemo.esbox.core.HostUtils;
-import org.maemo.esbox.core.IPreferenceMigrator;
-import org.maemo.esbox.internal.api.core.OldESboxPreferenceMigrator;
-
-import java.util.Properties;
-
-/**
- * To migrate preferences, we use the 1.4 -> newer conversion and also pick
- * an OS-specific initial value for the X server command.
- * @author eswartz
- *
- */
-public class MaemoPreferenceMigrator extends OldESboxPreferenceMigrator
-		implements IPreferenceMigrator {
-
-	/* (non-Javadoc)
-	 * @see org.maemo.esbox.internal.api.core.OldESboxPreferenceMigrator#adjustDefaultSettings(java.util.Properties)
-	 */
-	@Override
-	public void adjustDefaultSettings(Properties newPropertyDefaults) {
-		super.adjustDefaultSettings(newPropertyDefaults);
-		// adjust any environment-dependent defaults
-		String hostEnvKey;
-		if (HostUtils.isWindows())
-			hostEnvKey = MaemoPreferenceConstants.DISPLAY_X_COMMAND_WIN32;
-		else
-			hostEnvKey = MaemoPreferenceConstants.DISPLAY_X_COMMAND_UNIX;
-		newPropertyDefaults.put(MaemoPreferenceConstants.DISPLAY_X_COMMAND, 
-				newPropertyDefaults.getProperty(hostEnvKey));
-		newPropertyDefaults.remove(hostEnvKey);
-	}
-	
-}

Added: trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/maemosdk/core/MaemoPreferenceMigrator.java
===================================================================
--- trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/maemosdk/core/MaemoPreferenceMigrator.java	                        (rev 0)
+++ trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/maemosdk/core/MaemoPreferenceMigrator.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+
+package org.maemo.esbox.maemosdk.core;
+
+import org.maemo.esbox.core.HostUtils;
+import org.maemo.esbox.core.IPreferenceMigrator;
+import org.maemo.esbox.internal.api.core.OldESboxPreferenceMigrator;
+
+import java.util.Properties;
+
+/**
+ * To migrate preferences, we use the 1.4 -> newer conversion and also pick
+ * an OS-specific initial value for the X server command.
+ * @author eswartz
+ *
+ */
+public class MaemoPreferenceMigrator extends OldESboxPreferenceMigrator
+		implements IPreferenceMigrator {
+
+	/* (non-Javadoc)
+	 * @see org.maemo.esbox.internal.api.core.OldESboxPreferenceMigrator#adjustDefaultSettings(java.util.Properties)
+	 */
+	@Override
+	public void adjustDefaultSettings(Properties newPropertyDefaults) {
+		super.adjustDefaultSettings(newPropertyDefaults);
+		// adjust any environment-dependent defaults
+		String hostEnvKey;
+		if (HostUtils.isWindows())
+			hostEnvKey = MaemoPreferenceConstants.DISPLAY_X_COMMAND_WIN32;
+		else
+			hostEnvKey = MaemoPreferenceConstants.DISPLAY_X_COMMAND_UNIX;
+		newPropertyDefaults.put(MaemoPreferenceConstants.DISPLAY_X_COMMAND, 
+				newPropertyDefaults.getProperty(hostEnvKey));
+		
+		if (HostUtils.isWindows())
+			hostEnvKey = MaemoPreferenceConstants.X_PATH_WIN32;
+		else
+			hostEnvKey = MaemoPreferenceConstants.X_PATH_UNIX;
+		newPropertyDefaults.put(MaemoPreferenceConstants.X_PATH, 
+				newPropertyDefaults.getProperty(hostEnvKey));
+		
+	}
+	
+}


Property changes on: trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/maemosdk/core/MaemoPreferenceMigrator.java
___________________________________________________________________
Name: svn:mergeinfo
   + 

Modified: trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/maemosdk/core/scratchbox/ScratchboxFacade.java
===================================================================
--- trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/maemosdk/core/scratchbox/ScratchboxFacade.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/maemosdk/core/scratchbox/ScratchboxFacade.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -11,12 +11,14 @@
  *******************************************************************************/
 package org.maemo.esbox.maemosdk.core.scratchbox;
 
+import org.eclipse.core.filesystem.IFileInfo;
 import org.eclipse.core.runtime.*;
 import org.maemo.esbox.core.*;
+import org.maemo.esbox.core.env.*;
 import org.maemo.esbox.core.machine.*;
-import org.maemo.esbox.core.process.IProcessLauncher;
-import org.maemo.esbox.core.process.IProcessLauncherFactory;
+import org.maemo.esbox.core.process.*;
 import org.maemo.esbox.core.sdk.*;
+import org.maemo.esbox.internal.api.core.machine.HostUnixMachine;
 import org.maemo.esbox.internal.api.core.sdk.UserAwarePreferenceProviderWrapper;
 import org.maemo.esbox.internal.maemosdk.core.Activator;
 import org.maemo.esbox.internal.maemosdk.core.command.ICommand;
@@ -50,7 +52,7 @@
 	private boolean useCaching;
 
 	private PersistentCache cache;
-	
+
 	/** String for URI of machine where we detected scratchbox 1 */
 	private static final String SB1_MACHINE = "sb1_machine";
 	/** String for scratchbox 1 version or <code>null</code> */
@@ -153,9 +155,45 @@
 		}
 	}
 
-	/** SB1 is usually installed to contain softlinks into /usr/bin, but the .tar.gz
-	 * installation method doesn't do this.  So be sure to handle sb1 commands which might not be on /usr/bin. */
-	private ICommandAbstractor getSb1WrappedCommandAbstractor(final ICommandAbstractor commandAbstractor) {
+	private boolean areToolsOnPath(IMachine machine, String identifyingTool) {
+		boolean toolsOnPath = false;
+		Properties env = machine.getStandardEnvironment();
+		String pathVar = env.getProperty("PATH");
+		if (pathVar == null) {
+			toolsOnPath = false;  // assume not!
+		} else {
+			String[] pathEntries = pathVar.split(":");
+			for (String pathEntry : pathEntries) {
+				IPath path = new Path(pathEntry).append(identifyingTool); 
+				IFileInfo info = machine.getFileSystemAccess().getFileStore(path).fetchInfo();
+				if (info.exists()) {
+					toolsOnPath = true;
+					break;
+				}
+			}
+			
+		}
+		return toolsOnPath;
+	}
+
+	/**
+	 * For launching commands on the SDK's machine in order to control the machine, ensure
+	 * we can access the tools for that SDK.
+	 *  
+	 * SB1 is usually installed to contain softlinks into /usr/bin, but the .tar.gz
+	 * installation method doesn't do this.  So be sure to handle sb1 commands which might not be on /usr/bin. 
+	 * @param toolsPath 
+	 * 
+	 */
+	private ICommandAbstractor wrapCommandAbstractorForSDK(
+			final ICommandAbstractor commandAbstractor,
+			IMachine machine,
+			final String identifyingTool,
+			final String toolsPath) {
+		if (areToolsOnPath(machine, identifyingTool)) {
+			return commandAbstractor;
+		}
+		
 		return new ICommandAbstractor() {
 
 			public String getPreferenceValue(String key) {
@@ -166,29 +204,29 @@
 				final IProcessLauncherFactory launcherFactory = commandAbstractor.getProcessLauncherFactory();
 				IProcessLauncherFactory wrappedLauncherFactory = new IProcessLauncherFactory() {
 
-					public IProcessLauncher createProcessLaunchHandler(
+					public IProcessLauncher createProcessLauncher(
 							IPath workingDirectory,
 							List<String> commandLine,
-							Properties environment) {
-						if (environment == null) {
-							environment = getStandardEnvironment();
-						}
+							IEnvironmentModifierBlock envBlock) {
+						// fallback for cases where sbox is installed via .tar.gz with no softlinks into /usr/bin.
 						
-						// fallback for cases where sbox is installed via .tar.gz with no softlinks into /usr/bin
-						String path = environment.getProperty("PATH");
-						if (path == null)
-							path = ":/usr/bin:/bin";
-						else if (!path.startsWith(":"))
-							path = ":" + path;
-						path = "/scratchbox/tools/bin" + path;
-						environment.put("PATH", path);
+						envBlock = ProcessLauncherUtils.addToPATH(
+									new HostUnixMachine(Platform.OS_LINUX), 
+									getRawEnvironment(),
+									envBlock != null ? envBlock : defaultEnvironmentModifierBlock(),
+									toolsPath, 
+									true);
 						
-						return launcherFactory.createProcessLaunchHandler(workingDirectory, commandLine, environment);
+						return launcherFactory.createProcessLauncher(workingDirectory, commandLine, envBlock);
 					}
 
-					public Properties getStandardEnvironment() {
-						return launcherFactory.getStandardEnvironment();
+					public IEnvironmentModifierBlock defaultEnvironmentModifierBlock() {
+						return launcherFactory.defaultEnvironmentModifierBlock();
 					}
+
+					public Properties getRawEnvironment() {
+						return launcherFactory.getRawEnvironment();
+					}
 					
 				};
 				return wrappedLauncherFactory;
@@ -204,6 +242,37 @@
 		};
 	}
 	
+	/**
+	 * Get a command abstractor that updates the PATH if sb1 tools are not on the path.
+	 * @param commandAbstractor
+	 * @param machine
+	 * @return 
+	 */
+	private ICommandAbstractor getSb1WrappedAbstractor(ICommandAbstractor commandAbstractor,
+			IMachine machine) {
+		// XXX: the default path should be provided some other way
+		return wrapCommandAbstractorForSDK(
+				commandAbstractor,
+				machine, 
+				"sb-conf",
+				"/scratchbox/tools/bin");
+	}
+	/**
+	 * Get a command abstractor that updates the PATH if sb2 tools are not on the path.
+	 * @param commandAbstractor
+	 * @param machine
+	 * @return
+	 */
+	private ICommandAbstractor getSb2WrappedAbstractor(ICommandAbstractor commandAbstractor,
+			IMachine machine) {
+		// XXX: the default path should be provided some other way
+		return wrapCommandAbstractorForSDK(
+				commandAbstractor,
+				machine, 
+				"sb2",
+				"/usr/bin");
+	}
+
 	/** Get a command abstractor for the host. */
 	public ICommandAbstractor getHostCommandAbstractor(final IMachine machine) throws ESboxException {
 		// ensure machine is alive
@@ -230,8 +299,13 @@
 		};
 	}
 
-	/** Get a command abstractor for an SDK.  Scratchbox commands can
-	 * run outside scratchbox, so launch these as native processes. */
+	/**
+	 * Get a command abstractor for an SDK.  Scratchbox commands can
+	 * run outside scratchbox, so launch these as native processes for their host machine. 
+	 * 
+	 * Some sb1 configurations place binaries only in /scratchbox/tools/bin, making it
+	 * invisible to the default PATH.  A scratchbox SDK will detect this.
+	 */
 	public ICommandAbstractor getCommandAbstractor(final ISDK sdk) throws ESboxException {
 		// ensure machine is alive
 		acquireMachine(sdk.getMachine());
@@ -256,7 +330,9 @@
 
 		// be sure to account for possibly missing softlinks
 		if (sdk instanceof IScratchbox1SDK) {
-			commandAbstractor = getSb1WrappedCommandAbstractor(commandAbstractor);
+			return getSb1WrappedAbstractor(commandAbstractor, sdk.getMachine());
+		} else if (sdk instanceof IScratchbox2SDK) { 
+			return getSb2WrappedAbstractor(commandAbstractor, sdk.getMachine());
 		}
 		
 		return commandAbstractor;
@@ -298,6 +374,7 @@
 			setCachedValue(machineKey, machineURI);
 		}
 	}
+	
 	/**
 	 * Return the current version of Scratchbox 1.
 	 * @param machine 
@@ -317,7 +394,7 @@
 		// do the hard work
 		acquireMachine(machine);
 		ICommandAbstractor commandAbstractor = getHostCommandAbstractor(machine);
-		commandAbstractor = getSb1WrappedCommandAbstractor(commandAbstractor);
+		commandAbstractor = getSb1WrappedAbstractor(commandAbstractor, machine);
 		GetVersionScratchboxCommand getVersionCommand = new GetVersionScratchboxCommand(
 				commandAbstractor, 1);
 	
@@ -347,6 +424,7 @@
 		// do the hard work
 		acquireMachine(machine);
 		ICommandAbstractor commandAbstractor = getHostCommandAbstractor(machine); 
+		commandAbstractor = getSb2WrappedAbstractor(commandAbstractor, machine);
 		GetVersionScratchboxCommand getVersionCommand = new GetVersionScratchboxCommand(
 				commandAbstractor, 2);
 		

Modified: trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/maemosdk/core/scratchbox/XLauncher.java
===================================================================
--- trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/maemosdk/core/scratchbox/XLauncher.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/maemosdk/org.maemo.esbox.maemosdk.core/src/org/maemo/esbox/maemosdk/core/scratchbox/XLauncher.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -17,7 +17,7 @@
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.ui.console.MessageConsole;
 import org.maemo.esbox.core.*;
-import org.maemo.esbox.core.env.*;
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
 import org.maemo.esbox.core.machine.IMachine;
 import org.maemo.esbox.core.machine.MachineRegistry;
 import org.maemo.esbox.core.process.*;
@@ -28,7 +28,6 @@
 import java.net.Socket;
 import java.text.MessageFormat;
 import java.util.List;
-import java.util.Properties;
 
 /**
  * This class maintains knowledge about whether the X server is running in
@@ -155,20 +154,18 @@
 			
 			IProcessLauncherFactory factory = localMachine.getProcessLauncherFactory();
 
-			Properties env = null;
+			IEnvironmentModifierBlock envBlock = null;
 			
-			// XXX: HOST$XSERVER_PATH is hack to get Cygwin visible from Windows
-			String path = getXServerPath(prefProvider);
-			if (path != null) {
-				env = factory.getStandardEnvironment();
-				env.put("PATH", path);
+			String path = prefProvider.getPreferenceValue(MaemoPreferenceConstants.X_PATH);
+			if (path != null && path.length() > 0) {
+				envBlock = ProcessLauncherUtils.addToPATH(localMachine, factory, path, true); 
 			}
 			
 			// launch command
 			IProcessLauncher processLauncher = ProcessLauncherCreator.createProcessLauncher(factory, 
 					null,
 					cmdLine,
-					env);
+					envBlock);
 			
 			final Process process = processLauncher.createProcess();
 			
@@ -256,25 +253,11 @@
 		return command;
 	}
 	
-	// TODO: see if this needs to be SDK-specific
 	private String getDisplayValue(IPreferenceProvider prefProvider) {
-		IEnvironmentVariableBlock envBlock = EnvironmentVariableManager.getInstance().getGlobalEnvironmentBlock();
-		IEnvironmentVariable variable = envBlock.getVariable(ESboxCommonVariables.DISPLAY);
-		if (variable == null)
-			return ESboxCommonVariables.DISPLAY_DEFAULT_VALUE;
-		else if (variable.getValue() != null)
-			return variable.getValue();
+		String value = prefProvider.getPreferenceValue(MaemoPreferenceConstants.X_DISPLAY);
+		if (value.length() > 0)
+			return value;
 		else
 			return System.getenv("DISPLAY"); // get from system
 	}
-	
-	// TODO: see if this needs to be SDK-specific
-	private String getXServerPath(IPreferenceProvider prefProvider) {
-		IEnvironmentVariableBlock envBlock = EnvironmentVariableManager.getInstance().getGlobalEnvironmentBlock();
-		IEnvironmentVariable variable = envBlock.getVariable(ESboxCommonVariables.XSERVER_PATH);
-		if (variable == null)
-			return null;
-		else
-			return variable.getValue();
-	}
 }

Modified: trunk/maemosdk/org.maemo.esbox.maemosdk.tests/src/org/maemo/esbox/maemosdk/tests/TestProcessLauncher.java
===================================================================
--- trunk/maemosdk/org.maemo.esbox.maemosdk.tests/src/org/maemo/esbox/maemosdk/tests/TestProcessLauncher.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/maemosdk/org.maemo.esbox.maemosdk.tests/src/org/maemo/esbox/maemosdk/tests/TestProcessLauncher.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -23,7 +23,6 @@
 import org.maemo.esbox.core.sdk.*;
 import org.maemo.esbox.core.tests.core.BaseTest;
 import org.maemo.esbox.internal.api.core.sdk.HostSDK;
-import org.maemo.esbox.maemosdk.core.sdk.IScratchboxSDKTarget;
 
 import java.io.ByteArrayOutputStream;
 import java.io.OutputStream;
@@ -67,7 +66,9 @@
 			int count = MAX_TARGETS;
 			ISDKTarget[] targets = sdk.getSDKTargets();
 			for (ISDKTarget target : targets) {
-				if (target.getName().contains("libtool"))
+				if (target.getName().contains("libtool") 
+						|| target.getName().contains("REMOVE")
+						|| target.getName().contains("bora"))
 					continue;
 				if (!validateMachine(target.getSDK().getMachine()))
 					continue;
@@ -88,27 +89,31 @@
 
 			public void run(ISDKTarget target) throws Exception {
 
-				String cmdText = "echo $CC $LDFLAGS =$SPACEY= \"$LAST\"";
-				Properties envVars = new Properties();
-				envVars.put("CC", "gcc");
-				envVars.put("LDFLAGS", "-lm");
-				envVars.put("SPACEY", "-a -b larry's -d");	// the ' should not cause a problem
-				envVars.put("LAST", "*");  // this should not be expanded
+				String cmdText = "echo $CC $LDFLAGS =$SPACEY= \"$LAST\" $LANG$MAIL$IFS .";
+				IEnvironmentModifierBlock envVarBlock = EnvironmentManager.getInstance().createEnvironmentModifierBlock();
+				envVarBlock.define("CC", "gcc");
+				envVarBlock.define("LDFLAGS", "-lm");
+				envVarBlock.define("SPACEY", "-a -b larry's -d");	// the ' should not cause a problem
+				envVarBlock.define("LAST", "*");  // this should not be expanded
+				envVarBlock.undefine("LANG");
+				envVarBlock.undefine("MAIL");
+				envVarBlock.undefine("IFS");
+				
 				IProcessLauncher processLauncher = createAndLaunchStockProcessForScript(
-						target, null, cmdText, envVars);
+						target, null, cmdText, envVarBlock);
 
 				ByteArrayOutputStream out = new ByteArrayOutputStream();
 				ByteArrayOutputStream err = new ByteArrayOutputStream();
 				int exit = processLauncher.waitAndRead(out, err);
 				assertEquals(target.getName() + ": " + err.toString(), 0, exit);	// some targets can't handle export $@
 				assertEquals("", err.toString());
-				assertStdTextEquals("gcc -lm =-a -b larry's -d= *\n", out.toString());
+				assertStdTextEquals("gcc -lm =-a -b larry's -d= * .\n", out.toString());
 			}
 
 		});
 	}
 
-	/** Make sure env vars are not lost entirely */
+	/** Make sure env vars are not lost entirely when passing null envBlock */
 	@Test
 	public void testEnvVars2() throws Exception {
 		runOverTargets(new IRunner() {
@@ -122,7 +127,7 @@
 				ByteArrayOutputStream out = new ByteArrayOutputStream();
 				ByteArrayOutputStream err = new ByteArrayOutputStream();
 				int exit = processLauncher.waitAndRead(out, err);
-				assertEquals(0, exit);
+				assertEquals(target+":\n"+err.toString(), 0, exit);
 
 				assertEquals("", err.toString());
 				assertTrue(out.toString().contains(":"));
@@ -146,7 +151,7 @@
 				ByteArrayOutputStream out = new ByteArrayOutputStream();
 				ByteArrayOutputStream err = new ByteArrayOutputStream();
 				int exit = processLauncher.waitAndRead(out, err);
-				assertEquals(0, exit);
+				assertEquals(target+":\n"+err.toString(), 0, exit);
 
 				assertStdTextEquals("stderr1\nstderr2\nstderr3\nstderr4\n", err
 						.toString());
@@ -190,12 +195,12 @@
 	 * @param target SDK target to use
 	 * @param cwd target-relative CWD or null
 	 * @param cmdText text to copy into script
-	 * @param envVars environment variables
+	 * @param envVarBlock environment variables
 	 * @param pty pty or null
 	 * @return new process launcher
 	 */
 	IProcessLauncher createAndLaunchStockProcessForScript(
-			ISDKTarget target, IPath cwd, String cmdText, Properties envVars)
+			ISDKTarget target, IPath cwd, String cmdText, IEnvironmentModifierBlock envVarBlock)
 			throws Exception {
 		IProcessLauncherFactory processLauncherFactory = target
 				.getProcessLauncherFactory();
@@ -203,11 +208,11 @@
 		return createAndLaunchStockProcessForScript(
 				processLauncherFactory,
 				target, cwd, cmdText,
-				envVars);
+				envVarBlock);
 	}
 
 	IProcessLauncher createAndLaunchStockProcessForScript(IProcessLauncherFactory processLauncherFactory,
-			ISDKTarget target, IPath cwd, String cmdText, Properties envVars)
+			ISDKTarget target, IPath cwd, String cmdText, IEnvironmentModifierBlock envVarBlock)
 			throws Exception {
 		createStockScript(target, cmdText);
 
@@ -216,7 +221,7 @@
 		IProcessLauncher processLauncher = ProcessLauncherCreator.createProcessLauncher(
 				processLauncherFactory, cwd, 
 				CommandLineArguments.wrapScriptCommandLineForShell(cmdLine),
-				envVars);
+				envVarBlock);
 		// System.out.println(processLauncher.getLaunchCommandArguments().toCommandLine());
 
 		theProcess = processLauncher.createProcess();
@@ -295,7 +300,7 @@
 				ByteArrayOutputStream out = new ByteArrayOutputStream();
 				ByteArrayOutputStream err = new ByteArrayOutputStream();
 				int exit = processLauncher.waitAndRead(out, err);
-				assertEquals(0, exit);
+				assertEquals(target+":\n"+err.toString(), 0, exit);
 
 				assertStdTextEquals("", err.toString());
 				assertEquals(target.getName(), "/usr/games", out.toString().trim());
@@ -321,7 +326,7 @@
 				ByteArrayOutputStream out = new ByteArrayOutputStream();
 				ByteArrayOutputStream err = new ByteArrayOutputStream();
 				int exit = processLauncher.waitAndRead(out, err);
-				assertEquals(0, exit);
+				assertEquals(target+":\n"+err.toString(), 0, exit);
 				
 				// some sdks don't have sed
 				if (!err.toString().contains("command not found")) {
@@ -340,42 +345,37 @@
 		runOverTargets(new IRunner() {
 			
 			public void run(ISDKTarget target) throws Exception {
-				// the local host launcher does not pass ESbox variables.
-				if (!(target instanceof IScratchboxSDKTarget))
-					return;
-				
-				IEnvironmentVariableBlock envBlockOrig = new EnvironmentVariableBlock();
-				IEnvironmentVariableBlock envBlock = EnvironmentVariableManager.getInstance().getGlobalEnvironmentBlock();
-				envBlock.copyTo(envBlockOrig);
+				IEnvironmentModifierBlock globalBlock = EnvironmentManager.getInstance().getGlobalEnvironmentModifierBlock();
+				IEnvironmentModifierBlock envBlockOrig = globalBlock.copy();
 
 				try {
 					// DISPLAY comes from the .bashrc in scratchbox or from the X11 environment
-					envBlock.clear();
+					globalBlock.clear();
 					
 					// set ESbox variables
-					envBlock.define("ESBOXONLY", "fromesbox_original");
-					envBlock.define("ESBOXOVERRIDE", "fromesbox_original");
-					envBlock.define("DISPLAY", "esbox:3");
+					globalBlock.define("ESBOXONLY", "fromesbox_original");
+					globalBlock.define("ESBOXOVERRIDE", "fromesbox_original");
+					globalBlock.define("DISPLAY", "esbox:3");
 					
 					// construct an environment that consists of overrides of the standard environment
 					IProcessLauncherFactory factory = target.getProcessLauncherFactory(); 
-					Properties envVars = factory.getStandardEnvironment();
+					IEnvironmentModifierBlock envVarBlock = factory.defaultEnvironmentModifierBlock();
 					
-					assertTrue(envVars.containsKey("ESBOXONLY"));
-					assertTrue(envVars.containsKey("ESBOXOVERRIDE"));
-					assertTrue(envVars.containsKey("DISPLAY"));
+					assertNotNull(envVarBlock.findOperation("ESBOXONLY"));
+					assertNotNull(envVarBlock.findOperation("ESBOXOVERRIDE"));
+					assertNotNull(envVarBlock.findOperation("DISPLAY"));
 					
-					envVars.put("ESBOXOVERRIDE", "launch_override");
-					envVars.put("PASSEDIN", "launch_passedin");
+					envVarBlock.define("ESBOXOVERRIDE", "launch_override");
+					envVarBlock.define("PASSEDIN", "launch_passedin");
 					
 					String cmdText = "echo $DISPLAY,$ESBOXONLY,$ESBOXOVERRIDE,$PASSEDIN\necho $USER\n";
 					IProcessLauncher processLauncher = createAndLaunchStockProcessForScript(
-							factory, target, null, cmdText, envVars);
+							factory, target, null, cmdText, envVarBlock);
 	
 					ByteArrayOutputStream out = new ByteArrayOutputStream();
 					ByteArrayOutputStream err = new ByteArrayOutputStream();
 					int exit = processLauncher.waitAndRead(out, err);
-					assertEquals(0, exit);
+					assertEquals(target+":\n"+err.toString(), 0, exit);
 	
 					assertStdTextEquals("", err.toString());
 					String[] lines = out.toString().trim().split("\r\n|\n");
@@ -386,23 +386,24 @@
 					//////////
 	
 					// construct an environment that consists of a clean environment
-					envVars = new Properties(); 
-					envVars.put("ESBOXOVERRIDE", "launch_override");
-					envVars.put("PASSEDIN", "launch_passedin");
+					envVarBlock = EnvironmentManager.getInstance().createEnvironmentModifierBlock(); 
+					envVarBlock.define("ESBOXOVERRIDE", "launch_override");
+					envVarBlock.define("PASSEDIN", "launch_passedin");
 					
 					cmdText = "echo $ESBOXONLY,$ESBOXOVERRIDE,$PASSEDIN";
 					processLauncher = createAndLaunchStockProcessForScript(
-							target, null, cmdText, envVars);
+							target, null, cmdText, envVarBlock);
 	
 					out = new ByteArrayOutputStream();
 					err = new ByteArrayOutputStream();
 					exit = processLauncher.waitAndRead(out, err);
-					assertEquals(0, exit);
+					assertEquals(target+":\n"+err.toString(), 0, exit);
 	
 					assertEquals("", err.toString());
 					assertStdTextEquals(",launch_override,launch_passedin\n", out.toString());
 				} finally {
-					envBlockOrig.copyTo(EnvironmentVariableManager.getInstance().getGlobalEnvironmentBlock());
+					EnvironmentManager.getInstance().getGlobalEnvironmentModifierBlock().clear();
+					EnvironmentManager.getInstance().getGlobalEnvironmentModifierBlock().apply(envBlockOrig);
 				}
 			}
 		});
@@ -420,21 +421,24 @@
 				createStockScript(target, "echo hello\n");
 				
 				// make an overridden environment that has the script directory in its PATH
-				Properties env = target.getProcessLauncherFactory().getStandardEnvironment();
-				env.put("PATH", env.get("PATH") + ":" + new Path(STOCK_SCRIPT_NAME).removeLastSegments(1));
+				String scriptDir = new Path(STOCK_SCRIPT_NAME).removeLastSegments(1).toPortableString();
+				IEnvironmentModifierBlock envVarBlock =
+					ProcessLauncherUtils.addToPATH(target.getSDK().getMachine(),
+							target.getProcessLauncherFactory(), 
+							scriptDir, true);
 				
 				IProcessLauncher processLauncher = ProcessLauncherCreator.createProcessLauncher(
 						target.getProcessLauncherFactory(),
 						null,
 						CommandLineArguments.createFromCommandLine(new Path(STOCK_SCRIPT_NAME).lastSegment()),
-						env);
+						envVarBlock);
 				
 				processLauncher.createProcess();
 				
 				ByteArrayOutputStream out = new ByteArrayOutputStream();
 				ByteArrayOutputStream err = new ByteArrayOutputStream();
 				int exit = processLauncher.waitAndRead(out, err);
-				assertEquals(0, exit);
+				assertEquals(target+":\n"+err.toString(), 0, exit);
 				
 				assertStdTextEquals("hello\n", out.toString());
 			}

Modified: trunk/maemosdk/org.maemo.esbox.maemosdk.tests/src/org/maemo/esbox/maemosdk/tests/TestSB1ProcessLauncher.java
===================================================================
--- trunk/maemosdk/org.maemo.esbox.maemosdk.tests/src/org/maemo/esbox/maemosdk/tests/TestSB1ProcessLauncher.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/maemosdk/org.maemo.esbox.maemosdk.tests/src/org/maemo/esbox/maemosdk/tests/TestSB1ProcessLauncher.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -13,6 +13,8 @@
 import org.eclipse.core.runtime.*;
 import org.junit.Test;
 import org.maemo.esbox.core.*;
+import org.maemo.esbox.core.env.EnvironmentManager;
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
 import org.maemo.esbox.core.process.*;
 import org.maemo.esbox.core.sdk.*;
 import org.maemo.esbox.internal.maemosdk.core.sdk.providers.Scratchbox1SDKProvider;
@@ -75,21 +77,16 @@
 			public void run(ISDKTarget target) throws Exception {
 				IProcessLauncherFactory processLauncherFactory = target
 						.getProcessLauncherFactory();
-				IProcessLauncher processLauncher = ProcessLauncherCreator.createProcessLauncher(processLauncherFactory, "ls");
+				IProcessLauncher processLauncher = ProcessLauncherCreator.createProcessLauncher(
+						processLauncherFactory, "ls");
 				List<String> args = processLauncher.getLaunchCommandArguments();
 				assertNotNull(args);
 
 				// be sure no variables are left unexpanded
 				assertFalse(CommandLineArguments.toCommandLine(args).contains("${"));
 
-				// assume the pattern is still /scratchbox/login -d ...
-				// ".../run.sh ... \".... <command>\""
-				// (basically verifying the command is wrapped)
+				// assume the pattern is still /scratchbox/login ... 
 				assertEquals("/scratchbox/login", args.get(0));
-				String last = args.get(args.size() - 1);
-				// System.out.println(last);
-				assertTrue(last
-						.matches("\\Q./run.sh /\\E\\s+\\S+=\\S+\\s+\\Q\\\"ls \\\"\\E"));
 			}
 		});
 	}
@@ -102,11 +99,12 @@
 			public void run(ISDKTarget target) throws Exception {
 				IProcessLauncherFactory processLauncherFactory = target
 						.getProcessLauncherFactory();
-				Properties envVars = new Properties();
-				envVars.put("CC", "gcc");
-				envVars.put("LDFLAGS", "-lm");
-				envVars.put("SPACEY", "a b c");
-				envVars.put("WILD", "*");
+				IEnvironmentModifierBlock envVars = EnvironmentManager.getInstance().createEnvironmentModifierBlock();
+				envVars.define("CC", "gcc");
+				envVars.define("LDFLAGS", "-lm");
+				envVars.define("SPACEY", "a b c");
+				envVars.define("WILD", "*");
+				envVars.undefine("FOOBAR");
 				IPath tempPath = new Path("/tmp");
 				IProcessLauncher processLauncher = ProcessLauncherCreator.createProcessLauncher(processLauncherFactory,
 						tempPath, 
@@ -116,8 +114,8 @@
 
 				// the env vars are encoded into run.sh, not passed outside the
 				// process
-				Properties launchEnvironment = processLauncher
-						.getLaunchEnvironment();
+				IEnvironmentModifierBlock launchEnvironment = processLauncher
+						.getLaunchEnvironmentModifierBlock();
 				assertNull(launchEnvironment);
 
 				List<String> args = processLauncher.getLaunchCommandArguments();
@@ -133,7 +131,7 @@
 				String last = args.get(args.size() - 1);
 				// System.out.println(last);
 				assertEquals(
-						"./run.sh " + tempPath.toPortableString() + " \\\"CC=gcc,LDFLAGS=-lm,SPACEY=a b c,WILD=*\\\" \\\"./configure --enable-maintainer-mode --disable-gtk\\\"",
+						"./run.sh " + tempPath.toPortableString() + " \\\"CC=gcc,LDFLAGS=-lm,SPACEY=a b c,WILD=*,-FOOBAR\\\" \\\"./configure --enable-maintainer-mode --disable-gtk\\\"",
 						last);
 
 			}
@@ -141,21 +139,17 @@
 	}
 
 	
-	/** Test that the Esbox environment variables are passed properly.
-	 * DISPLAY is defined on the user account */
+	/** Test that the Esbox environment variables are passed properly. */
 	@Test
-	public void testEnvironmentDefaultsSb1() throws Exception {
+	public void testEnvironmentPassingSb1() throws Exception {
 		runOverTargets(new IRunner() {
 			
 			public void run(ISDKTarget target) throws Exception {
-				// DISPLAY comes from the .bashrc in scratchbox or from the X11 environment
-
-				// construct an environment that consists of a clean environment
-				Properties envVars = new Properties(); 
+				IEnvironmentModifierBlock envVars = EnvironmentManager.getInstance().createEnvironmentModifierBlock();
 				
-				envVars.put("DISPLAY", ":2");
-				envVars.put("ESBOXOVERRIDE", "launch_override");
-				envVars.put("PASSEDIN", "launch_passedin");
+				envVars.define("DISPLAY", ":2");
+				envVars.define("ESBOXOVERRIDE", "launch_override");
+				envVars.define("PASSEDIN", "launch_passedin");
 				
 				String cmdText = "echo $DISPLAY,$ESBOXONLY,$ESBOXOVERRIDE,$PASSEDIN";
 				IProcessLauncher processLauncher = createAndLaunchStockProcessForScript(

Modified: trunk/maemosdk/org.maemo.esbox.maemosdk.tests/src/org/maemo/esbox/maemosdk/tests/TestSB2ProcessLauncher.java
===================================================================
--- trunk/maemosdk/org.maemo.esbox.maemosdk.tests/src/org/maemo/esbox/maemosdk/tests/TestSB2ProcessLauncher.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/maemosdk/org.maemo.esbox.maemosdk.tests/src/org/maemo/esbox/maemosdk/tests/TestSB2ProcessLauncher.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -23,7 +23,7 @@
 import java.util.List;
 
 /**
- * If SB1 is installed, make sure its SDKs and targets are properly detected,
+ * If SB2 is installed, make sure its SDKs and targets are properly detected,
  * and that it launches processes in the expected way
  * 
  * @author eswartz
@@ -46,7 +46,7 @@
 		List<ISDKProvider> providers = factory.getSDKProviders();
 		assertNotNull(providers);
 
-		// don't worry if we don't find an SB1 installation
+		// don't worry if we don't find an SB2 installation
 		// on this host (this is mostly a manual test)
 		for (ISDKProvider provider : providers) {
 			if (provider instanceof Scratchbox2SDKProvider) {

Modified: trunk/maemosdk/org.maemo.esbox.maemosdk.tests/src/org/maemo/esbox/maemosdk/tests/TestSB2SDKProvider.java
===================================================================
--- trunk/maemosdk/org.maemo.esbox.maemosdk.tests/src/org/maemo/esbox/maemosdk/tests/TestSB2SDKProvider.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/maemosdk/org.maemo.esbox.maemosdk.tests/src/org/maemo/esbox/maemosdk/tests/TestSB2SDKProvider.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -83,11 +83,10 @@
 		List<ISDK> sdks = sb2Provider.createSDKs();
 		for (ISDK sdk : sdks) {
 			ISDKTarget[] targets = sdk.getSDKTargets();
-			// for this test, we need to have something to test
-			if (targets.length > 0) {
-				for (ISDKTarget target : targets) {
-					_testSDKTarget(target);
-				}
+			for (ISDKTarget target : targets) {
+				if (target.getName().contains("DELETEME") || target.getName().contains("bora"))
+					continue;
+				_testSDKTarget(target);
 			}
 		}
 	}

Modified: trunk/maemosdk/org.maemo.esbox.maemosdk.tests/src/org/maemo/esbox/maemosdk/tests/commands/MockCommandAbstractor.java
===================================================================
--- trunk/maemosdk/org.maemo.esbox.maemosdk.tests/src/org/maemo/esbox/maemosdk/tests/commands/MockCommandAbstractor.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/maemosdk/org.maemo.esbox.maemosdk.tests/src/org/maemo/esbox/maemosdk/tests/commands/MockCommandAbstractor.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -44,14 +44,14 @@
 		return lastLauncherFactory;
 	}
 	
-	public List<String> getLastCommandLine() {
-		return lastLauncherFactory.getLastCommandLine();
-	}
-	
 	/* (non-Javadoc)
 	 * @see org.maemo.esbox.internal.core.command.ICommandAbstractor#getFileSystemAccess()
 	 */
 	public IFileSystemAccess getFileSystemAccess() {
 		return target.getTargetFileSystemAccess();
 	}
+
+	public List<String> getLastCommandLine() {
+		return lastLauncherFactory.getLastCommandLine();
+	}
 }
\ No newline at end of file

Modified: trunk/maemosdk/org.maemo.esbox.maemosdk.tests/src/org/maemo/esbox/maemosdk/tests/commands/MockProcessLauncher.java
===================================================================
--- trunk/maemosdk/org.maemo.esbox.maemosdk.tests/src/org/maemo/esbox/maemosdk/tests/commands/MockProcessLauncher.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/maemosdk/org.maemo.esbox.maemosdk.tests/src/org/maemo/esbox/maemosdk/tests/commands/MockProcessLauncher.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -15,6 +15,7 @@
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.ui.console.MessageConsole;
 import org.maemo.esbox.core.*;
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
 import org.maemo.esbox.core.process.IProcessLauncher;
 import org.maemo.esbox.core.process.IStreamLineMonitor;
 import org.maemo.esbox.core.sdk.ISDKTarget;
@@ -22,7 +23,6 @@
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.util.List;
-import java.util.Properties;
 
 /**
  * This process launcher does not actually launch anything but allows
@@ -102,8 +102,8 @@
 	/* (non-Javadoc)
 	 * @see org.maemo.esbox.core.IProcessLauncher#getLaunchEnvironment()
 	 */
-	public Properties getLaunchEnvironment() {
-		return wrapped.getLaunchEnvironment();
+	public IEnvironmentModifierBlock getLaunchEnvironmentModifierBlock() {
+		return wrapped.getLaunchEnvironmentModifierBlock();
 	}
 
 	/* (non-Javadoc)

Modified: trunk/maemosdk/org.maemo.esbox.maemosdk.tests/src/org/maemo/esbox/maemosdk/tests/commands/MockProcessLauncherFactory.java
===================================================================
--- trunk/maemosdk/org.maemo.esbox.maemosdk.tests/src/org/maemo/esbox/maemosdk/tests/commands/MockProcessLauncherFactory.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/maemosdk/org.maemo.esbox.maemosdk.tests/src/org/maemo/esbox/maemosdk/tests/commands/MockProcessLauncherFactory.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -12,6 +12,7 @@
 package org.maemo.esbox.maemosdk.tests.commands;
 
 import org.eclipse.core.runtime.IPath;
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
 import org.maemo.esbox.core.process.IProcessLauncher;
 import org.maemo.esbox.core.process.IProcessLauncherFactory;
 
@@ -33,22 +34,31 @@
 		this.wrapped = wrapped;
 	}
 	/* (non-Javadoc)
-	 * @see org.maemo.esbox.core.IProcessLauncherFactory#createProcessLaunchHandler(org.eclipse.core.runtime.IPath, java.util.List, java.util.Properties, org.eclipse.cdt.utils.pty.PTY)
+	 * @see org.maemo.esbox.core.IProcessLauncherFactory#createProcessLauncher(org.eclipse.core.runtime.IPath, java.util.List, java.util.Properties, org.eclipse.cdt.utils.pty.PTY)
 	 */
-	public IProcessLauncher createProcessLaunchHandler(IPath workingDirectory,
-			List<String> commandLine, Properties environment) {
-		lastProcessLauncher = wrapped.createProcessLaunchHandler(workingDirectory, commandLine, environment);
+	public IProcessLauncher createProcessLauncher(IPath workingDirectory,
+			List<String> commandLine, IEnvironmentModifierBlock environment) {
+		lastProcessLauncher = wrapped.createProcessLauncher(workingDirectory, commandLine, environment);
 		return new MockProcessLauncher(lastProcessLauncher);
 	}
-
 	/* (non-Javadoc)
-	 * @see org.maemo.esbox.core.IProcessLauncherFactory#getStandardEnvironment()
+	 * @see org.maemo.esbox.core.process.IProcessLauncherFactory#getDefaultEnvironmentModifierBlock()
 	 */
-	public Properties getStandardEnvironment() {
-		return wrapped.getStandardEnvironment();
+	public IEnvironmentModifierBlock defaultEnvironmentModifierBlock() {
+		return wrapped.defaultEnvironmentModifierBlock();
 	}
+	/* (non-Javadoc)
+	 * @see org.maemo.esbox.core.process.IProcessLauncherFactory#getRawEnvironment()
+	 */
+	public Properties getRawEnvironment() {
+		return wrapped.getRawEnvironment();
+	}
+
 	public List<String> getLastCommandLine() {
 		return lastProcessLauncher.getLaunchCommandArguments();
 	}
+	
 
+	
+
 }

Modified: trunk/maemosdk/org.maemo.esbox.maemosdk.tests/src/org/maemo/esbox/maemosdk/tests/commands/TestListSb2Commands.java
===================================================================
--- trunk/maemosdk/org.maemo.esbox.maemosdk.tests/src/org/maemo/esbox/maemosdk/tests/commands/TestListSb2Commands.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/maemosdk/org.maemo.esbox.maemosdk.tests/src/org/maemo/esbox/maemosdk/tests/commands/TestListSb2Commands.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -14,6 +14,7 @@
 import org.eclipse.core.runtime.Path;
 import org.eclipse.jface.preference.IPreferenceStore;
 import org.maemo.esbox.core.*;
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
 import org.maemo.esbox.core.machine.IFileSystemAccess;
 
 import org.maemo.esbox.core.process.IProcessLauncher;
@@ -182,19 +183,20 @@
 					final IProcessLauncherFactory factory = sb2Command.getProcessLauncherFactory();
 					return new IProcessLauncherFactory() {
 
-						public IProcessLauncher createProcessLaunchHandler(
+						public IProcessLauncher createProcessLauncher(
 								IPath workingDirectory,
 								List<String> commandLine,
-								Properties environment) {
-							return factory.createProcessLaunchHandler(workingDirectory, commandLine, environment);
+								IEnvironmentModifierBlock environment) {
+							return factory.createProcessLauncher(workingDirectory, commandLine, environment);
 						}
 
-						public Properties getStandardEnvironment() {
-							Properties stdenv = factory.getStandardEnvironment();
-							stdenv.put("http_proxy", "http://10.241.32.11:8080");
-							return stdenv;
+						public IEnvironmentModifierBlock defaultEnvironmentModifierBlock() {
+							return factory.defaultEnvironmentModifierBlock();
 						}
-						
+
+						public Properties getRawEnvironment() {
+							return factory.getRawEnvironment();
+						}
 					};
 				}
 				

Modified: trunk/maemosdk/org.maemo.esbox.maemosdk.ui/src/org/maemo/esbox/maemosdk/ui/preferences/ESboxXServerPreferencePage.java
===================================================================
--- trunk/maemosdk/org.maemo.esbox.maemosdk.ui/src/org/maemo/esbox/maemosdk/ui/preferences/ESboxXServerPreferencePage.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/maemosdk/org.maemo.esbox.maemosdk.ui/src/org/maemo/esbox/maemosdk/ui/preferences/ESboxXServerPreferencePage.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -16,6 +16,8 @@
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.graphics.GC;
 import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Label;
 import org.eclipse.ui.IWorkbench;
 import org.eclipse.ui.IWorkbenchPreferencePage;
 import org.maemo.esbox.maemosdk.core.MaemoPreferenceConstants;
@@ -28,7 +30,9 @@
  */
 public class ESboxXServerPreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage, IPreferencePage {
 	
-	private StringFieldEditor xServerSyntax = null;	
+	private StringFieldEditor xServerSyntax = null;
+	private StringFieldEditor xDisplay;
+	private StringFieldEditor xPath;	
 	
 	/**
 	 * The constructor
@@ -36,7 +40,8 @@
 	public ESboxXServerPreferencePage() {
 		super(GRID);		
 		setPreferenceStore(MaemoPreferenceConstants.getPreferenceStore());
-		setDescription("Preferences for Running Graphical Programs inside Scratchbox:");
+		setDescription("Preferences for running X:\n\n"
+				+ "(The X server is launched on the host machine, so use a command syntax and display appropriate to the host.)\n");
 	}
 
 	/*
@@ -45,8 +50,8 @@
 	 */
 	public void createFieldEditors() {
 		xServerSyntax = new StringFieldEditor(
-				MaemoPreferenceConstants.DISPLAY_X_COMMAND.toString(),
-				"Command template for X server:", 
+				MaemoPreferenceConstants.DISPLAY_X_COMMAND,
+				"Command template to launch server:", 
 				getFieldEditorParent());		
 		
 		// make this string manageable
@@ -55,33 +60,32 @@
 		gridData.widthHint = gc.getAdvanceWidth('m') * 32;
 		gc.dispose();
 		xServerSyntax.getTextControl(getFieldEditorParent()).setLayoutData(gridData);
+
+		xDisplay = new StringFieldEditor(
+				MaemoPreferenceConstants.X_DISPLAY,
+				"DISPLAY setting for server:", 
+				getFieldEditorParent());		
 		
-		addField(xServerSyntax);		
+		// make this string manageable
+		xDisplay.getTextControl(getFieldEditorParent()).setLayoutData(gridData);
 		
-		initializeValues();
+		
+		xPath = new StringFieldEditor(
+				MaemoPreferenceConstants.X_PATH,
+				"Additional PATH entries for server:", 
+				getFieldEditorParent());		
+		
+		// make this string manageable
+		xPath.getTextControl(getFieldEditorParent()).setLayoutData(gridData);
+		
+		
+		addField(xServerSyntax);
+		addField(xDisplay);
+		addField(xPath);
 	}
 	
-	/**
-	 * Initializes the values of the fields
-	 */
-	private void initializeValues() {
-		IPreferenceStore store = getPreferenceStore();
-		xServerSyntax.setStringValue(store.getDefaultString(MaemoPreferenceConstants.DISPLAY_X_COMMAND.toString()));
-	}
-	
 	/*
 	 * (non-Javadoc)
-	 * @see org.eclipse.jface.preference.FieldEditorPreferencePage#performOk()
-	 */
-	@Override	
-	public boolean performOk() {
-		IPreferenceStore store = getPreferenceStore();
-		store.setValue(MaemoPreferenceConstants.DISPLAY_X_COMMAND.toString(), xServerSyntax.getStringValue());		
-		return super.performOk();
-	};
-
-	/*
-	 * (non-Javadoc)
 	 * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
 	 */
 	public void init(IWorkbench workbench) {

Modified: trunk/python/org.maemo.esbox.python.launch/src/org/maemo/esbox/python/launch/BasePythonLaunchParameterAccessor.java
===================================================================
--- trunk/python/org.maemo.esbox.python.launch/src/org/maemo/esbox/python/launch/BasePythonLaunchParameterAccessor.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/python/org.maemo.esbox.python.launch/src/org/maemo/esbox/python/launch/BasePythonLaunchParameterAccessor.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -13,7 +13,6 @@
 
 import java.io.File;
 import java.text.MessageFormat;
-import java.util.Properties;
 
 import org.eclipse.core.resources.IContainer;
 import org.eclipse.core.resources.IFile;
@@ -23,6 +22,7 @@
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.debug.core.ILaunchConfiguration;
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
 import org.maemo.esbox.internal.python.launch.Activator;
 import org.maemo.esbox.launch.ESboxLaunchUtils;
 import org.maemo.esbox.launch.core.AbstractLaunchParameterAccessor;
@@ -65,8 +65,8 @@
 	/* (non-Javadoc)
 	 * @see org.maemo.esbox.debug.core.ILaunchParameterAccessor#getEnvironmentAsProperty()
 	 */
-	public Properties getEnvironmentAsProperty() throws CoreException {
-		return ESboxLaunchUtils.getEnvironmentAsProperty(getLaunchConfiguration());
+	public IEnvironmentModifierBlock getEnvironmentModifierBlock() throws CoreException {
+		return ESboxLaunchUtils.getEnvironmentModifierBlock(getLaunchConfiguration());
 	}
 
 	/* (non-Javadoc)

Modified: trunk/python/org.maemo.esbox.python.launch/src/org/maemo/esbox/python/launch/PythonLaunchConfigurationData.java
===================================================================
--- trunk/python/org.maemo.esbox.python.launch/src/org/maemo/esbox/python/launch/PythonLaunchConfigurationData.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/python/org.maemo.esbox.python.launch/src/org/maemo/esbox/python/launch/PythonLaunchConfigurationData.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -12,15 +12,13 @@
 
 import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
 import org.eclipse.debug.core.ILaunchManager;
-import org.maemo.esbox.core.process.EnvironmentProperties;
 import org.maemo.esbox.core.sdk.ISDK;
 import org.maemo.esbox.core.sdk.ISDKTarget;
 import org.maemo.esbox.launch.ESboxLaunchUtils;
 import org.maemo.esbox.launch.LaunchProtocolFactory;
 import org.maemo.esbox.launch.adapters.IRunStandaloneAdapter;
 
-import java.util.Map;
-import java.util.Properties;
+import java.util.HashMap;
 
 /**
  * @author raulherbster
@@ -42,7 +40,6 @@
 		configuration.setAttribute(ATTR_SDK_NAME, getUniqueSDKName(sdkTarget.getSDK()));
 		configuration.setAttribute(ATTR_SDK_TARGET_NAME, sdkTarget.getName());
 		
-		Properties defaultEnv = sdkTarget.getProcessLauncherFactory().getStandardEnvironment();
 
 		//---------- Maemo Local debug specific --------------------------------
 		//
@@ -62,23 +59,15 @@
 			
 	    	// Obsolete
 	    	configuration.setAttribute(ATTR_COPY_BINS, COPY_BINS_DEFAULT);
-	    	
-	    	//XXX: remove once we add IMachine for remote machines
-			String[] envStrs = {
-					"DISPLAY=:0.0", 
-					"DBUS_SESSION_BUS_ADDRESS=unix:path=/tmp/session_bus_socket"
-					};
-			defaultEnv = EnvironmentProperties.createFromEnvp(envStrs);
-			
 		}	
 
 		
-		// Replace native env.
-		// For our remote debug, don't pass any host env vars to device program/command.
-		// Instead, add those required by default.
-		configuration.setAttribute(ILaunchManager.ATTR_APPEND_ENVIRONMENT_VARIABLES, false);
-		
-		configuration.setAttribute(ILaunchManager.ATTR_ENVIRONMENT_VARIABLES, (Map<Object, Object>) defaultEnv);
+		// Pass the environment modifier for the process launcher by default, and let
+		// user add variables.  The user can choose to replace variables -- meaning no
+		// global settings are used -- but it's up the process launcher to honor this.
+		//
+		configuration.setAttribute(ILaunchManager.ATTR_APPEND_ENVIRONMENT_VARIABLES, true);
+		configuration.setAttribute(ILaunchManager.ATTR_ENVIRONMENT_VARIABLES, new HashMap<Object, Object>());			
 
 	}
 	

Modified: trunk/python/org.maemo.esbox.python.launch/src/org/maemo/esbox/python/launch/PythonLaunchUtils.java
===================================================================
--- trunk/python/org.maemo.esbox.python.launch/src/org/maemo/esbox/python/launch/PythonLaunchUtils.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/python/org.maemo.esbox.python.launch/src/org/maemo/esbox/python/launch/PythonLaunchUtils.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -20,14 +20,28 @@
 import org.eclipse.core.variables.VariablesPlugin;
 import org.eclipse.debug.core.DebugPlugin;
 import org.eclipse.debug.core.ILaunchConfiguration;
+import org.maemo.esbox.core.ESboxException;
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
+import org.maemo.esbox.core.env.IEnvironmentOperation;
+import org.maemo.esbox.core.sdk.ISDKTarget;
+import org.python.pydev.core.IInterpreterManager;
 import org.python.pydev.debug.core.Constants;
+import org.python.pydev.plugin.PydevPlugin;
+import org.python.pydev.plugin.nature.PythonNature;
 
+import java.util.*;
+
 /**
  *
  */
 public abstract class PythonLaunchUtils {
 
 	/**
+	 * 
+	 */
+	public static final String PYTHONPATH = "PYTHONPATH";
+
+	/**
 	 * Expands and returns the working directory attribute of the given launch
 	 * configuration. Returns <code>null</code> if a working directory is not
 	 * specified. If specified, the working is verified to point to an existing
@@ -150,5 +164,112 @@
         }
         String[] res= DebugPlugin.parseArguments(arguments);
         return res;     
-    }   
+    }
+    
+    /**
+     * Get the paths composing PYTHONPATH from the project settings.
+     * @param project
+     * @return Map of host to target paths for entries in PYTHONPATH for the project
+     */
+    public static List<String> getProjectPythonPath(IProject project) {
+    	PythonNature pythonNature = PythonNature.getPythonNature(project);
+    	if (pythonNature == null)
+    		return Collections.emptyList();
+    	
+    	IInterpreterManager interpreterManager = PydevPlugin.getInterpreterManager(pythonNature); 
+    	String interpreter = interpreterManager.getDefaultInterpreter();
+    	
+    	List<String> pythonPaths = pythonNature.getPythonPathNature().getCompleteProjectPythonPath(interpreter);
+        
+        if (pythonPaths != null) {
+        	return pythonPaths;
+        } else {
+        	return Collections.emptyList();
+        }
+    }
+
+	/**
+	 * Get the mappings from host to target for entries in the Python path mappings.  This will silently
+	 * accept conversion failures, with the assumption that the same path will exist on the
+	 * host and target; check for getKey()==getEntry() to verify.
+	 * @param project
+	 * @param interpreter
+	 * @param sdkTarget
+	 * @return Map of host to target paths for entries in PYTHONPATH for the project
+	 */
+	public static Map<IPath, IPath> getPythonProjectPathMappings(IProject project, ISDKTarget sdkTarget) {
+		PythonNature pythonNature = PythonNature.getPythonNature(project);
+		if (pythonNature == null)
+			return Collections.EMPTY_MAP;
+		
+		IInterpreterManager interpreterManager = PydevPlugin.getInterpreterManager(pythonNature); 
+		String interpreter = interpreterManager.getDefaultInterpreter();
+		
+		Map<IPath, IPath> map = new LinkedHashMap<IPath, IPath>();
+		
+		List<String> pythonPaths = pythonNature.getPythonPathNature().getCompleteProjectPythonPath(interpreter);
+	    
+	    if (pythonPaths != null) {
+	    	for (String element : pythonPaths) {
+	        	IPath hostPath = new Path(element);
+	        	try {
+	        		IPath targetPath = sdkTarget.convertHostToTargetPath(hostPath);
+	        		map.put(hostPath, targetPath);
+	        	} catch (ESboxException e) {
+	        		// not inside scratchbox; hope it's visible on target!
+	        		map.put(hostPath, hostPath);
+	        	}
+	        }
+	    }
+	        
+	    return map;
+	}
+
+	/**
+	 * Sets the PYTHONPATH from the remote Python paths.
+	 * @param remotePythonPaths the Python paths on the remote side 
+	 * @param envBlock the environment block to modify
+	 */
+	public static void setPythonPathEnvironment(Collection<IPath> remotePythonPaths, IEnvironmentModifierBlock envBlock) {
+		StringBuilder builder = new StringBuilder();
+		for (IPath path : remotePythonPaths) {
+			if (builder.length() > 0)
+				builder.append(':');
+			builder.append(path.toPortableString());
+		}
+		
+		String pythonPath = builder.toString();
+		envBlock.define(PYTHONPATH, pythonPath);
+	}
+
+	/**
+	 * Get the mappings from host to target for any entries in a user override
+	 * of PYTHONPATH (which contains target paths).  Ignore any values not located
+	 * on the host.
+	 * 
+	 * @param envBlock
+	 *            environment modifications
+	 * @param sdkTarget
+	 * @return Map of host to target paths for entries in user setting of
+	 *         PYTHONPATH (never <code>null</code>)
+	 */
+	public static Map<IPath, IPath> getUserPythonPathMappings(IEnvironmentModifierBlock envBlock, ISDKTarget sdkTarget) {
+		Map<IPath, IPath> map = new LinkedHashMap<IPath, IPath>();
+		
+		IEnvironmentOperation operation = envBlock.findOperation(PYTHONPATH);
+		if (operation != null && operation.getValue() != null) {
+	    	for (String element : operation.getValue().split(":")) {
+	        	IPath targetPath = new Path(element);
+	        	try {
+	        		IPath hostPath = sdkTarget.convertTargetToHostPath(targetPath);
+	        		map.put(hostPath, targetPath);
+	        	} catch (ESboxException e) {
+	        		// not inside host; ignore
+	        	}
+	        }
+	    }
+	        
+	    return map;
+	}
+ 
 }

Modified: trunk/python/org.maemo.esbox.python.launch/src/org/maemo/esbox/python/launch/PythonLocalLaunchProxy.java
===================================================================
--- trunk/python/org.maemo.esbox.python.launch/src/org/maemo/esbox/python/launch/PythonLocalLaunchProxy.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/python/org.maemo.esbox.python.launch/src/org/maemo/esbox/python/launch/PythonLocalLaunchProxy.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -12,15 +12,15 @@
 package org.maemo.esbox.python.launch;
 
 import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
 import org.eclipse.debug.core.ILaunchConfiguration;
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
 import org.maemo.esbox.core.process.ProcessRunnerParameters;
 import org.maemo.esbox.internal.python.launch.Activator;
 import org.maemo.esbox.launch.core.AbstractLocalLaunchProxy;
 import org.maemo.esbox.launch.core.ILaunchParameterAccessor;
-import org.maemo.esbox.python.launch.debug.PythonDebugger;
 
-import java.util.List;
-import java.util.Properties;
+import java.util.*;
 
 /**
  * @author LWang
@@ -60,13 +60,16 @@
 		
 		cmdLine.add(0, interpreter);
 		
-		// This will get env for the launch config, which may or may not include 
-		// standard env vars based on the user option "Append environment to native environment"
-		// in Environment Tab.
-		Properties env = info.getEnvVars();
+		// This will get changes to the env from the launch config.
+		//
+		IEnvironmentModifierBlock envBlock = info.getEnvironmentModifierBlock();
 
-		// setup PYTHONPATH
-		PythonDebugger.augmentEnvironment(fLPA.getProject(), fLPA.getSDKTarget(), env);
+		// setup PYTHONPATH if not already set
+		if (envBlock.findOperation(PythonLaunchUtils.PYTHONPATH) == null) {
+			Map<IPath, IPath> pythonPathMappings = PythonLaunchUtils.getPythonProjectPathMappings(
+					fLPA.getProject(), fLPA.getSDKTarget());
+			PythonLaunchUtils.setPythonPathEnvironment(pythonPathMappings.values(), envBlock);
+		}
 
 		return info;
 	}

Modified: trunk/python/org.maemo.esbox.python.launch/src/org/maemo/esbox/python/launch/PythonRemoteLaunchProxy.java
===================================================================
--- trunk/python/org.maemo.esbox.python.launch/src/org/maemo/esbox/python/launch/PythonRemoteLaunchProxy.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/python/org.maemo.esbox.python.launch/src/org/maemo/esbox/python/launch/PythonRemoteLaunchProxy.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -12,15 +12,16 @@
 package org.maemo.esbox.python.launch;
 
 import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
 import org.eclipse.debug.core.ILaunchConfiguration;
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
 import org.maemo.esbox.core.process.ProcessRunnerParameters;
 import org.maemo.esbox.internal.python.launch.Activator;
 import org.maemo.esbox.launch.core.AbstractRemoteLaunchProxy;
 import org.maemo.esbox.launch.core.ILaunchParameterAccessor;
-import org.maemo.esbox.python.launch.debug.PythonDebugger;
 
 import java.util.List;
-import java.util.Properties;
+import java.util.Map;
 
 /**
  * @author LWang
@@ -53,13 +54,16 @@
 		
 		cmdLine.add(0, interpreter);
 		
-		// This will get env for the launch config, which may or may not include 
-		// standard env vars based on the user option "Append environment to native environment"
-		// in Environment Tab.
-		Properties env = info.getEnvVars();
+		// This will get env overrides for the launch config.
+		//
+		IEnvironmentModifierBlock envBlock = info.getEnvironmentModifierBlock();
 
-		// setup PYTHONPATH
-		PythonDebugger.augmentEnvironment(fLPA.getProject(), fLPA.getSDKTarget(), env);
+		// setup PYTHONPATH if not already set
+		if (envBlock.findOperation(PythonLaunchUtils.PYTHONPATH) == null) {
+			Map<IPath, IPath> pythonPathMappings = PythonLaunchUtils.getPythonProjectPathMappings(
+					fLPA.getProject(), fLPA.getSDKTarget());
+			PythonLaunchUtils.setPythonPathEnvironment(pythonPathMappings.values(), envBlock);
+		}
 
 		return info;
 	}

Modified: trunk/python/org.maemo.esbox.python.launch/src/org/maemo/esbox/python/launch/debug/ESboxPythonDebugger.java
===================================================================
--- trunk/python/org.maemo.esbox.python.launch/src/org/maemo/esbox/python/launch/debug/ESboxPythonDebugger.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/python/org.maemo.esbox.python.launch/src/org/maemo/esbox/python/launch/debug/ESboxPythonDebugger.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -18,6 +18,7 @@
 import org.eclipse.debug.core.*;
 import org.eclipse.debug.core.model.IProcess;
 import org.maemo.esbox.core.ESboxException;
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
 import org.maemo.esbox.core.process.*;
 import org.maemo.esbox.core.sdk.ISDKTarget;
 import org.maemo.esbox.internal.python.launch.Activator;
@@ -78,12 +79,19 @@
 		PythonRunnerConfig pythonConfiguration;
 		pythonConfiguration = getPythonRunnerConfig(mode, config);
 
-		Properties env = myLPA.getEnvironmentAsProperty();
+		IEnvironmentModifierBlock envBlock = myLPA.getEnvironmentModifierBlock();
+
+		// setup python path mappings
+		Map<IPath, IPath> pythonPathMappings = PythonLaunchUtils.getPythonProjectPathMappings(project, sdkTarget);
+
+		// set PYTHONPATH in environment if user did not
+		if (envBlock.findOperation(PythonLaunchUtils.PYTHONPATH) == null) {
+			PythonLaunchUtils.setPythonPathEnvironment(pythonPathMappings.values(), envBlock);
+		} else {
+			// else, add any mappings from a user override of PYTHONPATH
+			pythonPathMappings.putAll(PythonLaunchUtils.getUserPythonPathMappings(envBlock, sdkTarget));
+		}
 		
-		// setup PYTHONPATH
-		Map<IPath, IPath> pythonPathMappings = mapPythonPath(project, sdkTarget, env);
-		augmentEnvironment(pythonPathMappings, env);
-
 		if (monitor == null)
 			monitor = new NullProgressMonitor();
 		IProgressMonitor subMonitor = new SubProgressMonitor(monitor, 5);
@@ -103,7 +111,7 @@
 		// the main file should map, at the very least
 		localToRemotePathMappings.put(exePath, exeInSb);
 		
-		// now map PYTHONPATH
+		// now map Python interpreter path entries
 		localToRemotePathMappings.putAll(pythonPathMappings);
 		
 		// Copy the debug scripts over
@@ -133,7 +141,7 @@
 		IPath wdInSb = myLPA.getWorkingDirectory();
 		
 		ProcessLauncherParameters parameters = new ProcessLauncherParameters(
-				wdInSb, cmdLine, env);
+				wdInSb, cmdLine, envBlock);
 
 		ESboxLaunchUtils.updateForRunStandalone(sdkTarget, 
 				config,
@@ -147,7 +155,7 @@
 		try {
 			proc = launcher.createProcess();
 		} catch (ESboxException e) {
-			throw new CoreException(PydevDebugPlugin.makeStatus(IStatus.ERROR, "Cannot create process", e));			
+			throw new CoreException(Activator.createErrorStatus("Cannot create process", e));			
 		}
 		
 		IProcess process = registerWithDebugPlugin(pythonConfiguration, launch, proc);

Modified: trunk/python/org.maemo.esbox.python.launch/src/org/maemo/esbox/python/launch/debug/ESboxPythonRemoteDebugger.java
===================================================================
--- trunk/python/org.maemo.esbox.python.launch/src/org/maemo/esbox/python/launch/debug/ESboxPythonRemoteDebugger.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/python/org.maemo.esbox.python.launch/src/org/maemo/esbox/python/launch/debug/ESboxPythonRemoteDebugger.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -15,13 +15,13 @@
 import org.eclipse.core.runtime.*;
 import org.eclipse.debug.core.*;
 import org.eclipse.debug.core.model.IProcess;
+import org.maemo.esbox.core.env.IEnvironmentModifierBlock;
 import org.maemo.esbox.core.process.ProcessLauncherParameters;
 import org.maemo.esbox.core.sdk.ISDKTarget;
 import org.maemo.esbox.internal.python.launch.Activator;
 import org.maemo.esbox.launch.*;
 import org.maemo.esbox.python.launch.*;
 import org.python.pydev.debug.core.Constants;
-import org.python.pydev.debug.core.PydevDebugPlugin;
 import org.python.pydev.debug.model.PyDebugTarget;
 import org.python.pydev.debug.model.remote.RemoteDebugger;
 import org.python.pydev.debug.ui.launching.PythonRunnerConfig;
@@ -77,12 +77,18 @@
 		// for remote debug, the working directory doesn't apply, and we don't want pydev to complain, so clear it
 		config.setAttribute(Constants.ATTR_WORKING_DIRECTORY, "/");
 
-		Properties env = myLPA.getEnvironmentAsProperty();
+		IEnvironmentModifierBlock envBlock = myLPA.getEnvironmentModifierBlock();
 
-		// setup PYTHONPATH
-		Map<IPath, IPath> pythonPathMappings = mapPythonPath(project, sdkTarget, env);
-		augmentEnvironment(pythonPathMappings, env);
+		// setup python path mappings
+		Map<IPath, IPath> pythonPathMappings = PythonLaunchUtils.getPythonProjectPathMappings(project, sdkTarget);
 
+		// set PYTHONPATH in environment if user did not
+		if (envBlock.findOperation(PythonLaunchUtils.PYTHONPATH) == null) {
+			PythonLaunchUtils.setPythonPathEnvironment(pythonPathMappings.values(), envBlock);
+		} else {
+			// else, add any mappings from a user override of PYTHONPATH
+			pythonPathMappings.putAll(PythonLaunchUtils.getUserPythonPathMappings(envBlock, sdkTarget));
+		}
 		
 		// in remote debug, need to map source directories: only handle the project directory
 		setupSourceLocator(launch, config, project, protocol);
@@ -104,7 +110,7 @@
 			}
 		}
 		
-		// now map PYTHONPATH, assuming (if anything) that the SDK is installed in
+		// now map entries in the path mappings, assuming (if anything) that the SDK is installed in
 		// the same place on device as in scratchbox (to allow debugging system files)
 		localToRemotePathMappings.putAll(pythonPathMappings);
 
@@ -134,7 +140,7 @@
 		Process proc = null;
 
 		ProcessLauncherParameters parameters = new ProcessLauncherParameters(
-				cwdPathRemote, remoteCmdLine, env);
+				cwdPathRemote, remoteCmdLine, envBlock);
 		
 		monitor.subTask("Start program");
 		try {
@@ -161,7 +167,7 @@
 			String message = "Unexpected error setting up the debugger";
 			if (ex instanceof SocketTimeoutException)
 				message = "Timed out after " + Float.toString(pythonConfiguration.acceptTimeout/1000) + " seconds while waiting for python script to connect.";
-			throw new CoreException(PydevDebugPlugin.makeStatus(IStatus.ERROR, message, ex));			
+			throw new CoreException(Activator.createErrorStatus(message, ex));			
 		}
 		subMonitor.subTask("Done");
 		// hook up debug model, and we are off & running

Modified: trunk/python/org.maemo.esbox.python.launch/src/org/maemo/esbox/python/launch/debug/PythonDebugger.java
===================================================================
--- trunk/python/org.maemo.esbox.python.launch/src/org/maemo/esbox/python/launch/debug/PythonDebugger.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/python/org.maemo.esbox.python.launch/src/org/maemo/esbox/python/launch/debug/PythonDebugger.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -19,22 +19,16 @@
 import org.eclipse.debug.core.model.IProcess;
 import org.maemo.esbox.core.ESboxException;
 import org.maemo.esbox.core.machine.*;
-
-import org.maemo.esbox.core.sdk.ISDKTarget;
-import org.maemo.esbox.internal.python.launch.Activator;
 import org.maemo.esbox.launch.ESboxDebuggerStatus;
 import org.maemo.esbox.launch.ESboxLaunchUtils;
-import org.maemo.esbox.python.launch.IESboxPythonLaunchConstants;
-import org.maemo.esbox.python.launch.PydevDebugScriptCopier;
+import org.maemo.esbox.python.launch.*;
 import org.maemo.esbox.ssh.ISSHMachine;
-import org.python.pydev.core.IInterpreterManager;
+import org.python.copiedfromeclipsesrc.JDTNotAvailableException;
 import org.python.pydev.debug.core.Constants;
 import org.python.pydev.debug.core.PydevDebugPlugin;
 import org.python.pydev.debug.model.PySourceLocator;
 import org.python.pydev.debug.ui.launching.InvalidRunException;
 import org.python.pydev.debug.ui.launching.PythonRunnerConfig;
-import org.python.pydev.plugin.PydevPlugin;
-import org.python.pydev.plugin.nature.PythonNature;
 
 import java.io.File;
 import java.io.IOException;
@@ -171,105 +165,9 @@
     
     protected void setupSourceLocator(ILaunch launch, ILaunchConfiguration config, IProject project, Object converter) throws CoreException {
     	launch.setSourceLocator(new PySourceLocator());
-    	/*
-		ESboxPythonSourceLocator pythonSourceLocator = new ESboxPythonSourceLocator();
-		launch.setSourceLocator(pythonSourceLocator);
-		pythonSourceLocator.initializeDefaults(config);
-		
-		IPath targetPath = project.getLocation();
-		IPath hostPath;
-		try {
-			if (converter instanceof ISDKTarget)
-				hostPath = ((ISDKTarget) converter).convertHostToTargetPath(targetPath);
-			else if (converter instanceof ILaunchProtocol)
-				hostPath = ((ILaunchProtocol) converter).getFileLocationOnTarget(targetPath.addTrailingSeparator());
-			else
-				throw new IllegalStateException("Unhandled converter type");
-			ESboxLaunchUtils.addSourceMappingToDirector(hostPath, targetPath, "SDK Target Mapping", pythonSourceLocator);
-		} catch (ESboxException e3) {
-		}
-	*/
     }
     
  	/**
-     * Get the mappings from host to target for entries in PYTHONPATH.  This will silently
-     * accept conversion failures, with the assumption that the same path will exist on the
-     * host and target; check for getKey()==getEntry() to verify.
-     * @param project
-     * @param interpreter
-     * @param sdkTarget
-     * @param env
-     * @return Map of host to target paths for entries in PYTHONPATH for the project
-     */
-    public static Map<IPath, IPath> mapPythonPath(IProject project, ISDKTarget sdkTarget, Properties env) {
-    	PythonNature pythonNature = PythonNature.getPythonNature(project);
-    	if (pythonNature == null)
-    		return Collections.EMPTY_MAP;
-    	
-    	IInterpreterManager interpreterManager = PydevPlugin.getInterpreterManager(pythonNature); 
-    	String interpreter = interpreterManager.getDefaultInterpreter();
-    	
-    	Map<IPath, IPath> map = new LinkedHashMap<IPath, IPath>();
-    	
-    	List<String> pythonPaths = pythonNature.getPythonPathNature().getCompleteProjectPythonPath(interpreter);
-        
-        if (pythonPaths != null) {
-        	for (String element : pythonPaths) {
-            	IPath hostPath = new Path(element);
-            	try {
-            		IPath targetPath = sdkTarget.convertHostToTargetPath(hostPath);
-            		map.put(hostPath, targetPath);
-            	} catch (ESboxException e) {
-            		// not inside scratchbox; hope it's visible on target!
-            		map.put(hostPath, hostPath);
-            	}
-            }
-        }
-            
-        return map;
-    }
-    
- 	/**
-     * Add necessary environment variables for a python launch.  Converts the python path
-     * elements to target-side locations and appends entries to PYTHONPATH.
-     * @param project
-     * @param interpreter
-     * @param sdkTarget
-     * @param env
-     */
-    public static void augmentEnvironment(Map<IPath, IPath> pythonPathMappings, Properties env) {
-    	StringBuilder builder = new StringBuilder();
-    	for (Map.Entry<IPath, IPath> entry : pythonPathMappings.entrySet()) {
-    		if (builder.length() > 0)
-    			builder.append(':');
-    		builder.append(entry.getValue().toPortableString());
-    	}
-    	
-		String pythonPath = builder.toString();
-    	try {
-            env.put("PYTHONPATH", pythonPath);
-        } catch (Exception e) {
-        	Activator.getErrorLogger().logError("Cannot determine PYTHONPATH", e);
-        }
-    }
-    
- 	/**
-     * Add necessary environment variables for a python launch.  Converts the python path
-     * elements to target-side locations and appends entries to PYTHONPATH.
-     * @param project
-     * @param sdkTarget
-     * @param env
-     */
-    public static void augmentEnvironment(IProject project, ISDKTarget sdkTarget, Properties env) {
-    	PythonNature pythonNature = PythonNature.getPythonNature(project);
-    	if (pythonNature == null)
-    		return;
-    	
-    	Map<IPath, IPath> localToTargetMappings = mapPythonPath(project, sdkTarget, env);
-    	augmentEnvironment(localToTargetMappings, env);
-    }
-    
-    /**
      * Get the IP of the client machine (Eclipse)
      * @param sdkTarget
      * @return addresss

Modified: trunk/python/org.maemo.esbox.python.launch/src/org/maemo/esbox/python/launch/local/ESboxPythonLocalRunConfigurationTabGroup.java
===================================================================
--- trunk/python/org.maemo.esbox.python.launch/src/org/maemo/esbox/python/launch/local/ESboxPythonLocalRunConfigurationTabGroup.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/python/org.maemo.esbox.python.launch/src/org/maemo/esbox/python/launch/local/ESboxPythonLocalRunConfigurationTabGroup.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -14,10 +14,10 @@
 
 import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
 import org.eclipse.debug.ui.CommonTab;
-import org.eclipse.debug.ui.EnvironmentTab;
 import org.eclipse.debug.ui.ILaunchConfigurationDialog;
 import org.eclipse.debug.ui.ILaunchConfigurationTab;
 import org.eclipse.debug.ui.RefreshTab;
+import org.maemo.esbox.launch.ui.ESboxEnvironmentTab;
 import org.maemo.esbox.python.launch.*;
 import org.maemo.esbox.python.launch.ui.ArgumentsTab;
 import org.maemo.esbox.python.launch.ui.MainModuleTab;
@@ -35,7 +35,7 @@
 			new MainModuleTab(),
 			new ArgumentsTab(),          
 			new RefreshTab(),
-			new EnvironmentTab(),
+			new ESboxEnvironmentTab(),
 			new CommonTab()	};
 		setTabs(tabs);
 	}

Modified: trunk/python/org.maemo.esbox.python.launch/src/org/maemo/esbox/python/launch/remote/EsboxPythonRemoteRunConfigurationTabGroup.java
===================================================================
--- trunk/python/org.maemo.esbox.python.launch/src/org/maemo/esbox/python/launch/remote/EsboxPythonRemoteRunConfigurationTabGroup.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/python/org.maemo.esbox.python.launch/src/org/maemo/esbox/python/launch/remote/EsboxPythonRemoteRunConfigurationTabGroup.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -13,6 +13,7 @@
 import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
 import org.eclipse.debug.ui.*;
 import org.maemo.esbox.launch.ui.ESboxDownloadTab;
+import org.maemo.esbox.launch.ui.ESboxEnvironmentTab;
 import org.maemo.esbox.python.launch.*;
 import org.maemo.esbox.python.launch.ui.ArgumentsTab;
 import org.maemo.esbox.python.launch.ui.MainModuleTab;
@@ -29,7 +30,7 @@
 			new MainModuleTab(),
 			new ArgumentsTab(),          
 			new RefreshTab(),
-			new EnvironmentTab(),
+			new ESboxEnvironmentTab(),
 			new ESboxDownloadTab(),
 			new CommonTab()	};
 		setTabs(tabs);

Modified: trunk/python/org.maemo.esbox.python.launch.analysis/src/org/maemo/esbox/python/launch/analysis/oprofile/OProfilePythonLaunchConfigurationTabGroup.java
===================================================================
--- trunk/python/org.maemo.esbox.python.launch.analysis/src/org/maemo/esbox/python/launch/analysis/oprofile/OProfilePythonLaunchConfigurationTabGroup.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/python/org.maemo.esbox.python.launch.analysis/src/org/maemo/esbox/python/launch/analysis/oprofile/OProfilePythonLaunchConfigurationTabGroup.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -11,10 +11,10 @@
 package org.maemo.esbox.python.launch.analysis.oprofile;
 
 import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
-import org.eclipse.debug.ui.EnvironmentTab;
 import org.eclipse.debug.ui.ILaunchConfigurationDialog;
 import org.eclipse.debug.ui.ILaunchConfigurationTab;
 import org.maemo.esbox.launch.ui.ESboxDownloadTab;
+import org.maemo.esbox.launch.ui.ESboxEnvironmentTab;
 import org.maemo.esbox.python.launch.*;
 import org.maemo.esbox.python.launch.ui.ArgumentsTab;
 import org.maemo.esbox.python.launch.ui.MainModuleTab;
@@ -31,7 +31,7 @@
 		ILaunchConfigurationTab[] tabs = new ILaunchConfigurationTab[] {
 				new MainModuleTab(),
 				new ArgumentsTab(),
-				new EnvironmentTab(),
+				new ESboxEnvironmentTab(),
 				new ESboxDownloadTab()};
 		setTabs(tabs);
 	}

Modified: trunk/python/org.maemo.esbox.python.launch.analysis/src/org/maemo/esbox/python/launch/analysis/valgrind/ValgrindPythonLaunchConfigurationTabGroup.java
===================================================================
--- trunk/python/org.maemo.esbox.python.launch.analysis/src/org/maemo/esbox/python/launch/analysis/valgrind/ValgrindPythonLaunchConfigurationTabGroup.java	2008-10-07 14:19:05 UTC (rev 836)
+++ trunk/python/org.maemo.esbox.python.launch.analysis/src/org/maemo/esbox/python/launch/analysis/valgrind/ValgrindPythonLaunchConfigurationTabGroup.java	2008-10-07 18:56:06 UTC (rev 837)
@@ -11,9 +11,9 @@
 package org.maemo.esbox.python.launch.analysis.valgrind;
 
 import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
-import org.eclipse.debug.ui.EnvironmentTab;
 import org.eclipse.debug.ui.ILaunchConfigurationDialog;
 import org.eclipse.debug.ui.ILaunchConfigurationTab;
+import org.maemo.esbox.launch.ui.ESboxEnvironmentTab;
 import org.maemo.esbox.python.launch.*;
 import org.maemo.esbox.python.launch.ui.ArgumentsTab;
 import org.maemo.esbox.python.launch.ui.MainModuleTab;
@@ -30,7 +30,7 @@
 		ILaunchConfigurationTab[] tabs = new ILaunchConfigurationTab[] {
 				new MainModuleTab(),
 				new ArgumentsTab(),
-				new EnvironmentTab()};
+				new ESboxEnvironmentTab()};
 			setTabs(tabs);
 	}
 



More information about the Esbox-commits mailing list