SimpleDateFormat sdf = new SimpleDateFormat("dd'/'MM'/'yyyy '0:0 AM, 'z");
SimpleDateFormat sdf = new SimpleDateFormat("dd'/'MM'/'yyyy");
    public static void createOutput()    {        // start a string buffer to hold the final output        StringBuffer summary = new StringBuffer();                // define an iterator that will be used to go over the hashmap keys        Iterator keys = null;                // output the number of lines parsed        summary.append("log_lines=" + Integer.toString(lineCount) + "\n");                // output the number of warnings encountered        summary.append("warnings=" + Integer.toString(warnCount) + "\n");                // set the general summary config up in the aggregator file        for (int i = 0; i < generalSummary.size(); i++)        {            summary.append("general_summary=" + generalSummary.get(i) + "\n");        }                // output the host name        summary.append("server_name=" + hostName + "\n");                // output the service name         summary.append("service_name=" + name + "\n");                // output the date information if necessary        SimpleDateFormat sdf = new SimpleDateFormat("dd'/'MM'/'yyyy '0:0 AM, 'z");        if (startDate != null)        {            summary.append("start_date=" + sdf.format(startDate) + "\n");        }        else if (logStartDate != null)        {            summary.append("start_date=" + sdf.format(logStartDate) + "\n");        }                if (endDate != null)        {            summary.append("end_date=" + sdf.format(endDate) + "\n");        }        else if (logEndDate != null)        {            summary.append("end_date=" + sdf.format(logEndDate) + "\n");        }                // write out the archive stats        keys = archiveStats.keySet().iterator();        while (keys.hasNext())        {            String key = (String) keys.next();            summary.append("archive." + key + "=" + archiveStats.get(key) + "\n");        }                // write out the action aggregation results        keys = actionAggregator.keySet().iterator();        while (keys.hasNext())        {            String key = (String) keys.next();            summary.append("action." + key + "=" + actionAggregator.get(key) + "\n");        }                // depending on the config settings for reporting on emails output the        // login information        summary.append("user_email=" + userEmail + "\n");        int address = 1;        keys = userAggregator.keySet().iterator();        // for each email address either write out the address and the count        // or alias it with an "Address X" label, to keep the data confidential        // FIXME: the users reporting should also have a floor value        while (keys.hasNext())        {            String key = (String) keys.next();            summary.append("user.");            if (userEmail.equals("on"))            {                summary.append(key + "=" + userAggregator.get(key) + "\n");            }            else if (userEmail.equals("alias"))            {                summary.append("Address " + Integer.toString(address++) + "=" + userAggregator.get(key) + "\n");            }        }                // FIXME: all values which have floors set should provide an "other"        // record which counts how many other things which didn't make it into        // the listing there are                // output the search word information        summary.append("search_floor=" + searchFloor + "\n");        keys = searchAggregator.keySet().iterator();        while (keys.hasNext())        {            String key = (String) keys.next();            if (((Integer) searchAggregator.get(key)).intValue() >= searchFloor)            {                summary.append("search." + key + "=" + searchAggregator.get(key) + "\n");            }        }                // FIXME: we should do a lot more with the search aggregator        // Possible feature list:        //  - constrain by collection/community perhaps?        //  - we should consider building our own aggregator class which can        //      be full of rich data.  Perhaps this and the Stats class should        //      be the same thing.                // item viewing information        summary.append("item_floor=" + itemFloor + "\n");        summary.append("host_url=" + url + "\n");        summary.append("item_lookup=" + itemLookup + "\n");                // write out the item access information        keys = itemAggregator.keySet().iterator();        while (keys.hasNext())        {            String key = (String) keys.next();            if (((Integer) itemAggregator.get(key)).intValue() >= itemFloor)            {                summary.append("item." + key + "=" + itemAggregator.get(key) + "\n");            }        }                // output the average views per item        if (views > 0)        {            summary.append("avg_item_views=" + views + "\n");        }                // insert the analysis processing time information        Calendar endTime = new GregorianCalendar();        long timeInMillis = (endTime.getTimeInMillis() - startTime.getTimeInMillis());        summary.append("analysis_process_time=" + Long.toString(timeInMillis / 1000) + "\n");                // finally write the string into the output file        try         {            BufferedWriter out = new BufferedWriter(new FileWriter(outFile));            out.write(summary.toString());            out.close();        }         catch (IOException e)         {            System.out.println("Unable to write to output file " + outFile);            System.exit(0);        }                return;    }