public MemoryUsagePanel() {
    super();

    // initializes members
    m_Memory      = new Memory();
    m_History     = new Vector<Double>();
    m_Percentages = new Vector<Double>();
    m_Colors      = new Hashtable<Double,Color>();

    // colors and percentages
    m_BackgroundColor = parseColor("BackgroundColor", Color.WHITE);
    m_DefaultColor    = parseColor("DefaultColor", Color.GREEN);
    String[] percs    = PROPERTIES.getProperty("Percentages", "70,80,90").split(",");
    for (int i = 0; i < percs.length; i++) {
      // do we have a color associated with percentage?
      if (PROPERTIES.getProperty(percs[i]) != null) {
	double perc;
	Color color;
	
	// try parsing the number
	try {
	  perc = Double.parseDouble(percs[i]);
	}
	catch (Exception e) {
	  System.err.println(
	      "MemoryUsagePanel: cannot parse percentage '" 
	      + percs[i] + "' - ignored!");
	  continue;
	}

	// try parsing the color
	color = parseColor(percs[i], null);
	if (color == null)
	  continue;
	
	// store color and percentage
	m_Percentages.add(perc);
	m_Colors.put(perc, color);
      }
      else {
	System.err.println(
	    "MemoryUsagePanel: cannot find color for percentage '" 
	    + percs[i] + "' - ignored!");
      }
    }
    Collections.sort(m_Percentages);
    
    // layout
    setLayout(new BorderLayout());

    JPanel panel = new JPanel(new BorderLayout());
    add(panel, BorderLayout.EAST);
    
    m_ButtonGC = new JButton("GC");
    m_ButtonGC.setToolTipText("Runs the garbage collector.");
    m_ButtonGC.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent evt) {
	System.gc();
      }
    });
    panel.add(m_ButtonGC, BorderLayout.NORTH);

    // dimensions
    int height;
    int width;
    try {
      height = Integer.parseInt(PROPERTIES.getProperty("Height", "" + (int) m_ButtonGC.getPreferredSize().getHeight()));
      width  = Integer.parseInt(PROPERTIES.getProperty("Width", "400"));
    }
    catch (Exception e) {
      System.err.println("MemoryUsagePanel: Problem parsing the dimensions - " + e);
      height = (int) m_ButtonGC.getPreferredSize().getHeight();
      width = 400;
    }
    setPreferredSize(new Dimension(width, height));

    // position
    int top;
    int left;
    try {
      top  = Integer.parseInt(PROPERTIES.getProperty("Top", "0"));
      left = Integer.parseInt(PROPERTIES.getProperty("Left", "0"));
    }
    catch (Exception e) {
      System.err.println("MemoryUsagePanel: Problem parsing the position - " + e);
      top  = 0;
      left = 0;
    }
    m_FrameLocation = new Point(left, top);
    
    // monitoring thread
    int interval;
    try {
      interval = Integer.parseInt(PROPERTIES.getProperty("Interval", "1000"));
    }
    catch (Exception e) {
      System.err.println("MemoryUsagePanel: Problem parsing the refresh interval - " + e);
      interval = 1000;
    }
    m_Monitor = new MemoryMonitor();
    m_Monitor.setInterval(interval);
    m_Monitor.setPriority(Thread.MAX_PRIORITY);
    m_Monitor.start();
  }