/*   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
    {
        StringBuilder buf = new StringBuilder();
        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;
        StringBuilder buf = new StringBuilder();
        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;
    }

}


