/**
  * Removes statistics for a given event and blame
  *
  * @param eventName The name of the event to remove
  * @param blameObject The blame for the event to remove
  */
 public static void removeStats(String eventName, Object blameObject) {
   synchronized (statMap) {
     for (Iterator<PerformanceStats> it = statMap.keySet().iterator(); it.hasNext(); ) {
       PerformanceStats stats = it.next();
       if (stats.getEvent().equals(eventName) && stats.getBlame().equals(blameObject)) it.remove();
     }
   }
 }
 /* (non-Javadoc)
  * @see java.lang.Object#equals()
  */
 @Override
 public boolean equals(Object obj) {
   // count and time are not considered part of equality
   if (!(obj instanceof PerformanceStats)) return false;
   PerformanceStats that = (PerformanceStats) obj;
   if (!this.event.equals(that.event)) return false;
   if (!this.getBlameString().equals(that.getBlameString())) return false;
   return this.context == null ? that.context == null : this.context.equals(that.context);
 }
 /**
  * Creates a stats object representing a performance failure
  *
  * @param contextName The failure context information.
  * @param elapsed The elapsed time in milliseconds
  * @return The failure stats
  */
 private PerformanceStats createFailureStats(String contextName, long elapsed) {
   PerformanceStats failedStat = new PerformanceStats(event, blame, contextName);
   PerformanceStats old = statMap.get(failedStat);
   if (old == null) statMap.put(failedStat, failedStat);
   else failedStat = old;
   failedStat.isFailure = true;
   failedStat.runCount++;
   failedStat.runningTime += elapsed;
   return failedStat;
 }