*/
            Runtime rt = null;
            BufferedReader commandsStdOut = null;
            BufferedReader commandsStdErr = null;
            BufferedOutputStream commandsStdIn = null;
            Process proc = null;
            int bufRead = -1;
            //create query arguments
            Enumeration paramNames = params.keys();
            StringBuffer cmdAndArgs = new StringBuffer("\"" + command + "\"");
            if (paramNames != null && paramNames.hasMoreElements()) {
                cmdAndArgs.append(" ");
                while (paramNames.hasMoreElements()) {
                    String k = (String) paramNames.nextElement();
                    String v = params.get(k).toString();
                    if ((k.indexOf("=") < 0) && (v.indexOf("=") < 0)) {
                        cmdAndArgs.append("\"");
                        cmdAndArgs.append(k);
                        cmdAndArgs.append("=");
                        v = java.net.URLEncoder.encode(v);
                        cmdAndArgs.append(v);
                        cmdAndArgs.append("\"");
                        cmdAndArgs.append(" ");
                    }
                }
            }
            /*String postIn = getPostInput(params);
            int contentLength = (postIn.length()
                    + System.getProperty("line.separator").length());
            if ("POST".equals(env.get("REQUEST_METHOD"))) {
                env.put("CONTENT_LENGTH", new Integer(contentLength));
            }*/
        //if (command.endsWith(".pl") || command.endsWith(".cgi")) {
            StringBuffer perlCommand = new StringBuffer("perl ");
            perlCommand.append(cmdAndArgs.toString());
            cmdAndArgs = perlCommand;
        //}
            rt = Runtime.getRuntime();
            proc = rt.exec(cmdAndArgs.toString(), hashToStringArray(env), wd);
            /*
             * provide input to cgi
             * First  -- parameters
             * Second -- any remaining input
             */
            /*commandsStdIn = new BufferedOutputStream(proc.getOutputStream());
            if (debug >= 2 ) {
                log("runCGI stdin=[" + stdin + "], qs="
                    + env.get("QUERY_STRING"));
            }
            if ("POST".equals(env.get("REQUEST_METHOD"))) {
                if (debug >= 2) {
                    log("runCGI: writing ---------------\n");
                    log(postIn);
                    log("runCGI: new content_length=" + contentLength
                        + "---------------\n");
                }
                commandsStdIn.write(postIn.getBytes());
            }
            if (stdin != null) {
                //REMIND: document this
                /* assume if nothing is available after a time, that nothing is
                 * coming...
                 */
                /*if (stdin.available() <= 0) {
                    if (debug >= 2 ) {
                        log("runCGI stdin is NOT available ["
                            + stdin.available() + "]");
                    }
                    try {
                        Thread.currentThread().sleep(iClientInputTimeout);
                    } catch (InterruptedException ignored) {
                    }
                }
                if (stdin.available() > 0) {
                    if (debug >= 2 ) {
                        log("runCGI stdin IS available ["
                            + stdin.available() + "]");
                    }
                    byte[] bBuf = new byte[1024];
                    bufRead = -1;
                    try {
                        while ((bufRead = stdin.read(bBuf)) != -1) {
                            if (debug >= 2 ) {
                                log("runCGI: read [" + bufRead
                                    + "] bytes from stdin");
                            }
                            commandsStdIn.write(bBuf, 0, bufRead);
                        }
                        if (debug >= 2 ) {
                            log("runCGI: DONE READING from stdin");
                        }
                    } catch (IOException ioe) {
                        //REMIND: replace with logging
                        //REMIND: should I throw this exception?
                        log("runCGI: couldn't write all bytes.");
                        ioe.printStackTrace();
                    }
                }
            }
            commandsStdIn.flush();
            commandsStdIn.close();*/
      String sContentLength = (String) env.get("CONTENT_LENGTH");
      if(!"".equals(sContentLength)) {
          commandsStdIn = new BufferedOutputStream(proc.getOutputStream());
          byte[] content = new byte[Integer.parseInt(sContentLength)];
          int lenRead = stdin.read(content);
          if ("POST".equals(env.get("REQUEST_METHOD"))) {
              String paramStr = getPostInput(params);
              if (paramStr != null) {
                  byte[] paramBytes = paramStr.getBytes();
                  commandsStdIn.write(paramBytes);
                  int contentLength = paramBytes.length;
                  if (lenRead > 0) {
                      String lineSep = System.getProperty("line.separator");
                      commandsStdIn.write(lineSep.getBytes());
                      contentLength = lineSep.length() + lenRead;
                  }
                  env.put("CONTENT_LENGTH", new Integer(contentLength));
              }
          }
          if (lenRead > 0) {
              commandsStdIn.write(content, 0, lenRead);
          }
          commandsStdIn.flush();
          commandsStdIn.close();
      }
            /* we want to wait for the process to exit,  Process.waitFor()
             * is useless in our situation; see
             * http://developer.java.sun.com/developer/
             *                               bugParade/bugs/4223650.html
             */
            boolean isRunning = true;
            commandsStdOut = new BufferedReader
                (new InputStreamReader(proc.getInputStream()));
            commandsStdErr = new BufferedReader
                (new InputStreamReader(proc.getErrorStream()));
            BufferedWriter servletContainerStdout = null;
            try {
                if (response.getOutputStream() != null) {
                    servletContainerStdout =
                        new BufferedWriter(new OutputStreamWriter
                            (response.getOutputStream()));
                }
            } catch (IOException ignored) {
                //NOOP: no output will be written
            }
            final BufferedReader stdErrRdr = commandsStdErr ;
            new Thread() {
                public void run () {
                    sendToLog(stdErrRdr) ;
                } ;
            }.start() ;
            while (isRunning) {
                try {
                    //set headers
                    String line = null;
                    while (((line = commandsStdOut.readLine()) != null)
                           && !("".equals(line))) {
                        if (debug >= 2) {
                            log("runCGI: addHeader(\"" + line + "\")");
                        }
                        if (line.startsWith("HTTP")) {
                            //TODO: should set status codes (NPH support)
                            /*
                             * response.setStatus(getStatusCode(line));
                             */
                        } else if (line.indexOf(":") >= 0) {
                            response.addHeader
                                (line.substring(0, line.indexOf(":")).trim(),
                                line.substring(line.indexOf(":") + 1).trim());
                        } else {
                            log("runCGI: bad header line \"" + line + "\"");
                        }
                    }
                    //write output
                    char[] cBuf = new char[1024];
                    while ((bufRead = commandsStdOut.read(cBuf)) != -1) {
                        if (servletContainerStdout != null) {
                            if (debug >= 4) {
                                log("runCGI: write(\"" + new String(cBuf, 0, bufRead) + "\")");
                            }
                            servletContainerStdout.write(cBuf, 0, bufRead);
                        }
                    }
                    if (servletContainerStdout != null) {
                        servletContainerStdout.flush();
                    }
                    proc.exitValue(); // Throws exception if alive
                    isRunning = false;
                } catch (IllegalThreadStateException e) {
                    try {