diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/framework/exec/Environment.java b/proposal/myrmidon/src/java/org/apache/myrmidon/framework/exec/Environment.java
new file mode 100644
index 000000000..5b381df36
--- /dev/null
+++ b/proposal/myrmidon/src/java/org/apache/myrmidon/framework/exec/Environment.java
@@ -0,0 +1,286 @@
+/*
+ * Copyright (C) The Apache Software Foundation. All rights reserved.
+ *
+ * This software is published under the terms of the Apache Software License
+ * version 1.1, a copy of which has been included with this distribution in
+ * the LICENSE.txt file.
+ */
+package org.apache.myrmidon.framework.exec;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Properties;
+import org.apache.myrmidon.api.TaskException;
+import org.apache.myrmidon.framework.Os;
+import org.apache.tools.ant.taskdefs.exec.Execute;
+import org.apache.tools.ant.taskdefs.exec.PumpStreamHandler;
+
+/**
+ * This is the class that can be used to retrieve the environment
+ * variables of the native process.
+ *
+ * @author Peter Donald
+ * @author Thomas Haas
+ * @version $Revision$ $Date$
+ */
+public final class Environment
+{
+ private static final String LINE_SEP = System.getProperty( "line.separator" );
+
+ private static final String[] COMMAND_COM = new String[]{"command.com", "/c", "set"};
+ private static final String[] CMD_EXE = new String[]{"cmd", "/c", "set"};
+
+ // Alternatively one could use: /bin/sh -c env
+ private static final String[] ENV_CMD = new String[]{"/usr/bin/env"};
+ private static final String[] ENV_RAW = new String[]{"env"};
+
+ private static Properties c_procEnvironment;
+
+ /**
+ * Private constructor to block instantiation.
+ */
+ private Environment()
+ {
+ }
+
+ public static String[] toNativeFormat( final Properties environment )
+ throws TaskException
+ {
+ final ArrayList newEnvironment = new ArrayList();
+
+ final Iterator keys = environment.keySet().iterator();
+ while( keys.hasNext() )
+ {
+ final String key = (String)keys.next();
+ final String value = environment.getProperty( key );
+ newEnvironment.add( key + '=' + value );
+ }
+
+ return (String[])newEnvironment.toArray( new String[ newEnvironment.size() ] );
+ }
+
+ /**
+ * @deprecated Dont use me!!!
+ */
+ public static Properties createEnvVars( final String[] environment )
+ throws TaskException
+ {
+ final Properties newEnvironment = new Properties();
+
+ for( int i = 0; i < environment.length; i++ )
+ {
+ final String var = environment[ i ];
+ addProperty( newEnvironment, var );
+ }
+
+ return newEnvironment;
+ }
+
+ public static void addNativeEnvironment( final Properties environment )
+ throws TaskException, IOException
+ {
+ final Properties nativeEnvironment = getEnvironmentVariables();
+ final Iterator nativeKeys = nativeEnvironment.keySet().iterator();
+ while( nativeKeys.hasNext() )
+ {
+ final String key = (String)nativeKeys.next();
+ if( environment.contains( key ) )
+ {
+ //Skip environment variables that are overidden
+ continue;
+ }
+
+ final String value = nativeEnvironment.getProperty( key );
+ environment.setProperty( key, value );
+ }
+ }
+
+ /**
+ * Retrieve an array of EnvironmentData vars that contains a list of all
+ * native EnvironmentData Variables for the current process.
+ */
+ private static String[] getNativeEnvironmentAsArray()
+ throws IOException, TaskException
+ {
+ final Properties environment = getEnvironmentVariables();
+
+ final String[] env = new String[ environment.size() ];
+ final Iterator keys = environment.keySet().iterator();
+ int index = 0;
+ while( keys.hasNext() )
+ {
+ final String key = (String)keys.next();
+ final String value = environment.getProperty( key );
+ env[ index ] = key + '=' + value;
+ index++;
+ }
+
+ return env;
+ }
+
+ /**
+ * Retrieve a Properties object that contains the list of all
+ * native EnvironmentData Variables for the current process.
+ */
+ public static Properties getNativeEnvironment()
+ throws IOException, TaskException
+ {
+ return new Properties( getEnvironmentVariables() );
+ }
+
+ /**
+ * Get the Property object with all environment variables and
+ * attempt to load it if it has not already been loaded.
+ */
+ private synchronized static Properties getEnvironmentVariables()
+ throws IOException, TaskException
+ {
+ if( null == c_procEnvironment )
+ {
+ c_procEnvironment = retrieveEnvironmentVariables();
+ }
+
+ return c_procEnvironment;
+ }
+
+ /**
+ * Retrieve a last of environment variables from the native OS.
+ */
+ private static synchronized Properties retrieveEnvironmentVariables()
+ throws IOException, TaskException
+ {
+ final Properties properties = new Properties();
+ final String data = getEnvironmentText();
+
+ final BufferedReader in = new BufferedReader( new StringReader( data ) );
+ String var = null;
+ String line;
+ while( ( line = in.readLine() ) != null )
+ {
+ if( line.indexOf( '=' ) == -1 )
+ {
+ // Chunk part of previous env var (UNIX env vars can
+ // contain embedded new lines).
+ if( var == null )
+ {
+ var = LINE_SEP + line;
+ }
+ else
+ {
+ var += LINE_SEP + line;
+ }
+ }
+ else
+ {
+ // New env var...append the previous one if we have it.
+ if( var != null )
+ {
+ addProperty( properties, var );
+ }
+ var = line;
+ }
+ }
+
+ // Since we "look ahead" before adding, there's one last env var.
+ addProperty( properties, var );
+ return properties;
+ }
+
+ /**
+ * Parse the specified data into a key=value pair. If there is no
+ * '=' character then generate an exception. After parsed data place
+ * the key-value pair into the specified Properties object.
+ */
+ private static void addProperty( final Properties properties,
+ final String data )
+ throws TaskException
+ {
+ final int index = data.indexOf( '=' );
+ if( -1 == index )
+ {
+ //Our env variable does not have any = in it.
+ final String message = "EnvironmentData variable '" + data +
+ "' does not have a '=' character in it";
+ throw new TaskException( message );
+ }
+ else
+ {
+ final String key = data.substring( 0, index );
+ final String value = data.substring( index + 1 );
+ properties.setProperty( key, value );
+ }
+ }
+
+ /**
+ * Retrieve the text of data that is the result of
+ * running the environment command.
+ */
+ private static String getEnvironmentText()
+ throws IOException, TaskException
+ {
+ final ByteArrayOutputStream output = new ByteArrayOutputStream();
+ final Execute exe = new Execute( new PumpStreamHandler( output ) );
+ exe.setCommandline( getEnvCommand() );
+
+ // Make sure we do not recurse forever
+ exe.setNewenvironment( true );
+
+ final int retval = exe.execute();
+ if( retval != 0 )
+ {
+ // Just try to use what we got
+ }
+
+ return output.toString();
+ }
+
+ /**
+ * Retrieve the command that will display a list of environment
+ * variables.
+ */
+ private static String[] getEnvCommand()
+ throws TaskException
+ {
+ if( Os.isFamily( "os/2" ) )
+ {
+ // OS/2 - use same mechanism as Windows 2000
+ return CMD_EXE;
+ }
+ else if( Os.isFamily( "windows" ) )
+ {
+ final String osname =
+ System.getProperty( "os.name" ).toLowerCase( Locale.US );
+ // Determine if we're running under 2000/NT or 98/95
+ if( osname.indexOf( "nt" ) >= 0 || osname.indexOf( "2000" ) >= 0 )
+ {
+ // Windows 2000/NT
+ return CMD_EXE;
+ }
+ else
+ {
+ // Windows 98/95 - need to use an auxiliary script
+ return COMMAND_COM;
+ }
+ }
+ else if( Os.isFamily( "unix" ) )
+ {
+ // Generic UNIX
+ return ENV_CMD;
+ }
+ else if( Os.isFamily( "netware" ) )
+ {
+ return ENV_RAW;
+ }
+ else
+ {
+ final String message =
+ "Unable to determine native environment variables";
+ throw new TaskException( message );
+ }
+ }
+}