sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.function/src/com/nokia/carbide/cpp/pi/function/NewFunctionAnalyse.java
changeset 2 b9ab3b238396
child 5 844b047e260d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.function/src/com/nokia/carbide/cpp/pi/function/NewFunctionAnalyse.java	Thu Feb 11 15:32:31 2010 +0200
@@ -0,0 +1,2108 @@
+/*
+ * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Nokia Corporation - initial contribution.
+ *
+ * Contributors:
+ *
+ * Description: 
+ *
+ */
+
+/*
+ * NewFunctionAnalyse.java
+ */
+package com.nokia.carbide.cpp.pi.function;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Graphics;
+import java.awt.GridLayout;
+import java.awt.Toolkit;
+import java.awt.datatransfer.Clipboard;
+import java.awt.datatransfer.StringSelection;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.ComponentAdapter;
+import java.awt.event.ComponentEvent;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.text.DecimalFormat;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import javax.swing.AbstractAction;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JList;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JSplitPane;
+import javax.swing.KeyStroke;
+import javax.swing.ListCellRenderer;
+import javax.swing.border.LineBorder;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+
+import org.eclipse.swt.graphics.RGB;
+
+import com.nokia.carbide.cpp.internal.pi.analyser.NpiInstanceRepository;
+import com.nokia.carbide.cpp.internal.pi.model.Function;
+import com.nokia.carbide.cpp.internal.pi.model.GUITooltips;
+import com.nokia.carbide.cpp.internal.pi.model.GenericSampledTrace;
+import com.nokia.carbide.cpp.internal.pi.model.GenericTrace;
+import com.nokia.carbide.cpp.internal.pi.model.ParsedTraceData;
+import com.nokia.carbide.cpp.internal.pi.model.TraceDataRepository;
+import com.nokia.carbide.cpp.internal.pi.test.PIAnalyser;
+import com.nokia.carbide.cpp.internal.pi.utils.QuickSortImpl;
+import com.nokia.carbide.cpp.internal.pi.utils.Sortable;
+import com.nokia.carbide.cpp.internal.pi.visual.Defines;
+import com.nokia.carbide.cpp.internal.pi.visual.PICompositePanel;
+import com.nokia.carbide.cpp.pi.address.GppSample;
+import com.nokia.carbide.cpp.pi.address.GppTrace;
+import com.nokia.carbide.cpp.pi.call.GfcSample;
+import com.nokia.carbide.cpp.pi.call.GfcTrace;
+import com.nokia.carbide.cpp.pi.util.AWTColorPalette;
+
+
+public class NewFunctionAnalyse extends JPanel implements ListSelectionListener, ChangeListener
+{
+	private static final long serialVersionUID = 3803217794859007866L;
+
+	private PICompositePanel compositePanel;
+	//private TraceDataRepository traceData;
+	
+	private JList threadList;
+	private JList binaryList;
+	private JList percentList;	
+	
+	private JDialog frame;
+	
+	private GppTrace gppTrace;
+	private GfcTrace gfcTrace;
+	private GenericTrace ittTrace;
+	
+	private Vector gppSamples;
+	private Vector gfcSamples;
+	//private Vector ittSamples;
+	
+	private Hashtable threads;
+	private Vector binaryVector;
+	
+	private Hashtable binaries;
+	private Vector threadVector;
+	
+	private JSplitPane split;
+	private JSplitPane functionSplit;
+	
+	private JButton ittPrimary;
+	private JButton symPrimary;
+	
+	private JCheckBox totalPercents;
+	private JCheckBox functionPercents;
+	
+	private String[] originallySelectedThreads;
+	private String[] originallySelectedBinaries;
+	private int[] originallySelectedIndices;
+	private Vector selectedButNotVisibleBinaries;
+	private Vector selectedButNotVisibleThreads;
+	
+	private GfcTraceVisualiser gfcTraceVisualiser;
+	private Thread updateThread = null;
+	
+	private boolean symbolPrimary = true;
+	
+	private boolean gfcEnabled;
+	
+	//private int stateChangedCounter = 0;
+	//private Object[] oldSelectedBinaries;
+	private Object[] selectedBinaries;
+	//private boolean stateChanged = false;
+	
+	private Hashtable functionNameCacheSym;
+	private Hashtable functionNameCacheItt;
+	private final int mode; //thread mode(0) or binary mode(1)
+	
+public NewFunctionAnalyse(PICompositePanel compositePanel,
+								/*TraceDataRepository traceData,*/
+								String[] selectedItems,
+								boolean gfcEnabled, int mode)
+	{		
+		this.selectedButNotVisibleBinaries = new Vector();
+		this.selectedButNotVisibleThreads = new Vector();
+		this.gfcEnabled = gfcEnabled;
+		this.functionNameCacheSym = new Hashtable();
+		this.functionNameCacheItt = new Hashtable();
+		
+		//this.originallySelectedThreads = selectedThreads;
+		this.mode = mode;
+		if (selectedItems != null)
+		{
+			if (mode == Defines.BINARIES || mode == Defines.BINARIES_FUNCTIONS)
+			    this.originallySelectedBinaries = (String[])selectedItems.clone();
+			else
+			    this.originallySelectedThreads = (String[])selectedItems.clone();
+		}
+		
+		this.compositePanel = compositePanel;
+		//this.traceData = traceData;
+		int uid = NpiInstanceRepository.getInstance().activeUid();
+		
+		ParsedTraceData ptd = TraceDataRepository.getInstance().getTrace(uid, "com.nokia.carbide.cpp.pi.address.GppTrace"); //$NON-NLS-1$
+		if (ptd != null)
+			this.gppTrace = (GppTrace)ptd.traceData;
+		ptd = TraceDataRepository.getInstance().getTrace(uid, "com.nokia.carbide.cpp.pi.call.GfcTrace"); //$NON-NLS-1$
+		if (ptd != null)
+			this.gfcTrace = (GfcTrace)ptd.traceData;
+		
+		//if (traceData.getIttTrace() instanceof IttTrace)
+		ptd = TraceDataRepository.getInstance().getTrace(uid, "com.nokia.carbide.cpp.pi.instr.IttTrace"); //$NON-NLS-1$
+		if (ptd != null)
+			this.ittTrace = ptd.traceData;
+		
+		this.refreshFrame();
+		if (mode == Defines.THREADS || mode == Defines.THREADS_FUNCTIONS)
+		    this.refreshThreadListComponent(true);
+		else
+		{
+		    this.refreshBinaryListComponent(true);
+		    this.refreshThreadListComponentSec();
+		}
+		//this.binaryList.grabFocus();
+		this.updateGfc();
+	}
+	
+	private void clearReferences()
+	{
+		// clear all possible references to other
+		// parts of the trace, to avoid memory leak
+		// execute this before disposing the frame
+		compositePanel = null;
+		//traceData = null;
+		
+		threadList = null;
+		binaryList = null;
+		percentList = null;	
+		
+		frame = null;
+		
+		gppTrace = null;
+		gfcTrace = null;
+		ittTrace = null;
+		
+		gppSamples = null;
+		gfcSamples = null;
+		//ittSamples = null;
+		
+		threads = null;
+		binaryVector = null;
+		
+		binaries = null;
+		threadVector = null;
+		
+		split = null;
+		functionSplit = null;
+		
+		ittPrimary = null;
+		symPrimary = null;
+		
+		totalPercents = null;
+		functionPercents = null;
+		
+		originallySelectedThreads = null;
+		originallySelectedBinaries = null;
+		originallySelectedIndices = null;
+		selectedButNotVisibleBinaries = null;
+		selectedButNotVisibleThreads = null;
+		
+		gfcTraceVisualiser = null;
+		updateThread = null;
+		selectedBinaries = null;
+		functionNameCacheSym = null;
+		functionNameCacheItt = null;
+	}
+	
+	private void refreshFrame()
+	{
+		this.extractSamples();
+		if (mode == Defines.THREADS || mode == Defines.THREADS_FUNCTIONS)
+		{
+			this.refreshThreadListComponent(false);
+			this.refreshBinaryListComponentSec();
+		}
+		else
+		{
+		    this.refreshBinaryListComponent(false);
+		    this.refreshThreadListComponentSec();
+		}
+		this.refreshPercentListComponent();
+
+		if (frame == null)
+		{
+			frame = new JDialog(PIAnalyser.getFrame());
+			frame.setSize(1000,900);
+			frame.getContentPane().setLayout(new BorderLayout());
+			frame.addComponentListener(new ComponentAdapter()
+			{
+				public void componentResized(ComponentEvent e) 
+				{
+					split.setDividerLocation((double)0.4);
+					if (gfcEnabled)
+						functionSplit.setDividerLocation((double)0.4);
+					else
+						functionSplit.setDividerLocation((double)1);					
+				}
+			});
+			
+			frame.addWindowListener(new WindowAdapter()
+			{
+				public void windowClosing(WindowEvent e)
+				{
+					// clear all possible references to the trace
+					//System.err.println("Closing");
+					frame.dispose();
+					clearReferences();
+				}
+				public void windowClosed(WindowEvent e)
+				{
+					// clear all possible references to the trace
+					//System.err.println("Closed");
+					clearReferences();
+				}
+			});
+			
+			JPanel leftPanel = new JPanel();
+			JPanel rightPanel = new JPanel();
+			this.functionSplit = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
+			this.functionSplit.setOneTouchExpandable(true);
+			
+			leftPanel.setLayout(new GridLayout(3,1));
+			rightPanel.setLayout(new BorderLayout());
+
+			JButton clearSelectionButton = null;
+			if (mode == Defines.THREADS || mode == Defines.THREADS_FUNCTIONS)
+			    clearSelectionButton = new JButton(Messages.getString("NewFunctionAnalyse.clearSelectedBinaries")); //$NON-NLS-1$
+			else 
+			    clearSelectionButton = new JButton(Messages.getString("NewFunctionAnalyse.clearSelectedThreads")); //$NON-NLS-1$
+			clearSelectionButton.setToolTipText(GUITooltips.getClearSelectedBinariesButton());
+			clearSelectionButton.addActionListener(new ActionListener()
+			{
+				public void actionPerformed(ActionEvent ae)
+				{
+					selectedButNotVisibleBinaries.clear();
+					binaryList.clearSelection();
+					selectedButNotVisibleThreads.clear();
+					threadList.clearSelection();
+				}
+			});
+			JButton setOriginallySelectedButton = null;
+			if (mode == Defines.THREADS || mode == Defines.THREADS_FUNCTIONS)
+			    setOriginallySelectedButton = new JButton(Messages.getString("NewFunctionAnalyse.selectOriginalThreads")); //$NON-NLS-1$
+			else
+			    setOriginallySelectedButton = new JButton(Messages.getString("NewFunctionAnalyse.selectOriginalBinaries")); //$NON-NLS-1$
+			setOriginallySelectedButton.setToolTipText(GUITooltips.getSetOriginalThreads());
+			setOriginallySelectedButton.addActionListener(new ActionListener()
+			{
+				public void actionPerformed(ActionEvent ae)
+				{
+					if (originallySelectedIndices != null && threadList != null && 
+					        (mode == Defines.THREADS || mode == Defines.THREADS_FUNCTIONS))
+						threadList.setSelectedIndices(originallySelectedIndices);
+					else if (originallySelectedIndices != null && binaryList != null && 
+					        (mode == Defines.BINARIES || mode == Defines.BINARIES_FUNCTIONS))
+					    binaryList.setSelectedIndices(originallySelectedIndices);
+				}
+			});
+			
+			this.ittPrimary = new JButton(Messages.getString("NewFunctionAnalyse.primarilyUseITT")); //$NON-NLS-1$
+			this.ittPrimary.setToolTipText(GUITooltips.getUsePrimarilyItt());
+			this.ittPrimary.addActionListener(new ActionListener()
+			{
+				public void actionPerformed(ActionEvent ae)
+				{
+					symbolPrimary = false;
+					
+					if (gfcEnabled) updateGfc();
+
+					if (mode == Defines.BINARIES || mode == Defines.BINARIES_FUNCTIONS)
+					{
+						refreshBinaryListComponent(false);
+						//refreshBinaryListComponentSec();
+					    refreshThreadListComponentSec();
+					}
+					else
+					{
+						//refreshBinaryListComponent(false);
+					    refreshBinaryListComponentSec();
+					}
+					refreshPercentListComponent();
+				}
+			});
+			
+			this.symPrimary = new JButton(Messages.getString("NewFunctionAnalyse.primarilyUseSymbolFile")); //$NON-NLS-1$
+			this.symPrimary.setToolTipText(GUITooltips.getUsePrimarilySymbol());
+			this.symPrimary.addActionListener(new ActionListener()
+			{
+				public void actionPerformed(ActionEvent ae)
+				{
+					symbolPrimary = true;
+					
+					if (gfcEnabled) updateGfc();
+					
+				    if (mode == Defines.BINARIES || mode == Defines.BINARIES_FUNCTIONS)
+					{
+						refreshBinaryListComponent(false);
+						//refreshBinaryListComponentSec();				    	
+				    	refreshThreadListComponentSec();
+					}
+					else
+					{
+						//refreshBinaryListComponent(false);
+					    refreshBinaryListComponentSec();
+					}
+					refreshPercentListComponent();
+					
+				}
+			});
+			
+			this.totalPercents = new JCheckBox(Messages.getString("NewFunctionAnalyse.showPercentsOfTotalLoad")); //$NON-NLS-1$
+			this.totalPercents.addChangeListener(this);
+			this.totalPercents.setToolTipText(GUITooltips.getAbsolutePercentage());
+			this.totalPercents.setSelected(true);
+			
+			this.functionPercents = new JCheckBox(Messages.getString("NewFunctionAnalyse.showPositionSpecificPercents")); //$NON-NLS-1$
+			this.functionPercents.addChangeListener(this);
+			this.functionPercents.setSelected(false);
+			
+			if (this.ittTrace == null)
+			{
+				this.ittPrimary.setEnabled(false);
+				this.symPrimary.setEnabled(false);
+			}
+			
+			JPanel checkBoxPanel = new JPanel();
+			checkBoxPanel.setLayout(new GridLayout(6,1));
+			checkBoxPanel.add(clearSelectionButton);
+			checkBoxPanel.add(setOriginallySelectedButton);
+			checkBoxPanel.add(this.symPrimary);
+			checkBoxPanel.add(this.ittPrimary);
+			checkBoxPanel.add(this.totalPercents);
+			checkBoxPanel.add(this.functionPercents);
+			
+			JScrollPane temp = new JScrollPane(this.threadList);
+			temp.setBorder(javax.swing.BorderFactory.createTitledBorder(null, Messages.getString("NewFunctionAnalyse.threadList"), //$NON-NLS-1$
+			        javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION,
+			        javax.swing.border.TitledBorder.DEFAULT_POSITION, null, null));
+			//temp.setColumnHeaderView(new JLabel("Thread list")); //tulee exceptioneja tästä
+			leftPanel.add(temp);
+			temp = new JScrollPane(this.binaryList);
+			temp.setBorder(javax.swing.BorderFactory.createTitledBorder(null, Messages.getString("NewFunctionAnalyse.binaryList"), //$NON-NLS-1$
+			        javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION,
+			        javax.swing.border.TitledBorder.DEFAULT_POSITION, null, null));
+			//temp.setColumnHeaderView(new JLabel("Binary list")); //tulee exceptioneja tästä
+			leftPanel.add(temp);
+			
+			leftPanel.add(checkBoxPanel);
+			
+			rightPanel.add(new JScrollPane(this.percentList));
+			this.functionSplit.setTopComponent(rightPanel);
+			this.functionSplit.setBottomComponent(new JPanel());
+						
+			split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
+			split.setTopComponent(leftPanel);
+			split.setBottomComponent(this.functionSplit);
+			
+			frame.getContentPane().add(split);
+			
+
+            // frame.setVisible(true); //poikkeuksia
+
+
+			this.split.setDividerLocation((double)0.4);
+			if (this.gfcEnabled)
+				this.functionSplit.setDividerLocation((double)0.4);
+			else
+				this.functionSplit.setDividerLocation((double)1);					
+
+		}
+
+		String analysisName = ""; //$NON-NLS-1$
+		String modeString = ""; //$NON-NLS-1$
+		if (mode == Defines.THREADS || mode == Defines.THREADS_FUNCTIONS)
+		    modeString = Messages.getString("NewFunctionAnalyse.threadMode"); //$NON-NLS-1$
+		else if (mode == Defines.BINARIES || mode == Defines.BINARIES_FUNCTIONS)
+		    modeString = Messages.getString("NewFunctionAnalyse.binaryMode"); //$NON-NLS-1$
+		frame.setTitle(Messages.getString("NewFunctionAnalyse.functionAnalysis1") + analysisName + Messages.getString("NewFunctionAnalyse.functionAnalysis2")+ //$NON-NLS-1$ //$NON-NLS-2$
+							this.compositePanel.getSelectionStart()/1000.0+Messages.getString("NewFunctionAnalyse.functionAnalysis3")+ //$NON-NLS-1$
+							this.compositePanel.getSelectionEnd()/1000.0+Messages.getString("NewFunctionAnalyse.functionAnalysis4") + modeString); //$NON-NLS-1$
+		frame.validate();
+		frame.setVisible(true);
+	}
+	
+	private void extractSamples()
+	{		
+		getSelectedSamples(gppTrace);
+		getSelectedSamples(gfcTrace);
+		//getSelectedSamples(ittTrace);				
+	}
+	
+	private void getSelectedSamples(GenericSampledTrace gst)
+	{
+		if (gst != null)
+		{
+			int selectionStart = (int) this.compositePanel.getSelectionStart()+1;
+			int selectionEnd = (int) this.compositePanel.getSelectionEnd();
+		
+			System.out.println(Messages.getString("NewFunctionAnalyse.start")+selectionStart+Messages.getString("NewFunctionAnalyse.end")+selectionEnd); //$NON-NLS-1$ //$NON-NLS-2$
+			Vector s = gst.getSamplesInsideTimePeriod(selectionStart,selectionEnd);
+			System.out.println(Messages.getString("NewFunctionAnalyse.gotSamples")+s.size()); //$NON-NLS-1$
+			
+			if (gst instanceof GppTrace)
+			{
+				this.gppSamples = s;
+			}		
+			else if (gst instanceof GfcTrace)
+			{
+				this.gfcSamples = s;
+			}	
+			//else if (gst instanceof IttTrace)
+			//{
+			//	this.ittSamples = s;
+			//}
+		}	
+	}
+	
+	private void refreshThreadListComponent(boolean setValuesFromGraph)
+	{
+		threads = new Hashtable();
+		Vector listData = new Vector();
+		Enumeration enumer = this.gppSamples.elements();
+		Hashtable threadSampleAmount = new Hashtable();
+		
+		while(enumer.hasMoreElements())
+		{
+			//System.out.println("Class:"+enumer.nextElement().getClass().getName());
+			GppSample sample = (GppSample)enumer.nextElement();
+			String s = sample.thread.process.name+"::"+sample.thread.threadName+"_"+sample.thread.threadId; //$NON-NLS-1$ //$NON-NLS-2$
+			
+			if (!threads.containsKey(sample.thread.process.name+"::"+sample.thread.threadName+"_"+sample.thread.threadId)) //$NON-NLS-1$ //$NON-NLS-2$
+			{
+				threads.put(s,sample.thread);
+				//listData.add(sample.thread.process.name+"::"+sample.thread.threadName);
+				threadSampleAmount.put(s,new Integer(1));
+			}
+			else
+			{
+				int value = ((Integer)threadSampleAmount.get(s)).intValue();
+				threadSampleAmount.remove(s);
+				threadSampleAmount.put(s,new Integer(value+1));
+			}
+		}
+		
+		while(threadSampleAmount.size() > 0)
+		{
+			Enumeration sampEnum = threadSampleAmount.keys();
+			String threadName = ""; //$NON-NLS-1$
+			int maxValue = 0;
+			String maxString = ""; //$NON-NLS-1$
+
+			while(sampEnum.hasMoreElements())
+			{
+				threadName = (String)sampEnum.nextElement();
+				int value = ((Integer)threadSampleAmount.get(threadName)).intValue();
+				if (maxValue < value)
+				{
+					maxString = threadName;
+					maxValue = value;
+				}
+			}
+			threadSampleAmount.remove(maxString);
+			listData.add( maxValue+Messages.getString("NewFunctionAnalyse.samplesEqual")+((float)maxValue*100f)/this.gppSamples.size()+"% "+maxString); //$NON-NLS-1$ //$NON-NLS-2$
+		}
+		
+		if (this.threadList == null)
+		{
+			this.threadList = new JList(listData);
+			customKeys(threadList);
+			customKeys(threadList);
+			this.threadList.addListSelectionListener(this);
+		}
+		else
+		{
+			this.threadList.removeListSelectionListener(this);
+			
+			this.threadList.setListData(listData);
+
+			if (setValuesFromGraph && this.originallySelectedThreads != null)
+			{
+				Vector<Integer> selectedIndx = new Vector<Integer>();
+				for (int i=0;i<this.originallySelectedThreads.length;i++)
+				{
+					for (int k=0;k<listData.size();k++)
+					{
+						String test = ((String)listData.get(k));
+						test = test.substring(test.indexOf('%')+2,test.length());
+						if (test != null && this.originallySelectedThreads[i] != null)
+						{				
+							if (this.originallySelectedThreads[i].equals(test))
+							{
+								//System.out.println("Match:"+this.originallySelectedThreads[i]+" index "+k);
+								selectedIndx.add(new Integer(k));
+							}
+						}
+					}
+				}
+				
+				if (selectedIndx.size() > 0)
+				{
+					this.originallySelectedIndices = new int[selectedIndx.size()];
+					for (int i=0;i<this.originallySelectedIndices.length;i++)
+					{
+						this.originallySelectedIndices[i] = selectedIndx.elementAt(i);
+					}
+					this.threadList.setSelectedIndices(this.originallySelectedIndices);
+				}
+			}
+			this.threadList.addListSelectionListener(this);
+		}
+	}
+	
+	private void refreshBinaryListComponent(boolean setValuesFromGraph)
+	{
+	    binaries = new Hashtable();
+		Vector<BinaryNameItem> listData = new Vector<BinaryNameItem>();
+		Enumeration enumer = this.gppSamples.elements();
+		Hashtable<BinaryNameItem,Integer> binarySampleAmount = new Hashtable<BinaryNameItem,Integer>();
+		
+		while(enumer.hasMoreElements())
+		{
+			//System.out.println("Class:"+enumer.nextElement().getClass().getName());
+			GppSample sample = (GppSample)enumer.nextElement();
+			//String s = this.getBinaryNameForGppSample(sample).toString();
+			BinaryNameItem bi = this.getBinaryNameForGppSample(sample);
+			boolean containsKey = false;
+			for (Enumeration e = binaries.keys(); e.hasMoreElements();)
+			{
+			    String tmp = ((BinaryNameItem)e.nextElement()).toString();
+			    if (tmp.equalsIgnoreCase(bi.toString()))
+			    {
+			        containsKey = true;
+			        break;
+			    }
+			}
+			if (!containsKey)
+		    {
+		        binaries.put(bi, sample);
+		        binarySampleAmount.put(bi, new Integer(1));
+		    }
+		    else
+		    {
+		        for (Enumeration<BinaryNameItem> e = binarySampleAmount.keys(); e.hasMoreElements();)
+		        {
+		            BinaryNameItem biTemp = e.nextElement();
+		            if (biTemp.toString().equalsIgnoreCase(bi.toString()))
+		            {
+		                int value = ((Integer)binarySampleAmount.get(biTemp)).intValue();
+		                binarySampleAmount.remove(biTemp);
+						binarySampleAmount.put(biTemp, new Integer(value+1));
+		            }
+		        }
+		    }
+		}
+
+		int totalSamples = 0;
+		while(binarySampleAmount.size() > 0)
+		{
+		    Enumeration<BinaryNameItem> sampEnum = binarySampleAmount.keys();
+
+			BinaryNameItem binaryName;
+			int maxValue = 0;
+			BinaryNameItem maxItem = null;
+
+			while(sampEnum.hasMoreElements())
+			{
+			    binaryName = sampEnum.nextElement();
+				int value = binarySampleAmount.get(binaryName);
+				if (maxValue < value)
+				{
+					maxItem = binaryName;
+					maxValue = value;
+				}
+			}
+			binarySampleAmount.remove(maxItem);
+			totalSamples += maxValue;
+
+			maxItem.setSampleAmount(maxValue);
+			listData.add(maxItem);
+		}
+		
+		for (Enumeration<BinaryNameItem> e = listData.elements();e.hasMoreElements();)
+		{
+			BinaryNameItem item = e.nextElement();
+			item.setTotalSampleAmount(totalSamples);
+		}
+		
+		if (this.binaryList == null)
+		{
+			this.binaryList = new JList(listData);
+			customKeys(binaryList);
+			this.binaryList.setCellRenderer(new FunctionItemRenderer());
+			this.binaryList.addListSelectionListener(this);
+		}
+		else
+		{
+			this.binaryList.removeListSelectionListener(this);
+			this.binaryList.setListData(listData);
+
+			if (setValuesFromGraph && this.originallySelectedBinaries != null)
+			{
+				Vector<Integer> selectedIndx = new Vector<Integer>();
+				for (int i=0;i<this.originallySelectedBinaries.length;i++)
+				{
+					for (int k=0;k<listData.size();k++)
+					{
+						//String test = ((String)listData.get(k));
+						String test = listData.get(k).toString();
+						//test = test.substring(test.indexOf('%')+2,test.length());
+						if (test != null && this.originallySelectedBinaries[i] != null)
+						{				
+							if (this.originallySelectedBinaries[i].equalsIgnoreCase(test))
+							{
+								//System.out.println("Match:"+this.originallySelectedThreads[i]+" index "+k);
+								selectedIndx.add(new Integer(k));
+							}
+						}
+					}
+				}
+				
+				if (selectedIndx.size() > 0)
+				{
+					this.originallySelectedIndices = new int[selectedIndx.size()];
+					for (int i=0;i<this.originallySelectedIndices.length;i++)
+					{
+						this.originallySelectedIndices[i] = selectedIndx.elementAt(i);
+					}
+					this.binaryList.setSelectedIndices(this.originallySelectedIndices);
+				}
+			}
+			this.binaryList.addListSelectionListener(this);
+		}
+	}
+	
+	private void refreshThreadListComponentSec()
+	{
+	    threadVector = new Vector();
+		Vector listData = new Vector();
+		Vector threadSampleAmount = new Vector();
+//		Object[] selectedBinaries = this.removePercents(this.binaryList.getSelectedValues());
+		Object[] selectedBinaries = this.binaryList.getSelectedValues();
+		
+		Enumeration enumer = this.gppSamples.elements();
+		
+		while(enumer.hasMoreElements())
+		{
+			boolean match = false;
+			GppSample sample = (GppSample)enumer.nextElement();
+			for (int i=0;i<selectedBinaries.length;i++)
+			{
+				if ((this.getBinaryNameForGppSample(sample).toString()).
+				        equalsIgnoreCase(selectedBinaries[i].toString()))
+				{
+					match = true;
+					break;
+				}
+			}
+			
+			if (match == true)
+			{
+				String threadName = sample.thread.process.name+"::"+sample.thread.threadName+"_"+sample.thread.threadId; //$NON-NLS-1$ //$NON-NLS-2$
+	
+				if (!threadVector.contains(threadName))
+				{
+					threadVector.add(threadName);
+					threadSampleAmount.add(new Integer(1));
+				}
+				else
+				{	
+					//int value = ((Integer)binarySampleAmount.get(binaryName)).intValue();
+					int index = threadVector.indexOf(threadName);
+					int value = ((Integer)threadSampleAmount.get(index)).intValue();
+					
+					threadSampleAmount.remove(index);
+					threadSampleAmount.add(index,new Integer(value+1));
+				}
+			}
+		}
+		
+		int totalSamples = 0;
+		while(threadSampleAmount.size() > 0)
+		{
+			String sampItem = null;
+			int maxValue = 0;
+			String maxString = null;
+			int maxIndex = 0; 
+			
+			for (int i=0;i<this.threadVector.size();i++)
+			{
+				sampItem = (String)threadVector.get(i);
+				int value = ((Integer)threadSampleAmount.get(i)).intValue();
+				if (maxValue < value)
+				{
+					maxString = sampItem;
+					maxValue = value;
+					maxIndex = i;
+				}
+			}
+			threadSampleAmount.remove(maxIndex);
+			threadVector.remove(maxIndex);
+			totalSamples += maxValue;
+			
+			listData.add( maxValue+Messages.getString("NewFunctionAnalyse.samplesEqual")+((float)maxValue*100f)/this.gppSamples.size()+"% "+maxString); //$NON-NLS-1$ //$NON-NLS-2$
+		}
+		
+		if (this.threadList == null)
+		{
+			this.threadList = new JList(listData);
+			customKeys(threadList);
+			//this.threadList.setCellRenderer(new FunctionItemRenderer());
+			this.threadList.addListSelectionListener(this);
+		}
+		else
+		{			
+			Object[] valueStore = this.threadList.getSelectedValues();
+			Vector indexStore = new Vector();
+			Vector notVisibleStore = new Vector();
+			
+			for (int i=0;i<valueStore.length;i++)
+			{
+				int counter = 0;
+				boolean found = false;
+			    for (Enumeration e = listData.elements(); e.hasMoreElements(); counter++)
+			    {
+			        String listElement = (String)e.nextElement();
+			        listElement =  listElement.substring(listElement.indexOf("% ")+2,listElement.length()); //$NON-NLS-1$
+			        String valueString = (String)valueStore[i];
+			        valueString =  valueString.substring(valueString.indexOf("% ")+2,valueString.length()); //$NON-NLS-1$
+			        if (listElement.equals(valueString))
+			        {
+			            found = true;
+			            break;
+			        }
+			    }
+//			    int index = listData.indexOf(valueStore[i]);
+			    int index = (found) ? counter : -1;
+				if (index != -1)
+				{
+					indexStore.add(new Integer(index));
+				}
+				else
+				{
+					notVisibleStore.add(valueStore[i]);
+				}
+			}
+			
+			for (Enumeration e=this.selectedButNotVisibleThreads.elements();e.hasMoreElements();)
+			{
+				Object value = e.nextElement();
+				int counter = 0;
+				boolean found = false;
+				for (Enumeration enume = listData.elements(); enume.hasMoreElements(); counter++)
+			    {
+			        String listElement = (String)enume.nextElement();
+			        listElement =  listElement.substring(listElement.indexOf("% ")+2,listElement.length()); //$NON-NLS-1$
+			        String valueString = (String)value;
+			        valueString =  valueString.substring(valueString.indexOf("% ")+2,valueString.length()); //$NON-NLS-1$
+			        if (listElement.equals(valueString))
+			        {
+			            found = true;
+			            break;
+			        }
+			    }
+			    int index = (found) ? counter : -1;
+//				int index = listData.indexOf(value);
+				if (index != -1)
+				{
+					indexStore.add(new Integer(index));
+				}
+				else
+				{
+					notVisibleStore.add(value);
+				}
+			}
+			this.threadList.removeListSelectionListener(this);
+			this.threadList.setListData(listData);
+
+			if (indexStore.size() != 0)
+			{
+				int[] indexList = new int[indexStore.size()];
+				for (int i=0;i<indexStore.size();i++)
+				{
+					indexList[i] = ((Integer)indexStore.elementAt(i)).intValue();
+				}
+				this.threadList.setSelectedIndices(indexList);
+			}			
+			
+			this.selectedButNotVisibleThreads.clear();
+			this.selectedButNotVisibleThreads.addAll(notVisibleStore);
+			this.threadList.addListSelectionListener(this);
+
+		}
+	}
+	private void refreshBinaryListComponentSec()
+	{
+		binaryVector = new Vector();
+		Vector listData = new Vector();
+		Vector binarySampleAmount = new Vector();
+		Object[] selectedThreads = this.removePercents(this.threadList.getSelectedValues());
+		
+		Enumeration enumer = this.gppSamples.elements();
+		
+		while(enumer.hasMoreElements())
+		{
+			boolean match = false;
+			GppSample sample = (GppSample)enumer.nextElement();
+			for (int i=0;i<selectedThreads.length;i++)
+			{
+				if ((sample.thread.process.name+"::"+sample.thread.threadName+"_"+sample.thread.threadId).equals(selectedThreads[i])) //$NON-NLS-1$ //$NON-NLS-2$
+				{
+					match = true;
+					break;
+				}
+			}
+			
+			if (match == true)
+			{
+				BinaryNameItem binaryName = getBinaryNameForGppSample(sample);
+	
+				if (!binaryVector.contains(binaryName))
+				{
+					binaryVector.add(binaryName);
+					binarySampleAmount.add(new Integer(1));
+				}
+				else
+				{	
+					//int value = ((Integer)binarySampleAmount.get(binaryName)).intValue();
+					int index = binaryVector.indexOf(binaryName);
+					int value = ((Integer)binarySampleAmount.get(index)).intValue();
+					
+					binarySampleAmount.remove(index);
+					binarySampleAmount.add(index,new Integer(value+1));
+				}
+			}
+		}
+		
+		int totalSamples = 0;
+		while(binarySampleAmount.size() > 0)
+		{
+			BinaryNameItem sampItem = null;
+			int maxValue = 0;
+			BinaryNameItem maxItem = null;
+			int maxIndex = 0; 
+			
+			for (int i=0;i<this.binaryVector.size();i++)
+			{
+				sampItem = (BinaryNameItem)binaryVector.get(i);
+				int value = ((Integer)binarySampleAmount.get(i)).intValue();
+				if (maxValue < value)
+				{
+					maxItem = sampItem;
+					maxValue = value;
+					maxIndex = i;
+				}
+			}
+			binarySampleAmount.remove(maxIndex);
+			binaryVector.remove(maxIndex);
+			totalSamples += maxValue;
+
+			maxItem.setSampleAmount(maxValue);
+			listData.add(maxItem);
+		}
+		
+		for (Enumeration e = listData.elements();e.hasMoreElements();)
+		{
+			BinaryNameItem item = (BinaryNameItem)e.nextElement();
+			item.setTotalSampleAmount(totalSamples);
+		}
+		
+		if (this.binaryList == null)
+		{
+			this.binaryList = new JList(listData);
+			customKeys(binaryList);
+			this.binaryList.setCellRenderer(new FunctionItemRenderer());
+			this.binaryList.addListSelectionListener(this);
+		}
+		else
+		{			
+			Object[] valueStore = this.binaryList.getSelectedValues();
+			Vector indexStore = new Vector();
+			Vector notVisibleStore = new Vector();
+			
+			for (int i=0;i<valueStore.length;i++)
+			{
+				int index = listData.indexOf(valueStore[i]);
+				if (index != -1)
+				{
+					indexStore.add(new Integer(index));
+				}
+				else
+				{
+					notVisibleStore.add(valueStore[i]);
+				}
+			}
+			
+			for (Enumeration e=this.selectedButNotVisibleBinaries.elements();e.hasMoreElements();)
+			{
+				Object value = e.nextElement();
+				int index = listData.indexOf(value);
+				if (index != -1)
+				{
+					indexStore.add(new Integer(index));
+				}
+				else
+				{
+					notVisibleStore.add(value);
+				}
+			}
+
+			this.binaryList.removeListSelectionListener(this);
+			this.binaryList.setListData(listData);
+
+			if (indexStore.size() != 0)
+			{
+				int[] indexList = new int[indexStore.size()];
+				for (int i=0;i<indexStore.size();i++)
+				{
+					indexList[i] = ((Integer)indexStore.elementAt(i)).intValue();
+				}
+				this.binaryList.setSelectedIndices(indexList);
+			}			
+			
+			this.selectedButNotVisibleBinaries.clear();
+			this.selectedButNotVisibleBinaries.addAll(notVisibleStore);
+			this.binaryList.addListSelectionListener(this);
+		}
+	}
+	
+	private Object[] removePercents(Object[] data)
+	{
+		String[] fin = new String[data.length];
+		for (int i=0;i<data.length;i++)
+		{
+			String s = (String)data[i];
+			fin[i] = s.substring(s.indexOf("% ")+2,s.length()); //$NON-NLS-1$
+		}
+		return fin;
+	}
+	
+	private void refreshPercentListComponent()
+	{
+	    if (threadList == null)
+	        return;
+	    Vector percentData = new Vector();
+		Object[] selectedThreads = this.removePercents(this.threadList.getSelectedValues());
+		selectedBinaries = this.binaryList.getSelectedValues();
+//		if ((selectedBinaries != null) && (oldSelectedBinaries != null) && !stateChanged)
+//			if (selectedBinaries.length == oldSelectedBinaries.length)
+//			{
+//				boolean similar = true;
+//				for (int i=0;i<selectedBinaries.length;i++)
+//				{
+//					if (selectedBinaries[i].hashCode() != oldSelectedBinaries[i].hashCode())
+//					{
+//						similar = false;
+//						break;
+//					}
+//				}
+//				if (similar)
+//					return;
+//			}
+//		stateChanged = false;
+				
+		this.percentList = new JList();
+		customKeys(percentList);
+		Vector percentValueList = new Vector();
+		Vector functionIndexList = new Vector();
+		
+		int totalSamples = 0;
+		
+		Enumeration enumer = this.gppSamples.elements();
+		while(enumer.hasMoreElements())
+		{
+			GppSample s = (GppSample)enumer.nextElement();
+			boolean match = false;
+			// check if the thread has been selected from the thread list
+			for (int i=0;i<selectedThreads.length;i++)
+			{
+				String st = (String)selectedThreads[i];
+				int threadId = Integer.parseInt(st.substring (st.lastIndexOf("_")+1,st.length()) ); //$NON-NLS-1$
+				if (s.thread.threadId.intValue() == threadId)
+				{
+					match = true;
+					// yes, go ahead
+					break;
+				}
+			}
+			
+			if (match == true)
+			{
+				match = false;
+				for (int i=0;i<selectedBinaries.length;i++)
+				{
+					BinaryNameItem binaryName = getBinaryNameForGppSample(s);
+					
+					if (binaryName.equals(selectedBinaries[i]))
+					{
+						match = true;
+						break;
+					}
+				}
+			}
+			
+			// from now on, the match variable tells whether the function has already been
+			// found from the previous samples
+			if (match == true)
+			{
+				match = false;
+				for (int i=0;i<percentData.size();i++)
+				{
+					FunctionNameItem test = (FunctionNameItem)percentData.elementAt(i);
+					if (test.equals(getFunctionNameForGppSample(s)))
+					{
+						match = true;
+						break;
+					}
+				}
+					
+				if (!match)
+				{
+					// add the function name to percentData
+					percentData.add(getFunctionNameForGppSample(s));
+					// this is the first sample for this function, thus add number 1
+					// to the percent value list
+					percentValueList.add(new Integer(1));
+					// add a vector for the function offset values
+					
+					if (this.functionPercents.isSelected() == true)
+					{
+						Vector functionIndexVector = new Vector();
+						Long offset = getFunctionOffsetForGppSample(s);
+						functionIndexVector.add(offset);
+						functionIndexList.add(functionIndexVector);
+					}
+
+					//System.out.println("Added name "+s.currentFunctionSym.functionName);
+					totalSamples++;
+				}
+				else
+				{
+					int index = percentData.indexOf(getFunctionNameForGppSample(s));
+					
+					/*
+					System.out.println("old "+((String)percentData.elementAt(index))+
+							" = "+
+							((Integer)percentValueList.elementAt(index)).intValue());
+					*/
+					
+					Integer value = (Integer)percentValueList.elementAt(index);
+					percentValueList.remove(index);
+					percentValueList.add(index,new Integer(value.intValue()+1));
+					
+					if (this.functionPercents.isSelected() == true)
+					{					
+						Vector functionIndexVector = (Vector)functionIndexList.elementAt(index);
+						Long offset = getFunctionOffsetForGppSample(s);
+						functionIndexVector.add(offset);
+					}
+					
+					totalSamples++;
+				}
+			}
+		}
+		
+		if (totalSamples != 0)
+		{
+			sortFunctionIndexList(functionIndexList);
+			Vector finalList = this.sortPercentData(percentValueList,percentData,functionIndexList,totalSamples);
+			
+			if (this.percentList == null)
+			{
+				this.percentList = new JList(finalList);
+				customKeys(percentList);
+				this.percentList.setCellRenderer(new FunctionItemRenderer());
+				JScrollPane temp = new JScrollPane(this.percentList);
+				if (this.gfcEnabled)
+				{
+				    temp.setBorder(javax.swing.BorderFactory.createTitledBorder(null, Messages.getString("NewFunctionAnalyse.functionPercentListDoubleClick"), //$NON-NLS-1$
+					        javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION,
+					        javax.swing.border.TitledBorder.DEFAULT_POSITION, null, null));
+//					temp.setColumnHeaderView(
+//							new JLabel("Function percent list - double click to see the function in the linked function view"));
+				}
+				else
+				{
+				    temp.setBorder(javax.swing.BorderFactory.createTitledBorder(null, Messages.getString("NewFunctionAnalyse.functionPercentList"), //$NON-NLS-1$
+					        javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION,
+					        javax.swing.border.TitledBorder.DEFAULT_POSITION, null, null));
+//				    temp.setColumnHeaderView(
+//							new JLabel("Function percent list"));
+				}
+				this.functionSplit.setTopComponent(temp);
+//				this.split.setDividerLocation((double)0.4);
+				if (this.gfcEnabled)
+					this.functionSplit.setDividerLocation((double)0.4);
+				else
+					this.functionSplit.setDividerLocation((double)1);					
+			}
+			else
+			{
+				this.percentList = new JList(finalList);
+				customKeys(percentList);
+				this.percentList.setCellRenderer(new FunctionItemRenderer());
+				this.percentList.addMouseListener(new MouseAdapter()
+				{
+				 public void mouseClicked(MouseEvent e) 
+					{
+				 	if (e.getClickCount() > 1)
+				 		{
+				 			showLinkedData();
+				 		}
+					}
+				});
+
+				JScrollPane temp = new JScrollPane(this.percentList);
+				if (this.gfcEnabled)
+				{
+				    temp.setBorder(javax.swing.BorderFactory.createTitledBorder(null, Messages.getString("NewFunctionAnalyse.functionPercentListDoubleClick"), //$NON-NLS-1$
+					        javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION,
+					        javax.swing.border.TitledBorder.DEFAULT_POSITION, null, null));
+//					temp.setColumnHeaderView(
+//							new JLabel("Function percent list - double click to see the function in the linked function view"));
+				}
+				else
+				{
+				    temp.setBorder(javax.swing.BorderFactory.createTitledBorder(null, Messages.getString("NewFunctionAnalyse.functionPercentList"), //$NON-NLS-1$
+					        javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION,
+					        javax.swing.border.TitledBorder.DEFAULT_POSITION, null, null));
+//				    temp.setColumnHeaderView(
+//							new JLabel("Function percent list"));
+				}	
+				this.functionSplit.setTopComponent(temp);
+				
+//				this.split.setDividerLocation((double)0.4);
+				if (this.gfcEnabled)
+					this.functionSplit.setDividerLocation((double)0.4);
+				else
+					this.functionSplit.setDividerLocation((double)1);					
+			}
+		}	
+		else if (this.split != null)
+		{
+			Vector finalList = new Vector();
+			this.percentList = new JList(finalList);
+			customKeys(percentList);
+			this.percentList.setCellRenderer(new FunctionItemRenderer());
+			this.functionSplit.setTopComponent(new JScrollPane(this.percentList));
+//			this.split.setDividerLocation((double)0.4);
+			if (this.gfcEnabled)
+				this.functionSplit.setDividerLocation((double)0.4);
+			else
+				this.functionSplit.setDividerLocation((double)1);					
+		}
+//		oldSelectedBinaries = selectedBinaries;
+	}
+	
+	private BinaryNameItem getBinaryNameForGppSample(GppSample s)
+	{
+		String binaryName;
+		if (this.symbolPrimary || this.ittTrace == null)
+		{
+			binaryName = s.currentFunctionSym.functionBinary.binaryName;
+			if (!binaryName.endsWith(Messages.getString("NewFunctionAnalyse.notFound"))) //$NON-NLS-1$
+				return new BinaryNameItem(binaryName,false);
+		}
+
+		if (s.currentFunctionItt != null)
+		{
+			binaryName = s.currentFunctionItt.functionBinary.binaryName;
+			if (!binaryName.endsWith(Messages.getString("NewFunctionAnalyse.notFound"))) //$NON-NLS-1$
+			{
+				return new BinaryNameItem(binaryName,true);
+			}
+			else
+			{
+				binaryName = s.currentFunctionSym.functionBinary.binaryName;
+				if (binaryName.endsWith(Messages.getString("NewFunctionAnalyse.notFound"))) //$NON-NLS-1$
+					return new BinaryNameItem(Messages.getString("NewFunctionAnalyse.binaryNotFound"),true); //$NON-NLS-1$
+				else
+					return new BinaryNameItem(binaryName,false);
+			}			
+		}
+		else if (!s.currentFunctionSym.functionBinary.binaryName.endsWith(Messages.getString("NewFunctionAnalyse.notFound"))) //$NON-NLS-1$
+		{
+			binaryName = s.currentFunctionSym.functionBinary.binaryName;
+			return new BinaryNameItem(binaryName,false);
+		}
+		else
+		{
+			return new BinaryNameItem(Messages.getString("NewFunctionAnalyse.binaryNotFound"),false); //$NON-NLS-1$
+		}
+	}
+/*	
+	private IttSample getIttSampleForGppSample(GppSample s)
+	{
+		IttSample first = (IttSample)this.ittSamples.firstElement();
+		IttSample ittSample = null;
+		int diff = (int)(s.sampleSynchTime-first.sampleSynchTime);
+		
+		// the sample was found from the first index
+		if (diff == 0) return first;
+		
+		// normal case, the first itt sample number is smaller than the
+		// required sample number
+		if (diff > 0)
+		{
+			if (diff < this.ittSamples.size())
+			{
+				// try from the itt sample array, from the location
+				// marked by the diff value between the sample synch times
+				ittSample = (IttSample)this.ittSamples.elementAt(diff);
+				
+				if (ittSample.sampleSynchTime == s.sampleSynchTime)
+				{
+					// the right sample was found with the diff offset 
+					return ittSample; 
+				}
+			}
+			else
+			{
+				// the index points outside the itt sample array
+				// take the last itt sample
+				ittSample = (IttSample)this.ittSamples.lastElement();
+				diff = this.ittSamples.size()-1;
+			}
+		}
+		else
+		{
+			// the requested sample is outside the itt sample range
+			// (smaller than the first element)
+			return null;
+		}
+		
+		if ( ((IttSample)this.ittSamples.lastElement()).sampleSynchTime < s.sampleSynchTime)
+		{
+			// the requested sample is outside the itt sample range
+			// (larger than the last element)
+			return null;
+		}
+		
+		// the requested sample is in the itt sample range
+		// start with the current element and go backwards until it
+		// is found, or the correct one is not found
+		while(ittSample.sampleSynchTime > s.sampleSynchTime)
+		{
+			diff--;
+			ittSample = (IttSample)this.ittSamples.elementAt(diff);
+		}
+		
+		if (ittSample.sampleSynchTime == s.sampleSynchTime)
+		{
+			// the sample was finally found
+			return ittSample;
+		}
+		else
+		{
+			// this sample number is missing from the ITT trace
+			return null;
+		}
+		
+	}
+	*/
+	
+	private Long getFunctionOffsetForGppSample(GppSample s)
+	{
+		//String functionName;
+		if ((this.symbolPrimary || this.ittTrace == null) && 
+				!s.currentFunctionSym.functionBinary.binaryName.endsWith(Messages.getString("NewFunctionAnalyse.notFound")) ) //$NON-NLS-1$
+		{
+			return new Long(s.programCounter-s.currentFunctionSym.startAddress.longValue());
+		}
+		if (s.currentFunctionItt != null && !s.currentFunctionItt.functionName.endsWith(Messages.getString("NewFunctionAnalyse.notFound"))) //$NON-NLS-1$
+		{
+			//System.out.println("OFF:"+(s.programCounter-s.currentFunctionItt.startAddress.longValue())+" PC: "+Long.toHexString(s.programCounter)+" start"+Long.toHexString(s.currentFunctionItt.startAddress.longValue()));
+			return new Long(s.programCounter-s.currentFunctionItt.startAddress.longValue());
+		}
+		else if (s.currentFunctionSym != null)
+		{
+			return new Long(s.programCounter-s.currentFunctionSym.startAddress.longValue());
+		}
+		else
+		{
+			return new Long(666666);
+		}		
+	}
+	
+	private FunctionNameItem getFunctionNameForGppSample(GppSample s)
+	{
+		String functionName;
+		if (this.symbolPrimary || this.ittTrace == null)
+		{
+//			functionName = s.currentFunctionSym.functionName;
+//			if (!functionName.endsWith("not found"))
+//				return new FunctionNameItem(functionName,s.currentFunctionSym,false);
+			FunctionNameItem item = (FunctionNameItem)this.functionNameCacheSym.get(s);
+			if (item != null) 
+			{	
+				return item;
+			}
+			else
+			{
+				functionName = s.currentFunctionSym.functionName;
+				if (!functionName.endsWith(Messages.getString("NewFunctionAnalyse.notFound"))) //$NON-NLS-1$
+				{					
+					item = new FunctionNameItem(functionName,s.currentFunctionSym,false);
+					this.functionNameCacheSym.put(s,item);
+					return item;
+				}
+			}
+		}
+		
+		if (s.currentFunctionItt != null)
+		{
+			FunctionNameItem item = (FunctionNameItem)this.functionNameCacheItt.get(s);
+			if (item != null) return item;
+			
+			functionName = s.currentFunctionItt.functionName;
+
+			if (!functionName.endsWith(Messages.getString("NewFunctionAnalyse.notFound"))) //$NON-NLS-1$
+			{
+				item = new FunctionNameItem(functionName,s.currentFunctionItt,true);
+				this.functionNameCacheItt.put(s,item);
+				return item;
+//				return new FunctionNameItem(functionName,s.currentFunctionItt,true);
+			}
+			else
+			{
+				item = (FunctionNameItem)this.functionNameCacheSym.get(s);
+				if (item != null) return item;
+				
+				functionName = s.currentFunctionSym.functionName;
+				item = new FunctionNameItem(functionName,s.currentFunctionSym,false);
+				this.functionNameCacheSym.put(s,item);
+				return item;
+//				return new FunctionNameItem(functionName,s.currentFunctionSym,false);
+			}
+		}
+		else if (s.currentFunctionSym != null)
+		{
+			FunctionNameItem item = (FunctionNameItem)this.functionNameCacheSym.get(s);
+			if (item != null) return item;
+			
+			functionName = s.currentFunctionSym.functionName;
+			item = new FunctionNameItem(functionName,s.currentFunctionSym,false);
+			this.functionNameCacheSym.put(s,item);
+			return item;
+//			return new FunctionNameItem(functionName,s.currentFunctionSym,false);
+		}
+		else
+		{
+			FunctionNameItem item = new FunctionNameItem(Messages.getString("NewFunctionAnalyse.functionNotFound"),null,false); //$NON-NLS-1$
+			this.functionNameCacheItt.put(s,item);
+			this.functionNameCacheSym.put(s,item);
+			return item;
+//			return new FunctionNameItem("Function not found",null,false);
+		}
+	}
+	
+	private void sortFunctionIndexList(Vector offsets)
+	{
+		class IndexElement implements Sortable
+		{
+			long offset;
+			int count;
+			
+			public long valueOf()
+			{
+				return count;
+			}
+		}
+		
+		for (Enumeration e=offsets.elements();e.hasMoreElements();)
+		{
+			Vector functionOffsets = (Vector)e.nextElement();
+
+			Hashtable temp = new Hashtable();
+			
+			// count together the amounts of each offset
+			for (Enumeration b=functionOffsets.elements();b.hasMoreElements();)
+			{
+				Long offset = (Long)b.nextElement();
+				IndexElement ie = (IndexElement)temp.get(offset);
+				if (ie != null)
+				{
+					ie.count++;
+					//temp.remove(offset);
+					//count = new Long(count.longValue()+1);
+					//temp.put(offset,count);
+				}
+				else
+				{
+					ie = new IndexElement();
+					ie.count = 1;
+					ie.offset = offset.longValue();
+					temp.put(offset,ie);
+					//count = new Long(1);
+					//temp.put(offset,count);
+				}
+			}
+
+			//int tempCount = 0;
+			//for (Enumeration b=temp.elements();b.hasMoreElements();)
+			//{
+			//	Long l = (Long)b.nextElement();
+			//	tempCount+=l.longValue();
+			//}
+			
+			// all offsets counted together, now sort and put back to original vector
+			// the vector will then contain amount/offset pairs of data each element pair
+			// one after another
+			functionOffsets.clear();
+			Vector tempVec = new Vector();
+			tempVec.addAll(temp.values());
+			QuickSortImpl.sort(tempVec);
+			Enumeration finalEnum = tempVec.elements();
+			
+			while(finalEnum.hasMoreElements())
+			{
+				IndexElement ie = (IndexElement)finalEnum.nextElement();
+				functionOffsets.add(new Long(ie.offset));
+				functionOffsets.add(new Long(ie.count));
+			}
+			//System.out.print(" new count: "+functionOffsets.size()+"\n");
+			/*
+			long totalAmount=0;
+
+			while(temp.size()>0)
+			{
+				long largestAmount=0;
+				long largestOffset=0;
+
+				for (Enumeration keys = temp.keys();keys.hasMoreElements();)
+				{
+					Long offset = (Long)keys.nextElement();
+					Long amount = (Long)temp.get(offset);
+					if (amount.longValue()>largestAmount) 
+					{
+						largestAmount = amount.longValue();
+						largestOffset = offset.longValue();
+					}
+				}
+
+				temp.remove(new Long(largestOffset));
+				functionOffsets.add(new Long(largestOffset));
+				functionOffsets.add(new Long(largestAmount));
+				totalAmount+=largestAmount;
+			}	*/	
+		}
+	}
+	
+	private Vector sortPercentData(Vector percents, Vector names,Vector offsets,int totalSamples)
+	{
+		for (int i=0;i<names.size();i++)
+		{
+			FunctionNameItem item = (FunctionNameItem)names.get(i);
+			item.setTotalSampleAmount(totalSamples);
+			item.setSampleAmount(((Integer)percents.elementAt(i)).intValue());
+			
+			Vector offsetVector = null;
+			if (functionPercents.isSelected() == true)
+			{
+				offsetVector = (Vector)offsets.elementAt(i);
+			}
+			item.setOffsetVector(offsetVector);
+		}
+		QuickSortImpl.sortReversed(names);
+		return names;
+	}
+
+	private boolean updating = false;
+	
+	public void valueChanged(ListSelectionEvent lse)
+	{
+		if (lse.getValueIsAdjusting())
+			return;
+		
+		if (updating == true) 
+		{
+			return;
+		}
+		
+		updating = true;
+		
+		if (lse.getSource() == this.threadList && (mode == Defines.THREADS || mode == Defines.THREADS_FUNCTIONS))
+			this.refreshBinaryListComponentSec();
+		else if (lse.getSource() == this.binaryList && (mode == Defines.BINARIES || mode == Defines.BINARIES_FUNCTIONS))
+		    this.refreshThreadListComponentSec();
+		
+		this.refreshPercentListComponent();
+		
+		updating = false;
+	}
+	
+	public void updateGfc()
+	{
+		if (this.gfcEnabled == false)
+			return;
+		
+		if (this.updateThread != null)
+			return;
+
+		updateThread = new Thread()
+		{
+			public void run()
+			{
+			if (gfcTrace != null)
+				{
+				gfcTraceVisualiser = new GfcTraceVisualiser(gfcTrace);
+		
+				gfcTraceVisualiser.setStartAndEnd((int)((GfcSample)gfcSamples.firstElement()).sampleNumber
+						,(int)((GfcSample)gfcSamples.lastElement()).sampleNumber,
+						symbolPrimary);
+		
+				JPanel linkedPanel = new JPanel();
+				linkedPanel.setLayout(new BorderLayout());
+				linkedPanel.add(gfcTraceVisualiser.getCalleeList(),BorderLayout.NORTH);
+				linkedPanel.add(gfcTraceVisualiser.getCenterPanel(),BorderLayout.CENTER);
+				linkedPanel.add(gfcTraceVisualiser.getCallerList(),BorderLayout.SOUTH);
+				linkedPanel.add(gfcTraceVisualiser.getSelectionPanel(),BorderLayout.WEST);
+      
+				functionSplit.setBottomComponent(linkedPanel);
+				functionSplit.setDividerLocation((double)0.4);
+				functionSplit.revalidate();
+				functionSplit.updateUI();
+				updateUI();
+	
+				if (mode == Defines.BINARIES || mode == Defines.BINARIES_FUNCTIONS)
+				{
+				    refreshThreadListComponentSec();
+				}
+				else
+				{
+				    refreshBinaryListComponentSec();
+				};
+				refreshPercentListComponent();
+				updateThread = null;
+				}
+			}
+		};
+		updateThread.start();
+	}
+	
+	public void stateChanged(ChangeEvent ce)
+	{
+		if (this.updating == true) return;
+		
+		this.updating = true;
+		
+		if (ce.getSource() == this.totalPercents)
+		{
+			this.refreshPercentListComponent();
+			if (mode == Defines.BINARIES || mode == Defines.BINARIES_FUNCTIONS)
+			{
+			    refreshThreadListComponentSec();
+			}
+			else
+			{
+			    refreshBinaryListComponentSec();
+			}
+		}
+		else if (ce.getSource() == this.functionPercents)
+		{
+			this.refreshPercentListComponent();
+		}
+		
+		this.updating = false;
+	}
+	
+	public void customKeys(JList list)
+	{
+	    final JList tmpList = list;
+	    list.getInputMap().put(KeyStroke.getKeyStroke("control C"), "ctrl c"); //$NON-NLS-1$ //$NON-NLS-2$
+		
+		list.getActionMap().put("ctrl c", //$NON-NLS-1$
+	            new AbstractAction("ctrl c")  //$NON-NLS-1$
+	            {
+					private static final long serialVersionUID = 4692089714529176119L;
+
+					public void actionPerformed(ActionEvent evt) 
+	                {      
+	                    String toClipboard = ""; //$NON-NLS-1$
+	                    Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
+	        			StringSelection contents;
+	                    Object[] listValues = tmpList.getSelectedValues();
+	                    for (int i = 0; i < listValues.length; i++)
+	                    {
+	                        Object listValue = listValues[i];
+	                        if (listValue instanceof String)
+	                        {
+	                            toClipboard += (String)listValue + "\n"; //$NON-NLS-1$
+	                        }
+	                        else if (listValue instanceof BinaryNameItem)
+	                        {
+	                            BinaryNameItem item = (BinaryNameItem)listValue;
+	                            if (totalPercents.isSelected())
+	            					toClipboard += item.sampleAmount+Messages.getString("NewFunctionAnalyse.samplesEqual")+((float)item.sampleAmount*100f)/gppSamples.size()+"% "+item + "\n"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+	            				else 
+	            					toClipboard += item.sampleAmount+Messages.getString("NewFunctionAnalyse.samplesEqual")+((float)item.sampleAmount*100f)/item.totalSamples+"% "+item + "\n"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+	                        }
+	                        else if (listValue instanceof FunctionNameItem)
+	                        {
+	                            FunctionNameItem item = (FunctionNameItem)listValue;
+	                            String offsetString = ""; //$NON-NLS-1$
+	            				
+	            				if (functionPercents.isSelected() == true)
+	            				{
+	            					DecimalFormat df = new DecimalFormat(Messages.getString("NewFunctionAnalyse.decimalFormat")); //$NON-NLS-1$
+	            					float total = 0;
+	            					for (Enumeration e = item.offsetVector.elements();e.hasMoreElements();)
+	            					{
+	            						Long offset = (Long)e.nextElement();
+	            						Long amount = (Long)e.nextElement();
+	            						offsetString += "(+"+offset.longValue()+"b "; //$NON-NLS-1$ //$NON-NLS-2$
+	            						offsetString += amount.longValue()+"s "; //$NON-NLS-1$
+	            						offsetString += "="+df.format(100f*(float)amount.longValue()/item.sampleAmount)+"% ) "; //$NON-NLS-1$ //$NON-NLS-2$
+	            						total+=(float)amount.longValue()/item.sampleAmount;
+	            					}
+	            				}
+
+	            				if (totalPercents != null)
+	            				{
+	            					if (!totalPercents.isSelected())
+	            					    toClipboard += item.sampleAmount+Messages.getString("NewFunctionAnalyse.samplesEqual")+((float)item.sampleAmount*100f)/item.totalSamples+"% "+item; //$NON-NLS-1$ //$NON-NLS-2$
+	            					else
+	            					    toClipboard += item.sampleAmount+Messages.getString("NewFunctionAnalyse.samplesEqual")+((float)item.sampleAmount*100f)/gppSamples.size()+"% "+item; //$NON-NLS-1$ //$NON-NLS-2$
+
+	            					toClipboard += offsetString;
+	            				}
+	            				toClipboard += "\n"; //$NON-NLS-1$
+	                        }
+	                    }
+	                    contents = new StringSelection(toClipboard);
+	        	        cb.setContents(contents, contents);
+				    }
+	            });
+	}
+	
+	public void showLinkedData()
+	{
+		if (this.gfcTraceVisualiser != null)
+		{
+			FunctionNameItem item = (FunctionNameItem)this.percentList.getSelectedValue();
+			this.gfcTraceVisualiser.selectFunction(item.name);
+		} 
+	}
+	
+	private class BinaryNameItem
+	{
+		public String name;
+		public boolean itt;
+		public int sampleAmount;
+		public int totalSamples;
+		
+		public BinaryNameItem(String name, boolean itt)
+		{
+			this.name = name.toLowerCase();
+			this.itt = itt;
+			this.sampleAmount = 0;
+		}
+		
+		public String toString()
+		{
+			return this.name;
+		}
+		
+		public void setSampleAmount(int amount)
+		{
+			this.sampleAmount = amount;
+		}
+		
+		public void setTotalSampleAmount(int total)
+		{
+			this.totalSamples = total;
+		}
+
+		public boolean equals(Object o)
+		{
+			if (o == null) return false;
+
+			if (o instanceof String)
+			{
+				if ( ((String)o).equals(this.name) ) return true;
+			}
+			else if (o instanceof BinaryNameItem)
+			{
+				if ( ((BinaryNameItem)o).name.equals(this.name) ) return true;
+			}
+			else if (this.name.equals(o.toString())) 
+			{
+				return true;
+			}
+						
+			return false;
+		}
+		
+		public int hashCode()
+		{
+			return this.name.hashCode();
+		}
+
+	}
+	
+	private static class FunctionNameItem implements Sortable
+	{
+		public String name;
+		public boolean itt;
+		public int sampleAmount;
+		public int totalSamples;
+		public Function function;
+		public Vector offsetVector;
+		public double currentPercent;
+		
+		public FunctionNameItem(String name, Function function, boolean itt)
+		{
+			this.offsetVector = new Vector();
+			this.sampleAmount = 0;
+			this.totalSamples = 0;
+			this.function = function;
+			this.name = name;
+			this.itt = itt;
+		}
+		
+		public long valueOf()
+		{
+			return this.sampleAmount;
+		}
+		
+		public String toString()
+		{
+			return this.name;
+		}
+		
+		public void setSampleAmount(int amount)
+		{
+			this.sampleAmount = amount;
+		}
+		
+		public void setTotalSampleAmount(int total)
+		{
+			this.totalSamples = total;
+		}
+		public void setOffsetVector(Vector offsetVector)
+		{
+			this.offsetVector = offsetVector;
+		}
+		
+		public boolean equals(Object o)
+		{
+			if (o == null) return false;
+
+			if (o instanceof String)
+			{
+				if ( ((String)o).equals(this.name) ) return true;
+			}
+			else if (o instanceof FunctionNameItem)
+			{
+				if ( ((FunctionNameItem)o).name.equals(this.name) ) return true;
+			}
+			else if (this.name.equals(o.toString())) 
+			{
+				return true;
+			}
+
+			return false;
+		}
+		
+		public int hashCode()
+		{
+			return this.name.hashCode();
+		}
+	}
+	
+	private class FunctionItemRenderer extends JLabel implements ListCellRenderer
+	{
+		private static final long serialVersionUID = 2036360032509070443L;
+
+		public Color ittColor = Color.ORANGE.darker();
+		public Color gppColor = Color.BLUE.darker();
+		public Color selectionColor = Color.YELLOW.brighter();
+		public FunctionNameItem functionNameItem = null;
+		
+		public void paint(Graphics g)
+		{
+			super.paint(g);
+
+			if (this.functionNameItem != null && this.functionNameItem.offsetVector != null)
+			{
+				
+				long length = this.functionNameItem.function.length;
+				g.setColor(
+						// AWT
+					    AWTColorPalette.getColor(new RGB(255, 255, 255))
+					    // SWT
+					    //ColorPalette.getColor(new RGB(255, 255, 255))
+				);
+				g.fillRect(0,0,100,14);
+				
+				int[] array = new int[100];
+				int maxAmount = 0;
+				
+				for (Enumeration e=functionNameItem.offsetVector.elements();e.hasMoreElements();)
+				{
+					long offset = ((Long)e.nextElement()).longValue();
+					long amount = ((Long)e.nextElement()).longValue();
+					//int color = (int)(amount*255/this.functionNameItem.sampleAmount);
+					
+					if (length > 0 /*&& !this.functionNameItem.itt*/)
+					{
+						//float width = (100f/(float)length);
+
+						if (offset > length)
+						{
+							// there is a problem with the offsets
+							// bail out and display a blue box
+							g.setColor(
+									// AWT
+								    AWTColorPalette.getColor(new RGB(100, 100, 200))
+								    // SWT
+								    //ColorPalette.getColor(new RGB(100, 100, 200))
+							);
+							g.fillRect(0,0,100,14);
+							break;
+						}
+						else
+						{	
+							if (offset == length) offset = length-1;
+							
+							float x1 = (float)(offset*100f)/((float)length);
+							float x2 = (float)((offset+1)*100f)/((float)length);
+							for (int j=(int)x1;j<(int)x2;j++)
+							{
+								array[j]+=amount;
+								if (maxAmount<array[j]) maxAmount = array[j];
+							}
+						}
+					}
+					else
+					{
+						// there is a problem with the offsets
+						// bail out and display a blue box
+						g.setColor(
+								// AWT
+							    AWTColorPalette.getColor(new RGB(100, 100, 200))
+							    // SWT
+							    //ColorPalette.getColor(new RGB(100, 100, 200))
+						);
+						g.fillRect(0,0,100,14);
+					}
+				}
+				
+				if (maxAmount != 0)
+				{
+					for (int j=0;j<100;j++)
+					{
+						if (array[j] > 0)
+						{
+							array[j] = (array[j]*255)/maxAmount;
+							Color c = 
+								// AWT
+							    AWTColorPalette.getColor(new RGB(array[j], 255-array[j], array[j]/2));
+							    // SWT
+							    //ColorPalette.getColor(new RGB(array[j], 255-array[j], array[j]/2));
+							g.setColor(c);
+							g.drawLine(j,0,j,14);
+						}
+					}
+				}
+				
+				g.setColor(					// AWT
+					    AWTColorPalette.getColor(new RGB(0, 0, 0))
+					    // SWT
+					    //ColorPalette.getColor(new RGB(0, 0, 0))
+				);
+				g.drawRect(0,0,100,14);
+				g.setColor(Color.BLACK);
+				g.drawString(""+length,10,12); //$NON-NLS-1$
+			}
+		}
+		
+		public Component getListCellRendererComponent(
+				JList list,
+				Object value,            // value to display
+				int index,               // cell index
+				boolean isSelected,      // is the cell selected
+				boolean cellHasFocus)    // the list and the cell have the focus
+		{	
+			if (value instanceof BinaryNameItem)
+			{
+				BinaryNameItem item = (BinaryNameItem)value;
+				String s;
+				
+				if (totalPercents.isSelected())
+					s = item.sampleAmount+Messages.getString("NewFunctionAnalyse.samplesEqual")+((float)item.sampleAmount*100f)/gppSamples.size()+"% "+item; //$NON-NLS-1$ //$NON-NLS-2$
+				else 
+					s = item.sampleAmount+Messages.getString("NewFunctionAnalyse.samplesEqual")+((float)item.sampleAmount*100f)/item.totalSamples+"% "+item; //$NON-NLS-1$ //$NON-NLS-2$
+				
+				setText(s);
+				
+				Color color;
+				if (item.itt)
+				{
+					color = this.ittColor;
+				}
+				else
+				{
+					color = this.gppColor;
+				}
+					
+				setOpaque(true);
+				
+				if (isSelected)
+				{
+					setForeground(color);					
+					if (cellHasFocus)
+						setBorder(new LineBorder(
+							// AWT
+						    AWTColorPalette.getColor(new RGB(0, 0, 0))
+						    // SWT
+						    //ColorPalette.getColor(new RGB(0, 0, 0))
+						));
+						else setBorder(null);
+					setBackground(this.selectionColor);	
+				}
+				else
+				{
+					setForeground(color);
+					setBackground(
+							// AWT
+						    AWTColorPalette.getColor(new RGB(255, 255, 255))
+						    // SWT
+						    //ColorPalette.getColor(new RGB(255, 255, 255))
+					);
+					setBorder(null);
+				}
+
+				setEnabled(list.isEnabled());
+				setFont(list.getFont());
+			}
+			else if (value instanceof FunctionNameItem)
+			{	
+				FunctionNameItem item = (FunctionNameItem)value;
+				this.functionNameItem = item;
+				String s = ""; //$NON-NLS-1$
+					
+				String offsetString = ""; //$NON-NLS-1$
+				
+				if (functionPercents.isSelected() == true)
+				{
+					DecimalFormat df = new DecimalFormat(Messages.getString("NewFunctionAnalyse.decimalFormal")); //$NON-NLS-1$
+					float total = 0;
+					for (Enumeration e = item.offsetVector.elements();e.hasMoreElements();)
+					{
+						Long offset = (Long)e.nextElement();
+						Long amount = (Long)e.nextElement();
+						offsetString += "(+"+offset.longValue()+"b "; //$NON-NLS-1$ //$NON-NLS-2$
+						offsetString += amount.longValue()+"s "; //$NON-NLS-1$
+						offsetString += "="+df.format(100f*(float)amount.longValue()/item.sampleAmount)+"% ) "; //$NON-NLS-1$ //$NON-NLS-2$
+						total+=(float)amount.longValue()/item.sampleAmount;
+						s = "                                         "; //$NON-NLS-1$
+					}
+				}
+
+				if (totalPercents != null)
+				{
+					if (!totalPercents.isSelected())
+						s += item.sampleAmount+Messages.getString("NewFunctionAnalyse.samplesEqual")+((float)item.sampleAmount*100f)/item.totalSamples+"% "+item; //$NON-NLS-1$ //$NON-NLS-2$
+					else
+						s += item.sampleAmount+Messages.getString("NewFunctionAnalyse.samplesEqual")+((float)item.sampleAmount*100f)/gppSamples.size()+"% "+item; //$NON-NLS-1$ //$NON-NLS-2$
+
+					setText(s +"  "+ offsetString); //$NON-NLS-1$
+				}
+				
+				
+				Color color;
+				if (item.itt)
+				{
+					color = this.ittColor;
+				}
+				else
+				{
+					color = this.gppColor;
+				}
+					
+				setOpaque(true);
+				
+				if (isSelected)
+				{
+					setForeground(color);
+					setBackground(this.selectionColor);
+					
+					if (cellHasFocus)
+						setBorder(new LineBorder(
+							// AWT
+						    AWTColorPalette.getColor(new RGB(0, 0, 0))
+						    // SWT
+						    //ColorPalette.getColor(new RGB(0, 0, 0))
+						));
+						else setBorder(null);
+				}
+				else
+				{
+					setForeground(color);
+					setBackground(
+							// AWT
+						    AWTColorPalette.getColor(new RGB(255, 255, 255))
+						    // SWT
+						    //ColorPalette.getColor(new RGB(255, 255, 255))
+					);					
+					setBorder(null);
+				}
+				
+				if (item.function != null)
+				{
+					if (item.function.functionBinary != null && item.function.functionBinary.binaryName != null)
+					{
+						this.setToolTipText(Messages.getString("NewFunctionAnalyse.function1")+item.function.functionName+Messages.getString("NewFunctionAnalyse.function2")+ //$NON-NLS-1$ //$NON-NLS-2$
+								Long.toHexString(item.function.startAddress.longValue())+
+								Messages.getString("NewFunctionAnalyse.function3")+item.function.functionBinary.binaryName); //$NON-NLS-1$
+					}
+					else
+					{
+						this.setToolTipText(Messages.getString("NewFunctionAnalyse.function1")+item.function.functionName+Messages.getString("NewFunctionAnalyse.function2")+ //$NON-NLS-1$ //$NON-NLS-2$
+								Long.toHexString(item.function.startAddress.longValue())+
+								Messages.getString("NewFunctionAnalyse.function3") + Messages.getString("NewFunctionAnalyse.binaryNotFound")); //$NON-NLS-1$ //$NON-NLS-2$
+					}
+				}
+				else
+				{
+					this.setToolTipText(Messages.getString("NewFunctionAnalyse.functionNotFound")); //$NON-NLS-1$
+				}
+			}
+		
+			return this;
+		}
+	}
+
+}