/*   Copyright 2004 The Apache Software Foundation
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package tools.util;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URL;
import java.net.URLConnection;
import java.net.JarURLConnection;
import java.security.MessageDigest;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.DriverManager;
import java.sql.Connection;

import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.Vector;
import java.util.Iterator;

import java.util.regex.Pattern;
import java.util.regex.Matcher;

import java.util.zip.ZipFile;
import java.util.zip.ZipEntry;

/**
 * Utilities to copy files, directories, etc.
 */
public class Util
{
    private static byte[] _byteBuffer = new byte[32768];
    private static char[] _charBuffer = new char[32768];
    private static boolean filteredStackTrace = true;

    /**
     * Read the contents of the given file into a String.
     */
    public static String read(File file)
            throws IOException
    {
        FileInputStream fis = new FileInputStream(file);
        return read(new InputStreamReader(fis, "UTF8"));
    }

    /**
     * Read the contents of the given input stream into a String.  This will
     * also close the stream.
     */
    public static String read(InputStream in)
            throws IOException
    {
        return read(new InputStreamReader(in, "UTF8"));
    }

    /**
     * Read the contents in the given <code>Reader</code> into a String. This
     * will also close the reader.
     */
    public static String read(Reader in)
            throws IOException
    {
        try
        {
            StringBuffer sb = new StringBuffer(_charBuffer.length);
            int amount = 0;

            while (true)
            {
                synchronized (_charBuffer)
                {
                    amount = in.read(_charBuffer);

                    if (amount != -1)
                        sb.append(_charBuffer, 0, amount);
                    else
                        break;
                }
            }
            return sb.toString();
        }
        finally
        {
            close(in);
        }
    }

    public static String read(Reader in, int length)
            throws IOException
    {
        BufferedReader bin = null;

        try
        {
            bin = new BufferedReader(in, length);
            char[] s = new char[length];
            bin.read(s, 0, length);

            return new String(s);
        }
        finally
        {
            close(bin);
        }
    }

    /**
     * Read the contents of the given file line by line into a String array
     *
     * If the second argument is true, then all whitespace lines at the end will
     * be removed from the array
     */
    public static String[] readIntoArray(File file, boolean trimLines)
            throws IOException
    {
        BufferedReader reader = new BufferedReader(new FileReader(file));
        Vector v = new Vector();

        while (true)
        {
            String s = reader.readLine();
            if (s == null) break;
            v.addElement(s);
        }
        reader.close();
        // Discard all trailing lines that are only whitespaces..
        if (trimLines)
        {
            int i = v.size();
            while (--i >= 0)
                if (isWhiteSpace((String) v.get(i)))
                    v.removeElementAt(i);
        }

        String[] strArray = new String[v.size()];
        v.copyInto(strArray);
        return strArray;
    }

    public static void copy(InputStream in, OutputStream out)
            throws IOException
    {
        try
        {
            int amount = 0;

            while (true)
            {
                synchronized (_byteBuffer)
                {
                    amount = in.read(_byteBuffer);
                    if (amount == -1)
                        break;
                    out.write(_byteBuffer, 0, amount);
                }
            }
        }
        finally
        {
            close(in);
            close(out);
        }
    }

    /**
     * Copy a stream to a file.
     */
    public static void copyToFile(InputStream in, File toFile,
                                  boolean overwrite)
            throws IOException
    {
        if (toFile.exists() && !overwrite)
            return;

        // create any parent directories
        File parent = toFile.getParentFile();
        if (parent != null)
            parent.mkdirs();

        // creates a new file only if it doesn't exist
        toFile.createNewFile();

        copy(in, new FileOutputStream(toFile));
    }

    /**
     * Copy URL to file.
     */
    public static void copyToFile(URL url, File toFile,
                                  boolean replaceNewer)
            throws IOException
    {
        Log.debug("copyToFile(url=" + url + ",\n toFile=" + toFile + ")");

        URLConnection conn = url.openConnection();
        if (toFile.exists() &&
                toFile.lastModified() > conn.getLastModified() &&
                !replaceNewer)
            return;

        copyToFile(conn.getInputStream(), toFile, true);
    }

    /**
     * Copy file to file.
     */
    public static void copyToFile(File fromFile, File toFile,
                                  boolean replaceNewer)
            throws IOException
    {
        Log.debug("copyToFile(fromFile=" + fromFile + ",\n toFile=" + toFile +
                  ")");

        // don't replace newer files unless flag is set
        if (toFile.exists() &&
                toFile.lastModified() > fromFile.lastModified() &&
                !replaceNewer)
            return;

        copyToFile(new FileInputStream(fromFile),
                   toFile, true);
    }

    /**
     * Copy file to a dir.
     */
    public static void copyToDir(File fromFile, File toDir,
                                 boolean replaceNewer)
            throws IOException
    {
        //System.out.println("copyToDir(fromFile=" + fromFile +
        //",\n toDir=" + toDir + ")");

        toDir.mkdirs();

        copyToFile(fromFile, new File(toDir, fromFile.getName()),
                   replaceNewer);
    }

    /**
     * Copy URL to a dir.
     */
    public static void copyToDir(URL url, File toDir,
                                 boolean replaceNewer)
            throws IOException
    {
        //System.out.println("copyToDir(url=" + url +
        //",\n toDir=" + toDir + ")");

        toDir.mkdirs();

        copyToFile(url, new File(toDir, url.getFile()),
                   replaceNewer);
    }

    /**
     * Recursively copy a dir to a new dir. Creates target tree if needed.
     */
    public static void copyDirToDir(File fromDir, File toDir,
                                    boolean replaceNewer, final String[] exclude)
            throws IOException
    {
        //System.out.println("copyDirToDir(fromDir=" + fromDir +
        //",\n toDir=" + toDir + ")");

        File[] fs = fromDir.listFiles();
        COPY_FILE_LOOP:
        for (int i = 0; i < fs.length; i++)
        {
            // exclude based only on last part of file name
            String name = fs[i].getName();

            if (exclude != null)
            {
                for (int j = 0; j < exclude.length; ++j)
                {
                    if (name.equals(exclude[j]))
                        continue COPY_FILE_LOOP;
                }
            }

            if (fs[i].isFile())
            {
                copyToDir(fs[i], toDir, replaceNewer);
            } else
            {
                copyDirToDir(fs[i], new File(toDir, fs[i].getName()),
                             replaceNewer, exclude);
            }
        }
    }

    /**
     * Recursively copy a jar dir entry to a new dir.  This is expensive since
     * we have to iterate over all the entries in the .zip/.jar file.
     * The <code>fromDir</code> parameter must end in '/'.
     */
    public static void copyDirToDir(ZipFile zip, String fromDir,
                                    File toDir, boolean replaceNewer, final String[] exclude)
            throws IOException
    {
        //System.out.println("copyDirToDir(zip=" + zip +
        //", fromDir=" + fromDir +
        //", toDir=" + toDir + ")");

        if (!fromDir.endsWith("/"))
            return;

        Enumeration _enum = zip.entries();
        COPY_JAR_LOOP:
        while (_enum.hasMoreElements())
        {
            ZipEntry entry = (ZipEntry) _enum.nextElement();
            //System.out.println("  entry = " + entry.getName());

            // skip directories
            if (entry.isDirectory())
                continue;

            if (!entry.getName().startsWith(fromDir))
                continue;

            String entryFile = entry.getName().substring(fromDir.length());

            // FIXME: exclude files matching any pattern in exclude array

            // use this class' loader to obtain the resource
            URL url = Util.class.getResource("/" + entry.getName());
            if (url == null)
            {
                throw new java.io.IOException("Resource not found: " +
                                              entry.toString());
            }
            copyToFile(url, new File(toDir, entryFile), replaceNewer);
        }
    }

    /**
     * Copy a dir url to a new dir.
     */
    public static void copyDirToDir(URL url, File toDir,
                                    boolean replaceNewer, String[] exclude)
            throws IOException
    {
        Log.debug("copyDirToDir(url=" + url + ", toDir=" + toDir + ")");

        // url must end in '/'
        if (!url.getFile().endsWith("/"))
            return;

        if ("file".equals(url.getProtocol()))
        {
            copyDirToDir(new File(url.getPath()), toDir,
                         replaceNewer, exclude);
        } else if ("jar".equals(url.getProtocol()))
        {
            JarURLConnection conn = (JarURLConnection) url.openConnection();
            copyDirToDir(conn.getJarFile(), conn.getEntryName(),
                         toDir, replaceNewer, exclude);
        } else if ("zip".equals(url.getProtocol()))
        {
            URL newUrl = new URL("jar:file:" + url.getPath());
            Log.debug("changed zip url to = " + newUrl);

            copyDirToDir(newUrl, toDir, replaceNewer, exclude);
        } else
        {
            throw new IOException("Protocol not supported yet: " +
                                  url.getProtocol());
        }
    }

    /**
     * Copy a dir to a new dir.
     */
    public static void copyDirToDir(File fromDir, File toDir,
                                    boolean replaceNewer)
            throws IOException
    {
        copyDirToDir(fromDir, toDir, replaceNewer, null);
    }

    /**
     * Recursively remove a directory and it's contents.
     */
    public static void remove(String file)
    {
        remove(new File(file));
    }

    /**
     * Recursively remove a directory and it's contents.
     */
    public static void remove(File file)
    {
        if (file == null || !file.exists())
            return;

        if (file.isFile())
            removeFile(file);
        else if (file.isDirectory())
            removeDir(file);
    }

    /**
     * Remove a directory's contents.
     */
    private static void removeDir(File dir)
    {
        File[] entries = dir.listFiles();

        if (entries == null)
        {
            Log.fatal("IO Error or dir doesn't exist: " + dir);
            return;
        }

        for (int i = 0; i < entries.length; ++i)
            remove(entries[i]);

        Log.debug("removing dir: " + dir.toString());
        dir.delete();
    }

    /**
     * Remote a file.
     */
    private static void removeFile(File file)
    {
        Log.debug("removing file: " + file.toString());
        file.delete();
    }

    /**
     * @deprecated This is really overkill.
     *
     *             Parses command-line arguments into a Hashtable.
     *             <pre>
     *             command-line : ( arg-assignment )* the-rest
     *             arg-assignment : option-name option-value?
     *             option-name : "any string with a leading '-' "
     *             option-value : "any string without a leading '-' "
     *             the-rest : "any args after options ended"
     *
     *             The following rules are used:
     *             - If an option appears multiple times, then its value is OVERWRITTEN!
     *             - If no value is given for an option, then the Hashtable entry contains a Boolean object TRUE
     *             - the rest of the arguments are stored as an array under the special key @REST
     *             - @REST value is always filled, at least with an EMPTY ARRAY (and not a null!!!)
     *             - An option of "-" ends option parsing.  Use this when a value-less option is followed by the-rest
     *
     *             Examples: (1) "-foo bar -goo zabba -boo -hoo" is parsed as
     *                           {foo -> bar, goo -> zabba, -boo -> TRUE, -hoo -> TRUE}
     *                       (2) "-foo bar -foo bar2 aaa bbb ccc" is parsed as { foo -> bar2, @REST -> [aaa,bbb,ccc] }
     *
     *             Rationale:
     *               The above grammar and rules are less powerful than those given by gnu.getopt, but
     *               are easier to use for our purposes
     *             </pre>
     */
    public static HashMap parseArgs(String args[])
    {
        HashMap ht = new HashMap();
        int k;
        int n = args.length;

        for (k = 0; k < n; k++)
        {
            // Stop option processing if not an option or is the single character '-'
            if (args[k].startsWith("-"))
            {
                // eat the '-' and end option processing if it's just a '-'
                if (args[k].length() == 1)
                {
                    k++;
                    break;
                }

                String opt = args[k].substring(1); // skip -
                String optarg = null;
                if ((k < n - 1) && !args[k + 1].startsWith("-"))
                {
                    // got an option value
                    optarg = args[k + 1];
                    k++;
                }

                ht.put(opt,
                       (null != optarg) ?
                       (Object) optarg :
                       (Object) Boolean.TRUE);
            } else
            {
                break;
            }
        }

        // either we have run out of options or
        // we have hit the first non-option argument
        //
        int n_rest = n - k;
        String rest[] = new String[n_rest];
        int j;

        for (j = 0; k < n; j++, k++)
        {
            rest[j] = args[k];
        }

        ht.put("@REST", rest);

        return ht;
    }

    /**
     * @deprecated This is really overkill.
     *
     *             This is a subset of the above parser.  It assumes only boolean options, but
     *             allows arguments to be interspersed with options.
     *
     *             Parses command-line arguments into a Hashtable using the following grammar:
     *             command-line : ( option-name | argument )*
     *             option-name : "any string with a leading '-' "
     *             argument : "any string without a leading '-' "
     *
     *             The following rules are used:
     *             - If an option appears multiple times, then its value is OVERWRITTEN!
     *             - The Hashtable entry for any option contains a Boolean object TRUE
     *             - the rest of the arguments are stored as an array under the special key @REST
     *             - @REST value is always filled, at least with an EMPTY ARRAY (and not a null!!!)
     *             - An option of "-" ends option parsing.  Use this before an argument that must begin with a '-'
     *
     *             Examples: (1) "-foo bar -goo zabba -boo -hoo" is parsed as
     *             {foo -> TRUE, goo -> TRUE, -boo -> TRUE, -hoo -> TRUE, @REST -> [bar,zabba]}
     *             (2) "-foo bar -foo bar2 aaa - -bbb -ccc"
     *             is parsed as { foo -> TRUE, @REST -> [bar,bar2,aaa,-bbb,-ccc] }
     *
     *             Rationale:
     *             parseArgs does not have a way of specifying a trailing boolean option followed by an
     *             argument except through the '-' hack.  It is unable to implement, for example, the argument scanning of
     *             SystemSchemaBooter without forcing a change in the command-line syntax
     */
    public static HashMap parseOptions(String args[])
    {
        HashMap ht = new HashMap();
        int k;
        int n = args.length;
        int nOptions = 0;

        for (k = 0; k < n; k++)
        {
            // Stop option processing if not an option or is the single character '-'
            if (args[k].startsWith("-"))
            {
                nOptions++;
                // eat the '-' and end option processing if it's just a '-'
                if (args[k].length() == 1)
                {
                    k++;
                    break;
                }

                String opt = args[k].substring(1); // skip -
                ht.put(opt, (Object) Boolean.TRUE);
            }
        }

        // either we have run out of options or
        // we have hit a single '-'
        //
        int n_rest = n - nOptions;
        String rest[] = new String[n_rest];
        boolean bIgnoreOptions = false;
        int j = 0;
        // Rescan the args and put non-options in the rest array
        for (k = 0; k < n; k++)
        {
            if (bIgnoreOptions || !args[k].startsWith("-"))
            {
                rest[j++] = args[k];
            } else if (args[k].length() == 1)
            {
                bIgnoreOptions = true;
            }
        }

        ht.put("@REST", rest);

        return ht;
    }


    /**
     * Close a possibly null output stream. Ignore any exceptions.
     */
    static public void close(OutputStream stream)
    {
        if (stream == null)
            return;

        try
        {
            stream.close();
        }
        catch (Exception ignore)
        {
        }
    }

    /**
     * Close a possibly null input stream. Ignore any exceptions.
     */
    static public void close(InputStream stream)
    {
        if (stream == null)
            return;

        try
        {
            stream.close();
        }
        catch (Exception ignore)
        {
        }
    }


    /**
     * Close a possibly null reader. Ignore any exceptions.
     */
    static public void close(Reader reader)
    {
        if (reader == null)
            return;

        try
        {
            reader.close();
        }
        catch (Exception ignore)
        {
        }
    }

    /**
     * Close a possibly null writer. Ignore any exceptions.
     */
    static public void close(Writer writer)
    {
        if (writer == null)
            return;

        try
        {
            writer.close();
        }
        catch (Exception ignore)
        {
        }
    }

    /**
     * Close a possibly null server socket. Ignore any exceptions.
     */
    static public void close(ServerSocket socket)
    {
        if (socket == null)
            return;

        try
        {
            socket.close();
        }
        catch (Exception ignore)
        {
        }
    }

    /**
     * Close a possibly null socket. Ignore any exceptions.
     */
    static public void close(Socket socket)
    {
        if (socket == null)
            return;

        try
        {
            socket.close();
        }
        catch (Exception ignore)
        {
        }
    }

    /**
     * Copy from an output stream to an input stream.
     */

    static public int
            copyStream(InputStream in, OutputStream out, byte[] buffer)
            throws IOException
    {
        int c;
        int length = 0;

        if (buffer == null)
            buffer = new byte[4096];

        while ((c = in.read(buffer)) > 0)
        {
            length += c;
            out.write(buffer, 0, c);
        }

        return length;
    }

    public static String
            hexStringFromBytes(byte[] bytes)
    {
        String hex = "0123456789abcdef";
        StringBuffer buf = new StringBuffer(2 * bytes.length);

        for (int i = 0; i < bytes.length; i++)
        {
            int b = bytes[i];
            buf.append(hex.charAt((b >> 4) & 0xf));
            buf.append(hex.charAt(b & 0xf));
        }

        return buf.toString();
    }

    /**
     * Convert a nibble to a hex character
     *
     * @param	nibble	the nibble to convert.
     */
    public static char toHex(int nibble)
    {
        return hexDigit[(nibble & 0xF)];
    }

    /**
     * A table of hex digits
     */
    private static final char[] hexDigit = {
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
    };

    public static String gobbleUpReader(Reader in)
            throws Exception
    {
        StringBuffer buf = new StringBuffer();
        int c;

        while (-1 != (c = in.read()))
        {
            buf.append(c);
        }

        return buf.toString();
    }

    public static String createHashedPassword(String user, String password)
    {
        MessageDigest md = null;
        try
        {
            md = MessageDigest.getInstance("SHA1", "SUN");
        }
        catch (Exception e)
        {
            throw new RuntimeException(e.getMessage());
        }

        md.update(user.getBytes());
        md.update(password.getBytes());

        return hexStringFromBytes(md.digest());
    }

    static public String makeHtmlStringNoNewLine(String sIn)
    {
        if (null == sIn)
            return null;

        int lenIn = sIn.length();
        int iIn;

        StringBuffer outBuf = new StringBuffer(lenIn + lenIn / 4);  // Plenty of room for extra characters
        char c;

        for (iIn = 0; iIn < lenIn; ++iIn)
        {
            c = sIn.charAt(iIn);
            switch (c)
            {
                case '&':
                    outBuf.append("&amp;");
                    break;
                case '"':
                    outBuf.append("&quot;");
                    break;
                case '<':
                    outBuf.append("&lt;");
                    break;
                case '>':
                    outBuf.append("&gt;");
                    break;
                default:
                    outBuf.append(c);
                    break;
            }
        }

        return outBuf.toString();
    }

    /**
     * Helper function to split a String into an array of Strings somewhat
     * like the JDK 1.4.1 {@link java.lang.String#split(String)} method does.
     */
    public static java.util.List splitList(String s, String match)
    {
        java.util.List strings = new java.util.ArrayList();
        s.trim();

        while (!s.equals(""))
        {
            if (s.indexOf(match) != -1)
            {
                strings.add(s.substring(0, s.indexOf(match)));
                s = s.substring(s.indexOf(match) + 1, s.length());
            } else
            {
                strings.add(s);
                s = "";
            }
            s.trim();
        }

        return strings;
    }

    /**
     * Helper function to split a String into an array of Strings somewhat
     * like the JDK 1.4.1 {@link java.lang.String#split(String)} method does.
     */
    public static String[] split(String s, String match)
    {
        java.util.List strings = splitList(s, match);
        return (String[]) strings.toArray((Object[]) (new String[0]));
    }

    /**
     * Programtically turn on/off the stack trace filter.
     */
    public static void setFilteredStackTrace(boolean filter)
    {
        Util.filteredStackTrace = filter;
    }

    /**
     * State of the stack trace filter.
     */
    public static boolean isFilteredStackTrace()
    {
        return Util.filteredStackTrace;
    }

    /**
     * Helper to get the stack trace of an Exception as a String.
     *
     * @param t Use the stack trace of this exception.
     * @return The stack trace as a String.
     */
    public static String getStackTrace(Throwable t)
    {
        if (t == null)
            return null;

        StringWriter sw = new StringWriter();
        t.printStackTrace(new PrintWriter(sw));
        return sw.toString();
    }

    /**
     * Filter a stack trace by removing any lines matching the set.  A default
     * set will always be applied, but a custom set can also be provided.
     *
     * @param t Use the stack trace of this exception.
     * @return The filtered stack trace as a String.
     */
    public static String getFilteredStackTrace(Throwable t)
    {
        return getFilteredStackTrace(t, null);
    }

    /**
     * Filter a stack trace by removing any lines matching the set.  A default
     * set will always be applied, but a custom set can also be provided.
     *
     * @param t       Use the stack trace of this exception.
     * @param filters Set of custom filters where each filter is
     *                the beginning of a class name.
     * @return The filtered stack trace as a String.
     */
    public static String getFilteredStackTrace(Throwable t, String[] filters)
    {
        return filterStack(getStackTrace(t), filters);
    }

    /**
     * Helper for the {@link #getFilteredStackTrace(java.lang.Throwable)}
     * method.
     *
     * @param stack   A stack trace as a String.
     * @param filters Set of custom filters where each filter is
     *                the beginning of a class name.
     * @return The filtered stack trace as a String.
     */
    public static String filterStack(String stack, String[] filters)
    {
        if (!isFilteredStackTrace())
            return stack;

        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        BufferedReader br = new BufferedReader(new StringReader(stack));

        String line;

        try
        {
            while ((line = br.readLine()) != null)
            {
                if (!isFiltered(line, filters))
                {
                    pw.println(line);
                }
            }
        }
        catch (Exception e)
        {
            return stack;
        }

        return sw.toString();
    }

    /**
     * Helper for the {@link #getFilteredStackTrace(java.lang.Throwable)}
     * method.
     *
     * @param line    A single line from the stack trace.
     * @param filters Set of custom filters where each filter is
     *                the beginning of a class name.
     * @return true if the line should be filtered; false otherwise.
     */
    static boolean isFiltered(String line, String[] filters)
    {
        final String[] defaultFilters = new String[]{
            "org.apache.xmlbeansbeans.test.tools.moosehead",
            "org.apache.xmlbeansbeans.test.tools.harness.Main",
            "org.junit.Assert.",
            "junit.framework.TestCase",
            "junit.framework.TestResult",
            "junit.framework.TestSuite",
            "junit.framework.Assert.", // don't filter AssertException
            "java.lang.reflect.Method.invoke(",
            "org.apache.tools.ant"
        };

        for (int i = 0; i < defaultFilters.length; ++i)
        {
            if (line.indexOf(defaultFilters[i]) > 0)
            {
                return true;
            }
        }

        if (filters != null)
            for (int i = 0; i < filters.length; ++i)
            {
                if (line.indexOf(filters[i]) > 0)
                    return true;
            }

        return false;
    }

    /**
     * @deprecated
     */
    public static URL getURL(String name)
    {
        return ResourceUtil.getURL(name);
    }

    /**
     * @deprecated
     */
    public static InputStream getStream(String name)
    {
        return ResourceUtil.getStream(name);
    }

    /**
     * @deprecated
     */
    public static File getFile(String name)
    {
        return ResourceUtil.getFile(name);
    }

    /**
     * /**
     * Expand key/value pairs in a String.
     * Replaces patterns in the string of the form ${key} where
     * the keys and values are taken from the hash map.  I'm sure someone
     * could write this more efficiently if they wanted to.  Replacement is
     * recursive.  Eg, if the map contains the key "foo" with value "bar", the
     * string "My dog has ${foo}." will become "My dog has bar."
     *
     * @param str String to be expanded.
     * @param map Map of key value pairs.
     * @return The string after replacement.
     *
     * @deprecated See <code>expand()</code>.
     */
    public static String _expand(String str, HashMap map)
    {
        if (str == null)
            return null;

        if (map == null)
            return str;

        StringBuffer result = new StringBuffer();

        int pos = 0;
        int open = -1;

        //System.out.println("expand("+str+")");

        while (-1 != (open = str.indexOf("${", pos)))
        {
            //System.out.println("open: " + open + " = " + str.charAt(open));
            //System.out.println("appending: " + str.substring(pos, open) + "<");

            // replace everything we've passed so far.
            result.append(str.substring(pos, open));
            pos = open + 1;

            int close = str.indexOf("}", open);
            if (close == -1)
                continue;
            //System.out.println("close: " + close + " = " + str.charAt(close));
            //System.out.println("whole region: " + str.substring(open, close+1));
            //System.out.println("match region: " + str.substring(open+2, close));

            String key = str.substring(open + 2, close);
            if (map.containsKey(key))
            {
                String value = expand((String) map.get(key), map);
                result.append(value);

                // non-recursive implementation below:
                //result.append(map.get(key));

                pos = close + 1;
                continue;
            }

            // we've passed the start character (pos = open+1) and didn't find
            // a match, so copy the '$' to the result string
            result.append('$');

        }

        result.append(str.substring(pos));

        //System.out.println("## expanded: " + result.toString());
        return result.toString();
    }

    /**
     * Expand key/value pairs in a String.
     * Replaces patterns in the string of the form ${key} where
     * the keys and values are taken from the hash map.  I'm sure someone
     * could write this more efficiently if they wanted to.  Replacement is
     * recursive.  Eg, if the map contains the key "foo" with value "bar", the
     * string "My dog has ${foo}." will become "My dog has bar."  This version
     * uses the JDK 1.4 regex classes.
     *
     * @param str String to be expanded.
     * @param map Map of key value pairs.
     * @return The string after replacement.
     */
    public static String expand(String str, HashMap map)
    {
        final Pattern p = Pattern.compile("\\$\\{.+?\\}");

        if (str == null)
            return null;

        if (map == null)
            return str;

        int last = 0;
        StringBuffer buf = new StringBuffer();
        Matcher m = p.matcher(str);

        while (m.find())
        {

            // guarenteed to return ${key} where key is at least one character
            // in length.  match will never be null.
            String match = m.group();
            int start = m.start();
            int end = m.end();

            // remove the ${ and } from the match
            String key = match.substring("${".length(),
                                         match.length() - "}".length());

            if (map.containsKey(key))
            {
                String value = expand((String) map.get(key), map);

                buf.append(str.substring(last, start));
                buf.append(value);

                last = end;
            }
        }

        buf.append(str.substring(last, str.length()));

        return buf.toString();
    }

    /**
     * Escape a string for writing to a property file.
     * This is a simplistic version of the Properties.store() escaping.
     */
    public static String escapeProperty(String s)
    {
        int len = s.length();
        StringBuffer buf = new StringBuffer(len * 2);

        for (int i = 0; i < len; ++i)
        {
            char c = s.charAt(i);

            switch (c)
            {
                case '\t':
                    buf.append('\\').append('t');
                    break;
                case '\n':
                    buf.append('\\').append('n');
                    break;
                case '\r':
                    buf.append('\\').append('r');
                    break;
                case '\f':
                    buf.append('\\').append('f');
                    break;

                case '\\':
                case ' ':
                case '=':
                case ':':
                case '#':
                case '!':
                    buf.append('\\').append(c);
                    break;

                default:
                    if ((c < 0x0020) || (c > 0x007e))
                    {
                        buf.append('\\');
                        buf.append('u');
                        buf.append(toHex((c >> 12) & 0xF));
                        buf.append(toHex((c >> 8) & 0xF));
                        buf.append(toHex((c >> 4) & 0xF));
                        buf.append(toHex(c & 0xF));
                    } else
                    {
                        buf.append(c);
                    }
            }
        }

        return buf.toString();
    }

    /**
     * Checks if a string is entirely whitespace
     */
    public static boolean isWhiteSpace(String s)
    {
        for (int i = 0; i < s.length(); i++)
            if (!Character.isWhitespace(s.charAt(i)))
                return false;

        return true;
    }

}


