Performance Investigator Carbide extension 2.3.0
authorToni Pulkkinen <ext-toni.p.pulkkinen@nokia.com>
Wed, 21 Apr 2010 15:14:16 +0300
changeset 5 844b047e260d
parent 4 615035072f7e
child 6 f65f740e69f9
Performance Investigator Carbide extension 2.3.0
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi-feature/feature.xml
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/META-INF/MANIFEST.MF
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/internal/pi/address/AddrBinaryTableSMP.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/internal/pi/address/AddrFunctionTableSMP.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/internal/pi/address/AddrThreadTableSMP.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/internal/pi/address/GppModelAdapter.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/internal/pi/address/GppTraceGraphSMP.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/internal/pi/address/Messages.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/internal/pi/address/messages.properties
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/pi/address/AddrBinaryTable.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/pi/address/AddrFunctionTable.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/pi/address/AddrThreadTable.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/pi/address/AddressPlugin.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/pi/address/GenericAddrTable.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/pi/address/GppSample.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/pi/address/GppTableSorter.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/pi/address/GppTrace.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/pi/address/GppTraceCsvPrinter.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/pi/address/GppTraceGraph.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/pi/address/GppTraceParser.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/pi/address/GppTraceUtil.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/pi/address/GppVisualiserPanel.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/pi/address/IGppTraceGraph.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/pi/address/messages.properties
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.button/META-INF/MANIFEST.MF
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.button/src/com/nokia/carbide/cpp/internal/pi/button/ui/BupMapTableViewer.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.button/src/com/nokia/carbide/cpp/internal/pi/button/ui/ModifyCachedBupEventMap.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.button/src/com/nokia/carbide/cpp/internal/pi/button/ui/messages.properties
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.button/src/com/nokia/carbide/cpp/pi/button/BupEventMapManager.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.button/src/com/nokia/carbide/cpp/pi/button/BupTrace.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.button/src/com/nokia/carbide/cpp/pi/button/BupTraceGraph.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.button/src/com/nokia/carbide/cpp/pi/button/ButtonPlugin.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.button/src/com/nokia/carbide/cpp/pi/button/messages.properties
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.call/META-INF/MANIFEST.MF
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.call/src/com/nokia/carbide/cpp/pi/call/CallPlugin.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.call/src/com/nokia/carbide/cpp/pi/call/CallTraceGraph.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.call/src/com/nokia/carbide/cpp/pi/call/CallVisualiser.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.call/src/com/nokia/carbide/cpp/pi/call/GfcFunctionItem.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.call/src/com/nokia/carbide/cpp/pi/call/GfcSample.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.call/src/com/nokia/carbide/cpp/pi/call/GfcTrace.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.call/src/com/nokia/carbide/cpp/pi/call/GfcTraceParser.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.call/src/com/nokia/carbide/cpp/pi/call/messages.properties
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.core/META-INF/MANIFEST.MF
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/META-INF/MANIFEST.MF
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/about.html
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/Getting_Started/GS_index.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/Getting_Started/example_project.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/Getting_Started/tour.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/bugs_fixed.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/abbrev.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/analyser.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/basic_operation.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/button_press_capture.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/dll_support.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/func_level_load.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/images/con_memory_usage.png
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/images/pi_thread_load_01.png
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/images/view_button_markers.png
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/learn_prof.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/memory_usage_capture.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/methods.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/overview/overview.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/overview/sw_performance.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/perfanalysis/perf_basic_procedures.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/perfanalysis/perf_other_dynamic_mem.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/perfanalysis/perf_other_server_threads.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/perfanalysis/perf_other_subjects.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/perfanalysis/perfanalysis.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/power_usage_capture.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/context_help/com_nokia_carbide_pi_ipc.xml
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/context_help/com_nokia_carbide_pi_irq.xml
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/context_help/com_nokia_carbide_pi_memory.xml
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/context_help/com_nokia_carbide_pi_pec.xml
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/context_help/com_nokia_carbide_pi_power.xml
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/legal.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/profiler.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/abbrev.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/GUI_tour.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/an_installation.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/an_use_case_features.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/analyser.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/analyzing_table_data.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/binary_load.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/context_menu.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/function_calls.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/function_load.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/IPC_view.png
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/MIPS_speed_dialog.png
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/Performance_counters_drop-down.png
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/analyzer_mainview.png
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/binary_mode_graph.png
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/event_loaded.png
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/event_unloaded.png
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/function_mode_graph.png
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/help_button.png
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/interrupts_view_HW.png
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/interrupts_view_SW.png
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/interrupts_view_drop-down.png
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/investigator_menu.png
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/investigator_menu_SMP.png
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/linkto_help.png
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/maximize_graph.png
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/maximize_restore_graph.png
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/memory_graph_drop_down.png
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/menu_memory_usage.png
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/minimize_graph.png
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/minimize_restore_graph.png
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/move_graph_down.png
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/move_graph_up.png
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/performance_counters_view_all_graphs.png
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/thread_mode_graph.png
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/thread_mode_separate_graphs.png
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/view_memory_library_events.png
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/view_memory_usage.png
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/view_power_usage.png
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/import_rom_build_files.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/interrupts_view.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/investigator_menu.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/main_view.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/menu_memory_graph.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/menu_power_graph.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/save_table.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/thread_load.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/threshold.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/traceable_events.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/view_IPC.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/view_memory_usage.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/view_performance_counters.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/view_power_usage.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/wnd_memory_usage_statistics.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/wnd_power_graph_settings.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/wnd_power_usage_statistics.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/banked_registers.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/compile_time.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/cpu_timer.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/curr_pgm_status_reg.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/delayed_fn_call.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/dynamic_bin_res.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/file_sys_storing.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/int_stack.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/kernel_containers.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/kernel_hook.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/link_register.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/os_thread.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/periodic_int.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/pgm_counter.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/proc_mode.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/read_write_load.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/rofs.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/saved_pgm_status_reg.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/serial_output.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/sw_interrupt.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/swi_interrupt.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/tcpip.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/BUP_trace.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/DSP_trace.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/GFC_trace.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/GPP_trace.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/IRQ_trace.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/ITT_trace.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/MEM_trace.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/PRI_trace.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/PWR_trace.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/Prof_counter_settings.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/SWI_trace.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/TIP_trace.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/Trace_Items.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/advanced_options.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/cmd_line_overview.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/images/profiler_PEC_settings1.png
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/images/profiler_PEC_settings2.png
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/images/profiler_PEC_settings3.png
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/images/profiler_PEC_settings4.png
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/images/profiler_PEC_settings5.png
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/images/profiler_PEC_settings6.png
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/output_settings.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/prof_using.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/profiler.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/tracing_options.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/settings.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/release_notes.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/analyser/an_load_trace_files.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/analyser/btn_press_change.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/analyser/btn_press_show.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/analyser/chng_graphcolor.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/analyser/images/CB_import_step2.PNG
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/analyser/images/import_dat_file_step5.png
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/analyser/images/pi_thread_load_01.png
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/analyser/images/pi_thread_load_02.png
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/analyser/key_profile_exp.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/analyser/key_profile_imp.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/analyser/key_profile_pref.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/analyser/key_profile_select.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/analyser/key_profile_switch.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/analyser/set_thresholds.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/analyser/source_lookup.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/analyser/time_interval.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/profiler/bluetooth_connection.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/profiler/btn_press_enable.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/profiler/key_profile_exp.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/profiler/key_profile_imp.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/profiler/prof_installation.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/profiler/serial_connection.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/profiler/usb_connection.htm
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/plugin.xml
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/tocAnalyzer.xml
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/tocPI.xml
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.function/META-INF/MANIFEST.MF
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.function/src/com/nokia/carbide/cpp/pi/function/NewFunctionAnalyse.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/META-INF/MANIFEST.MF
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/src/com/nokia/carbide/cpp/pi/instr/AdvancedMemoryMap.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/src/com/nokia/carbide/cpp/pi/instr/BinaryReader.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/src/com/nokia/carbide/cpp/pi/instr/BinaryReader122.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/src/com/nokia/carbide/cpp/pi/instr/BinaryReaderResult.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/src/com/nokia/carbide/cpp/pi/instr/DecidedPool.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/src/com/nokia/carbide/cpp/pi/instr/InstrPlugin.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/src/com/nokia/carbide/cpp/pi/instr/IttEvent122.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/src/com/nokia/carbide/cpp/pi/instr/IttSample.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/src/com/nokia/carbide/cpp/pi/instr/IttTrace.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/src/com/nokia/carbide/cpp/pi/instr/IttTrace122.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/src/com/nokia/carbide/cpp/pi/instr/IttTraceParser.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/src/com/nokia/carbide/cpp/pi/instr/MapFile.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/src/com/nokia/carbide/cpp/pi/instr/PiInstrFunctionResolver.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/src/com/nokia/carbide/cpp/pi/instr/ProcessedBinary.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/src/com/nokia/carbide/cpp/pi/instr/UndecidedPool.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/src/com/nokia/carbide/cpp/pi/instr/messages.properties
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.ipc/.classpath
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.ipc/.settings/org.eclipse.jdt.core.prefs
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.ipc/META-INF/MANIFEST.MF
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.ipc/build.properties
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.ipc/plugin.xml
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.ipc/src/com/nokia/carbide/cpp/pi/internal/ipc/IpcSample.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.ipc/src/com/nokia/carbide/cpp/pi/internal/ipc/IpcTrace.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.ipc/src/com/nokia/carbide/cpp/pi/internal/ipc/IpcTraceParser.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.ipc/src/com/nokia/carbide/cpp/pi/internal/ipc/Messages.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.ipc/src/com/nokia/carbide/cpp/pi/internal/ipc/messages.properties
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.ipc/src/com/nokia/carbide/cpp/pi/ipc/IpcPlugin.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.ipc/src/com/nokia/carbide/cpp/pi/ipc/IpcReturnPlugin.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.ipc/src/com/nokia/carbide/cpp/pi/ipc/Messages.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.ipc/src/com/nokia/carbide/cpp/pi/ipc/messages.properties
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.irq/.classpath
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.irq/.settings/org.eclipse.jdt.core.prefs
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.irq/META-INF/MANIFEST.MF
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.irq/build.properties
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.irq/plugin.xml
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.irq/src/com/nokia/carbide/cpp/pi/irq/IrqLineLabelProvider.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.irq/src/com/nokia/carbide/cpp/pi/irq/IrqLineTable.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.irq/src/com/nokia/carbide/cpp/pi/irq/IrqPlugin.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.irq/src/com/nokia/carbide/cpp/pi/irq/IrqReturnPlugin.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.irq/src/com/nokia/carbide/cpp/pi/irq/IrqSample.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.irq/src/com/nokia/carbide/cpp/pi/irq/IrqSampleTypeWrapper.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.irq/src/com/nokia/carbide/cpp/pi/irq/IrqTrace.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.irq/src/com/nokia/carbide/cpp/pi/irq/IrqTraceGraph.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.irq/src/com/nokia/carbide/cpp/pi/irq/IrqTraceParser.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.irq/src/com/nokia/carbide/cpp/pi/irq/Messages.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.irq/src/com/nokia/carbide/cpp/pi/irq/SwiFunctionLabelProvider.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.irq/src/com/nokia/carbide/cpp/pi/irq/SwiFunctionTable.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.irq/src/com/nokia/carbide/cpp/pi/irq/SwiThreadLabelProvider.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.irq/src/com/nokia/carbide/cpp/pi/irq/SwiThreadTable.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.irq/src/com/nokia/carbide/cpp/pi/irq/SwiThreadWrapper.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.irq/src/com/nokia/carbide/cpp/pi/irq/messages.properties
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.memory/META-INF/MANIFEST.MF
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.memory/src/com/nokia/carbide/cpp/internal/pi/memory/actions/MemoryStatisticsDialog.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.memory/src/com/nokia/carbide/cpp/pi/memory/LibraryEventColorPalette.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.memory/src/com/nokia/carbide/cpp/pi/memory/MemLibraryEventTable.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.memory/src/com/nokia/carbide/cpp/pi/memory/MemSample.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.memory/src/com/nokia/carbide/cpp/pi/memory/MemThreadTable.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.memory/src/com/nokia/carbide/cpp/pi/memory/MemTrace.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.memory/src/com/nokia/carbide/cpp/pi/memory/MemTraceGraph.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.memory/src/com/nokia/carbide/cpp/pi/memory/MemTraceParser.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.memory/src/com/nokia/carbide/cpp/pi/memory/MemoryPlugin.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.memory/src/com/nokia/carbide/cpp/pi/memory/ProfiledLibraryEvent.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.memory/src/com/nokia/carbide/cpp/pi/memory/messages.properties
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.peccommon/.classpath
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.peccommon/.settings/org.eclipse.jdt.core.prefs
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.peccommon/META-INF/MANIFEST.MF
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.peccommon/build.properties
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.peccommon/src/com/nokia/carbide/cpp/pi/peccommon/Messages.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.peccommon/src/com/nokia/carbide/cpp/pi/peccommon/PecCommonGuiManager.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.peccommon/src/com/nokia/carbide/cpp/pi/peccommon/PecCommonLegend.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.peccommon/src/com/nokia/carbide/cpp/pi/peccommon/PecCommonLegendContentProvider.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.peccommon/src/com/nokia/carbide/cpp/pi/peccommon/PecCommonLegendElement.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.peccommon/src/com/nokia/carbide/cpp/pi/peccommon/PecCommonLegendLabelProvider.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.peccommon/src/com/nokia/carbide/cpp/pi/peccommon/PecCommonLegendViewerSorter.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.peccommon/src/com/nokia/carbide/cpp/pi/peccommon/PecCommonPlugin.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.peccommon/src/com/nokia/carbide/cpp/pi/peccommon/PecCommonSample.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.peccommon/src/com/nokia/carbide/cpp/pi/peccommon/PecCommonTrace.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.peccommon/src/com/nokia/carbide/cpp/pi/peccommon/PecCommonTraceGraph.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.peccommon/src/com/nokia/carbide/cpp/pi/peccommon/messages.properties
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.perfcounters/.classpath
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.perfcounters/.settings/org.eclipse.jdt.core.prefs
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.perfcounters/META-INF/MANIFEST.MF
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.perfcounters/build.properties
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.perfcounters/plugin.xml
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.perfcounters/src/com/nokia/carbide/cpp/pi/internal/perfcounters/Messages.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.perfcounters/src/com/nokia/carbide/cpp/pi/internal/perfcounters/PecGuiManager.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.perfcounters/src/com/nokia/carbide/cpp/pi/internal/perfcounters/PecLegend.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.perfcounters/src/com/nokia/carbide/cpp/pi/internal/perfcounters/PecLegendContentProvider.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.perfcounters/src/com/nokia/carbide/cpp/pi/internal/perfcounters/PecLegendElement.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.perfcounters/src/com/nokia/carbide/cpp/pi/internal/perfcounters/PecLegendLabelProvider.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.perfcounters/src/com/nokia/carbide/cpp/pi/internal/perfcounters/PecLegendViewerSorter.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.perfcounters/src/com/nokia/carbide/cpp/pi/internal/perfcounters/PecSample.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.perfcounters/src/com/nokia/carbide/cpp/pi/internal/perfcounters/PecTrace.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.perfcounters/src/com/nokia/carbide/cpp/pi/internal/perfcounters/PecTraceGraph.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.perfcounters/src/com/nokia/carbide/cpp/pi/internal/perfcounters/PecTraceParser.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.perfcounters/src/com/nokia/carbide/cpp/pi/internal/perfcounters/messages.properties
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.perfcounters/src/com/nokia/carbide/cpp/pi/internal/perfcounters/ui/Messages.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.perfcounters/src/com/nokia/carbide/cpp/pi/internal/perfcounters/ui/ProcessorSpeedInputDialog.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.perfcounters/src/com/nokia/carbide/cpp/pi/internal/perfcounters/ui/messages.properties
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.perfcounters/src/com/nokia/carbide/cpp/pi/perfcounters/Messages.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.perfcounters/src/com/nokia/carbide/cpp/pi/perfcounters/PecPlugin.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.perfcounters/src/com/nokia/carbide/cpp/pi/perfcounters/PecReturnPlugin.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.perfcounters/src/com/nokia/carbide/cpp/pi/perfcounters/messages.properties
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.power/META-INF/MANIFEST.MF
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.power/src/com/nokia/carbide/cpp/internal/pi/power/actions/PowerStatisticsDialog.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.power/src/com/nokia/carbide/cpp/pi/power/PowerPlugin.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.power/src/com/nokia/carbide/cpp/pi/power/PowerTraceGraph.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.power/src/com/nokia/carbide/cpp/pi/power/PwrTraceGraph.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.power/src/com/nokia/carbide/cpp/pi/power/messages.properties
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.priority/META-INF/MANIFEST.MF
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.priority/src/com/nokia/carbide/cpp/pi/priority/PriTrace.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.priority/src/com/nokia/carbide/cpp/pi/priority/PriTraceParser.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.priority/src/com/nokia/carbide/cpp/pi/priority/PriorityPlugin.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.priority/src/com/nokia/carbide/cpp/pi/priority/messages.properties
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.priority2/META-INF/MANIFEST.MF
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.priority2/src/com/nokia/carbide/cpp/pi/priority2/NewPriTrace.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.priority2/src/com/nokia/carbide/cpp/pi/priority2/NewPriTraceParser.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.priority2/src/com/nokia/carbide/cpp/pi/priority2/Priority2Plugin.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.priority2/src/com/nokia/carbide/cpp/pi/priority2/messages.properties
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.ui/META-INF/MANIFEST.MF
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.util/META-INF/MANIFEST.MF
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.util/src/com/nokia/carbide/cpp/pi/util/TestDataMiningPalette.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.util/src/com/nokia/carbide/cpp/pi/util/ThreadColorPalette.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.wizards/META-INF/MANIFEST.MF
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.wizards/src/com/nokia/carbide/cpp/internal/pi/wizards/ui/AbstractBaseGroup.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.wizards/src/com/nokia/carbide/cpp/internal/pi/wizards/ui/FileSelectionGroup.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.wizards/src/com/nokia/carbide/cpp/internal/pi/wizards/ui/NewPIWizard.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.wizards/src/com/nokia/carbide/cpp/internal/pi/wizards/ui/NewPIWizardPageBupMapTask.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.wizards/src/com/nokia/carbide/cpp/internal/pi/wizards/ui/NewPIWizardPageInputTask.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.wizards/src/com/nokia/carbide/cpp/internal/pi/wizards/ui/NewPIWizardPageOutputTask.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.wizards/src/com/nokia/carbide/cpp/internal/pi/wizards/ui/NewPIWizardPagePkgListTask.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.wizards/src/com/nokia/carbide/cpp/internal/pi/wizards/ui/NewPIWizardSettings.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.wizards/src/com/nokia/carbide/cpp/internal/pi/wizards/ui/ProfilerDataPlugins.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.wizards/src/com/nokia/carbide/cpp/internal/pi/wizards/ui/TraceSelectionGroup.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.wizards/src/com/nokia/carbide/cpp/internal/pi/wizards/ui/messages.properties
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.wizards/src/com/nokia/carbide/cpp/internal/pi/wizards/ui/util/PkgListTreeContentProvider.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.wizards/src/com/nokia/carbide/cpp/internal/pi/wizards/ui/util/SdkChooserBase.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.wizards/src/com/nokia/carbide/cpp/internal/pi/wizards/ui/util/messages.properties
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/BackupOfccbuild.xml
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/META-INF/MANIFEST.MF
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/ccbuild_tests.xml
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/icons/linkto_help.gif
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/icons/maximize_graph.png
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/icons/maximize_restore_graph.png
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/icons/minimize_graph.png
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/icons/minimize_restore_graph.png
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/icons/move_graph_down.png
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/icons/move_graph_up.png
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/actions/SetThresholdsDialog.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/analyser/AnalyserDataProcessor.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/analyser/NpiInstanceRepository.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/analyser/ProfileReader.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/analyser/ProfileVisualiser.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/analyser/StreamFileParser.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/analyser/messages.properties
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/manager/PluginInitialiser.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/manager/TraceTypePreviewer.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/Binary.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/CusSample.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/Function.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/FunctionResolver.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/GenericSampledTrace.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/IBinary.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/IFunction.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/ParsedTraceData.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/PiManager.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/ProfiledBinary.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/ProfiledDspHook.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/ProfiledFunction.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/ProfiledGeneric.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/ProfiledThread.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/ProfiledThreshold.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/ProgressBar.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/RefinableTrace.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/TraceDataRepository.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/UnresolvedBinary.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/UnresolvedFunction.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/messages.properties
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/plugin/model/IFinalizeTrace.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/plugin/model/IReportable.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/plugin/model/ITitleBarMenu.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/plugin/model/ITrace.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/plugin/model/ITraceSMP.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/plugin/model/IVisualizable.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/resolvers/CachedFunctionResolver.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/resolvers/RofsSymbolFileFunctionResolver.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/test/TraceAdditionalInfo.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/utils/AlphabeticValueGenerator.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/utils/PIUtilities.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/utils/PluginClassLoader.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/utils/QuickSortImpl.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/visual/AnalyserVisualState.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/visual/GenericTable.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/visual/GenericTraceGraph.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/visual/GraphComposite.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/visual/PICompositePanel.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/visual/PIEvent.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/visual/messages.properties
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/pi/PiPlugin.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/pi/editors/PIPageEditor.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/pi/editors/messages.properties
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/pi/importer/SampleImporter.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/pi/importer/messages.properties
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/pi/visual/IGenericTraceGraph.java
sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/pi/visual/IGraphChangeListener.java
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi-feature/feature.xml	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi-feature/feature.xml	Wed Apr 21 15:14:16 2010 +0300
@@ -2,7 +2,7 @@
 <feature
       id="com.nokia.carbide.cpp.pi"
       label="%featureName"
-      version="2.1.0.qualifier"
+      version="2.3.0.qualifier"
       provider-name="Nokia"
       plugin="com.nokia.carbide.cpp"
       image="Carbide_Image.png">
@@ -323,7 +323,34 @@
       <import plugin="org.eclipse.core.resources"/>
       <import plugin="org.eclipse.core.runtime"/>
       <import plugin="org.eclipse.ui.ide"/>
+      <import plugin="org.eclipse.draw2d"/>
+      <import plugin="com.nokia.carbide.cpp.featureTracker"/>
+      <import plugin="com.nokia.carbide.cpp.sdk.core"/>
+      <import plugin="org.eclipse.emf.common" version="2.4.0" match="greaterOrEqual"/>
+      <import plugin="com.nokia.carbide.cpp.ui"/>
+      <import plugin="org.eclipse.ui.ide" version="3.4.0" match="greaterOrEqual"/>
+      <import plugin="org.eclipse.ui.editors" version="3.4.0" match="greaterOrEqual"/>
+      <import plugin="org.eclipse.emf.ecore" version="2.5.0" match="greaterOrEqual"/>
+      <import plugin="org.eclipse.jface.text"/>
+      <import plugin="org.eclipse.ui.workbench.texteditor"/>
       <import plugin="org.eclipse.swt"/>
+      <import plugin="org.eclipse.cdt.core"/>
+      <import plugin="org.eclipse.cdt.ui"/>
+      <import plugin="com.nokia.carbide.cpp"/>
+      <import plugin="com.nokia.carbide.cdt.builder"/>
+      <import plugin="com.nokia.carbide.cpp.support"/>
+      <import plugin="com.nokia.cpp.utils.core"/>
+      <import plugin="org.eclipse.emf.ecore" version="2.4.0" match="greaterOrEqual"/>
+      <import plugin="org.eclipse.emf.ecore.xmi" version="2.4.0" match="greaterOrEqual"/>
+      <import plugin="com.nokia.carbide.cpp.sdk.core" version="2.0.0" match="greaterOrEqual"/>
+      <import plugin="org.eclipse.cdt.managedbuilder.core"/>
+      <import plugin="com.nokia.carbide.cpp.epoc.engine"/>
+      <import plugin="com.nokia.carbide.cpp.sdk.ui"/>
+      <import plugin="com.nokia.carbide.cpp.pi" version="2.2.0" match="greaterOrEqual"/>
+      <import plugin="com.nokia.carbide.cpp.pi.util" version="2.2.0" match="greaterOrEqual"/>
+      <import plugin="com.nokia.carbide.cpp.pi.peccommon" version="2.2.0" match="greaterOrEqual"/>
+      <import plugin="com.nokia.carbide.cpp.pi.address" version="1.4.0" match="greaterOrEqual"/>
+      <import plugin="org.eclipse.ui.ide" version="3.5.0" match="greaterOrEqual"/>
    </requires>
 
    <plugin
@@ -431,4 +458,32 @@
          version="0.0.0"
          unpack="false"/>
 
+   <plugin
+         id="com.nokia.carbide.cpp.pi.perfcounters"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="com.nokia.carbide.cpp.pi.irq"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="com.nokia.carbide.cpp.pi.ipc"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="com.nokia.carbide.cpp.pi.peccommon"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
 </feature>
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/META-INF/MANIFEST.MF	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/META-INF/MANIFEST.MF	Wed Apr 21 15:14:16 2010 +0300
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: Carbide.c++ Performance Investigator Threads and Addresses
 Bundle-SymbolicName: com.nokia.carbide.cpp.pi.address;singleton:=true
-Bundle-Version: 1.5.0.qualifier
+Bundle-Version: 2.3.0.qualifier
 Bundle-Activator: com.nokia.carbide.cpp.pi.address.AddressPlugin
 Bundle-Vendor: Nokia
 Require-Bundle: org.eclipse.ui,
@@ -14,4 +14,5 @@
  com.nokia.carbide.cpp.pi.core,
  com.nokia.carbide.cpp.pi.util
 Bundle-ActivationPolicy: lazy
-Export-Package: com.nokia.carbide.cpp.pi.address;x-friends:="com.nokia.carbide.cpp.pi.tests"
+Eclipse-ExtensibleAPI: true 
+Export-Package: com.nokia.carbide.cpp.pi.address;x-friends:="com.nokia.carbide.cpp.pi.tests,com.nokia.carbide.cpp.pi.irq"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/internal/pi/address/AddrBinaryTableSMP.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,39 @@
+/*
+ * 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: 
+ *
+ */
+package com.nokia.carbide.cpp.internal.pi.address;
+
+import org.eclipse.swt.widgets.Composite;
+
+import com.nokia.carbide.cpp.pi.address.AddrBinaryTable;
+import com.nokia.carbide.cpp.pi.address.GppTraceGraph;
+
+/**
+ * 
+ * AddrBinaryTable implementation for SMP
+ */
+public class AddrBinaryTableSMP extends AddrBinaryTable{
+
+	/**
+	 * Constructor
+	 * @param myGraph the parent graph
+	 * @param parent the parent composite
+	 */
+	public AddrBinaryTableSMP(GppTraceGraph myGraph, Composite parent, GppModelAdapter adapter) {
+		super(myGraph, parent, adapter);
+	}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/internal/pi/address/AddrFunctionTableSMP.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,39 @@
+/*
+ * 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: 
+ *
+ */
+package com.nokia.carbide.cpp.internal.pi.address;
+
+import org.eclipse.swt.widgets.Composite;
+
+import com.nokia.carbide.cpp.pi.address.AddrFunctionTable;
+import com.nokia.carbide.cpp.pi.address.GppTraceGraph;
+
+/**
+ * 
+ * AddrFunctionTable implementation for SMP
+ */
+public class AddrFunctionTableSMP extends AddrFunctionTable{
+
+	/**
+	 * Constructor
+	 * @param myGraph the parent graph
+	 * @param parent the parent composite
+	 */
+	public AddrFunctionTableSMP(GppTraceGraph myGraph, Composite parent, GppModelAdapter adapter) {
+		super(myGraph, parent, adapter);
+	}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/internal/pi/address/AddrThreadTableSMP.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,40 @@
+/*
+ * 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: 
+ *
+ */
+package com.nokia.carbide.cpp.internal.pi.address;
+
+import org.eclipse.swt.widgets.Composite;
+
+import com.nokia.carbide.cpp.pi.address.AddrThreadTable;
+import com.nokia.carbide.cpp.pi.address.GppTraceGraph;
+
+/**
+ * 
+ * AddrThreadTable implementation for SMP
+ */
+public class AddrThreadTableSMP extends AddrThreadTable{
+
+	/**
+	 * Constructor
+	 * @param myGraph the parent graph
+	 * @param parent the parent composite
+	 * @param adapter a GppModelAdapter to ensure calls into the trace model are SMP specific
+	 */
+	public AddrThreadTableSMP(GppTraceGraph myGraph, Composite parent, GppModelAdapter adapter) {
+		super(myGraph, parent, adapter);
+	}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/internal/pi/address/GppModelAdapter.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,243 @@
+/*
+ * 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: 
+ *
+ */
+package com.nokia.carbide.cpp.internal.pi.address;
+
+import com.nokia.carbide.cpp.internal.pi.analyser.NpiInstanceRepository;
+import com.nokia.carbide.cpp.internal.pi.model.ProfiledGeneric;
+import com.nokia.carbide.cpp.internal.pi.model.ProfiledThreshold;
+import com.nokia.carbide.cpp.pi.address.GppTrace;
+import com.nokia.carbide.cpp.pi.address.GppTraceUtil;
+import com.nokia.carbide.cpp.pi.address.IGppTraceGraph;
+import com.nokia.carbide.cpp.pi.editors.PIPageEditor;
+
+/**
+ * This is an adapter for GppTrace model classes which decides whether to use the
+ * SMP version of a method or the non-SMP version.
+ * 
+ */
+public class GppModelAdapter {
+	
+	int cpu;
+	boolean singleCPUMode;
+	/** type of graph, must be one of PIPageEditor.THREADS_PAGE, PIPageEditor.BINARIES_PAGE, PIPageEditor.FUNCTIONS_PAGE */
+	private int graphType;
+	/** should only be true while testing */
+	private boolean testing;
+
+	/**
+	 * Constructor 
+	 * @param graphType type of graph, must be one of PIPageEditor.THREADS_PAGE, PIPageEditor.BINARIES_PAGE, PIPageEditor.FUNCTIONS_PAGE
+	 */
+	public GppModelAdapter(int graphType) {
+		if (graphType != PIPageEditor.THREADS_PAGE && graphType != PIPageEditor.BINARIES_PAGE && graphType != PIPageEditor.FUNCTIONS_PAGE){
+			throw new IllegalArgumentException();
+		}
+		singleCPUMode = false;
+		this.graphType = graphType;
+	}
+
+	/**
+	 * Constructor for a GppModelAdapter working in single CPU mode 
+	 * on SMP system
+	 * @param cpu the CPU index to use
+	 * @param graphType type of graph, must be one of PIPageEditor.THREADS_PAGE, PIPageEditor.BINARIES_PAGE, PIPageEditor.FUNCTIONS_PAGE
+	 */
+	public GppModelAdapter(int cpu, int graphType) {
+		singleCPUMode = true;
+		this.cpu = cpu; 
+		this.graphType = graphType;
+	}
+
+	/**
+	 * Constructor for sole purpose of unit testing. This will try to avoid the use of GUI widgets.
+	 * @param graphType type of graph, must be one of PIPageEditor.THREADS_PAGE, PIPageEditor.BINARIES_PAGE, PIPageEditor.FUNCTIONS_PAGE
+	 * @param testing true if testing
+	 */
+	public GppModelAdapter(int graphType, boolean testing) {
+		this(graphType);
+		this.testing = testing;
+	}
+
+	/**
+	 * Constructor for sole purpose of unit testing. This will try to avoid the use of GUI widgets.
+	 * @param cpu the CPU index to use
+	 * @param graphType type of graph, must be one of PIPageEditor.THREADS_PAGE, PIPageEditor.BINARIES_PAGE, PIPageEditor.FUNCTIONS_PAGE
+	 * @param testing true if testing
+	 */
+	public GppModelAdapter(int cpu, int graphType, boolean testing) {
+		this(cpu, graphType);
+		this.testing = testing;
+	}
+	
+	/**
+	 * @return the cpu
+	 */
+	public int getCPU() {
+		return cpu;
+	}
+
+	/**
+	 * Indicates whether this graph is a single-CPU graph in an SMP system
+	 * @return the singleCPUMode
+	 */
+	public boolean isSingleCPUMode() {
+		return singleCPUMode;
+	}
+
+	/**
+	 * Returns type of this graph, must be one of PIPageEditor.THREADS_PAGE, PIPageEditor.BINARIES_PAGE, PIPageEditor.FUNCTIONS_PAGE
+	 * @return the graphType
+	 */
+	public int getGraphType() {
+		return graphType;
+	}
+	
+	/**
+	 * Wrapper for {@link ProfiledGeneric.getTotalSampleCount(int)}
+	 * @param profiled the ProfiledGeneric to use
+	 * @return
+	 */
+	public int getTotalSampleCount(ProfiledGeneric profiled){
+		if (singleCPUMode){
+			return profiled.getTotalSampleCountForSMP(cpu);						
+		} else {
+			return profiled.getTotalSampleCount();			
+		}
+	}
+	
+	/**
+	 * Wrapper for {@link ProfiledThreshold.addItem(int, ProfiledGeneric, count)}
+	 * @param pti the ProfiledThreshold to use
+	 * @param graphIndex the current graph index
+	 * @param pGeneric the ProfiledGeneric to add
+	 * @param count the count by which to increase the total sample count
+	 */
+	public void addItem(ProfiledThreshold pti, int graphIndex, ProfiledGeneric pGeneric, int count){
+		if (singleCPUMode){
+			pti.addItemForSMP(cpu, graphIndex, pGeneric, count);
+		} else {
+			pti.addItem(graphIndex, pGeneric, count);
+		}
+	}
+	
+	/**
+	 * Wrapper for {@link ProfiledThreshold.init(int)}
+	 * @param pti the ProfiledThreshold to use
+	 * @param graphIndex the current graph index
+	 */
+	public void init(ProfiledThreshold pti, int graphIndex){
+		if (singleCPUMode){
+			pti.initForSMP(cpu, graphIndex);
+		} else {
+			pti.init(graphIndex);
+		}
+	}
+
+	/**
+	 * Returns one of the values in the given array depending on the current CPU.
+	 * Not intended to be used for non-SMP trace, or the all-CPU mode 
+	 * @param totalSamplesPerCPU the input array to use
+	 * @return the chosen value
+	 * @throws IllegalStateException if not used in single-CPU mode on an SMP trace
+	 */
+	public int getValueForCPU(final int[] totalSamplesPerCPU) {
+		if (!singleCPUMode){
+			throw new IllegalStateException();
+		}
+		return totalSamplesPerCPU[cpu];
+	}
+
+	/**
+	 * Returns the requested threshold item for the current graph 
+	 * @param gppTrace GppTrace to use for getting the graph
+	 * @param graphIndex index of the current graph
+	 * @param thresholdItemType similar to type of graph, must be one of PIPageEditor.THREADS_PAGE for threadThreshold, PIPageEditor.BINARIES_PAGE for binaryThreshold, PIPageEditor.FUNCTIONS_PAGE for functionThreshold
+	 * @return the requested ProfiledThreshold
+	 */
+	public ProfiledThreshold getThresholdItem(GppTrace gppTrace, int graphIndex, int thresholdItemType) {
+		int uid = NpiInstanceRepository.getInstance().activeUid();
+		if (testing){
+			//try getting around to actually having to create a GppTraceGraph as it has too many GUI widgets to be tested as unit test
+			
+			int granularityValue = gppTrace.samples.size() > 100 ? 100 : gppTrace.samples.size();  
+			int totalSampleCount = gppTrace.getSampleAmount();
+			int samplingInterval = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.samplingInterval"); //$NON-NLS-1$
+
+			// initialize the threshold items
+			int bucketDuration = granularityValue * samplingInterval;
+			int numberOfBuckets = GppTraceUtil.calculateNumberOfBuckets(gppTrace.getLastSampleTime(), granularityValue);
+
+			if (thresholdItemType == PIPageEditor.THREADS_PAGE){
+				NpiInstanceRepository.getInstance().setPersistState(uid, "com.nokia.carbide.cpp.pi.address.thresholdCountThread", Integer.valueOf(Double.valueOf(totalSampleCount * (Double)NpiInstanceRepository.getInstance().getPersistState(uid, "com.nokia.carbide.cpp.pi.address.thresholdLoadThread") + 0.5).intValue())); //$NON-NLS-1$ //$NON-NLS-2$
+				ProfiledThreshold thresholdThread = new ProfiledThreshold("dummy[0]::dummy_0", gppTrace.getCPUCount(), gppTrace.getGraphCount()); //$NON-NLS-1$	
+				thresholdThread.setColor(gppTrace.getThreadColorPalette().getColor(thresholdThread.getNameString()));
+				thresholdThread.createBuckets(numberOfBuckets);
+				thresholdThread.initialiseBuckets(bucketDuration);
+				return thresholdThread;
+			} else if (thresholdItemType == PIPageEditor.BINARIES_PAGE){
+				NpiInstanceRepository.getInstance().setPersistState(uid, "com.nokia.carbide.cpp.pi.address.thresholdCountBinary", Integer.valueOf(Double.valueOf(totalSampleCount * (Double)NpiInstanceRepository.getInstance().getPersistState(uid, "com.nokia.carbide.cpp.pi.address.thresholdLoadBinary") + 0.5).intValue())); //$NON-NLS-1$ //$NON-NLS-2$
+				ProfiledThreshold thresholdBinary = new ProfiledThreshold("\\dummy", gppTrace.getCPUCount(), gppTrace.getGraphCount()); //$NON-NLS-1$
+				thresholdBinary.setColor(gppTrace.getBinaryColorPalette().getColor(thresholdBinary.getNameString()));
+				thresholdBinary.createBuckets(numberOfBuckets);
+				thresholdBinary.initialiseBuckets(bucketDuration);
+				return thresholdBinary;
+			} else if (thresholdItemType == PIPageEditor.FUNCTIONS_PAGE){
+				NpiInstanceRepository.getInstance().setPersistState(uid, "com.nokia.carbide.cpp.pi.address.thresholdCountFunction", Integer.valueOf(Double.valueOf(totalSampleCount * (Double)NpiInstanceRepository.getInstance().getPersistState(uid, "com.nokia.carbide.cpp.pi.address.thresholdLoadFunction") + 0.5).intValue())); //$NON-NLS-1$ //$NON-NLS-2$
+				ProfiledThreshold thresholdFunction = new ProfiledThreshold("dummy::dummy()", gppTrace.getCPUCount(), gppTrace.getGraphCount()); //$NON-NLS-1$					
+				thresholdFunction.setColor(gppTrace.getFunctionColorPalette().getColor(thresholdFunction.getNameString()));
+				thresholdFunction.createBuckets(numberOfBuckets);
+				thresholdFunction.initialiseBuckets(bucketDuration);
+				return thresholdFunction;
+			}
+		} else {
+			IGppTraceGraph graph = gppTrace.getGppGraph(graphIndex, uid);			
+			if (thresholdItemType == PIPageEditor.THREADS_PAGE){
+				return graph.getThresholdThread();					
+			} else if (thresholdItemType == PIPageEditor.BINARIES_PAGE){
+				return graph.getThresholdBinary();					
+			} else if (thresholdItemType == PIPageEditor.FUNCTIONS_PAGE){
+				return graph.getThresholdFunction();					
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * In single-CPU mode on an SMP trace, compares the given CPU number with the adapter's CPU number.
+	 * In all other cases, returns true
+	 * @param cpuNumber the CPU number to compare
+	 * @return true, if CPU matches, false otherwise
+	 */
+	public boolean matchingCPU(int cpuNumber) {
+		return singleCPUMode ? cpu == cpuNumber : true;
+	}
+	
+	
+	/**
+	 * Returns the appropriate activity list for the given ProfiledGeneric.
+	 * This may be an SMP-specific list for the current CPU on an SMP trace.
+	 * @param pg The ProfiledGeneric to use
+	 * @return the sample list, i.e. array of bucket values
+	 */
+	public float[] getActivityList(ProfiledGeneric pg){
+		if (singleCPUMode){
+			return pg.getActivityListForSMP(cpu);
+		} else {
+			return pg.getActivityList();
+		}
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/internal/pi/address/GppTraceGraphSMP.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,194 @@
+/*
+ * 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: 
+ *
+ */
+package com.nokia.carbide.cpp.internal.pi.address;
+
+import java.awt.event.ActionListener;
+import java.awt.event.FocusListener;
+
+import org.eclipse.draw2d.MouseListener;
+import org.eclipse.draw2d.MouseMotionListener;
+import org.eclipse.swt.events.MouseMoveListener;
+import org.eclipse.swt.widgets.Composite;
+
+import com.nokia.carbide.cpp.internal.pi.analyser.NpiInstanceRepository;
+import com.nokia.carbide.cpp.internal.pi.model.ProfiledGeneric;
+import com.nokia.carbide.cpp.internal.pi.visual.Defines;
+import com.nokia.carbide.cpp.internal.pi.visual.PIEvent;
+import com.nokia.carbide.cpp.pi.address.GppSample;
+import com.nokia.carbide.cpp.pi.address.GppTrace;
+import com.nokia.carbide.cpp.pi.address.GppTraceGraph;
+import com.nokia.carbide.cpp.pi.address.IGppTraceGraph;
+import com.nokia.carbide.cpp.pi.editors.PIPageEditor;
+
+/**
+ * 
+ * Main class to draw charts for SMP traces. Manages one SMP graph for a single CPU and its associated
+ * legend checkbox table. 
+ * 
+ */
+public class GppTraceGraphSMP extends GppTraceGraph implements IGppTraceGraph, 
+		ActionListener, FocusListener, MouseMotionListener,
+		MouseListener, MouseMoveListener {
+
+
+	/** the index of the CPU for this graph */
+	private int cpuIndex;
+	/** type of graph, must be one of PIPageEditor.THREADS_PAGE, PIPageEditor.BINARIES_PAGE, PIPageEditor.FUNCTIONS_PAGE */
+	private int graphType;
+
+	/**
+	 * Constructor
+	 * @param graphIndex The graph index
+	 * @param gppTrace The trace model data to use
+	 * @param uid general Uid of this editor session
+	 * @param cpuIndex Index of the CPU
+	 * @param graphType The type of graph, one of PIPageEditor.THREADS_PAGE, PIPageEditor.BINARIES_PAGE, PIPageEditor.FUNCTIONS_PAGE
+	 */
+	public GppTraceGraphSMP(int graphIndex, GppTrace gppTrace, int uid, int cpuIndex, int graphType) {
+		super(graphIndex, gppTrace, uid);
+		this.graphIndex = graphIndex;
+		this.cpuIndex = cpuIndex;
+		this.graphType = graphType;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.pi.address.GppTraceGraph#doCreateAdapter()
+	 */
+	@Override
+	protected void doCreateAdapter() {
+		adapter = new GppModelAdapter(this.cpuIndex, graphType);
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.pi.address.GppTraceGraph#createLegendTables(org.eclipse.swt.widgets.Composite)
+	 */
+	@Override
+	protected void createLegendTables(Composite holdTablesComposite) {
+		this.threadTable   = new AddrThreadTableSMP(this, holdTablesComposite, adapter);
+		this.binaryTable   = new AddrBinaryTableSMP(this, holdTablesComposite, adapter);
+		this.functionTable = new AddrFunctionTableSMP(this, holdTablesComposite, adapter);
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.visual.PIEventListener#piEventReceived(com.nokia.carbide.cpp.internal.pi.visual.PIEvent)
+	 */
+	@Override
+	public void piEventReceived(PIEvent be) {
+		switch (be.getType())
+		{
+				
+			// when the selection area changes, change the percent loads
+			// and the sample counts in all tables of this GPP graph
+			case PIEvent.SELECTION_AREA_CHANGED:
+				// this is the first GPP graph to be told of the selection area change,
+				// so it gathers the overall trace information
+				double startTime = PIPageEditor.currentPageEditor().getStartTime();
+				double endTime   = PIPageEditor.currentPageEditor().getEndTime();
+				GppTrace trace = (GppTrace)this.getTrace();
+				trace.setSelectedArea(startTime, endTime);
+				
+				// recalculate threshold items
+				//CH: why? doesn't look like it takes the selected timeframe into account
+				//TODO: CH: do we need to recalculate the thresholds for binaries and functions too?
+				int sampleCount = 0;
+				int thresholdCount = (Integer)NpiInstanceRepository.getInstance().getPersistState(uid, "com.nokia.carbide.cpp.pi.address.thresholdCountThread"); //$NON-NLS-1$
+				if (thresholdCount > 0) {
+					for (ProfiledGeneric pt : profiledThreads) {
+						if (pt.getTotalSampleCountForSMP(cpuIndex) < thresholdCount){
+							sampleCount += pt.getTotalSampleCountForSMP(cpuIndex);							
+						}
+					}
+				}
+				thresholdThread.setSampleCount(this.graphIndex, sampleCount);
+
+				
+				// send this message to the other GPP graphs
+				PIEvent be2 = new PIEvent(be.getValueObject(), PIEvent.SELECTION_AREA_CHANGED2);
+				
+				// update the selection area shown
+				for (int i = 0; i < trace.getGraphCount(); i++)
+				{
+					IGppTraceGraph graph = trace.getGppGraph(i, getUid());
+
+					if (graph != this) {
+						graph.piEventReceived(be2);
+						// once per graph, update the selection interval shown
+						graph.getCompositePanel().getVisualiser().updateStatusBarTimeInterval(startTime, endTime);
+					}
+					
+					// change the graph's selected time interval
+					graph.setSelectionStart(startTime * 1000);
+					graph.setSelectionEnd(endTime * 1000);
+					graph.getCompositePanel().setSelectionFields((int)(startTime * 1000), (int)(endTime * 1000));
+				}
+
+				this.parentComponent.getSashForm().redraw();
+				be = be2;
+				// FALL THROUGH
+			case PIEvent.SELECTION_AREA_CHANGED2:
+			{
+				// this code lets each graph's base thread/binary/function table update the other tables
+		        this.threadTable.piEventReceived(be);
+
+				this.vPanel.refreshCumulativeThreadTable();
+				this.setGraphImageChanged(true);	// any selection change to drill down will change graph
+				this.repaint();
+				break;
+			}
+				
+			default:{
+				super.piEventReceived(be);
+				break;				
+			}
+				
+		}
+	}
+	
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.pi.address.GppTraceGraph#doCheckSampleMatch(com.nokia.carbide.cpp.pi.address.GppSample)
+	 */
+	@Override
+	protected boolean doCheckSampleMatch(GppSample sample){
+		return sample.cpuNumber == this.cpuIndex;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.pi.address.GppTraceGraph#sampleInChart(com.nokia.carbide.cpp.pi.address.GppSample)
+	 */
+	@Override
+	protected boolean sampleInChart(GppSample sample) {
+		return sample.cpuNumber == this.cpuIndex;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.pi.address.GppTraceGraph#refreshColoursFromTrace()
+	 */
+	@Override
+	public void refreshColoursFromTrace() {
+		//assuming that the SMP graphs are on the Threads page
+		getThreadTable().addColor(Defines.THREADS);
+	}
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.pi.address.GppTraceGraph#doSetTitle()
+	 */
+	@Override
+	protected void doSetTitle() {
+		title = String.format(com.nokia.carbide.cpp.internal.pi.address.Messages.GppTraceGraphSMP_0, this.cpuIndex);
+		shortTitle = String.format(com.nokia.carbide.cpp.internal.pi.address.Messages.GppTraceGraphSMP_1, this.cpuIndex);
+	}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/internal/pi/address/Messages.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,16 @@
+package com.nokia.carbide.cpp.internal.pi.address;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS {
+	private static final String BUNDLE_NAME = "com.nokia.carbide.cpp.internal.pi.address.messages"; //$NON-NLS-1$
+	public static String GppTraceGraphSMP_0;
+	public static String GppTraceGraphSMP_1;
+	static {
+		// initialize resource bundle
+		NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+	}
+
+	private Messages() {
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/internal/pi/address/messages.properties	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,2 @@
+GppTraceGraphSMP_0=CPU %d
+GppTraceGraphSMP_1=CPU %d Load
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/pi/address/AddrBinaryTable.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/pi/address/AddrBinaryTable.java	Wed Apr 21 15:14:16 2010 +0300
@@ -26,7 +26,6 @@
 import java.util.Arrays;
 import java.util.Comparator;
 import java.util.Enumeration;
-import java.util.Hashtable;
 import java.util.Vector;
 
 import org.eclipse.jface.viewers.CheckStateChangedEvent;
@@ -58,12 +57,11 @@
 import org.eclipse.swt.widgets.TableColumn;
 import org.eclipse.swt.widgets.TableItem;
 
+import com.nokia.carbide.cpp.internal.pi.address.GppModelAdapter;
 import com.nokia.carbide.cpp.internal.pi.analyser.NpiInstanceRepository;
 import com.nokia.carbide.cpp.internal.pi.analyser.ProfileVisualiser;
 import com.nokia.carbide.cpp.internal.pi.model.ProfiledBinary;
-import com.nokia.carbide.cpp.internal.pi.model.ProfiledFunction;
 import com.nokia.carbide.cpp.internal.pi.model.ProfiledGeneric;
-import com.nokia.carbide.cpp.internal.pi.model.ProfiledThread;
 import com.nokia.carbide.cpp.internal.pi.model.ProfiledThreshold;
 import com.nokia.carbide.cpp.internal.pi.visual.Defines;
 import com.nokia.carbide.cpp.internal.pi.visual.PIEvent;
@@ -78,10 +76,9 @@
 	// without affecting the original
 	Vector<ProfiledGeneric> profiledBinaries = new Vector<ProfiledGeneric>();
 
-	public AddrBinaryTable(GppTraceGraph myGraph, Composite parent)
+	public AddrBinaryTable(GppTraceGraph myGraph, Composite parent, GppModelAdapter adapter)
 	{
-		this.myGraph = myGraph;
-		this.parent  = parent;
+		super(myGraph, parent, adapter);
 	}
 
 	public void createTableViewer(int drawMode)
@@ -161,7 +158,7 @@
 		column = new TableColumn(table, SWT.CENTER);
 		column.setText(COLUMN_HEAD_SHOW);
 		column.setWidth(COLUMN_WIDTH_SHOW);
-		column.setData(new Integer(COLUMN_ID_SHOW));
+		column.setData(Integer.valueOf(COLUMN_ID_SHOW));
 		column.setMoveable(true);
 		column.setResizable(true);
 		column.addSelectionListener(new ColumnSelectionHandler());
@@ -170,7 +167,7 @@
 		column = new TableColumn(table, SWT.RIGHT);
 		column.setText(COLUMN_HEAD_PERCENT_LOAD);
 		column.setWidth(COLUMN_WIDTH_PERCENT_LOAD);
-		column.setData(new Integer(COLUMN_ID_PERCENT_LOAD));
+		column.setData(Integer.valueOf(COLUMN_ID_PERCENT_LOAD));
 		column.setMoveable(true);
 		column.setResizable(true);
 		column.addSelectionListener(new ColumnSelectionHandler());
@@ -179,7 +176,7 @@
 		column = new TableColumn(table, SWT.LEFT);
 		column.setText(COLUMN_HEAD_BINARY);
 		column.setWidth(COLUMN_WIDTH_BINARY_NAME);
-		column.setData(new Integer(COLUMN_ID_BINARY));
+		column.setData(Integer.valueOf(COLUMN_ID_BINARY));
 		column.setMoveable(true);
 		column.setResizable(true);
 		column.addSelectionListener(new ColumnSelectionHandler());
@@ -188,7 +185,7 @@
 		column = new TableColumn(table, SWT.LEFT);
 		column.setText(COLUMN_HEAD_PATH);
 		column.setWidth(COLUMN_WIDTH_PATH);
-		column.setData(new Integer(COLUMN_ID_PATH));
+		column.setData(Integer.valueOf(COLUMN_ID_PATH));
 		column.setMoveable(true);
 		column.setResizable(true);
 		column.addSelectionListener(new ColumnSelectionHandler());
@@ -197,7 +194,7 @@
 		column = new TableColumn(table, SWT.CENTER);
 		column.setText(COLUMN_HEAD_SAMPLE_COUNT);
 		column.setWidth(COLUMN_WIDTH_SAMPLE_COUNT);
-		column.setData(new Integer(COLUMN_ID_SAMPLE_COUNT));
+		column.setData(Integer.valueOf(COLUMN_ID_SAMPLE_COUNT));
 		column.setMoveable(true);
 		column.setResizable(true);
 		column.addSelectionListener(new ColumnSelectionHandler());
@@ -337,6 +334,9 @@
 			super();
 		}
 
+		/* (non-Javadoc)
+		 * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java.lang.Object, int)
+		 */
 		public String getColumnText(Object element, int columnIndex) {
 
 			int columnId = ((Integer) table.getColumn(columnIndex).getData()).intValue();
@@ -371,7 +371,7 @@
 					case COLUMN_ID_BINARY:
 					{
 						DecimalFormat timeFormat = new DecimalFormat(Messages.getString("AddrBinaryTable.decimalFormat")); //$NON-NLS-1$
-						int count = pThreshold.getItemCount(myGraph.getGraphIndex());
+						int count = pThreshold.getItemCount();
 
 						return count + (count > 1 ? Messages.getString("AddrBinaryTable.threshold1") : Messages.getString("AddrBinaryTable.threshold2"))   //$NON-NLS-1$ //$NON-NLS-2$
 								+ timeFormat.format((Double)NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdLoadBinary") * 100.0) + Messages.getString("AddrBinaryTable.threshold3") //$NON-NLS-1$ //$NON-NLS-2$ 
@@ -444,6 +444,7 @@
 		}
 	}
 
+	@Override
 	public void action(String actionString)
 	{
 		int graphIndex = this.myGraph.getGraphIndex();
@@ -572,9 +573,9 @@
 			this.tableItemData.clear();
 			this.profiledBinaries.clear();
 			this.myGraph.getSortedBinaries().clear();
-			if (threshold.getItems(graphIndex) != null)
-				threshold.getItems(graphIndex).clear();
-			threshold.initAll();
+			if (threshold.getItems() != null)
+				threshold.getItems().clear();
+			adapter.init(threshold, graphIndex);
 
 			// if this appears, it needs to be the first item, so that it is drawn at the bottom
 			myGraph.getSortedBinaries().add(threshold);
@@ -582,9 +583,9 @@
 			int binaryThreshold = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountBinary");	//$NON-NLS-1$
 			for (int i = 0; i < this.myGraph.getGppTrace().getSortedBinaries().size(); i++) {
 				ProfiledGeneric nextElement = (ProfiledGeneric)this.myGraph.getGppTrace().getSortedBinaries().get(i);
-				if (nextElement.getTotalSampleCount() < binaryThreshold) {
+				if (adapter.getTotalSampleCount(nextElement) < binaryThreshold) {
 					nextElement.setEnabled(graphIndex, enabled);
-					threshold.addItem(graphIndex, nextElement, 0);
+					adapter.addItem(threshold, graphIndex, nextElement, 0);
 				} else {
 					tableItemData.add(nextElement);
 					profiledBinaries.add(nextElement);
@@ -592,7 +593,7 @@
 				}
 			}
 
-			if (threshold.getItemCount(graphIndex) != 0) {
+			if (threshold.getItemCount() != 0) {
 				tableItemData.add(threshold);
 				profiledBinaries.add(threshold);
 			} else {
@@ -665,9 +666,8 @@
    				if (item instanceof ProfiledThreshold)
    				{
    					ProfiledThreshold pThreshold = (ProfiledThreshold)item;
-   					ArrayList<ProfiledGeneric> items = pThreshold.getItems(graphIndex);
-   					for (int j = 0; j < items.size(); j++)
-   						items.get(j).setEnabled(graphIndex, addIt);
+   					for (ProfiledGeneric p : pThreshold.getItems())
+   						p.setEnabled(graphIndex, addIt);
    				}
 			}
 		}
@@ -718,9 +718,8 @@
    				if (item instanceof ProfiledThreshold)
    				{
    					ProfiledThreshold pThreshold = (ProfiledThreshold)item;
-   					ArrayList<ProfiledGeneric> items = pThreshold.getItems(graphIndex);
-   					for (int j = 0; j < items.size(); j++)
-   						items.get(j).setEnabled(graphIndex, addIt);
+   					for (ProfiledGeneric p : pThreshold.getItems())
+   						p.setEnabled(graphIndex, addIt);
    				}
 			}
 		}
@@ -764,10 +763,16 @@
 						PIPageEditor.currentPageEditor().setDirty();
 						pGeneric.setColor(color);
 					} else {
-						// for the threshold item, we must change every graph's binary threshold item
-						gppTrace.getGppGraph(PIPageEditor.THREADS_PAGE,   uid).getThresholdBinary().setColor(color);
-						gppTrace.getGppGraph(PIPageEditor.BINARIES_PAGE,  uid).getThresholdBinary().setColor(color);
-						gppTrace.getGppGraph(PIPageEditor.FUNCTIONS_PAGE, uid).getThresholdBinary().setColor(color);
+						// for the threshold item, we must change every graph's thread threshold item
+						// CH: refactor! This could be done via an observer pattern. This class should not have knowledge of all other graphs  
+						gppTrace.getGppGraph(PIPageEditor.THREADS_PAGE,   uid).getThresholdThread().setColor(color);
+						gppTrace.getGppGraph(PIPageEditor.BINARIES_PAGE,  uid).getThresholdThread().setColor(color);
+						gppTrace.getGppGraph(PIPageEditor.FUNCTIONS_PAGE, uid).getThresholdThread().setColor(color);
+//						if (gppTrace.getCPUCount() > 1){ //SMP CH: comment this out once we have SMP graphs on the binaries page
+//							for (int cpu = 0; cpu < gppTrace.getCPUCount(); cpu++) {
+//								gppTrace.getGppGraph(7 + cpu, uid).getThresholdThread().setColor(color);															
+//							}
+//						}
 					}
 				}
 
@@ -785,7 +790,7 @@
 		
 		// if any other tabs are displaying this type of graph, they need to be scheduled for redrawing
 		for (int i = 0; i < 3; i++) {
-			GppTraceGraph graph = gppTrace.getGppGraph(i, uid);
+			IGppTraceGraph graph = gppTrace.getGppGraph(i, uid);
 
 			if (graph == this.myGraph)
 				continue;
@@ -821,11 +826,6 @@
 
 		setIsDrilldown(false);
 
-		// set the page's graph title
-		ProfileVisualiser pV =  NpiInstanceRepository.getInstance().getProfilePage(this.myGraph.getUid(), this.myGraph.getGraphIndex());
-		pV.getTitle().setText(Messages.getString("AddrBinaryTable.binaryLoad"));  //$NON-NLS-1$
-		pV.getTitle2().setText(""); //$NON-NLS-1$
-
 		// get rid of any existing tables and sashes
 		if (this.myGraph.getLeftSash() != null) {
 			this.myGraph.getLeftSash().dispose();
@@ -878,10 +878,6 @@
 		setIsDrilldown(true);
 
 		if (drawMode == Defines.BINARIES) {
-			// set the page's graph title
-			ProfileVisualiser pV =  NpiInstanceRepository.getInstance().getProfilePage(this.myGraph.getUid(), this.myGraph.getGraphIndex());
-			pV.getTitle().setText(Messages.getString("AddrBinaryTable.threadLoad"));  //$NON-NLS-1$
-			pV.getTitle2().setText(Messages.getString("AddrBinaryTable.binaryTo"));  //$NON-NLS-1$
 
 			// set the draw mode before populating table viewers, since the
 			// color column depends on the draw mode
@@ -894,14 +890,20 @@
 
 			// create a reduced set of thread entries based on enabled binary entries
 			GppTrace gppTrace = (GppTrace) this.myGraph.getTrace();
-			Vector<ProfiledGeneric> threads = gppTrace.setBinaryThread(graphIndex);
-			this.myGraph.setProfiledThreads(threads);
+			gppTrace.setBinaryThread(graphIndex, adapter, this.myGraph.getProfiledThreads());
 
 			// put check marks on all rows, and sort by sample count
 			threadTable.quickSort(COLUMN_ID_SAMPLE_COUNT, this.myGraph.getProfiledThreads());
 			threadTable.updateProfiledAndItemData(true);
 			threadTable.getTableViewer().setAllChecked(true);
 			threadTable.getTableViewer().refresh();
+
+			// put check marks on all enabled binary rows
+			for (int i = 0; i < this.table.getItemCount(); i++) {
+				ProfiledGeneric pBinary = (ProfiledGeneric) this.table.getItem(i).getData();
+				if (pBinary.isEnabled(graphIndex))
+					this.table.getItem(i).setChecked(true);
+			}
 			
 			// remove colors where appropriate
 			removeColor(Defines.BINARIES_THREADS);
@@ -947,10 +949,6 @@
 			this.myGraph.repaint();
 
 		} else if (drawMode == Defines.BINARIES_THREADS_FUNCTIONS) {
-			// set the page's graph title
-			ProfileVisualiser pV =  NpiInstanceRepository.getInstance().getProfilePage(this.myGraph.getUid(), this.myGraph.getGraphIndex());
-			pV.getTitle().setText(Messages.getString("AddrBinaryTable.threadLoad"));  //$NON-NLS-1$
-			pV.getTitle2().setText(Messages.getString("AddrBinaryTable.binaryTo"));  //$NON-NLS-1$
 
 			// get rid of the function table and its sash
 			if (this.myGraph.getRightSash() != null) {
@@ -1005,11 +1003,6 @@
 
 		setIsDrilldown(true);
 
-		// set the page's graph title
-		ProfileVisualiser pV =  NpiInstanceRepository.getInstance().getProfilePage(this.myGraph.getUid(), this.myGraph.getGraphIndex());
-		pV.getTitle().setText(Messages.getString("AddrBinaryTable.functionLoad"));  //$NON-NLS-1$
-		pV.getTitle2().setText(Messages.getString("AddrBinaryTable.binaryToThreadTo"));  //$NON-NLS-1$
-
 		// set the draw mode before populating table viewers, since the
 		// color column depends on the draw mode
 		this.myGraph.setDrawMode(Defines.BINARIES_THREADS_FUNCTIONS);
@@ -1021,8 +1014,7 @@
 
 		// create a reduced set of function entries based on enabled thread and binary entries
 		GppTrace gppTrace = (GppTrace) this.myGraph.getTrace();
-		Vector<ProfiledGeneric> functions = gppTrace.setBinaryThreadFunction(graphIndex);
-		this.myGraph.setProfiledFunctions(functions);
+		gppTrace.setBinaryThreadFunction(graphIndex, adapter, this.myGraph.getProfiledFunctions());
 
 		// put check marks on all rows, and sort by sample count
 		functionTable.quickSort(COLUMN_ID_SAMPLE_COUNT, this.myGraph.getProfiledFunctions());
@@ -1095,10 +1087,6 @@
 		setIsDrilldown(true);
 
 		if (drawMode == Defines.BINARIES) {
-			// set the page's graph title
-			ProfileVisualiser pV =  NpiInstanceRepository.getInstance().getProfilePage(this.myGraph.getUid(), this.myGraph.getGraphIndex());
-			pV.getTitle().setText(Messages.getString("AddrBinaryTable.functionLoad"));  //$NON-NLS-1$
-			pV.getTitle2().setText(Messages.getString("AddrBinaryTable.binaryTo"));  //$NON-NLS-1$
 
 			// set the draw mode
 			this.myGraph.setDrawMode(Defines.BINARIES_FUNCTIONS);
@@ -1110,8 +1098,8 @@
 
 			// create a reduced set of function entries based on enabled binary entries
 			GppTrace gppTrace = (GppTrace) this.myGraph.getTrace();
-			Vector<ProfiledGeneric> functions = gppTrace.setBinaryFunction(graphIndex);
-			this.myGraph.setProfiledFunctions(functions);
+			Vector<ProfiledGeneric> functions = this.myGraph.getProfiledFunctions();
+			gppTrace.setBinaryFunction(graphIndex, adapter, functions);
 
 			// put check marks on all rows, and sort by sample count
 			functionTable.quickSort(COLUMN_ID_SAMPLE_COUNT, this.myGraph.getProfiledFunctions());
@@ -1163,10 +1151,6 @@
 			this.myGraph.repaint();
 
 		} else if (drawMode == Defines.BINARIES_FUNCTIONS_THREADS) {
-			// set the page's graph title
-			ProfileVisualiser pV =  NpiInstanceRepository.getInstance().getProfilePage(this.myGraph.getUid(), this.myGraph.getGraphIndex());
-			pV.getTitle().setText(Messages.getString("AddrBinaryTable.functionLoad"));  //$NON-NLS-1$
-			pV.getTitle2().setText(Messages.getString("AddrBinaryTable.binaryTo"));  //$NON-NLS-1$
 
 			// get rid of the threads table and its sash
 			if (this.myGraph.getRightSash() != null) {
@@ -1222,11 +1206,6 @@
 
 		setIsDrilldown(true);
 
-		// set the page's graph title
-		ProfileVisualiser pV =  NpiInstanceRepository.getInstance().getProfilePage(this.myGraph.getUid(), this.myGraph.getGraphIndex());
-		pV.getTitle().setText(Messages.getString("AddrBinaryTable.threadLoad"));  //$NON-NLS-1$
-		pV.getTitle2().setText(Messages.getString("AddrBinaryTable.binaryToFunctionTo"));  //$NON-NLS-1$
-
 		// set the draw mode
 		this.myGraph.setDrawMode(Defines.BINARIES_FUNCTIONS_THREADS);
 
@@ -1237,8 +1216,7 @@
 
 		// create a reduced set of thread entries based on enabled binary and function entries
 		GppTrace gppTrace = (GppTrace) this.myGraph.getTrace();
-		Vector<ProfiledGeneric> threads = gppTrace.setBinaryFunctionThread(graphIndex);
-		this.myGraph.setProfiledThreads(threads);
+		gppTrace.setBinaryFunctionThread(graphIndex, adapter, this.myGraph.getProfiledThreads());
 
 		// put check marks on all rows, and sort by sample count
 		threadTable.quickSort(COLUMN_ID_SAMPLE_COUNT, this.myGraph.getProfiledThreads());
@@ -1297,14 +1275,15 @@
 		this.myGraph.repaint();
 	}
 
-	protected Menu getTableMenu(Decorations parent, int graphIndex, int drawMode) {
+	@Override
+	protected Menu getTableMenu(Decorations aParent, int graphIndex, int drawMode) {
 		// get rid of last Menu created so we don't have double menu
 		// on click
 		if (contextMenu != null) {
 			contextMenu.dispose();
 		}
 
-		contextMenu = new Menu(parent, SWT.POP_UP);
+		contextMenu = new Menu(aParent, SWT.POP_UP);
 
 		// Use drawMode to determine the drill down items and
 		// whether to show a color column
@@ -1446,7 +1425,7 @@
 					Vector<ProfiledGeneric> pGeneric = this.myGraph.getProfiledBinaries();
 					int sampleCount = 0;
 					for (int i = 0; i < pGeneric.size(); i++)
-						if (pGeneric.elementAt(i).getTotalSampleCount() < thresholdCount)
+						if (adapter.getTotalSampleCount(pGeneric.elementAt(i)) < thresholdCount)
 							sampleCount += pGeneric.elementAt(i).getSampleCount(graphIndex);
 					this.myGraph.getThresholdBinary().setSampleCount(graphIndex, sampleCount);
 				}
@@ -1472,87 +1451,12 @@
 				return;
 
 			GppTrace trace = (GppTrace)(this.myGraph.getTrace());
-			Vector<ProfiledGeneric> traceBinaries  = trace.getIndexedBinaries();
+			PIEvent be3 = new PIEvent(be.getValueObject(), PIEvent.SELECTION_AREA_CHANGED3);
 
-			int startSampleIndex = trace.getStartSampleIndex();
-			int endSampleIndex   = trace.getEndSampleIndex();
-			double percentPerSample;
-			if (startSampleIndex == endSampleIndex)
-				percentPerSample = 0.0;
-			else
-				percentPerSample = 100.0 / ((double)(endSampleIndex - startSampleIndex));
-
-			PIEvent be3 = new PIEvent(be.getValueObject(), PIEvent.SELECTION_AREA_CHANGED3);
-			
 			switch (drawMode) {
 				case Defines.BINARIES_THREADS:
 				{
-					// get new thread counts and loads
-					Vector<ProfiledGeneric> traceThreads  = trace.getIndexedThreads();
-					Vector<ProfiledGeneric> graphThreads  = this.myGraph.getProfiledThreads();
-					Hashtable<String,String> foundThreads = new Hashtable<String,String>();
-
-					// previous threads are not necessarily graphed this time
-					Enumeration<ProfiledGeneric> enu = graphThreads.elements();
-					while (enu.hasMoreElements()) {
-						ProfiledThread pThread = (ProfiledThread) enu.nextElement();
-						pThread.setEnabled(graphIndex, false);
-					}
-					graphThreads.clear();
-
-					ProfiledThreshold thresholdThread = this.myGraph.getThresholdThread();
-
-					if (thresholdThread.isEnabled(graphIndex)) {
-						ArrayList<ProfiledGeneric> items = thresholdThread.getItems(graphIndex);
-						// disable all items below the threshold
-						for (int i = 0; i < items.size(); i++) {
-							items.get(i).setEnabled(graphIndex, false);
-						}
-					}
-
-					GppSample[] sortedSamples = trace.getSortedGppSamples();
-
-					// set up in case we find threads below the threshold
-					boolean lowThread;
-					thresholdThread.init(graphIndex);
-
-					int threadThreshold = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountThread"); //$NON-NLS-1$
-					for (int i = startSampleIndex; i < endSampleIndex; i++) {
-						GppSample sample = sortedSamples[i];
-
-						ProfiledBinary pBinary = (ProfiledBinary) traceBinaries.elementAt(sample.binaryIndex);
-						if (pBinary.isEnabled(graphIndex)) {
-							// thread list is based on binaries
-							ProfiledThread pThread = (ProfiledThread) traceThreads.elementAt(sample.threadIndex);
-							String threadName = pThread.getNameString();
-
-							lowThread = pThread.getTotalSampleCount() < threadThreshold; 
-
-							if (!foundThreads.containsKey(threadName)) {
-								foundThreads.put(threadName, threadName);
-								if (lowThread) {
-									thresholdThread.addItem(graphIndex, pThread, 1);
-								} else {
-									pThread.setEnabled(graphIndex, true);
-									pThread.setSampleCount(graphIndex, 1);
-									graphThreads.add(pThread);
-								}
-							} else {
-								if (lowThread)
-									thresholdThread.incSampleCount(graphIndex);
-								else
-									pThread.incSampleCount(graphIndex);
-							}
-						}
-					}
-
-					// set the % load
-					for (int i = 0; i < graphThreads.size(); i++) {
-						ProfiledThread pThread = (ProfiledThread) graphThreads.elementAt(i);
-						pThread.setLoadAndString(graphIndex, (float)(pThread.getSampleCount(graphIndex)*percentPerSample));
-					}
-					thresholdThread.setLoadAndString(graphIndex,
-							(float)(thresholdThread.getSampleCount(graphIndex)*percentPerSample));
+					trace.setBinaryThread(graphIndex, adapter, this.myGraph.getProfiledThreads());
 
 					// update the table items and redraw the table
 					this.myGraph.getThreadTable().piEventReceived(be3);
@@ -1560,126 +1464,10 @@
 				}
 				case Defines.BINARIES_THREADS_FUNCTIONS:
 				{
-					// get new counts and loads
-					Vector<ProfiledGeneric> traceThreads    = trace.getIndexedThreads();
-					Vector<ProfiledGeneric> traceFunctions  = trace.getIndexedFunctions();
-					Vector<ProfiledGeneric> graphThreads    = this.myGraph.getProfiledThreads();
-					Vector<ProfiledGeneric> graphFunctions  = this.myGraph.getProfiledFunctions();
-					Hashtable<String,String> foundThreads   = new Hashtable<String,String>();
-					Hashtable<String,String> foundFunctions = new Hashtable<String,String>();
-
-					// previous functions are not necessarily graphed this time
-					Enumeration<ProfiledGeneric> enuFunctions = graphFunctions.elements();
-					while (enuFunctions.hasMoreElements()) {
-						ProfiledFunction pFunction = (ProfiledFunction) enuFunctions.nextElement();
-						pFunction.setEnabled(graphIndex, false);
-					}
-					graphFunctions.clear();
-
-					ProfiledThreshold thresholdFunction = this.myGraph.getThresholdFunction();
-
-					if (thresholdFunction.isEnabled(graphIndex)) {
-						ArrayList<ProfiledGeneric> items = thresholdFunction.getItems(graphIndex);
-						// disable all items below the threshold
-						for (int i = 0; i < items.size(); i++) {
-							items.get(i).setEnabled(graphIndex, false);
-						}
-					}
-
-					// previous threads are not necessarily graphed this time
-					Enumeration<ProfiledGeneric> enuThreads = graphThreads.elements();
-					while (enuThreads.hasMoreElements()) {
-						ProfiledThread pThread = (ProfiledThread) enuThreads.nextElement();
-						pThread.setEnabled(graphIndex, false);
-					}
-					graphThreads.clear();
-
-					ProfiledThreshold thresholdThread = this.myGraph.getThresholdThread();
-
-					if (thresholdThread.isEnabled(graphIndex)) {
-						ArrayList<ProfiledGeneric> items = thresholdThread.getItems(graphIndex);
-						// disable all items below the threshold
-						for (int i = 0; i < items.size(); i++) {
-							items.get(i).setEnabled(graphIndex, false);
-						}
-					}
-
-					GppSample[] sortedSamples = trace.getSortedGppSamples();
-
-					// set up in case we find threads below the threshold
-					boolean lowThread;
-					thresholdThread.init(graphIndex);
-
-					// set up in case we find threads below the threshold
-					boolean lowFunction;
-					thresholdFunction.init(graphIndex);
-
-					int threadThreshold = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountThread"); //$NON-NLS-1$
-					for (int i = startSampleIndex; i < endSampleIndex; i++) {
-						GppSample sample = sortedSamples[i];
-
-						ProfiledBinary pBinary = (ProfiledBinary) traceBinaries.elementAt(sample.binaryIndex);
-						if (pBinary.isEnabled(graphIndex)) {
-							// thread list is based on binaries
-							ProfiledThread pThread = (ProfiledThread) traceThreads.elementAt(sample.threadIndex);
-							String threadName = pThread.getNameString();
-
-							lowThread = pThread.getTotalSampleCount() < threadThreshold;
-
-							if (!foundThreads.containsKey(threadName)) {
-								foundThreads.put(threadName, threadName);
-								if (lowThread) {
-									thresholdThread.addItem(graphIndex, pThread, 1);
-								} else {
-									pThread.setEnabled(graphIndex, true);
-									pThread.setSampleCount(graphIndex, 1);
-									graphThreads.add(pThread);
-								}
-							} else {
-								if (lowThread)
-									thresholdThread.incSampleCount(graphIndex);
-								else
-									pThread.incSampleCount(graphIndex);
-							}
-
-							// function list is based on binaries and threads
-							ProfiledFunction pFunction = (ProfiledFunction) traceFunctions.elementAt(sample.functionIndex);
-							String functionName = pFunction.getNameString();
-
-							lowFunction = pFunction.getTotalSampleCount() < (Integer)NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountFunction"); //$NON-NLS-1$
-
-							if (!foundFunctions.containsKey(functionName)) {
-								foundFunctions.put(functionName, functionName);
-								if (lowFunction) {
-									thresholdFunction.addItem(graphIndex, pFunction, 1);
-								} else {
-									pFunction.setEnabled(graphIndex, true);
-									pFunction.setSampleCount(graphIndex, 1);
-									graphFunctions.add(pFunction);
-								}
-							} else {
-								if (lowFunction)
-									thresholdFunction.incSampleCount(graphIndex);
-								else
-									pFunction.incSampleCount(graphIndex);
-							}
-						}
-					}
-
-					// set the % load
-					for (int i = 0; i < graphThreads.size(); i++) {
-						ProfiledThread pThread = (ProfiledThread) graphThreads.elementAt(i);
-						pThread.setLoadAndString(graphIndex, (float)(pThread.getSampleCount(graphIndex)*percentPerSample));
-					}
-					thresholdThread.setLoadAndString(graphIndex,
-							(float)(thresholdThread.getSampleCount(graphIndex)*percentPerSample));
-
-					for (int i = 0; i < graphFunctions.size(); i++) {
-						ProfiledFunction pFunction = (ProfiledFunction) graphFunctions.elementAt(i);
-						pFunction.setLoadAndString(graphIndex, (float)(pFunction.getSampleCount(graphIndex)*percentPerSample));
-					}
-					thresholdFunction.setLoadAndString(graphIndex,
-							(float)(thresholdFunction.getSampleCount(graphIndex)*percentPerSample));
+					// previous threads are not necessarily graphed this time - reset
+					trace.setBinaryThread(graphIndex, adapter, this.myGraph.getProfiledThreads());
+					// previous functions are not necessarily graphed this time - reset
+					trace.setBinaryThreadFunction(graphIndex, adapter, this.myGraph.getProfiledFunctions());
 
 					// update the table items and redraw the table
 					this.myGraph.getThreadTable().piEventReceived(be3);
@@ -1688,72 +1476,7 @@
 				}
 				case Defines.BINARIES_FUNCTIONS:
 				{
-					// get new function counts and loads
-					Vector<ProfiledGeneric> traceFunctions  = trace.getIndexedFunctions();
-					Vector<ProfiledGeneric> graphFunctions  = this.myGraph.getProfiledFunctions();
-					Hashtable<String,String> foundFunctions = new Hashtable<String,String>();
-
-					// previous functions are not necessarily graphed this time
-					Enumeration<ProfiledGeneric> enu = graphFunctions.elements();
-					while (enu.hasMoreElements()) {
-						ProfiledFunction pFunction = (ProfiledFunction) enu.nextElement();
-						pFunction.setEnabled(graphIndex, false);
-					}
-					graphFunctions.clear();
-
-					ProfiledThreshold thresholdFunction = this.myGraph.getThresholdFunction();
-
-					if (thresholdFunction.isEnabled(graphIndex)) {
-						ArrayList<ProfiledGeneric> items = thresholdFunction.getItems(graphIndex);
-						// disable all items below the threshold
-						for (int i = 0; i < items.size(); i++) {
-							items.get(i).setEnabled(graphIndex, false);
-						}
-					}
-
-					GppSample[] sortedSamples = trace.getSortedGppSamples();
-
-					// set up in case we find functions below the threshold
-					boolean lowFunction;
-					thresholdFunction.init(graphIndex);
-
-					int functionThreshold = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountFunction"); //$NON-NLS-1$
-					for (int i = startSampleIndex; i < endSampleIndex; i++) {
-						GppSample sample = sortedSamples[i];
-
-						ProfiledBinary pBinary = (ProfiledBinary) traceBinaries.elementAt(sample.binaryIndex);
-						if (pBinary.isEnabled(graphIndex)) {
-							// function list is based on binaries
-							ProfiledFunction pFunction = (ProfiledFunction) traceFunctions.elementAt(sample.functionIndex);
-							String functionName = pFunction.getNameString();
-
-							lowFunction = pFunction.getTotalSampleCount() < functionThreshold;
-
-							if (!foundFunctions.containsKey(functionName)) {
-								foundFunctions.put(functionName, functionName);
-								if (lowFunction) {
-									thresholdFunction.addItem(graphIndex, pFunction, 1);
-								} else {
-									pFunction.setEnabled(graphIndex, true);
-									pFunction.setSampleCount(graphIndex, 1);
-									graphFunctions.add(pFunction);
-								}
-							} else {
-								if (lowFunction)
-									thresholdFunction.incSampleCount(graphIndex);
-								else
-									pFunction.incSampleCount(graphIndex);
-							}
-						}
-					}
-
-					// set the % load
-					for (int i = 0; i < graphFunctions.size(); i++) {
-						ProfiledFunction pFunction = (ProfiledFunction) graphFunctions.elementAt(i);
-						pFunction.setLoadAndString(graphIndex, (float)(pFunction.getSampleCount(graphIndex)*percentPerSample));
-					}
-					thresholdFunction.setLoadAndString(graphIndex,
-							(float)(thresholdFunction.getSampleCount(graphIndex)*percentPerSample));
+					trace.setBinaryFunction(graphIndex, adapter, this.myGraph.getProfiledFunctions());
 
 					// update the table items and redraw the table
 					this.myGraph.getFunctionTable().piEventReceived(be3);
@@ -1761,126 +1484,10 @@
 				}
 				case Defines.BINARIES_FUNCTIONS_THREADS:
 				{
-					// get new function and thread counts and loads
-					Vector<ProfiledGeneric> traceThreads    = trace.getIndexedThreads();
-					Vector<ProfiledGeneric> traceFunctions  = trace.getIndexedFunctions();
-					Vector<ProfiledGeneric> graphThreads    = this.myGraph.getProfiledThreads();
-					Vector<ProfiledGeneric> graphFunctions  = this.myGraph.getProfiledFunctions();
-					Hashtable<String,String> foundThreads   = new Hashtable<String,String>();
-					Hashtable<String,String> foundFunctions = new Hashtable<String,String>();
-
-					// previous threads are not necessarily graphed this time
-					Enumeration<ProfiledGeneric> enuThreads = graphThreads.elements();
-					while (enuThreads.hasMoreElements()) {
-						ProfiledThread pThread = (ProfiledThread) enuThreads.nextElement();
-						pThread.setEnabled(graphIndex, false);
-					}
-					graphThreads.clear();
-
-					ProfiledThreshold thresholdThread = this.myGraph.getThresholdThread();
-
-					if (thresholdThread.isEnabled(graphIndex)) {
-						ArrayList<ProfiledGeneric> items = thresholdThread.getItems(graphIndex);
-						// disable all items below the threshold
-						for (int i = 0; i < items.size(); i++) {
-							items.get(i).setEnabled(graphIndex, false);
-						}
-					}
-
-					// previous functions are not necessarily graphed this time
-					Enumeration<ProfiledGeneric> enuFunctions = graphFunctions.elements();
-					while (enuFunctions.hasMoreElements()) {
-						ProfiledFunction pFunction = (ProfiledFunction) enuFunctions.nextElement();
-						pFunction.setEnabled(graphIndex, false);
-					}
-					graphFunctions.clear();
-
-					ProfiledThreshold thresholdFunction = this.myGraph.getThresholdFunction();
-
-					if (thresholdFunction.isEnabled(graphIndex)) {
-						ArrayList<ProfiledGeneric> items = thresholdFunction.getItems(graphIndex);
-						// disable all items below the threshold
-						for (int i = 0; i < items.size(); i++) {
-							items.get(i).setEnabled(graphIndex, false);
-						}
-					}
-
-					GppSample[] sortedSamples = trace.getSortedGppSamples();
-
-					// set up in case we find threads below the threshold
-					boolean lowThread;
-					thresholdThread.init(graphIndex);
-
-					// set up in case we find functions below the threshold
-					boolean lowFunction;
-					thresholdFunction.init(graphIndex);
-
-					int functionThreshold = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountFunction"); //$NON-NLS-1$
-					for (int i = startSampleIndex; i < endSampleIndex; i++) {
-						GppSample sample = sortedSamples[i];
-
-						ProfiledBinary pBinary = (ProfiledBinary) traceBinaries.elementAt(sample.binaryIndex);
-						if (pBinary.isEnabled(graphIndex)) {
-							// function list is based on binaries
-							ProfiledFunction pFunction = (ProfiledFunction) traceFunctions.elementAt(sample.functionIndex);
-							String functionName = pFunction.getNameString();
-
-							lowFunction = pFunction.getTotalSampleCount() < functionThreshold;
-
-							if (!foundFunctions.containsKey(functionName)) {
-								foundFunctions.put(functionName, functionName);
-								if (lowFunction) {
-									thresholdFunction.addItem(graphIndex, pFunction, 1);
-								} else {
-									pFunction.setEnabled(graphIndex, true);
-									pFunction.setSampleCount(graphIndex, 1);
-									graphFunctions.add(pFunction);
-								}
-							} else {
-								if (lowFunction)
-									thresholdFunction.incSampleCount(graphIndex);
-								else
-									pFunction.incSampleCount(graphIndex);
-							}
-
-							// thread list is based on binaries and functions
-							ProfiledThread pThread = (ProfiledThread) traceThreads.elementAt(sample.threadIndex);
-							String threadName = pThread.getNameString();
-
-							lowThread = pThread.getTotalSampleCount() < (Integer)NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountThread"); //$NON-NLS-1$
-
-							if (!foundThreads.containsKey(threadName)) {
-								foundThreads.put(threadName, threadName);
-								if (lowThread) {
-									thresholdThread.addItem(graphIndex, pThread, 1);
-								} else {
-									pThread.setEnabled(graphIndex, true);
-									pThread.setSampleCount(graphIndex, 1);
-									graphThreads.add(pThread);
-								}
-							} else {
-								if (lowThread)
-									thresholdThread.incSampleCount(graphIndex);
-								else
-									pThread.incSampleCount(graphIndex);
-							}
-						}
-					}
-
-					// set the % load
-					for (int i = 0; i < graphThreads.size(); i++) {
-						ProfiledThread pThread = (ProfiledThread) graphThreads.elementAt(i);
-						pThread.setLoadAndString(graphIndex, (float)(pThread.getSampleCount(graphIndex)*percentPerSample));
-					}
-					thresholdThread.setLoadAndString(graphIndex,
-							(float)(thresholdThread.getSampleCount(graphIndex)*percentPerSample));
-
-					for (int i = 0; i < graphFunctions.size(); i++) {
-						ProfiledFunction pFunction = (ProfiledFunction) graphFunctions.elementAt(i);
-						pFunction.setLoadAndString(graphIndex, (float)(pFunction.getSampleCount(graphIndex)*percentPerSample));
-					}
-					thresholdFunction.setLoadAndString(graphIndex,
-							(float)(thresholdFunction.getSampleCount(graphIndex)*percentPerSample));
+					// previous functions are not necessarily graphed this time - reset
+					trace.setBinaryFunction(graphIndex, adapter, this.myGraph.getProfiledFunctions());
+					// previous threads are not necessarily graphed this time - reset
+					trace.setBinaryFunctionThread(graphIndex, adapter, this.myGraph.getProfiledThreads());
 
 					// update the table items and redraw the table
 					this.myGraph.getThreadTable().piEventReceived(be3);
@@ -1903,86 +1510,10 @@
 
 			// we don't need to redraw the binary table, since it has not changed
 
+			PIEvent be3 = new PIEvent(be.getValueObject(), PIEvent.SELECTION_AREA_CHANGED3);
 			GppTrace trace = (GppTrace)(this.myGraph.getTrace());
-			Vector<ProfiledGeneric> traceThreads = trace.getIndexedThreads();
-
 			int graphIndex = this.myGraph.getGraphIndex();
-			int startSampleIndex = trace.getStartSampleIndex();
-			int endSampleIndex   = trace.getEndSampleIndex();
-			double percentPerSample;
-			if (startSampleIndex == endSampleIndex)
-				percentPerSample = 0.0;
-			else
-				percentPerSample = 100.0 / ((double)(endSampleIndex - startSampleIndex));
-
-			PIEvent be3 = new PIEvent(be.getValueObject(), PIEvent.SELECTION_AREA_CHANGED3);
-
-			// get new function counts and loads
-			Vector<ProfiledGeneric> traceFunctions  = trace.getIndexedFunctions();
-			Vector<ProfiledGeneric> graphFunctions  = this.myGraph.getProfiledFunctions();
-			Hashtable<String,String> foundFunctions = new Hashtable<String,String>();
-
-			// previous functions are not necessarily graphed this time
-			Enumeration<ProfiledGeneric> enu = graphFunctions.elements();
-			while (enu.hasMoreElements()) {
-				ProfiledFunction pFunction = (ProfiledFunction) enu.nextElement();
-				pFunction.setEnabled(graphIndex, false);
-			}
-			graphFunctions.clear();
-
-			ProfiledThreshold thresholdFunction = this.myGraph.getThresholdFunction();
-
-			if (thresholdFunction.isEnabled(graphIndex)) {
-				ArrayList<ProfiledGeneric> items = thresholdFunction.getItems(graphIndex);
-				// disable all items below the threshold
-				for (int i = 0; i < items.size(); i++) {
-					items.get(i).setEnabled(graphIndex, false);
-				}
-			}
-
-			GppSample[] sortedSamples = trace.getSortedGppSamples();
-
-			// set up in case we find functions below the threshold
-			boolean lowFunction;
-			thresholdFunction.init(graphIndex);
-
-			int functionThreshold = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountFunction"); //$NON-NLS-1$
-			for (int i = startSampleIndex; i < endSampleIndex; i++) {
-				GppSample sample = sortedSamples[i];
-
-				ProfiledThread pThread = (ProfiledThread) traceThreads.elementAt(sample.threadIndex);
-				if (pThread.isEnabled(graphIndex)) {
-					// function list is based on threads
-					ProfiledFunction pFunction = (ProfiledFunction) traceFunctions.elementAt(sample.functionIndex);
-					String functionName = pFunction.getNameString();
-
-					lowFunction = pFunction.getTotalSampleCount() < functionThreshold;
-
-					if (!foundFunctions.containsKey(functionName)) {
-						foundFunctions.put(functionName, functionName);
-						if (lowFunction) {
-							thresholdFunction.addItem(graphIndex, pFunction, 1);
-						} else {
-							pFunction.setEnabled(graphIndex, true);
-							pFunction.setSampleCount(graphIndex, 1);
-							graphFunctions.add(pFunction);
-						}
-					} else {
-						if (lowFunction)
-							thresholdFunction.incSampleCount(graphIndex);
-						else
-							pFunction.incSampleCount(graphIndex);
-					}
-				}
-			}
-
-			// set the % load
-			for (int i = 0; i < graphFunctions.size(); i++) {
-				ProfiledFunction pFunction = (ProfiledFunction) graphFunctions.elementAt(i);
-				pFunction.setLoadAndString(graphIndex, (float)(pFunction.getSampleCount(graphIndex)*percentPerSample));
-			}
-			thresholdFunction.setLoadAndString(graphIndex,
-											(float)(thresholdFunction.getSampleCount(graphIndex)*percentPerSample));
+			trace.setBinaryThreadFunction(graphIndex, adapter, this.myGraph.getProfiledFunctions());
 			
 			// update the table items and redraw the table
 			this.myGraph.getFunctionTable().piEventReceived(be3);
@@ -1997,86 +1528,10 @@
 
 			// we don't need to redraw the binary table, since it has not changed
 
+			PIEvent be3 = new PIEvent(be.getValueObject(), PIEvent.SELECTION_AREA_CHANGED3);
 			GppTrace trace = (GppTrace)(this.myGraph.getTrace());
-			Vector<ProfiledGeneric> traceFunctions = trace.getIndexedFunctions();
-
 			int graphIndex = this.myGraph.getGraphIndex();
-			int startSampleIndex = trace.getStartSampleIndex();
-			int endSampleIndex   = trace.getEndSampleIndex();
-			double percentPerSample;
-			if (startSampleIndex == endSampleIndex)
-				percentPerSample = 0.0;
-			else
-				percentPerSample = 100.0 / ((double)(endSampleIndex - startSampleIndex));
-
-			PIEvent be3 = new PIEvent(be.getValueObject(), PIEvent.SELECTION_AREA_CHANGED3);
-
-			// get new thread counts and loads
-			Vector<ProfiledGeneric> traceThreads  = trace.getIndexedThreads();
-			Vector<ProfiledGeneric> graphThreads  = this.myGraph.getProfiledThreads();
-			Hashtable<String,String> foundThreads = new Hashtable<String,String>();
-
-			// previous threads are not necessarily graphed this time
-			Enumeration<ProfiledGeneric> enu = graphThreads.elements();
-			while (enu.hasMoreElements()) {
-				ProfiledThread pThread = (ProfiledThread) enu.nextElement();
-				pThread.setEnabled(graphIndex, false);
-			}
-			graphThreads.clear();
-
-			ProfiledThreshold thresholdThread = this.myGraph.getThresholdThread();
-
-			if (thresholdThread.isEnabled(graphIndex)) {
-				ArrayList<ProfiledGeneric> items = thresholdThread.getItems(graphIndex);
-				// disable all items below the threshold
-				for (int i = 0; i < items.size(); i++) {
-					items.get(i).setEnabled(graphIndex, false);
-				}
-			}
-
-			GppSample[] sortedSamples = trace.getSortedGppSamples();
-
-			// set up in case we find threads below the threshold
-			boolean lowThread;
-			thresholdThread.init(graphIndex);
-
-			int threadThreshold = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountThread"); //$NON-NLS-1$
-			for (int i = startSampleIndex; i < endSampleIndex; i++) {
-				GppSample sample = sortedSamples[i];
-
-				ProfiledFunction pFunction = (ProfiledFunction) traceFunctions.elementAt(sample.functionIndex);
-				if (pFunction.isEnabled(graphIndex)) {
-					// thread list is based on functions
-					ProfiledThread pThread = (ProfiledThread) traceThreads.elementAt(sample.threadIndex);
-					String threadName = pThread.getNameString();
-
-					lowThread = pThread.getTotalSampleCount() < threadThreshold;
-
-					if (!foundThreads.containsKey(threadName)) {
-						foundThreads.put(threadName, threadName);
-						if (lowThread) {
-							thresholdThread.addItem(graphIndex, pThread, 1);
-						} else {
-							pThread.setEnabled(graphIndex, true);
-							pThread.setSampleCount(graphIndex, 1);
-							graphThreads.add(pThread);
-						}
-					} else {
-						if (lowThread)
-							thresholdThread.incSampleCount(graphIndex);
-						else
-							pThread.incSampleCount(graphIndex);
-					}
-				}
-			}
-
-			// set the % load
-			for (int i = 0; i < graphThreads.size(); i++) {
-				ProfiledThread pThread = (ProfiledThread) graphThreads.elementAt(i);
-				pThread.setLoadAndString(graphIndex, (float)(pThread.getSampleCount(graphIndex)*percentPerSample));
-			}
-			thresholdThread.setLoadAndString(graphIndex,
-					(float)(thresholdThread.getSampleCount(graphIndex)*percentPerSample));
+			trace.setFunctionBinaryThread(graphIndex, adapter, this.myGraph.getProfiledThreads());
 
 			// update the table items and redraw the table
 			this.myGraph.getThreadTable().piEventReceived(be3);
@@ -2165,6 +1620,7 @@
 
 	private class ColumnSelectionHandler extends SelectionAdapter
 	{
+		@Override
 		public void widgetSelected(SelectionEvent e)
         {
         	// wait for the previous sort to finish
@@ -2175,6 +1631,15 @@
         }
 	}
 
+	/**
+	 * Adds ProfiledGenerics and threshold items to the table data
+	 * (this.tableItemData and this.profiledThreads). Sorts the ProfiledGenerics
+	 * according to load; and sets the graph's sorted list accordingly. Refreshes
+	 * the TableViewer if parameter setInput is true.
+	 * 
+	 * @param setInput
+	 *            if true, reset the TableViewer
+	 */
 	public void updateProfiledAndItemData(boolean setInput)
 	{
 		tableItemData.clear();
@@ -2189,7 +1654,7 @@
 			profiledBinaries.add(nextElement);
 		}
 
-		if (myGraph.getThresholdBinary().getItemCount(myGraph.getGraphIndex()) != 0) {
+		if (myGraph.getThresholdBinary().getItemCount() != 0) {
 			tableItemData.add(myGraph.getThresholdBinary());
 			profiledBinaries.add(myGraph.getThresholdBinary());
 		}
@@ -2201,17 +1666,16 @@
 			public int compare(Object arg0, Object arg1)
 			{
 				if (arg0 instanceof ProfiledGeneric && arg1 instanceof ProfiledGeneric)
-					return ((ProfiledGeneric)arg0).getTotalSampleCount() -
-							((ProfiledGeneric)arg1).getTotalSampleCount();
-				else
-					return 0;
+					return (adapter.getTotalSampleCount((ProfiledGeneric)arg0)) -
+							(adapter.getTotalSampleCount((ProfiledGeneric)arg1));
+				return 0;
 			}
 		});
 
 		// now create the sorted list used to draw the graph
 		myGraph.getSortedBinaries().clear();
 
-		if (myGraph.getThresholdBinary().getItemCount(myGraph.getGraphIndex()) != 0)
+		if (myGraph.getThresholdBinary().getItemCount() != 0)
 			myGraph.getSortedBinaries().add(myGraph.getThresholdBinary());
 
 		for (int i = 0; i < sorted.length; i++)
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/pi/address/AddrFunctionTable.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/pi/address/AddrFunctionTable.java	Wed Apr 21 15:14:16 2010 +0300
@@ -26,7 +26,6 @@
 import java.util.Arrays;
 import java.util.Comparator;
 import java.util.Enumeration;
-import java.util.Hashtable;
 import java.util.Vector;
 
 import org.eclipse.jface.viewers.CheckStateChangedEvent;
@@ -58,12 +57,11 @@
 import org.eclipse.swt.widgets.TableColumn;
 import org.eclipse.swt.widgets.TableItem;
 
+import com.nokia.carbide.cpp.internal.pi.address.GppModelAdapter;
 import com.nokia.carbide.cpp.internal.pi.analyser.NpiInstanceRepository;
 import com.nokia.carbide.cpp.internal.pi.analyser.ProfileVisualiser;
-import com.nokia.carbide.cpp.internal.pi.model.ProfiledBinary;
 import com.nokia.carbide.cpp.internal.pi.model.ProfiledFunction;
 import com.nokia.carbide.cpp.internal.pi.model.ProfiledGeneric;
-import com.nokia.carbide.cpp.internal.pi.model.ProfiledThread;
 import com.nokia.carbide.cpp.internal.pi.model.ProfiledThreshold;
 import com.nokia.carbide.cpp.internal.pi.visual.Defines;
 import com.nokia.carbide.cpp.internal.pi.visual.PIEvent;
@@ -79,10 +77,9 @@
 	// without affecting the original
 	Vector<ProfiledGeneric> profiledFunctions = new Vector<ProfiledGeneric>();
 
-	public AddrFunctionTable(GppTraceGraph myGraph, Composite parent)
+	public AddrFunctionTable(GppTraceGraph myGraph, Composite parent, GppModelAdapter adapter)
 	{
-		this.myGraph = myGraph;
-		this.parent  = parent;
+		super(myGraph, parent, adapter);
 	}
 
 	public void createTableViewer(int drawMode)
@@ -165,7 +162,7 @@
 		column = new TableColumn(table, SWT.CENTER);
 		column.setText(COLUMN_HEAD_SHOW);
 		column.setWidth(COLUMN_WIDTH_SHOW);
-		column.setData(new Integer(COLUMN_ID_SHOW));
+		column.setData(Integer.valueOf(COLUMN_ID_SHOW));
 		column.setMoveable(true);
 		column.setResizable(true);
 		column.addSelectionListener(new ColumnSelectionHandler());
@@ -174,7 +171,7 @@
 		column = new TableColumn(table, SWT.RIGHT);
 		column.setText(COLUMN_HEAD_PERCENT_LOAD);
 		column.setWidth(COLUMN_WIDTH_PERCENT_LOAD);
-		column.setData(new Integer(COLUMN_ID_PERCENT_LOAD));
+		column.setData(Integer.valueOf(COLUMN_ID_PERCENT_LOAD));
 		column.setMoveable(true);
 		column.setResizable(true);
 		column.addSelectionListener(new ColumnSelectionHandler());
@@ -183,7 +180,7 @@
 		column = new TableColumn(table, SWT.LEFT);
 		column.setText(COLUMN_HEAD_FUNCTION);
 		column.setWidth(COLUMN_WIDTH_FUNCTION_NAME);
-		column.setData(new Integer(COLUMN_ID_FUNCTION));
+		column.setData(Integer.valueOf(COLUMN_ID_FUNCTION));
 		column.setMoveable(true);
 		column.setResizable(true);
 		column.addSelectionListener(new ColumnSelectionHandler());
@@ -192,7 +189,7 @@
 		column = new TableColumn(table, SWT.CENTER);
 		column.setText(COLUMN_HEAD_START_ADDR);
 		column.setWidth(COLUMN_WIDTH_START_ADDRESS);
-		column.setData(new Integer(COLUMN_ID_START_ADDR));
+		column.setData(Integer.valueOf(COLUMN_ID_START_ADDR));
 		column.setMoveable(true);
 		column.setResizable(true);
 		column.addSelectionListener(new ColumnSelectionHandler());
@@ -201,7 +198,7 @@
 		column = new TableColumn(table, SWT.LEFT);
 		column.setText(COLUMN_HEAD_IN_BINARY);
 		column.setWidth(COLUMN_WIDTH_IN_BINARY);
-		column.setData(new Integer(COLUMN_ID_IN_BINARY));
+		column.setData(Integer.valueOf(COLUMN_ID_IN_BINARY));
 		column.setMoveable(true);
 		column.setResizable(true);
 		column.addSelectionListener(new ColumnSelectionHandler());
@@ -210,7 +207,7 @@
 		column = new TableColumn(table, SWT.LEFT);
 		column.setText(COLUMN_HEAD_IN_BINARY_PATH);
 		column.setWidth(COLUMN_WIDTH_IN_BINARY_PATH);
-		column.setData(new Integer(COLUMN_ID_IN_BINARY_PATH));
+		column.setData(Integer.valueOf(COLUMN_ID_IN_BINARY_PATH));
 		column.setMoveable(true);
 		column.setResizable(true);
 		column.addSelectionListener(new ColumnSelectionHandler());
@@ -219,7 +216,7 @@
 		column = new TableColumn(table, SWT.CENTER);
 		column.setText(COLUMN_HEAD_SAMPLE_COUNT);
 		column.setWidth(COLUMN_WIDTH_SAMPLE_COUNT);
-		column.setData(new Integer(COLUMN_ID_SAMPLE_COUNT));
+		column.setData(Integer.valueOf(COLUMN_ID_SAMPLE_COUNT));
 		column.setMoveable(true);
 		column.setResizable(true);
 		column.addSelectionListener(new ColumnSelectionHandler());
@@ -338,7 +335,7 @@
 		}
 
 		public Object[] getElements(Object inputElement) {
-			return ((Vector) inputElement).toArray();
+			return ((Vector<?>) inputElement).toArray();
 		}
 
 		public void dispose() {
@@ -354,6 +351,9 @@
 			super();
 		}
 
+		/* (non-Javadoc)
+		 * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java.lang.Object, int)
+		 */
 		public String getColumnText(Object element, int columnIndex) {
 			int columnId = ((Integer) table.getColumn(columnIndex).getData()).intValue();
 
@@ -387,7 +387,7 @@
 					case COLUMN_ID_FUNCTION:
 					{
 						DecimalFormat timeFormat = new DecimalFormat(Messages.getString("AddrFunctionTable.decimalFormat")); //$NON-NLS-1$
-						int count = pThreshold.getItemCount(myGraph.getGraphIndex());
+						int count = pThreshold.getItemCount();
 
 						return count + (count > 1 ? Messages.getString("AddrFunctionTable.threshold1") : Messages.getString("AddrFunctionTable.threshold2"))   //$NON-NLS-1$ //$NON-NLS-2$
 								+ timeFormat.format((Double)NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdLoadThread") * 100.0) + Messages.getString("AddrFunctionTable.threshold3")  //$NON-NLS-1$ //$NON-NLS-2$
@@ -470,7 +470,8 @@
 		}
 	}
 
-    public void action(String actionString)
+    @Override
+	public void action(String actionString)
 	{
 		int graphIndex = this.myGraph.getGraphIndex();
 
@@ -597,9 +598,9 @@
 			this.tableItemData.clear();
 			this.profiledFunctions.clear();
 			this.myGraph.getSortedFunctions().clear();
-			if (threshold.getItems(graphIndex) != null)
-				threshold.getItems(graphIndex).clear();
-			threshold.initAll();
+			if (threshold.getItems() != null)
+				threshold.getItems().clear();
+			adapter.init(threshold, graphIndex);
 
 			// if this appears, it needs to be the first item, so that it is drawn at the bottom
 			myGraph.getSortedFunctions().add(threshold);
@@ -607,9 +608,9 @@
 			int functionThreshold = (Integer)NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountFunction"); //$NON-NLS-1$
 			for (int i = 0; i < this.myGraph.getGppTrace().getSortedFunctions().size(); i++) {
 				ProfiledGeneric nextElement = (ProfiledGeneric)this.myGraph.getGppTrace().getSortedFunctions().get(i);
-				if (nextElement.getTotalSampleCount() < functionThreshold) {
+				if (adapter.getTotalSampleCount(nextElement) < functionThreshold) {
 					nextElement.setEnabled(graphIndex, enabled);
-					threshold.addItem(graphIndex, nextElement, 0);
+					adapter.addItem(threshold, graphIndex, nextElement, 0);
 				} else {
 					tableItemData.add(nextElement);
 					profiledFunctions.add(nextElement);
@@ -617,7 +618,7 @@
 				}
 			}
 
-			if (threshold.getItemCount(graphIndex) != 0) {
+			if (threshold.getItemCount() != 0) {
 				tableItemData.add(threshold);
 				profiledFunctions.add(threshold);
 			} else {
@@ -695,9 +696,8 @@
    				if (item instanceof ProfiledThreshold)
    				{
    					ProfiledThreshold pThreshold = (ProfiledThreshold)item;
-   					ArrayList<ProfiledGeneric> items = pThreshold.getItems(graphIndex);
-   					for (int j = 0; j < items.size(); j++)
-   						items.get(j).setEnabled(graphIndex, addIt);
+   					for (ProfiledGeneric p : pThreshold.getItems())
+   						p.setEnabled(graphIndex, addIt);
    				}
 			}
 		}
@@ -748,9 +748,8 @@
    				if (item instanceof ProfiledThreshold)
    				{
    					ProfiledThreshold pThreshold = (ProfiledThreshold)item;
-   					ArrayList<ProfiledGeneric> items = pThreshold.getItems(graphIndex);
-   					for (int j = 0; j < items.size(); j++)
-   						items.get(j).setEnabled(graphIndex, addIt);
+   					for (ProfiledGeneric p : pThreshold.getItems())
+   						p.setEnabled(graphIndex, addIt);
    				}
 			}
 		}
@@ -795,10 +794,16 @@
 						pGeneric.setColor(color);
 					}
 					else {
-						// for the threshold item, we must change every graph's function threshold item
-						gppTrace.getGppGraph(PIPageEditor.THREADS_PAGE,   uid).getThresholdFunction().setColor(color);
-						gppTrace.getGppGraph(PIPageEditor.BINARIES_PAGE,  uid).getThresholdFunction().setColor(color);
-						gppTrace.getGppGraph(PIPageEditor.FUNCTIONS_PAGE, uid).getThresholdFunction().setColor(color);
+						// for the threshold item, we must change every graph's thread threshold item
+						// CH: refactor! This could be done via an observer pattern. This class should not have knowledge of all other graphs  
+						gppTrace.getGppGraph(PIPageEditor.THREADS_PAGE,   uid).getThresholdThread().setColor(color);
+						gppTrace.getGppGraph(PIPageEditor.BINARIES_PAGE,  uid).getThresholdThread().setColor(color);
+						gppTrace.getGppGraph(PIPageEditor.FUNCTIONS_PAGE, uid).getThresholdThread().setColor(color);
+//						if (gppTrace.getCPUCount() > 1){ //SMP CH: comment this out once we have SMP graphs on the functions page
+//							for (int cpu = 0; cpu < gppTrace.getCPUCount(); cpu++) {
+//								gppTrace.getGppGraph(11 + cpu, uid).getThresholdThread().setColor(color);															
+//							}
+//						}
 					}
 				}
 
@@ -816,7 +821,7 @@
 		
 		// if any other tabs are displaying this type of graph, they need to be scheduled for redrawing
 		for (int i = 0; i < 3; i++) {
-			GppTraceGraph graph = gppTrace.getGppGraph(i, uid);
+			IGppTraceGraph graph = gppTrace.getGppGraph(i, uid);
 
 			if (graph == this.myGraph)
 				continue;
@@ -852,11 +857,6 @@
 
 		setIsDrilldown(false);
 
-		// set the page's graph title
-		ProfileVisualiser pV =  NpiInstanceRepository.getInstance().getProfilePage(this.myGraph.getUid(), this.myGraph.getGraphIndex());
-		pV.getTitle().setText(Messages.getString("AddrFunctionTable.functionLoad"));  //$NON-NLS-1$
-		pV.getTitle2().setText(""); //$NON-NLS-1$
-
 		// get rid of any existing tables and sashes
 		if (this.myGraph.getLeftSash() != null) {
 			this.myGraph.getLeftSash().dispose();
@@ -909,10 +909,6 @@
 		setIsDrilldown(true);
 
 		if (drawMode == Defines.FUNCTIONS) {
-			// set the page's graph title
-			ProfileVisualiser pV =  NpiInstanceRepository.getInstance().getProfilePage(this.myGraph.getUid(), this.myGraph.getGraphIndex());
-			pV.getTitle().setText(Messages.getString("AddrFunctionTable.binaryLoad"));  //$NON-NLS-1$
-			pV.getTitle2().setText(Messages.getString("AddrFunctionTable.functionTo"));  //$NON-NLS-1$
 
 			// set the draw mode
 			this.myGraph.setDrawMode(Defines.FUNCTIONS_BINARIES);
@@ -924,8 +920,7 @@
 
 			// create a reduced set of binary entries based on enabled function entries
 			GppTrace gppTrace = (GppTrace) this.myGraph.getTrace();
-			Vector<ProfiledGeneric> binaries = gppTrace.setFunctionBinary(graphIndex);
-			this.myGraph.setProfiledBinaries(binaries);
+			gppTrace.setFunctionBinary(graphIndex, adapter, this.myGraph.getProfiledBinaries());
 
 			// put check marks on all rows, and sort by sample count
 			binaryTable.quickSort(COLUMN_ID_SAMPLE_COUNT, this.myGraph.getProfiledBinaries());
@@ -933,6 +928,13 @@
 			binaryTable.getTableViewer().setAllChecked(true);
 			binaryTable.getTableViewer().refresh();
 
+			// put check marks on all enabled binary rows
+			for (int i = 0; i < this.table.getItemCount(); i++) {
+				ProfiledGeneric pFunction = (ProfiledGeneric) this.table.getItem(i).getData();
+				if (pFunction.isEnabled(graphIndex))
+					this.table.getItem(i).setChecked(true);
+			}
+
 			// remove colors where appropriate
 			removeColor(Defines.FUNCTIONS_BINARIES);
 
@@ -977,10 +979,6 @@
 			this.myGraph.repaint();
 
 		} else if (drawMode == Defines.FUNCTIONS_BINARIES_THREADS) {
-			// set the page's graph title
-			ProfileVisualiser pV =  NpiInstanceRepository.getInstance().getProfilePage(this.myGraph.getUid(), this.myGraph.getGraphIndex());
-			pV.getTitle().setText(Messages.getString("AddrFunctionTable.binaryLoad"));  //$NON-NLS-1$
-			pV.getTitle2().setText(Messages.getString("AddrFunctionTable.functionTo"));  //$NON-NLS-1$
 
 			// get rid of the thread table and its sash
 			if (this.myGraph.getRightSash() != null) {
@@ -1035,11 +1033,6 @@
 
 		setIsDrilldown(true);
 
-		// set the page's graph title
-		ProfileVisualiser pV =  NpiInstanceRepository.getInstance().getProfilePage(this.myGraph.getUid(), this.myGraph.getGraphIndex());
-		pV.getTitle().setText(Messages.getString("AddrFunctionTable.threadLoad"));  //$NON-NLS-1$
-		pV.getTitle2().setText(Messages.getString("AddrFunctionTable.functionToBinaryTo"));  //$NON-NLS-1$
-
 		// set the draw mode
 		this.myGraph.setDrawMode(Defines.FUNCTIONS_BINARIES_THREADS);
 
@@ -1050,8 +1043,7 @@
 
 		// create a reduced set of thread entries based on enabled binary and function entries
 		GppTrace gppTrace = (GppTrace) this.myGraph.getTrace();
-		Vector<ProfiledGeneric> threads = gppTrace.setFunctionBinaryThread(graphIndex);
-		this.myGraph.setProfiledThreads(threads);
+		gppTrace.setFunctionBinaryThread(graphIndex, adapter, this.myGraph.getProfiledThreads());
 
 		// put check marks on all rows, and sort by sample count
 		threadTable.quickSort(COLUMN_ID_SAMPLE_COUNT, this.myGraph.getProfiledThreads());
@@ -1124,10 +1116,6 @@
 		setIsDrilldown(true);
 
 		if (drawMode == Defines.FUNCTIONS) {
-			// set the page's graph title
-			ProfileVisualiser pV =  NpiInstanceRepository.getInstance().getProfilePage(this.myGraph.getUid(), this.myGraph.getGraphIndex());
-			pV.getTitle().setText(Messages.getString("AddrFunctionTable.threadLoad"));  //$NON-NLS-1$
-			pV.getTitle2().setText(Messages.getString("AddrFunctionTable.functionTo"));  //$NON-NLS-1$
 
 			// set the draw mode
 			this.myGraph.setDrawMode(Defines.FUNCTIONS_THREADS);
@@ -1139,8 +1127,7 @@
 
 			// create a reduced set of thread entries based on enabled function entries
 			GppTrace gppTrace = (GppTrace) this.myGraph.getTrace();
-			Vector<ProfiledGeneric> threads = gppTrace.setFunctionThread(graphIndex);
-			this.myGraph.setProfiledThreads(threads);
+			gppTrace.setFunctionThread(graphIndex, adapter, this.myGraph.getProfiledThreads());
 
 			// put check marks on all rows, and sort by sample count
 			threadTable.quickSort(COLUMN_ID_SAMPLE_COUNT, this.myGraph.getProfiledThreads());
@@ -1192,10 +1179,6 @@
 			this.myGraph.repaint();
 
 		} else if (drawMode == Defines.FUNCTIONS_THREADS_BINARIES) {
-			// set the page's graph title
-			ProfileVisualiser pV =  NpiInstanceRepository.getInstance().getProfilePage(this.myGraph.getUid(), this.myGraph.getGraphIndex());
-			pV.getTitle().setText(Messages.getString("AddrFunctionTable.threadLoad"));  //$NON-NLS-1$
-			pV.getTitle2().setText(Messages.getString("AddrFunctionTable.functionTo"));  //$NON-NLS-1$
 
 			// get rid of the binary table and its sash
 			if (this.myGraph.getRightSash() != null) {
@@ -1250,11 +1233,6 @@
 
 		setIsDrilldown(true);
 
-		// set the page's graph title
-		ProfileVisualiser pV =  NpiInstanceRepository.getInstance().getProfilePage(this.myGraph.getUid(), this.myGraph.getGraphIndex());
-		pV.getTitle().setText(Messages.getString("AddrFunctionTable.binaryLoad"));  //$NON-NLS-1$
-		pV.getTitle2().setText(Messages.getString("AddrFunctionTable.functionToThreadTo"));  //$NON-NLS-1$
-
 		// set the draw mode
 		this.myGraph.setDrawMode(Defines.FUNCTIONS_THREADS_BINARIES);
 
@@ -1265,8 +1243,7 @@
 
 		// create a reduced set of binary entries based on enabled thread entries
 		GppTrace gppTrace = (GppTrace) this.myGraph.getTrace();
-		Vector<ProfiledGeneric> binaries = gppTrace.setFunctionThreadBinary(graphIndex);
-		this.myGraph.setProfiledBinaries(binaries);
+		gppTrace.setFunctionThreadBinary(graphIndex, adapter, this.myGraph.getProfiledBinaries());
 
 		// put check marks on all rows, and sort by sample count
 		binaryTable.quickSort(COLUMN_ID_SAMPLE_COUNT, this.myGraph.getProfiledBinaries());
@@ -1378,7 +1355,7 @@
 					Vector<ProfiledGeneric> pGeneric = this.myGraph.getProfiledFunctions();
 					int sampleCount = 0;
 					for (int i = 0; i < pGeneric.size(); i++)
-						if (pGeneric.elementAt(i).getTotalSampleCount() < thresholdCount)
+						if (adapter.getTotalSampleCount(pGeneric.elementAt(i)) < thresholdCount)
 							sampleCount += pGeneric.elementAt(i).getSampleCount(graphIndex);
 					this.myGraph.getThresholdFunction().setSampleCount(graphIndex, sampleCount);
 				}
@@ -1404,86 +1381,12 @@
 				return;
 
 			GppTrace trace = (GppTrace)(this.myGraph.getTrace());
-			Vector<ProfiledGeneric> traceFunctions = trace.getIndexedFunctions();
-
-			int startSampleIndex = trace.getStartSampleIndex();
-			int endSampleIndex   = trace.getEndSampleIndex();
-			double percentPerSample;
-			if (startSampleIndex == endSampleIndex)
-				percentPerSample = 0.0;
-			else
-				percentPerSample = 100.0 / ((double)(endSampleIndex - startSampleIndex));
-
 			PIEvent be3 = new PIEvent(be.getValueObject(), PIEvent.SELECTION_AREA_CHANGED3);
 
 			switch (drawMode) {
 				case Defines.FUNCTIONS_THREADS:
 				{
-					// get new thread counts and loads
-					Vector<ProfiledGeneric> traceThreads  = trace.getIndexedThreads();
-					Vector<ProfiledGeneric> graphThreads  = this.myGraph.getProfiledThreads();
-					Hashtable<String,String> foundThreads = new Hashtable<String,String>();
-
-					// previous threads are not necessarily graphed this time
-					Enumeration<ProfiledGeneric> enu = graphThreads.elements();
-					while (enu.hasMoreElements()) {
-						ProfiledThread pThread = (ProfiledThread) enu.nextElement();
-						pThread.setEnabled(graphIndex, false);
-					}
-					graphThreads.clear();
-
-					ProfiledThreshold thresholdThread = this.myGraph.getThresholdThread();
-					if (thresholdThread.isEnabled(graphIndex)) {
-						ArrayList<ProfiledGeneric> items = thresholdThread.getItems(graphIndex);
-						// disable all items below the threshold
-						for (int i = 0; i < items.size(); i++) {
-							items.get(i).setEnabled(graphIndex, false);
-						}
-					}
-
-					GppSample[] sortedSamples = trace.getSortedGppSamples();
-
-					// set up in case we find threads below the threshold
-					boolean lowThread;
-					thresholdThread.init(graphIndex);
-
-					int threadThreshold = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountThread"); //$NON-NLS-1$
-					for (int i = startSampleIndex; i < endSampleIndex; i++) {
-						GppSample sample = sortedSamples[i];
-
-						ProfiledFunction pFunction = (ProfiledFunction) traceFunctions.elementAt(sample.functionIndex);
-						if (pFunction.isEnabled(graphIndex)) {
-							// thread list is based on functions
-							ProfiledThread pThread = (ProfiledThread) traceThreads.elementAt(sample.threadIndex);
-							String threadName = pThread.getNameString();
-
-							lowThread = pThread.getTotalSampleCount() < threadThreshold;
-
-							if (!foundThreads.containsKey(threadName)) {
-								foundThreads.put(threadName, threadName);
-								if (lowThread) {
-									thresholdThread.addItem(graphIndex, pThread, 1);
-								} else {
-									pThread.setEnabled(graphIndex, true);
-									pThread.setSampleCount(graphIndex, 1);
-									graphThreads.add(pThread);
-								}
-							} else {
-								if (lowThread)
-									thresholdThread.incSampleCount(graphIndex);
-								else
-									pThread.incSampleCount(graphIndex);
-							}
-						}
-					}
-
-					// set the % load
-					for (int i = 0; i < graphThreads.size(); i++) {
-						ProfiledThread pThread = (ProfiledThread) graphThreads.elementAt(i);
-						pThread.setLoadAndString(graphIndex, (float)(pThread.getSampleCount(graphIndex)*percentPerSample));
-					}
-					thresholdThread.setLoadAndString(graphIndex,
-							(float)(thresholdThread.getSampleCount(graphIndex)*percentPerSample));
+					trace.setFunctionThread(graphIndex, adapter, this.myGraph.getProfiledThreads());
 
 					// update the table items and redraw the table
 					this.myGraph.getThreadTable().piEventReceived(be3);
@@ -1491,126 +1394,10 @@
 				}
 				case Defines.FUNCTIONS_THREADS_BINARIES:
 				{
-					// get new thread and binary counts and loads
-					Vector<ProfiledGeneric> traceThreads   = trace.getIndexedThreads();
-					Vector<ProfiledGeneric> traceBinaries  = trace.getIndexedBinaries();
-					Vector<ProfiledGeneric> graphThreads   = this.myGraph.getProfiledThreads();
-					Vector<ProfiledGeneric> graphBinaries  = this.myGraph.getProfiledBinaries();
-					Hashtable<String,String> foundThreads  = new Hashtable<String,String>();
-					Hashtable<String,String> foundBinaries = new Hashtable<String,String>();
-
-					// previous binaries are not necessarily graphed this time
-					Enumeration<ProfiledGeneric> enuBinary = graphBinaries.elements();
-					while (enuBinary.hasMoreElements()) {
-						ProfiledBinary pBinary = (ProfiledBinary) enuBinary.nextElement();
-						pBinary.setEnabled(graphIndex, false);
-					}
-					graphBinaries.clear();
-
-					ProfiledThreshold thresholdBinary = this.myGraph.getThresholdBinary();
-
-					if (thresholdBinary.isEnabled(graphIndex)) {
-						ArrayList<ProfiledGeneric> items = thresholdBinary.getItems(graphIndex);
-						// disable all items below the threshold
-						for (int i = 0; i < items.size(); i++) {
-							items.get(i).setEnabled(graphIndex, false);
-						}
-					}
-
-					// previous threads are not necessarily graphed this time
-					Enumeration<ProfiledGeneric> enuThread = graphThreads.elements();
-					while (enuThread.hasMoreElements()) {
-						ProfiledThread pThread = (ProfiledThread) enuThread.nextElement();
-						pThread.setEnabled(graphIndex, false);
-					}
-					graphThreads.clear();
-
-					ProfiledThreshold thresholdThread = this.myGraph.getThresholdThread();
-
-					if (thresholdThread.isEnabled(graphIndex)) {
-						ArrayList<ProfiledGeneric> items = thresholdThread.getItems(graphIndex);
-						// disable all items below the threshold
-						for (int i = 0; i < items.size(); i++) {
-							items.get(i).setEnabled(graphIndex, false);
-						}
-					}
-
-					GppSample[] sortedSamples = trace.getSortedGppSamples();
-
-					// set up in case we find binaries below the threshold
-					boolean lowBinary;
-					thresholdBinary.init(graphIndex);
-
-					// set up in case we find threads below the threshold
-					boolean lowThread;
-					thresholdThread.init(graphIndex);
-
-					int threadThreshold = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountThread"); //$NON-NLS-1$
-					for (int i = startSampleIndex; i < endSampleIndex; i++) {
-						GppSample sample = sortedSamples[i];
-
-						ProfiledFunction pFunction = (ProfiledFunction) traceFunctions.elementAt(sample.functionIndex);
-						if (pFunction.isEnabled(graphIndex)) {
-							// thread list is based on functions
-							ProfiledThread pThread = (ProfiledThread) traceThreads.elementAt(sample.threadIndex);
-							String threadName = pThread.getNameString();
-
-							lowThread = pThread.getTotalSampleCount() < threadThreshold;
-
-							if (!foundThreads.containsKey(threadName)) {
-								foundThreads.put(threadName, threadName);
-								if (lowThread) {
-									thresholdThread.addItem(graphIndex, pThread, 1);
-								} else {
-									pThread.setEnabled(graphIndex, true);
-									pThread.setSampleCount(graphIndex, 1);
-									graphThreads.add(pThread);
-								}
-							} else {
-								if (lowThread)
-									thresholdThread.incSampleCount(graphIndex);
-								else
-									pThread.incSampleCount(graphIndex);
-							}
-
-							// binary list is based on functions and threads
-							ProfiledBinary pBinary = (ProfiledBinary) traceBinaries.elementAt(sample.binaryIndex);
-							String binaryName = pBinary.getNameString();
-
-							lowBinary = pBinary.getTotalSampleCount() < (Integer)NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountBinary"); //$NON-NLS-1$
-
-							if (!foundBinaries.containsKey(binaryName)) {
-								foundBinaries.put(binaryName, binaryName);
-								if (lowBinary) {
-									thresholdBinary.addItem(graphIndex, pBinary, 1);
-								} else {
-									pBinary.setEnabled(graphIndex, true);
-									pBinary.setSampleCount(graphIndex, 1);
-									graphBinaries.add(pBinary);
-								}
-							} else {
-								if (lowBinary)
-									thresholdBinary.incSampleCount(graphIndex);
-								else
-									pBinary.incSampleCount(graphIndex);
-							}
-						}
-					}
-
-					// set the % load
-					for (int i = 0; i < graphThreads.size(); i++) {
-						ProfiledThread pThread = (ProfiledThread) graphThreads.elementAt(i);
-						pThread.setLoadAndString(graphIndex, (float)(pThread.getSampleCount(graphIndex)*percentPerSample));
-					}
-					thresholdThread.setLoadAndString(graphIndex,
-							(float)(thresholdThread.getSampleCount(graphIndex)*percentPerSample));
-
-					for (int i = 0; i < graphBinaries.size(); i++) {
-						ProfiledBinary pBinary = (ProfiledBinary) graphBinaries.elementAt(i);
-						pBinary.setLoadAndString(graphIndex, (float)(pBinary.getSampleCount(graphIndex)*percentPerSample));
-					}
-					thresholdBinary.setLoadAndString(graphIndex,
-							(float)(thresholdBinary.getSampleCount(graphIndex)*percentPerSample));
+					// previous threads are not necessarily graphed this time - reset
+					trace.setFunctionThread(graphIndex, adapter, this.myGraph.getProfiledThreads());
+					// previous binaries are not necessarily graphed this time - reset
+					trace.setFunctionThreadBinary(graphIndex, adapter, this.myGraph.getProfiledBinaries());
 
 					// update the table items and redraw the table
 					this.myGraph.getThreadTable().piEventReceived(be3);
@@ -1619,72 +1406,7 @@
 				}
 				case Defines.FUNCTIONS_BINARIES:
 				{
-					// get new counts and loads
-					Vector<ProfiledGeneric> traceBinaries  = trace.getIndexedBinaries();
-					Vector<ProfiledGeneric> graphBinaries  = this.myGraph.getProfiledBinaries();
-					Hashtable<String,String> foundBinaries = new Hashtable<String,String>();
-
-					// previous binaries are not necessarily graphed this time
-					Enumeration<ProfiledGeneric> enu = graphBinaries.elements();
-					while (enu.hasMoreElements()) {
-						ProfiledBinary pBinary = (ProfiledBinary) enu.nextElement();
-						pBinary.setEnabled(graphIndex, false);
-					}
-					graphBinaries.clear();
-
-					ProfiledThreshold thresholdBinary = this.myGraph.getThresholdBinary();
-
-					if (thresholdBinary.isEnabled(graphIndex)) {
-						ArrayList<ProfiledGeneric> items = thresholdBinary.getItems(graphIndex);
-						// disable all items below the threshold
-						for (int i = 0; i < items.size(); i++) {
-							items.get(i).setEnabled(graphIndex, false);
-						}
-					}
-
-					GppSample[] sortedSamples = trace.getSortedGppSamples();
-
-					// set up in case we find binaries below the threshold
-					boolean lowBinary;
-					thresholdBinary.init(graphIndex);
-
-					int binaryThreshold = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountBinary"); //$NON-NLS-1$
-					for (int i = startSampleIndex; i < endSampleIndex; i++) {
-						GppSample sample = sortedSamples[i];
-
-						ProfiledFunction pFunction = (ProfiledFunction) traceFunctions.elementAt(sample.functionIndex);
-						if (pFunction.isEnabled(graphIndex)) {
-							// binary list is based on functions
-							ProfiledBinary pBinary = (ProfiledBinary) traceBinaries.elementAt(sample.binaryIndex);
-							String binaryName = pBinary.getNameString();
-
-							lowBinary = pBinary.getTotalSampleCount() < binaryThreshold;
-
-							if (!foundBinaries.containsKey(binaryName)) {
-								foundBinaries.put(binaryName, binaryName);
-								if (lowBinary) {
-									thresholdBinary.addItem(graphIndex, pBinary, 1);
-								} else {
-									pBinary.setEnabled(graphIndex, true);
-									pBinary.setSampleCount(graphIndex, 1);
-									graphBinaries.add(pBinary);
-								}
-							} else {
-								if (lowBinary)
-									thresholdBinary.incSampleCount(graphIndex);
-								else
-									pBinary.incSampleCount(graphIndex);
-							}
-						}
-					}
-
-					// set the % load
-					for (int i = 0; i < graphBinaries.size(); i++) {
-						ProfiledBinary pBinary = (ProfiledBinary) graphBinaries.elementAt(i);
-						pBinary.setLoadAndString(graphIndex, (float)(pBinary.getSampleCount(graphIndex)*percentPerSample));
-					}
-					thresholdBinary.setLoadAndString(graphIndex,
-							(float)(thresholdBinary.getSampleCount(graphIndex)*percentPerSample));
+					trace.setFunctionBinary(graphIndex, adapter, this.myGraph.getProfiledBinaries());
 
 					// update the table items and redraw the table
 					this.myGraph.getBinaryTable().piEventReceived(be3);
@@ -1692,126 +1414,10 @@
 				}
 				case Defines.FUNCTIONS_BINARIES_THREADS:
 				{
-					// get new binary and thread counts and loads
-					Vector<ProfiledGeneric> traceThreads    = trace.getIndexedThreads();
-					Vector<ProfiledGeneric> traceBinaries   = trace.getIndexedBinaries();
-					Vector<ProfiledGeneric> graphThreads    = this.myGraph.getProfiledThreads();
-					Vector<ProfiledGeneric> graphBinaries   = this.myGraph.getProfiledBinaries();
-					Hashtable<String,String> foundThreads   = new Hashtable<String,String>();
-					Hashtable<String,String> foundBinaries  = new Hashtable<String,String>();
-
-					// previous threads are not necessarily graphed this time
-					Enumeration<ProfiledGeneric> enuThreads = graphThreads.elements();
-					while (enuThreads.hasMoreElements()) {
-						ProfiledThread pThread = (ProfiledThread) enuThreads.nextElement();
-						pThread.setEnabled(graphIndex, false);
-					}
-					graphThreads.clear();
-
-					ProfiledThreshold thresholdThread = this.myGraph.getThresholdThread();
-
-					if (thresholdThread.isEnabled(graphIndex)) {
-						ArrayList<ProfiledGeneric> items = thresholdThread.getItems(graphIndex);
-						// disable all items below the threshold
-						for (int i = 0; i < items.size(); i++) {
-							items.get(i).setEnabled(graphIndex, false);
-						}
-					}
-
-					// previous binaries are not necessarily graphed this time
-					Enumeration<ProfiledGeneric> enuBinary = graphBinaries.elements();
-					while (enuBinary.hasMoreElements()) {
-						ProfiledBinary pBinary = (ProfiledBinary) enuBinary.nextElement();
-						pBinary.setEnabled(graphIndex, false);
-					}
-					graphBinaries.clear();
-
-					ProfiledThreshold thresholdBinary = this.myGraph.getThresholdBinary();
-
-					if (thresholdBinary.isEnabled(graphIndex)) {
-						ArrayList<ProfiledGeneric> items = thresholdBinary.getItems(graphIndex);
-						// disable all items below the threshold
-						for (int i = 0; i < items.size(); i++) {
-							items.get(i).setEnabled(graphIndex, false);
-						}
-					}
-
-					GppSample[] sortedSamples = trace.getSortedGppSamples();
-
-					// set up in case we find threads below the threshold
-					boolean lowThread;
-					thresholdThread.init(graphIndex);
-
-					// set up in case we find binaries below the threshold
-					boolean lowBinary;
-					thresholdBinary.init(graphIndex);
-
-					int binaryThreshold = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountBinary"); //$NON-NLS-1$
-					for (int i = startSampleIndex; i < endSampleIndex; i++) {
-						GppSample sample = sortedSamples[i];
-
-						ProfiledFunction pFunction = (ProfiledFunction) traceFunctions.elementAt(sample.functionIndex);
-						if (pFunction.isEnabled(graphIndex)) {
-							// binary list is based on
-							ProfiledBinary pBinary = (ProfiledBinary) traceBinaries.elementAt(sample.binaryIndex);
-							String binaryName = pBinary.getNameString();
-
-							lowBinary = pBinary.getTotalSampleCount() < binaryThreshold;
-
-							if (!foundBinaries.containsKey(binaryName)) {
-								foundBinaries.put(binaryName, binaryName);
-								if (lowBinary) {
-									thresholdBinary.addItem(graphIndex, pBinary, 1);
-								} else {
-									pBinary.setEnabled(graphIndex, true);
-									pBinary.setSampleCount(graphIndex, 1);
-									graphBinaries.add(pBinary);
-								}
-							} else {
-								if (lowBinary)
-									thresholdBinary.incSampleCount(graphIndex);
-								else
-									pBinary.incSampleCount(graphIndex);
-							}
-
-							// thread list is based on functions and binaries
-							ProfiledThread pThread = (ProfiledThread) traceThreads.elementAt(sample.threadIndex);
-							String threadName = pThread.getNameString();
-
-							lowThread = pThread.getTotalSampleCount() < (Integer)NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountThread"); //$NON-NLS-1$
-
-							if (!foundThreads.containsKey(threadName)) {
-								foundThreads.put(threadName, threadName);
-								if (lowThread) {
-									thresholdThread.addItem(graphIndex, pThread, 1);
-								} else {
-									pThread.setEnabled(graphIndex, true);
-									pThread.setSampleCount(graphIndex, 1);
-									graphThreads.add(pThread);
-								}
-							} else {
-								if (lowThread)
-									thresholdThread.incSampleCount(graphIndex);
-								else
-									pThread.incSampleCount(graphIndex);
-							}
-						}
-					}
-
-					// set the % load
-					for (int i = 0; i < graphThreads.size(); i++) {
-						ProfiledThread pThread = (ProfiledThread) graphThreads.elementAt(i);
-						pThread.setLoadAndString(graphIndex, (float)(pThread.getSampleCount(graphIndex)*percentPerSample));
-					}
-					thresholdThread.setLoadAndString(graphIndex,
-							(float)(thresholdThread.getSampleCount(graphIndex)*percentPerSample));
-
-					for (int i = 0; i < graphBinaries.size(); i++) {
-						ProfiledBinary pBinary = (ProfiledBinary) graphBinaries.elementAt(i);
-						pBinary.setLoadAndString(graphIndex, (float)(pBinary.getSampleCount(graphIndex)*percentPerSample));
-					}
-					thresholdBinary.setLoadAndString(graphIndex,
-							(float)(thresholdBinary.getSampleCount(graphIndex)*percentPerSample));
+					// previous binaries are not necessarily graphed this time - reset
+					trace.setFunctionBinary(graphIndex, adapter, this.myGraph.getProfiledBinaries());
+					// previous threads are not necessarily graphed this time - reset
+					trace.setFunctionBinaryThread(graphIndex, adapter, this.myGraph.getProfiledThreads());
 
 					// update the table items and redraw the table
 					this.myGraph.getThreadTable().piEventReceived(be3);
@@ -1834,86 +1440,10 @@
 
 			// we don't need to redraw the function table, since it has not changed
 
+			PIEvent be3 = new PIEvent(be.getValueObject(), PIEvent.SELECTION_AREA_CHANGED3);
 			GppTrace trace = (GppTrace)(this.myGraph.getTrace());
-			Vector<ProfiledGeneric> traceThreads = trace.getIndexedThreads();
-
 			int graphIndex = this.myGraph.getGraphIndex();
-			int startSampleIndex = trace.getStartSampleIndex();
-			int endSampleIndex   = trace.getEndSampleIndex();
-			double percentPerSample;
-			if (startSampleIndex == endSampleIndex)
-				percentPerSample = 0.0;
-			else
-				percentPerSample = 100.0 / ((double)(endSampleIndex - startSampleIndex));
-
-			PIEvent be3 = new PIEvent(be.getValueObject(), PIEvent.SELECTION_AREA_CHANGED3);
-
-			// get new binary counts and loads
-			Vector<ProfiledGeneric> traceBinaries  = trace.getIndexedBinaries();
-			Vector<ProfiledGeneric> graphBinaries  = this.myGraph.getProfiledBinaries();
-			Hashtable<String,String> foundBinaries = new Hashtable<String,String>();
-
-			// previous binaries are not necessarily graphed this time
-			Enumeration<ProfiledGeneric> enu = graphBinaries.elements();
-			while (enu.hasMoreElements()) {
-				ProfiledBinary pBinary = (ProfiledBinary) enu.nextElement();
-				pBinary.setEnabled(graphIndex, false);
-			}
-			graphBinaries.clear();
-
-			ProfiledThreshold thresholdBinary = this.myGraph.getThresholdBinary();
-
-			if (thresholdBinary.isEnabled(graphIndex)) {
-				ArrayList<ProfiledGeneric> items = thresholdBinary.getItems(graphIndex);
-				// disable all items below the threshold
-				for (int i = 0; i < items.size(); i++) {
-					items.get(i).setEnabled(graphIndex, false);
-				}
-			}
-
-			GppSample[] sortedSamples = trace.getSortedGppSamples();
-
-			// set up in case we find binaries below the threshold
-			boolean lowBinary;
-			thresholdBinary.init(graphIndex);
-			
-			int binaryThreshold = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountBinary"); //$NON-NLS-1$
-			for (int i = startSampleIndex; i < endSampleIndex; i++) {
-				GppSample sample = sortedSamples[i];
-
-				ProfiledThread pThread = (ProfiledThread) traceThreads.elementAt(sample.threadIndex);
-				if (pThread.isEnabled(graphIndex)) {
-					// binary list is based on threads
-					ProfiledBinary pBinary = (ProfiledBinary) traceBinaries.elementAt(sample.binaryIndex);
-					String binaryName = pBinary.getNameString();
-
-					lowBinary = pBinary.getTotalSampleCount() < binaryThreshold;
-
-					if (!foundBinaries.containsKey(binaryName)) {
-						foundBinaries.put(binaryName, binaryName);
-						if (lowBinary) {
-							thresholdBinary.addItem(graphIndex, pBinary, 1);
-						} else {
-							pBinary.setEnabled(graphIndex, true);
-							pBinary.setSampleCount(graphIndex, 1);
-							graphBinaries.add(pBinary);
-						}
-					} else {
-						if (lowBinary)
-							thresholdBinary.incSampleCount(graphIndex);
-						else
-							pBinary.incSampleCount(graphIndex);
-					}
-				}
-			}
-
-			// set the % load
-			for (int i = 0; i < graphBinaries.size(); i++) {
-				ProfiledBinary pBinary = (ProfiledBinary) graphBinaries.elementAt(i);
-				pBinary.setLoadAndString(graphIndex, (float)(pBinary.getSampleCount(graphIndex)*percentPerSample));
-			}
-			thresholdBinary.setLoadAndString(graphIndex,
-					(float)(thresholdBinary.getSampleCount(graphIndex)*percentPerSample));
+			trace.setFunctionThreadBinary(graphIndex, adapter, this.myGraph.getProfiledBinaries());
 
 			// update the table items and redraw the table
 			this.myGraph.getBinaryTable().piEventReceived(be3);
@@ -1928,86 +1458,10 @@
 
 			// we don't need to redraw the function table, since it has not changed
 
+			PIEvent be3 = new PIEvent(be.getValueObject(), PIEvent.SELECTION_AREA_CHANGED3);
 			GppTrace trace = (GppTrace)(this.myGraph.getTrace());
-			Vector<ProfiledGeneric> traceBinaries  = trace.getIndexedBinaries();
-
 			int graphIndex = this.myGraph.getGraphIndex();
-			int startSampleIndex = trace.getStartSampleIndex();
-			int endSampleIndex   = trace.getEndSampleIndex();
-			double percentPerSample;
-			if (startSampleIndex == endSampleIndex)
-				percentPerSample = 0.0;
-			else
-				percentPerSample = 100.0 / ((double)(endSampleIndex - startSampleIndex));
-
-			PIEvent be3 = new PIEvent(be.getValueObject(), PIEvent.SELECTION_AREA_CHANGED3);
-
-			// get new thread counts and loads
-			Vector<ProfiledGeneric> traceThreads  = trace.getIndexedThreads();
-			Vector<ProfiledGeneric> graphThreads  = this.myGraph.getProfiledThreads();
-			Hashtable<String,String> foundThreads = new Hashtable<String,String>();
-
-			// previous threads are not necessarily graphed this time
-			Enumeration<ProfiledGeneric> enu = graphThreads.elements();
-			while (enu.hasMoreElements()) {
-				ProfiledThread pThread = (ProfiledThread) enu.nextElement();
-				pThread.setEnabled(graphIndex, false);
-			}
-			graphThreads.clear();
-
-			ProfiledThreshold thresholdThread = this.myGraph.getThresholdThread();
-
-			if (thresholdThread.isEnabled(graphIndex)) {
-				ArrayList<ProfiledGeneric> items = thresholdThread.getItems(graphIndex);
-				// disable all items below the threshold
-				for (int i = 0; i < items.size(); i++) {
-					items.get(i).setEnabled(graphIndex, false);
-				}
-			}
-
-			GppSample[] sortedSamples = trace.getSortedGppSamples();
-
-			// set up in case we find threads below the threshold
-			boolean lowThread;
-			thresholdThread.init(graphIndex);
-
-			int threadThreshold = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountThread"); //$NON-NLS-1$
-			for (int i = startSampleIndex; i < endSampleIndex; i++) {
-				GppSample sample = sortedSamples[i];
-
-				ProfiledBinary pBinary = (ProfiledBinary) traceBinaries.elementAt(sample.binaryIndex);
-				if (pBinary.isEnabled(graphIndex)) {
-					// thread list is based on binaries
-					ProfiledThread pThread = (ProfiledThread) traceThreads.elementAt(sample.threadIndex);
-					String threadName = pThread.getNameString();
-
-					lowThread = pThread.getTotalSampleCount() < threadThreshold;
-
-					if (!foundThreads.containsKey(threadName)) {
-						foundThreads.put(threadName, threadName);
-						if (lowThread) {
-							thresholdThread.addItem(graphIndex, pThread, 1);
-						} else {
-							pThread.setEnabled(graphIndex, true);
-							pThread.setSampleCount(graphIndex, 1);
-							graphThreads.add(pThread);
-						}
-					} else {
-						if (lowThread)
-							thresholdThread.incSampleCount(graphIndex);
-						else
-							pThread.incSampleCount(graphIndex);
-					}
-				}
-			}
-
-			// set the % load
-			for (int i = 0; i < graphThreads.size(); i++) {
-				ProfiledThread pThread = (ProfiledThread) graphThreads.elementAt(i);
-				pThread.setLoadAndString(graphIndex, (float)(pThread.getSampleCount(graphIndex)*percentPerSample));
-			}
-			thresholdThread.setLoadAndString(graphIndex,
-					(float)(thresholdThread.getSampleCount(graphIndex)*percentPerSample));
+			trace.setFunctionBinaryThread(graphIndex, adapter, this.myGraph.getProfiledThreads());
 
 			// update the table items and redraw the table
 			this.myGraph.getThreadTable().piEventReceived(be3);
@@ -2041,7 +1495,7 @@
        		
        		// set the stored value to the checkbox value
        		ProfiledGeneric pg = (ProfiledGeneric)event.getElement();
-	        pg.setEnabled(myGraph.getGraphIndex(), event.getChecked());
+       		pg.setEnabled(myGraph.getGraphIndex(), event.getChecked());
  
 	        // this table's set of checkbox-selected rows has changed, so propagate that information
        		setSelectedNames();
@@ -2098,6 +1552,7 @@
 
 	private class ColumnSelectionHandler extends SelectionAdapter
 	{
+		@Override
 		public void widgetSelected(SelectionEvent e)
         {
         	// wait for the previous sort to finish
@@ -2108,6 +1563,15 @@
         }
 	}
 
+	/**
+	 * Adds ProfiledGenerics and threshold items to the table data
+	 * (this.tableItemData and this.profiledThreads). Sorts the ProfiledGenerics
+	 * according to load; and sets the graph's sorted list accordingly. Refreshes
+	 * the TableViewer if parameter setInput is true.
+	 * 
+	 * @param setInput
+	 *            if true, reset the TableViewer
+	 */
 	public void updateProfiledAndItemData(boolean setInput)
 	{
 		tableItemData.clear();
@@ -2122,7 +1586,7 @@
 			profiledFunctions.add(nextElement);
 		}
 
-		if (myGraph.getThresholdFunction().getItemCount(myGraph.getGraphIndex()) != 0) {
+		if (myGraph.getThresholdFunction().getItemCount() != 0) {
 			tableItemData.add(myGraph.getThresholdFunction());
 			profiledFunctions.add(myGraph.getThresholdFunction());
 		}
@@ -2134,17 +1598,16 @@
 			public int compare(Object arg0, Object arg1)
 			{
 				if (arg0 instanceof ProfiledGeneric && arg1 instanceof ProfiledGeneric)
-					return ((ProfiledGeneric)arg0).getTotalSampleCount() -
-							((ProfiledGeneric)arg1).getTotalSampleCount();
-				else
-					return 0;
+					return (adapter.getTotalSampleCount((ProfiledGeneric)arg0)) -
+					adapter.getTotalSampleCount(((ProfiledGeneric)arg1));
+				return 0;
 			}
 		});
 
 		// now create the sorted list used to draw the graph
 		myGraph.getSortedFunctions().clear();
 
-		if (myGraph.getThresholdFunction().getItemCount(myGraph.getGraphIndex()) != 0)
+		if (myGraph.getThresholdFunction().getItemCount() != 0)
 			myGraph.getSortedFunctions().add(myGraph.getThresholdFunction());
 
 		for (int i = 0; i < sorted.length; i++)
@@ -2260,14 +1723,15 @@
 		this.sorting = false;
 	}
 
-	protected Menu getTableMenu(Decorations parent, int graphIndex, int drawMode) {
+	@Override
+	protected Menu getTableMenu(Decorations aParent, int graphIndex, int drawMode) {
 		// get rid of last Menu created so we don't have double menu
 		// in on click
 		if (contextMenu != null) {
 			contextMenu.dispose();
 		}
 		
-		contextMenu = new Menu(parent, SWT.POP_UP);
+		contextMenu = new Menu(aParent, SWT.POP_UP);
 
 		// Use drawMode to determine the drill down items and
 		// whether to show a color column
@@ -2383,7 +1847,7 @@
 		return contextMenu;
 	}
 
-	public Vector getTableItemData() {
+	public Vector<ProfiledGeneric> getTableItemData() {
 		return this.tableItemData;
 	}
 
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/pi/address/AddrThreadTable.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/pi/address/AddrThreadTable.java	Wed Apr 21 15:14:16 2010 +0300
@@ -59,11 +59,10 @@
 import org.eclipse.swt.widgets.TableColumn;
 import org.eclipse.swt.widgets.TableItem;
 
+import com.nokia.carbide.cpp.internal.pi.address.GppModelAdapter;
 import com.nokia.carbide.cpp.internal.pi.analyser.NpiInstanceRepository;
 import com.nokia.carbide.cpp.internal.pi.analyser.ProfileVisualiser;
 import com.nokia.carbide.cpp.internal.pi.interfaces.ISaveSamples;
-import com.nokia.carbide.cpp.internal.pi.model.ProfiledBinary;
-import com.nokia.carbide.cpp.internal.pi.model.ProfiledFunction;
 import com.nokia.carbide.cpp.internal.pi.model.ProfiledGeneric;
 import com.nokia.carbide.cpp.internal.pi.model.ProfiledThread;
 import com.nokia.carbide.cpp.internal.pi.model.ProfiledThreshold;
@@ -85,10 +84,9 @@
 	private Hashtable<Integer,String> priorityTable;
 	private Hashtable<Integer,Integer> priorityValues;
 
-	public AddrThreadTable(GppTraceGraph myGraph, Composite parent)
+	public AddrThreadTable(GppTraceGraph myGraph, Composite parent, GppModelAdapter adapter)
 	{
-		this.myGraph = myGraph;
-		this.parent  = parent;
+		super(myGraph, parent, adapter);
 	}
 
 	public void createTableViewer(int drawMode)
@@ -132,8 +130,8 @@
 
 		// add the check state handler, label provider and content provider
 		tableViewer.addCheckStateListener(new SharedCheckHandler());
-		tableViewer.setLabelProvider(new shownThreadsLabelProvider());
-		tableViewer.setContentProvider(new shownThreadsContentProvider());
+		tableViewer.setLabelProvider(new ShownThreadsLabelProvider());
+		tableViewer.setContentProvider(new ShownThreadsContentProvider());
 		tableViewer.addSelectionChangedListener(new ISelectionChangedListener() {
 			public void selectionChanged(SelectionChangedEvent arg0) {
 				if (copyAction == null)
@@ -170,7 +168,7 @@
 		column = new TableColumn(table, SWT.CENTER);
 		column.setText(COLUMN_HEAD_SHOW);
 		column.setWidth(COLUMN_WIDTH_SHOW);
-		column.setData(new Integer(COLUMN_ID_SHOW));
+		column.setData(Integer.valueOf(COLUMN_ID_SHOW));
 		column.setMoveable(true);
 		column.setResizable(true);
 		column.addSelectionListener(new ColumnSelectionHandler());
@@ -179,7 +177,7 @@
 		column = new TableColumn(table, SWT.RIGHT);
 		column.setText(COLUMN_HEAD_PERCENT_LOAD);
 		column.setWidth(COLUMN_WIDTH_PERCENT_LOAD);
-		column.setData(new Integer(COLUMN_ID_PERCENT_LOAD));
+		column.setData(Integer.valueOf(COLUMN_ID_PERCENT_LOAD));
 		column.setMoveable(true);
 		column.setResizable(true);
 		column.addSelectionListener(new ColumnSelectionHandler());
@@ -188,7 +186,7 @@
 		column = new TableColumn(table, SWT.LEFT);
 		column.setText(COLUMN_HEAD_THREAD);
 		column.setWidth(COLUMN_WIDTH_THREAD_NAME);
-		column.setData(new Integer(COLUMN_ID_THREAD));
+		column.setData(Integer.valueOf(COLUMN_ID_THREAD));
 		column.setMoveable(true);
 		column.setResizable(true);
 		column.addSelectionListener(new ColumnSelectionHandler());
@@ -197,7 +195,7 @@
 		column = new TableColumn(table, SWT.CENTER);
 		column.setText(COLUMN_HEAD_SAMPLE_COUNT);
 		column.setWidth(COLUMN_WIDTH_SAMPLE_COUNT);
-		column.setData(new Integer(COLUMN_ID_SAMPLE_COUNT));
+		column.setData(Integer.valueOf(COLUMN_ID_SAMPLE_COUNT));
 		column.setMoveable(true);
 		column.setResizable(true);
 		column.addSelectionListener(new ColumnSelectionHandler());
@@ -313,9 +311,9 @@
 		table.redraw();
 	}
 
-	private static class shownThreadsContentProvider implements IStructuredContentProvider {
+	private static class ShownThreadsContentProvider implements IStructuredContentProvider {
 
-		public shownThreadsContentProvider() {
+		public ShownThreadsContentProvider() {
 			super();
 		}
 
@@ -330,12 +328,15 @@
 		}
 	}
 
-	private class shownThreadsLabelProvider extends LabelProvider implements ITableLabelProvider {
+	private class ShownThreadsLabelProvider extends LabelProvider implements ITableLabelProvider {
 
-        public shownThreadsLabelProvider() {
+        public ShownThreadsLabelProvider() {
 			super();
 		}
 
+		/* (non-Javadoc)
+		 * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java.lang.Object, int)
+		 */
 		public String getColumnText(Object element, int columnIndex) {
 
 			int graphIndex = myGraph.getGraphIndex();
@@ -373,7 +374,7 @@
 					{
 						DecimalFormat timeFormat = new DecimalFormat(Messages.getString("AddrThreadTable.decimalFormat")); //$NON-NLS-1$
 
-						int count = pThreshold.getItemCount(graphIndex);
+						int count = pThreshold.getItemCount();
 
 						return count + (count > 1 ? Messages.getString("AddrThreadTable.thresholdMsg1") : Messages.getString("AddrThreadTable.thresholdMsg2"))   //$NON-NLS-1$ //$NON-NLS-2$
 								+ timeFormat.format((Double)NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdLoadThread") * 100.0) + Messages.getString("AddrThreadTable.thresholdMsg3") //$NON-NLS-1$ //$NON-NLS-2$ 
@@ -423,7 +424,7 @@
 				case COLUMN_ID_PRIORITY:
 			    {
 					if (priorityAdded) {
-				        String priority = priorityTable.get(new Integer(profiledItem.getThreadId()));
+				        String priority = priorityTable.get(Integer.valueOf(profiledItem.getThreadId()));
 				        if (priority == null)
 				        	return Messages.getString("AddrThreadTable.unknownPriority"); //$NON-NLS-1$
 				        else
@@ -559,7 +560,7 @@
 			this.myGraph.getFunctionTable().action(actionString);
 			return;
 		}
-		else if (actionString.equals("changeThresholdThread")) //$NON-NLS-1$
+		else if (actionString.equals(IGppTraceGraph.ACTION_CHANGE_THRESHOLD_THREAD))
 		{
 			ProfiledThreshold threshold = this.myGraph.getThresholdThread();
 			boolean enabled = threshold.isEnabled(graphIndex);
@@ -567,9 +568,9 @@
 			this.tableItemData.clear();
 			this.profiledThreads.clear();
 			this.myGraph.getSortedThreads().clear();
-			if (threshold.getItems(graphIndex) != null)
-				threshold.getItems(graphIndex).clear();
-			threshold.initAll();
+			if (threshold.getItems() != null)
+				threshold.getItems().clear();
+			adapter.init(threshold, graphIndex);
 
 			// if this appears, it needs to be the first item, so that it is drawn at the bottom
 			myGraph.getSortedThreads().add(threshold);
@@ -577,9 +578,9 @@
 			int threadThreshold = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountThread"); //$NON-NLS-1$
 			for (int i = 0; i < this.myGraph.getGppTrace().getSortedThreads().size(); i++) {
 				ProfiledGeneric nextElement = (ProfiledGeneric)this.myGraph.getGppTrace().getSortedThreads().get(i);
-				if (nextElement.getTotalSampleCount() < threadThreshold) {
+				if (adapter.getTotalSampleCount(nextElement) < threadThreshold) {
 					nextElement.setEnabled(graphIndex, enabled);
-					threshold.addItem(graphIndex, nextElement, 0);
+					adapter.addItem(threshold, graphIndex, nextElement, 0);
 				} else {
 					tableItemData.add(nextElement);
 					profiledThreads.add(nextElement);
@@ -587,7 +588,7 @@
 				}
 			}
 
-			if (threshold.getItemCount(graphIndex) != 0) {
+			if (threshold.getItemCount() != 0) {
 				tableItemData.add(threshold);
 				profiledThreads.add(threshold);
 			} else {
@@ -660,9 +661,8 @@
    				if (item instanceof ProfiledThreshold)
    				{
    					ProfiledThreshold pThreshold = (ProfiledThreshold)item;
-   					ArrayList<ProfiledGeneric> items = pThreshold.getItems(graphIndex);
-   					for (int j = 0; j < items.size(); j++)
-   						items.get(j).setEnabled(graphIndex, addIt);
+   					for (ProfiledGeneric p : pThreshold.getItems())
+   						p.setEnabled(graphIndex, addIt);
    				}
 			}
 		}
@@ -713,9 +713,8 @@
    				if (item instanceof ProfiledThreshold)
    				{
    					ProfiledThreshold pThreshold = (ProfiledThreshold)item;
-   					ArrayList<ProfiledGeneric> items = pThreshold.getItems(graphIndex);
-   					for (int j = 0; j < items.size(); j++)
-   						items.get(j).setEnabled(graphIndex, addIt);
+   					for (ProfiledGeneric p : pThreshold.getItems())
+   						p.setEnabled(graphIndex, addIt);
    				}
 			}
 		}
@@ -760,9 +759,15 @@
 						pGeneric.setColor(color);
 					} else {
 						// for the threshold item, we must change every graph's thread threshold item
+						// CH: refactor! This could be done via an observer pattern. This class should not have knowledge of all other graphs  
 						gppTrace.getGppGraph(PIPageEditor.THREADS_PAGE,   uid).getThresholdThread().setColor(color);
 						gppTrace.getGppGraph(PIPageEditor.BINARIES_PAGE,  uid).getThresholdThread().setColor(color);
 						gppTrace.getGppGraph(PIPageEditor.FUNCTIONS_PAGE, uid).getThresholdThread().setColor(color);
+						if (gppTrace.getCPUCount() > 1){ //SMP
+							for (int cpu = 0; cpu < gppTrace.getCPUCount(); cpu++) {
+								gppTrace.getGppGraph(3 + cpu, uid).getThresholdThread().setColor(color);															
+							}
+						}
 					}
 				}
 
@@ -780,7 +785,7 @@
 		
 		// if any other tabs are displaying this type of graph, they need to be scheduled for redrawing
 		for (int i = 0; i < 3; i++) {
-			GppTraceGraph graph = gppTrace.getGppGraph(i, uid);
+			IGppTraceGraph graph = gppTrace.getGppGraph(i, uid);
 
 			if (graph == this.myGraph)
 				continue;
@@ -816,11 +821,6 @@
 		
 		setIsDrilldown(false);
 
-		// set the page's graph title
-		ProfileVisualiser pV =  NpiInstanceRepository.getInstance().getProfilePage(this.myGraph.getUid(), this.myGraph.getGraphIndex());
-		pV.getTitle().setText(Messages.getString("AddrThreadTable.threadLoad")); //$NON-NLS-1$
-		pV.getTitle2().setText(""); //$NON-NLS-1$
-
 		// get rid of any existing tables and sashes
 		if (this.myGraph.getLeftSash() != null) {
 			this.myGraph.getLeftSash().dispose();
@@ -873,10 +873,6 @@
 		setIsDrilldown(true);
 
 		if (drawMode == Defines.THREADS) {
-			// set the page's graph title
-			ProfileVisualiser pV =  NpiInstanceRepository.getInstance().getProfilePage(this.myGraph.getUid(), this.myGraph.getGraphIndex());
-			pV.getTitle().setText(Messages.getString("AddrThreadTable.binaryLoad")); //$NON-NLS-1$
-			pV.getTitle2().setText(Messages.getString("AddrThreadTable.threadTo")); //$NON-NLS-1$
 
 			// set the draw mode before populating table viewers, since the
 			// color column depends on the draw mode
@@ -889,8 +885,7 @@
 
 			// create a reduced set of binary entries based on enabled thread entries
 			GppTrace gppTrace = (GppTrace) this.myGraph.getTrace();
-			Vector<ProfiledGeneric> binaries = gppTrace.setThreadBinary(graphIndex);
-			this.myGraph.setProfiledBinaries(binaries);
+			gppTrace.setThreadBinary(graphIndex, adapter, this.myGraph.getProfiledBinaries());
 
 			// put check marks on all rows, and sort by sample count
 			binaryTable.quickSort(COLUMN_ID_SAMPLE_COUNT, this.myGraph.getProfiledBinaries());
@@ -949,10 +944,6 @@
 			this.myGraph.repaint();
 
 		} else if (drawMode == Defines.THREADS_BINARIES_FUNCTIONS) {
-			// set the page's graph title
-			ProfileVisualiser pV =  NpiInstanceRepository.getInstance().getProfilePage(this.myGraph.getUid(), this.myGraph.getGraphIndex());
-			pV.getTitle().setText(Messages.getString("AddrThreadTable.binaryLoad")); //$NON-NLS-1$
-			pV.getTitle2().setText(Messages.getString("AddrThreadTable.threadTo")); //$NON-NLS-1$
 
 			// get rid of the function table and its sash
 			if (this.myGraph.getRightSash() != null) {
@@ -969,14 +960,14 @@
 			try {
 				FormData formData = (FormData) this.myGraph.getBinaryTable().getTable().getLayoutData();
 				formData.right = new FormAttachment(100);
-			} catch (ClassCastException e1) {
+			} catch (ClassCastException e1) { //CH: refactor!  Runtime exceptions should not be caught!
 			}
 
 			// move the left sash to the middle
 			try {
 				FormData formData = (FormData) this.myGraph.getLeftSash().getLayoutData();
 				formData.left = new FormAttachment(50); // middle
-			} catch (ClassCastException e1) {
+			} catch (ClassCastException e1) { //CH: refactor!  Runtime exceptions should not be caught!
 			}
 
 			// set the draw mode
@@ -1007,11 +998,6 @@
 
 		setIsDrilldown(true);
 
-		// set the page's graph title
-		ProfileVisualiser pV =  NpiInstanceRepository.getInstance().getProfilePage(this.myGraph.getUid(), this.myGraph.getGraphIndex());
-		pV.getTitle().setText(Messages.getString("AddrThreadTable.functionLoad")); //$NON-NLS-1$
-		pV.getTitle2().setText(Messages.getString("AddrThreadTable.threadToBinaryTo")); //$NON-NLS-1$
-
 		// set the draw mode before populating table viewers, since the
 		// color column depends on the draw mode
 		this.myGraph.setDrawMode(Defines.THREADS_BINARIES_FUNCTIONS);
@@ -1023,8 +1009,7 @@
 
 		// create a reduced set of function entries based on enabled thread and binary entries
 		GppTrace gppTrace = (GppTrace) this.myGraph.getTrace();
-		Vector<ProfiledGeneric> functions = gppTrace.setThreadBinaryFunction(graphIndex);
-		this.myGraph.setProfiledFunctions(functions);
+		gppTrace.setThreadBinaryFunction(graphIndex, adapter, this.myGraph.getProfiledFunctions());
 
 		// put check marks on all rows, and sort by sample count
 		functionTable.quickSort(COLUMN_ID_SAMPLE_COUNT, this.myGraph.getProfiledFunctions());
@@ -1097,10 +1082,6 @@
 		setIsDrilldown(true);
 
 		if (drawMode == Defines.THREADS) {
-			// set the page's graph title
-			ProfileVisualiser pV =  NpiInstanceRepository.getInstance().getProfilePage(this.myGraph.getUid(), this.myGraph.getGraphIndex());
-			pV.getTitle().setText(Messages.getString("AddrThreadTable.functionLoad")); //$NON-NLS-1$
-			pV.getTitle2().setText(Messages.getString("AddrThreadTable.threadTo")); //$NON-NLS-1$
 
 			// set the draw mode
 			this.myGraph.setDrawMode(Defines.THREADS_FUNCTIONS);
@@ -1112,8 +1093,7 @@
 
 			// create a reduced set of function entries based on enabled thread and binary entries
 			GppTrace gppTrace = (GppTrace) this.myGraph.getTrace();
-			Vector<ProfiledGeneric> functions = gppTrace.setThreadFunction(graphIndex);
-			this.myGraph.setProfiledFunctions(functions);
+			gppTrace.setThreadFunction(graphIndex, adapter, this.myGraph.getProfiledFunctions());
 
 			// put check marks on all rows, and sort by sample count
 			functionTable.quickSort(COLUMN_ID_SAMPLE_COUNT, this.myGraph.getProfiledFunctions());
@@ -1165,11 +1145,6 @@
 			this.myGraph.repaint();
 
 		} else if (drawMode == Defines.THREADS_FUNCTIONS_BINARIES) {
-			// set the page's graph title
-			ProfileVisualiser pV =  NpiInstanceRepository.getInstance().getProfilePage(this.myGraph.getUid(), this.myGraph.getGraphIndex());
-			pV.getTitle().setText(Messages.getString("AddrThreadTable.functionLoad")); //$NON-NLS-1$
-			pV.getTitle2().setText(Messages.getString("AddrThreadTable.threadTo")); //$NON-NLS-1$
-
 			// get rid of the binary table and its sash
 			if (this.myGraph.getRightSash() != null) {
 				this.myGraph.getRightSash().dispose();
@@ -1223,11 +1198,6 @@
 
 		setIsDrilldown(true);
 
-		// set the page's graph title
-		ProfileVisualiser pV =  NpiInstanceRepository.getInstance().getProfilePage(this.myGraph.getUid(), this.myGraph.getGraphIndex());
-		pV.getTitle().setText(Messages.getString("AddrThreadTable.binaryLoad")); //$NON-NLS-1$
-		pV.getTitle2().setText(Messages.getString("AddrThreadTable.threadToFunctionTo")); //$NON-NLS-1$
-
 		// set the draw mode
 		this.myGraph.setDrawMode(Defines.THREADS_FUNCTIONS_BINARIES);
 
@@ -1238,8 +1208,7 @@
 
 		// create a reduced set of binary entries based on enabled thread and function entries
 		GppTrace gppTrace = (GppTrace) this.myGraph.getTrace();
-		Vector<ProfiledGeneric> binaries = gppTrace.setThreadFunctionBinary(graphIndex);
-		this.myGraph.setProfiledBinaries(binaries);
+		gppTrace.setThreadFunctionBinary(graphIndex, adapter, this.myGraph.getProfiledBinaries());
 
 		// put check marks on all rows, and sort by sample count
 		binaryTable.quickSort(COLUMN_ID_SAMPLE_COUNT, this.myGraph.getProfiledBinaries());
@@ -1337,7 +1306,7 @@
 					Vector<ProfiledGeneric> pGeneric = this.myGraph.getProfiledThreads();
 					int sampleCount = 0;
 					for (int i = 0; i < pGeneric.size(); i++)
-						if (pGeneric.elementAt(i).getTotalSampleCount() < thresholdCount)
+						if (adapter.getTotalSampleCount(pGeneric.elementAt(i)) < thresholdCount)
 							sampleCount += pGeneric.elementAt(i).getSampleCount(graphIndex);
 					this.myGraph.getThresholdThread().setSampleCount(graphIndex, sampleCount);
 				}
@@ -1363,87 +1332,12 @@
 				return;
 
 			GppTrace trace = (GppTrace)(this.myGraph.getTrace());
-			Vector<ProfiledGeneric> traceThreads = trace.getIndexedThreads();
-
-			int startSampleIndex = trace.getStartSampleIndex();
-			int endSampleIndex   = trace.getEndSampleIndex();
-			double percentPerSample;
-			if (startSampleIndex == endSampleIndex)
-				percentPerSample = 0.0;
-			else
-				percentPerSample = 100.0 / ((double)(endSampleIndex - startSampleIndex));
-
 			PIEvent be3 = new PIEvent(be.getValueObject(), PIEvent.SELECTION_AREA_CHANGED3);
 
 			switch (drawMode) {
 				case Defines.THREADS_BINARIES:
 				{
-					// get new binary counts and loads
-					Vector<ProfiledGeneric> traceBinaries = trace.getIndexedBinaries();
-					Vector<ProfiledGeneric> graphBinaries  = this.myGraph.getProfiledBinaries();
-					Hashtable<String,String> foundBinaries  = new Hashtable<String,String>();
-
-					// previous binaries are not necessarily graphed this time
-					Enumeration<ProfiledGeneric> enu = graphBinaries.elements();
-					while (enu.hasMoreElements()) {
-						ProfiledBinary pBinary = (ProfiledBinary) enu.nextElement();
-						pBinary.setEnabled(graphIndex, false);
-					}
-					graphBinaries.clear();
-
-					ProfiledThreshold thresholdBinary = this.myGraph.getThresholdBinary();
-
-					if (thresholdBinary.isEnabled(graphIndex)) {
-						ArrayList<ProfiledGeneric> items = thresholdBinary.getItems(graphIndex);
-						// disable all items below the threshold
-						for (int i = 0; i < items.size(); i++) {
-							items.get(i).setEnabled(graphIndex, false);
-						}
-					}
-
-					GppSample[] sortedSamples = trace.getSortedGppSamples();
-
-					// set up in case we find binaries below the threshold
-					boolean lowBinary;
-					thresholdBinary.init(graphIndex);
-					
-					int binaryThreshold = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountBinary"); //$NON-NLS-1$
-					for (int i = startSampleIndex; i < endSampleIndex; i++) {
-						GppSample sample = sortedSamples[i];
-
-						ProfiledThread pThread = (ProfiledThread) traceThreads.elementAt(sample.threadIndex);
-						if (pThread.isEnabled(graphIndex)) {
-							// binary list is based on threads
-							ProfiledBinary pBinary = (ProfiledBinary) traceBinaries.elementAt(sample.binaryIndex);
-							String binaryName = pBinary.getNameString();
-
-							lowBinary = pBinary.getTotalSampleCount() < binaryThreshold;
-
-							if (!foundBinaries.containsKey(binaryName)) {
-								foundBinaries.put(binaryName, binaryName);
-								if (lowBinary) {
-									thresholdBinary.addItem(graphIndex, pBinary, 1);
-								} else {
-									pBinary.setEnabled(graphIndex, true);
-									pBinary.setSampleCount(graphIndex, 1);
-									graphBinaries.add(pBinary);
-								}
-							} else {
-								if (lowBinary)
-									thresholdBinary.incSampleCount(graphIndex);
-								else
-									pBinary.incSampleCount(graphIndex);
-							}
-						}
-					}
-
-					// set the % load
-					for (int i = 0; i < graphBinaries.size(); i++) {
-						ProfiledBinary pBinary = (ProfiledBinary) graphBinaries.elementAt(i);
-						pBinary.setLoadAndString(graphIndex, (float)(pBinary.getSampleCount(graphIndex)*percentPerSample));
-					}
-					thresholdBinary.setLoadAndString(graphIndex,
-							(float)(thresholdBinary.getSampleCount(graphIndex)*percentPerSample));
+					trace.setThreadBinary(graphIndex, adapter, this.myGraph.getProfiledBinaries());
 
 					// update the table items and redraw the table
 					this.myGraph.getBinaryTable().piEventReceived(be3);
@@ -1451,126 +1345,10 @@
 				}
 				case Defines.THREADS_BINARIES_FUNCTIONS:
 				{
-					// get new binary and function counts and loads
-					Vector<ProfiledGeneric> traceBinaries   = trace.getIndexedBinaries();
-					Vector<ProfiledGeneric> traceFunctions  = trace.getIndexedFunctions();
-					Vector<ProfiledGeneric> graphBinaries   = this.myGraph.getProfiledBinaries();
-					Vector<ProfiledGeneric> graphFunctions  = this.myGraph.getProfiledFunctions();
-					Hashtable<String,String> foundBinaries  = new Hashtable<String,String>();
-					Hashtable<String,String> foundFunctions = new Hashtable<String,String>();
-
-					// previous functions are not necessarily graphed this time
-					Enumeration<ProfiledGeneric> enuFunctions = graphFunctions.elements();
-					while (enuFunctions.hasMoreElements()) {
-						ProfiledFunction pFunction = (ProfiledFunction) enuFunctions.nextElement();
-						pFunction.setEnabled(graphIndex, false);
-					}
-					graphFunctions.clear();
-
-					ProfiledThreshold thresholdFunction = this.myGraph.getThresholdFunction();
-
-					if (thresholdFunction.isEnabled(graphIndex)) {
-						ArrayList<ProfiledGeneric> items = thresholdFunction.getItems(graphIndex);
-						// disable all items below the threshold
-						for (int i = 0; i < items.size(); i++) {
-							items.get(i).setEnabled(graphIndex, false);
-						}
-					}
-
-					// previous binaries are not necessarily graphed this time
-					Enumeration<ProfiledGeneric> enuBinary = graphBinaries.elements();
-					while (enuBinary.hasMoreElements()) {
-						ProfiledBinary pBinary = (ProfiledBinary) enuBinary.nextElement();
-						pBinary.setEnabled(graphIndex, false);
-					}
-					graphBinaries.clear();
-
-					ProfiledThreshold thresholdBinary = this.myGraph.getThresholdBinary();
-
-					if (thresholdBinary.isEnabled(graphIndex)) {
-						ArrayList<ProfiledGeneric> items = thresholdBinary.getItems(graphIndex);
-						// disable all items below the threshold
-						for (int i = 0; i < items.size(); i++) {
-							items.get(i).setEnabled(graphIndex, false);
-						}
-					}
-
-					GppSample[] sortedSamples = trace.getSortedGppSamples();
-
-					// set up in case we find functions below the threshold
-					boolean lowFunction;
-					thresholdFunction.init(graphIndex);
-
-					// set up in case we find binaries below the threshold
-					boolean lowBinary;
-					thresholdBinary.init(graphIndex);
-
-					int binaryThreshold = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountBinary"); //$NON-NLS-1$
-					for (int i = startSampleIndex; i < endSampleIndex; i++) {
-						GppSample sample = sortedSamples[i];
-
-						ProfiledThread pThread = (ProfiledThread) traceThreads.elementAt(sample.threadIndex);
-						if (pThread.isEnabled(graphIndex)) {
-							// binary list is based on threads
-							ProfiledBinary pBinary = (ProfiledBinary) traceBinaries.elementAt(sample.binaryIndex);
-							String binaryName = pBinary.getNameString();
-
-							lowBinary = pBinary.getTotalSampleCount() < binaryThreshold;
-
-							if (!foundBinaries.containsKey(binaryName)) {
-								foundBinaries.put(binaryName, binaryName);
-								if (lowBinary) {
-									thresholdBinary.addItem(graphIndex, pBinary, 1);
-								} else {
-									pBinary.setEnabled(graphIndex, true);
-									pBinary.setSampleCount(graphIndex, 1);
-									graphBinaries.add(pBinary);
-								}
-							} else {
-								if (lowBinary)
-									thresholdBinary.incSampleCount(graphIndex);
-								else
-									pBinary.incSampleCount(graphIndex);
-							}
-
-							// function list is based on threads and binaries
-							ProfiledFunction pFunction = (ProfiledFunction) traceFunctions.elementAt(sample.functionIndex);
-							String functionName = pFunction.getNameString();
-
-							lowFunction = pFunction.getTotalSampleCount() < (Integer)NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountFunction"); //$NON-NLS-1$
-
-							if (!foundFunctions.containsKey(functionName)) {
-								foundFunctions.put(functionName, functionName);
-								if (lowFunction) {
-									thresholdFunction.addItem(graphIndex, pFunction, 1);
-								} else {
-									pFunction.setEnabled(graphIndex, true);
-									pFunction.setSampleCount(graphIndex, 1);
-									graphFunctions.add(pFunction);
-								}
-							} else {
-								if (lowFunction)
-									thresholdFunction.incSampleCount(graphIndex);
-								else
-									pFunction.incSampleCount(graphIndex);
-							}
-						}
-					}
-
-					// set the % load
-					for (int i = 0; i < graphBinaries.size(); i++) {
-						ProfiledBinary pBinary = (ProfiledBinary) graphBinaries.elementAt(i);
-						pBinary.setLoadAndString(graphIndex, (float)(pBinary.getSampleCount(graphIndex)*percentPerSample));
-					}
-					thresholdBinary.setLoadAndString(graphIndex,
-							(float)(thresholdBinary.getSampleCount(graphIndex)*percentPerSample));
-
-					for (int i = 0; i < graphFunctions.size(); i++) {
-						ProfiledFunction pFunction = (ProfiledFunction) graphFunctions.elementAt(i);
-						pFunction.setLoadAndString(graphIndex, (float)(pFunction.getSampleCount(graphIndex)*percentPerSample));
-					}
-					thresholdFunction.setLoadAndString(graphIndex,
-							(float)(thresholdFunction.getSampleCount(graphIndex)*percentPerSample));
+					// previous binaries are not necessarily graphed this time - reset
+					trace.setThreadBinary(graphIndex, adapter, this.myGraph.getProfiledBinaries());
+					// previous functions are not necessarily graphed this time - reset
+					trace.setThreadBinaryFunction(graphIndex, adapter, this.myGraph.getProfiledFunctions());
 
 					// update the table items and redraw the table
 					this.myGraph.getBinaryTable().piEventReceived(be3);
@@ -1579,72 +1357,8 @@
 				}
 				case Defines.THREADS_FUNCTIONS:
 				{
-					// get new function counts and loads
-					Vector<ProfiledGeneric> traceFunctions  = trace.getIndexedFunctions();
-					Vector<ProfiledGeneric> graphFunctions  = this.myGraph.getProfiledFunctions();
-					Hashtable<String,String> foundFunctions = new Hashtable<String,String>();
-
 					// previous functions are not necessarily graphed this time
-					Enumeration<ProfiledGeneric> enu = graphFunctions.elements();
-					while (enu.hasMoreElements()) {
-						ProfiledFunction pFunction = (ProfiledFunction) enu.nextElement();
-						pFunction.setEnabled(graphIndex, false);
-					}
-					graphFunctions.clear();
-
-					ProfiledThreshold thresholdFunction = this.myGraph.getThresholdFunction();
-
-					if (thresholdFunction.isEnabled(graphIndex)) {
-						ArrayList<ProfiledGeneric> items = thresholdFunction.getItems(graphIndex);
-						// disable all items below the threshold
-						for (int i = 0; i < items.size(); i++) {
-							items.get(i).setEnabled(graphIndex, false);
-						}
-					}
-
-					GppSample[] sortedSamples = trace.getSortedGppSamples();
-
-					// set up in case we find functions below the threshold
-					boolean lowFunction;
-					thresholdFunction.init(graphIndex);
-
-					int functionThreshold = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountFunction"); //$NON-NLS-1$
-					for (int i = startSampleIndex; i < endSampleIndex; i++) {
-						GppSample sample = sortedSamples[i];
-
-						ProfiledThread pThread = (ProfiledThread) traceThreads.elementAt(sample.threadIndex);
-						if (pThread.isEnabled(graphIndex)) {
-							// function list is based on threads
-							ProfiledFunction pFunction = (ProfiledFunction) traceFunctions.elementAt(sample.functionIndex);
-							String functionName = pFunction.getNameString();
-
-							lowFunction = pFunction.getTotalSampleCount() < functionThreshold;
-
-							if (!foundFunctions.containsKey(functionName)) {
-								foundFunctions.put(functionName, functionName);
-								if (lowFunction) {
-									thresholdFunction.addItem(graphIndex, pFunction, 1);
-								} else {
-									pFunction.setEnabled(graphIndex, true);
-									pFunction.setSampleCount(graphIndex, 1);
-									graphFunctions.add(pFunction);
-								}
-							} else {
-								if (lowFunction)
-									thresholdFunction.incSampleCount(graphIndex);
-								else
-									pFunction.incSampleCount(graphIndex);
-							}
-						}
-					}
-
-					// set the % load
-					for (int i = 0; i < graphFunctions.size(); i++) {
-						ProfiledFunction pFunction = (ProfiledFunction) graphFunctions.elementAt(i);
-						pFunction.setLoadAndString(graphIndex, (float)(pFunction.getSampleCount(graphIndex)*percentPerSample));
-					}
-					thresholdFunction.setLoadAndString(graphIndex,
-							(float)(thresholdFunction.getSampleCount(graphIndex)*percentPerSample));
+					trace.setThreadFunction(graphIndex, adapter, this.myGraph.getProfiledFunctions());
 
 					// update the table items and redraw the table
 					this.myGraph.getFunctionTable().piEventReceived(be3);
@@ -1652,126 +1366,9 @@
 				}
 				case Defines.THREADS_FUNCTIONS_BINARIES:
 				{
-					// get new function and binary counts and loads
-					Vector<ProfiledGeneric> traceBinaries   = trace.getIndexedBinaries();
-					Vector<ProfiledGeneric> traceFunctions  = trace.getIndexedFunctions();
-					Vector<ProfiledGeneric> graphBinaries   = this.myGraph.getProfiledBinaries();
-					Vector<ProfiledGeneric> graphFunctions  = this.myGraph.getProfiledFunctions();
-					Hashtable<String,String> foundBinaries  = new Hashtable<String,String>();
-					Hashtable<String,String> foundFunctions = new Hashtable<String,String>();
-
-					// previous binaries are not necessarily graphed this time
-					Enumeration<ProfiledGeneric> enuBinaries = graphBinaries.elements();
-					while (enuBinaries.hasMoreElements()) {
-						ProfiledBinary pBinary = (ProfiledBinary) enuBinaries.nextElement();
-						pBinary.setEnabled(graphIndex, false);
-					}
-					graphBinaries.clear();
-
-					ProfiledThreshold thresholdBinary = this.myGraph.getThresholdBinary();
-
-					if (thresholdBinary.isEnabled(graphIndex)) {
-						ArrayList<ProfiledGeneric> items = thresholdBinary.getItems(graphIndex);
-						// disable all items below the threshold
-						for (int i = 0; i < items.size(); i++) {
-							items.get(i).setEnabled(graphIndex, false);
-						}
-					}
-
-					// previous functions are not necessarily graphed this time
-					Enumeration<ProfiledGeneric> enuFunctions = graphFunctions.elements();
-					while (enuFunctions.hasMoreElements()) {
-						ProfiledFunction pFunction = (ProfiledFunction) enuFunctions.nextElement();
-						pFunction.setEnabled(graphIndex, false);
-					}
-					graphFunctions.clear();
-
-					ProfiledThreshold thresholdFunction = this.myGraph.getThresholdFunction();
-
-					if (thresholdFunction.isEnabled(graphIndex)) {
-						ArrayList<ProfiledGeneric> items = thresholdFunction.getItems(graphIndex);
-						// disable all items below the threshold
-						for (int i = 0; i < items.size(); i++) {
-							items.get(i).setEnabled(graphIndex, false);
-						}
-					}
-
-					GppSample[] sortedSamples = trace.getSortedGppSamples();
-
-					// set up in case we find binaries below the threshold
-					boolean lowBinary;
-					thresholdBinary.init(graphIndex);
-
-					// set up in case we find functions below the threshold
-					boolean lowFunction;
-					thresholdFunction.init(graphIndex);
-
-					int functionThreshold = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountFunction"); //$NON-NLS-1$
-					for (int i = startSampleIndex; i < endSampleIndex; i++) {
-						GppSample sample = sortedSamples[i];
-
-						ProfiledThread pThread = (ProfiledThread) traceThreads.elementAt(sample.threadIndex);
-						if (pThread.isEnabled(graphIndex)) {
-							// function list is based on threads
-							ProfiledFunction pFunction = (ProfiledFunction) traceFunctions.elementAt(sample.functionIndex);
-							String functionName = pFunction.getNameString();
-
-							lowFunction = pFunction.getTotalSampleCount() < functionThreshold;
-
-							if (!foundFunctions.containsKey(functionName)) {
-								foundFunctions.put(functionName, functionName);
-								if (lowFunction) {
-									thresholdFunction.addItem(graphIndex, pFunction, 1);
-								} else {
-									pFunction.setEnabled(graphIndex, true);
-									pFunction.setSampleCount(graphIndex, 1);
-									graphFunctions.add(pFunction);
-								}
-							} else {
-								if (lowFunction)
-									thresholdFunction.incSampleCount(graphIndex);
-								else
-									pFunction.incSampleCount(graphIndex);
-							}
-
-							// binary list is based on threads and functions
-							ProfiledBinary pBinary = (ProfiledBinary) traceBinaries.elementAt(sample.binaryIndex);
-							String binaryName = pBinary.getNameString();
-
-							lowBinary = pBinary.getTotalSampleCount() < (Integer)NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountBinary"); //$NON-NLS-1$
-
-							if (!foundBinaries.containsKey(binaryName)) {
-								foundBinaries.put(binaryName, binaryName);
-								if (lowBinary) {
-									thresholdBinary.addItem(graphIndex, pBinary, 1);
-								} else {
-									pBinary.setEnabled(graphIndex, true);
-									pBinary.setSampleCount(graphIndex, 1);
-									graphBinaries.add(pBinary);
-								}
-							} else {
-								if (lowBinary)
-									thresholdBinary.incSampleCount(graphIndex);
-								else
-									pBinary.incSampleCount(graphIndex);
-							}
-						}
-					}
-
-					// set the % load
-					for (int i = 0; i < graphBinaries.size(); i++) {
-						ProfiledBinary pBinary = (ProfiledBinary) graphBinaries.elementAt(i);
-						pBinary.setLoadAndString(graphIndex, (float)(pBinary.getSampleCount(graphIndex)*percentPerSample));
-					}
-					thresholdBinary.setLoadAndString(graphIndex,
-							(float)(thresholdBinary.getSampleCount(graphIndex)*percentPerSample));
-
-					for (int i = 0; i < graphFunctions.size(); i++) {
-						ProfiledFunction pFunction = (ProfiledFunction) graphFunctions.elementAt(i);
-						pFunction.setLoadAndString(graphIndex, (float)(pFunction.getSampleCount(graphIndex)*percentPerSample));
-					}
-					thresholdFunction.setLoadAndString(graphIndex,
-							(float)(thresholdFunction.getSampleCount(graphIndex)*percentPerSample));
+					// previous functions and binaries are not necessarily graphed this time
+					trace.setThreadFunction(graphIndex, adapter, this.myGraph.getProfiledFunctions());
+					trace.setThreadFunctionBinary(graphIndex, adapter, this.myGraph.getProfiledBinaries());
 
 					// update the table items and redraw the table
 					this.myGraph.getBinaryTable().piEventReceived(be3);
@@ -1791,88 +1388,12 @@
 			int drawMode = this.myGraph.getDrawMode();
 			if (drawMode != Defines.THREADS_BINARIES_FUNCTIONS)
 				return;
-
+			
 			// we don't need to redraw the thread table, since it has not changed
-
-			GppTrace trace = (GppTrace)(this.myGraph.getTrace());
-			Vector<ProfiledGeneric> traceBinaries  = trace.getIndexedBinaries();
-
-			int graphIndex = this.myGraph.getGraphIndex();
-			int startSampleIndex = trace.getStartSampleIndex();
-			int endSampleIndex   = trace.getEndSampleIndex();
-			double percentPerSample;
-			if (startSampleIndex == endSampleIndex)
-				percentPerSample = 0.0;
-			else
-				percentPerSample = 100.0 / ((double)(endSampleIndex - startSampleIndex));
-
 			PIEvent be3 = new PIEvent(be.getValueObject(), PIEvent.SELECTION_AREA_CHANGED3);
-
-			// get new function counts and loads
-			Vector<ProfiledGeneric> traceFunctions = trace.getIndexedFunctions();
-			Vector<ProfiledGeneric> graphFunctions = this.myGraph.getProfiledFunctions();
-			Hashtable<String,String> foundFunctions = new Hashtable<String,String>();
-
-			// previous functions are not necessarily graphed this time
-			Enumeration<ProfiledGeneric> enu = graphFunctions.elements();
-			while (enu.hasMoreElements()) {
-				ProfiledFunction pFunction = (ProfiledFunction) enu.nextElement();
-				pFunction.setEnabled(graphIndex, false);
-			}
-			graphFunctions.clear();
-
-			ProfiledThreshold thresholdFunction = this.myGraph.getThresholdFunction();
-
-			if (thresholdFunction.isEnabled(graphIndex)) {
-				ArrayList<ProfiledGeneric> items = thresholdFunction.getItems(graphIndex);
-				// disable all items below the threshold
-				for (int i = 0; i < items.size(); i++) {
-					items.get(i).setEnabled(graphIndex, false);
-				}
-			}
-
-			GppSample[] sortedSamples = trace.getSortedGppSamples();
-
-			// set up in case we find functions below the threshold
-			boolean lowFunction;
-			thresholdFunction.init(graphIndex);
-
-			for (int i = startSampleIndex; i < endSampleIndex; i++) {
-				GppSample sample = sortedSamples[i];
-
-				ProfiledBinary pBinary = (ProfiledBinary) traceBinaries.elementAt(sample.binaryIndex);
-				if (pBinary.isEnabled(graphIndex)) {
-					// function list is based on binaries
-					ProfiledFunction pFunction = (ProfiledFunction) traceFunctions.elementAt(sample.functionIndex);
-					String functionName = pFunction.getNameString();
-
-					lowFunction = pFunction.getTotalSampleCount() < (Integer)NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountFunction"); //$NON-NLS-1$
-
-					if (!foundFunctions.containsKey(functionName)) {
-						foundFunctions.put(functionName, functionName);
-						if (lowFunction) {
-							thresholdFunction.addItem(graphIndex, pFunction, 1);
-						} else {
-							pFunction.setEnabled(graphIndex, true);
-							pFunction.setSampleCount(graphIndex, 1);
-							graphFunctions.add(pFunction);
-						}
-					} else {
-						if (lowFunction)
-							thresholdFunction.incSampleCount(graphIndex);
-						else
-							pFunction.incSampleCount(graphIndex);
-					}
-				}
-			}
-
-			// set the % load
-			for (int i = 0; i < graphFunctions.size(); i++) {
-				ProfiledFunction pFunction = (ProfiledFunction) graphFunctions.elementAt(i);
-				pFunction.setLoadAndString(graphIndex, (float)(pFunction.getSampleCount(graphIndex)*percentPerSample));
-			}
-			thresholdFunction.setLoadAndString(graphIndex,
-					(float)(thresholdFunction.getSampleCount(graphIndex)*percentPerSample));
+			GppTrace trace = (GppTrace)(this.myGraph.getTrace());
+			int graphIndex = this.myGraph.getGraphIndex();
+			trace.setThreadBinaryFunction(graphIndex, adapter, this.myGraph.getProfiledFunctions());
 
 			// update the table items and redraw the table
 			this.myGraph.getFunctionTable().piEventReceived(be3);
@@ -1886,94 +1407,20 @@
 				return;
 
 			// we don't need to redraw the thread table, since it has not changed
-
+			PIEvent be3 = new PIEvent(be.getValueObject(), PIEvent.SELECTION_AREA_CHANGED3);
 			GppTrace trace = (GppTrace)(this.myGraph.getTrace());
-			Vector<ProfiledGeneric> traceFunctions = trace.getIndexedFunctions();
-
 			int graphIndex = this.myGraph.getGraphIndex();
-			int startSampleIndex = trace.getStartSampleIndex();
-			int endSampleIndex   = trace.getEndSampleIndex();
-			double percentPerSample;
-			if (startSampleIndex == endSampleIndex)
-				percentPerSample = 0.0;
-			else
-				percentPerSample = 100.0 / ((double)(endSampleIndex - startSampleIndex));
-
-			PIEvent be3 = new PIEvent(be.getValueObject(), PIEvent.SELECTION_AREA_CHANGED3);
-
-			// get new counts and loads
-			Vector<ProfiledGeneric> traceBinaries   = trace.getIndexedBinaries();
-			Vector<ProfiledGeneric> graphBinaries   = this.myGraph.getProfiledBinaries();
-			Hashtable<String,String> foundBinaries  = new Hashtable<String,String>();
-
-			// previous binaries are not necessarily graphed this time
-			Enumeration<ProfiledGeneric> enu = graphBinaries.elements();
-			while (enu.hasMoreElements()) {
-				ProfiledBinary pBinary = (ProfiledBinary) enu.nextElement();
-				pBinary.setEnabled(graphIndex, false);
-			}
-			graphBinaries.clear();
-
-			ProfiledThreshold thresholdBinary = this.myGraph.getThresholdBinary();
-
-			if (thresholdBinary.isEnabled(graphIndex)) {
-				ArrayList<ProfiledGeneric> items = thresholdBinary.getItems(graphIndex);
-				// disable all items below the threshold
-				for (int i = 0; i < items.size(); i++) {
-					items.get(i).setEnabled(graphIndex, false);
-				}
-			}
-
-			GppSample[] sortedSamples = trace.getSortedGppSamples();
-
-			// set up in case we find binaries below the threshold
-			boolean lowBinary;
-			thresholdBinary.init(graphIndex);
-
-			int binaryThreshold = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountBinary"); //$NON-NLS-1$
-			for (int i = startSampleIndex; i < endSampleIndex; i++) {
-				GppSample sample = sortedSamples[i];
-
-				ProfiledFunction pFunction = (ProfiledFunction) traceFunctions.elementAt(sample.functionIndex);
-				if (pFunction.isEnabled(graphIndex)) {
-					// binary list is based on functions
-					ProfiledBinary pBinary = (ProfiledBinary) traceBinaries.elementAt(sample.binaryIndex);
-					String binaryName = pBinary.getNameString();
-
-					lowBinary = pBinary.getTotalSampleCount() < binaryThreshold;
-
-					if (!foundBinaries.containsKey(binaryName)) {
-						foundBinaries.put(binaryName, binaryName);
-						if (lowBinary) {
-							thresholdBinary.addItem(graphIndex, pBinary, 1);
-						} else {
-							pBinary.setEnabled(graphIndex, true);
-							pBinary.setSampleCount(graphIndex, 1);
-							graphBinaries.add(pBinary);
-						}
-					} else {
-						if (lowBinary)
-							thresholdBinary.incSampleCount(graphIndex);
-						else
-							pBinary.incSampleCount(graphIndex);
-					}
-				}
-			}
-
-			// set the % load
-			for (int i = 0; i < graphBinaries.size(); i++) {
-				ProfiledBinary pBinary = (ProfiledBinary) graphBinaries.elementAt(i);
-				pBinary.setLoadAndString(graphIndex, (float)(pBinary.getSampleCount(graphIndex)*percentPerSample));
-			}
-			thresholdBinary.setLoadAndString(graphIndex,
-					(float)(thresholdBinary.getSampleCount(graphIndex)*percentPerSample));
+			trace.setThreadFunctionBinary(graphIndex, adapter, this.myGraph.getProfiledBinaries());
 
 			// update the table items and redraw the table
 			this.myGraph.getBinaryTable().piEventReceived(be3);
 		}
 	}
 
-	public void setSelectedNames()
+	/**
+	 * this table's set of checkbox-selected rows has changed, so propagate that information
+	 */
+	private void setSelectedNames()
 	{
 		Object[] selectedValues = this.tableViewer.getCheckedElements();
         String[] threadNames = new String[selectedValues.length];
@@ -2055,6 +1502,10 @@
 
 	private class ColumnSelectionHandler extends SelectionAdapter
 	{
+		/* (non-Javadoc)
+		 * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+		 */
+		@Override
 		public void widgetSelected(SelectionEvent e)
         {
         	// wait for the previous sort to finish
@@ -2065,6 +1516,15 @@
         }
 	}
 
+	/**
+	 * Adds ProfiledGenerics and threshold items to the table data
+	 * (this.tableItemData and this.profiledThreads). Sorts the ProfiledGenerics
+	 * according to load; and sets the graph's sorted list accordingly. Refreshes
+	 * the TableViewer if parameter setInput is true.
+	 * 
+	 * @param setInput
+	 *            if true, reset the TableViewer
+	 */
 	public void updateProfiledAndItemData(boolean setInput)
 	{
 		tableItemData.clear();
@@ -2079,7 +1539,7 @@
 			profiledThreads.add(nextElement);
 		}
 
-		if (myGraph.getThresholdThread().getItemCount(myGraph.getGraphIndex()) != 0) {
+		if (myGraph.getThresholdThread().getItemCount() != 0) {
 			tableItemData.add(myGraph.getThresholdThread());
 			profiledThreads.add(myGraph.getThresholdThread());
 		}
@@ -2091,17 +1551,16 @@
 			public int compare(Object arg0, Object arg1)
 			{
 				if (arg0 instanceof ProfiledGeneric && arg1 instanceof ProfiledGeneric)
-					return ((ProfiledGeneric)arg0).getTotalSampleCount() -
-							((ProfiledGeneric)arg1).getTotalSampleCount();
-				else
-					return 0;
+					return (adapter.getTotalSampleCount((ProfiledGeneric)arg0)) -
+							adapter.getTotalSampleCount(((ProfiledGeneric)arg1));
+				return 0;
 			}
 		});
 
 		// now create the sorted list used to draw the graph
 		myGraph.getSortedThreads().clear();
 
-		if (myGraph.getThresholdThread().getItemCount(myGraph.getGraphIndex()) != 0)
+		if (myGraph.getThresholdThread().getItemCount() != 0)
 			myGraph.getSortedThreads().add(myGraph.getThresholdThread());
 
 		for (int i = 0; i < sorted.length; i++)
@@ -2119,6 +1578,7 @@
 
 		this.sorting = true;
 
+		//if the last element is a threshold element - remove it
 		ProfiledGeneric pGeneric = profiled.elementAt(profiled.size() - 1);
 
 		if (pGeneric instanceof ProfiledThreshold) {
@@ -2210,6 +1670,7 @@
 		
 		if (enabled) {
 			saveSamplesItem.addSelectionListener(new SelectionAdapter() { 
+				@Override
 				public void widgetSelected(SelectionEvent e) {
 					action("savePrioritySamples"); //$NON-NLS-1$
 				}
@@ -2219,6 +1680,7 @@
 		return saveSamplesItem;
 	}
 
+	@Override
 	protected Menu getTableMenu(Decorations parent, int graphIndex, int drawMode) {
 
 		// get rid of last Menu created so we don't have double menu
@@ -2366,7 +1828,7 @@
 		column = new TableColumn(tableViewer.getTable(), SWT.LEFT);
 		column.setText(COLUMN_HEAD_PRIORITY);
 		column.setWidth(COLUMN_WIDTH_PRIORITY);
-		column.setData(new Integer(COLUMN_ID_PRIORITY));
+		column.setData(Integer.valueOf(COLUMN_ID_PRIORITY));
 		column.setMoveable(true);
 		column.setResizable(true);
 		column.addSelectionListener(new ColumnSelectionHandler());
@@ -2375,27 +1837,35 @@
 	private Integer parsePriorityValue(String priorityString)
 	{
 		if (priorityString == null || priorityString.equals(Messages.getString("AddrThreadTable.unsolvedPriority"))) //$NON-NLS-1$
-			return new Integer(Integer.MIN_VALUE);
+			return Integer.MIN_VALUE;
 		else
 		{
 			int endIndex = priorityString.indexOf(Messages.getString("AddrThreadTable.priorityStringEnding")); //$NON-NLS-1$
 			int beginIndex = priorityString.indexOf(Messages.getString("AddrThreadTable.priorityStringStart")); //$NON-NLS-1$
 			String value = priorityString.substring(beginIndex+2, endIndex);
-			return new Integer(Integer.parseInt(value));
+			return Integer.parseInt(value);
 		}
 	}
 
-    // class to pass sample data to the save wizard
+    /** class to pass sample data to the save wizard */
     public class SavePrioritySampleString implements ISaveSamples {
     	int graphIndex;
     	int drawMode;
     	boolean done = false;
     	
+    	/**
+    	 * Constructor
+    	 * @param graphIndex
+    	 * @param drawMode
+    	 */
     	public SavePrioritySampleString(int graphIndex, int drawMode) {
     		this.graphIndex = graphIndex;
     		this.drawMode   = drawMode;
 		}
 
+    	/* (non-Javadoc)
+    	 * @see com.nokia.carbide.cpp.internal.pi.interfaces.ISaveSamples#getData()
+    	 */
     	public String getData() {
     		if (done)
     			return null;
@@ -2409,10 +1879,16 @@
  			return getData();
 		}
 
+		/* (non-Javadoc)
+		 * @see com.nokia.carbide.cpp.internal.pi.interfaces.ISaveSamples#getIndex()
+		 */
 		public int getIndex() {
 			return done ? 1 : 0;
 		}
 
+		/* (non-Javadoc)
+		 * @see com.nokia.carbide.cpp.internal.pi.interfaces.ISaveSamples#clear()
+		 */
 		public void clear() {
 			done = false;
 		}
@@ -2433,7 +1909,7 @@
     protected void createPrioritySample(ArrayList<PrioritySample> prioritySamples, int graphIndex, ProfiledThread pt, int startTime, int endTime) {
     	PrioritySample localSample = null;
     	boolean addedLocalSample = false;
-    	String priority = priorityTable.get(new Integer(pt.getThreadId()));
+    	String priority = priorityTable.get(Integer.valueOf(pt.getThreadId()));
 		
 		if (priority == null) {
 			prioritySamples.add(new PrioritySample(0, pt, Messages.getString("AddrThreadTable.unknownPriority"))); //$NON-NLS-1$
@@ -2518,8 +1994,8 @@
 				createPrioritySample(prioritySamples, graphIndex, pt, startIndex, endIndex); 
 			} else if (profiledThreads.get(i) instanceof ProfiledThreshold) {
 				ProfiledThreshold pth = (ProfiledThreshold) profiledThreads.get(i);
-				for (int j = 0; j < pth.getItems(graphIndex).size(); j++) {
-					pt = (ProfiledThread) pth.getItems(graphIndex).get(j);
+				for (int j = 0; j < pth.getItems().size(); j++) {
+					pt = (ProfiledThread) pth.getItems().get(j);
 					
 					if (pt.isEnabled(graphIndex) && pt.getSampleCount(graphIndex) > 0)
 						createPrioritySample(prioritySamples, graphIndex, pt, startIndex, endIndex); 
@@ -2538,4 +2014,5 @@
 		
 		return returnString;
 	}
+	
 }
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/pi/address/AddressPlugin.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/pi/address/AddressPlugin.java	Wed Apr 21 15:14:16 2010 +0300
@@ -20,20 +20,24 @@
 import java.io.File;
 import java.io.IOException;
 import java.io.Serializable;
+import java.net.URL;
 import java.util.ArrayList;
 import java.util.Enumeration;
 import java.util.Hashtable;
 import java.util.Vector;
 
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.draw2d.FigureCanvas;
 import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
 import org.eclipse.jface.action.MenuManager;
 import org.eclipse.jface.action.Separator;
 import org.eclipse.jface.resource.ImageDescriptor;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.SelectionAdapter;
 import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.RGB;
 import org.eclipse.swt.layout.FillLayout;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Display;
@@ -42,6 +46,7 @@
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.swt.widgets.Text;
 import org.eclipse.ui.PlatformUI;
+import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 
 import com.nokia.carbide.cpp.internal.pi.actions.SetThresholdsDialog;
@@ -59,22 +64,21 @@
 import com.nokia.carbide.cpp.internal.pi.plugin.model.AbstractPiPlugin;
 import com.nokia.carbide.cpp.internal.pi.plugin.model.IClassReplacer;
 import com.nokia.carbide.cpp.internal.pi.plugin.model.IEventListener;
+import com.nokia.carbide.cpp.internal.pi.plugin.model.IFinalizeTrace;
 import com.nokia.carbide.cpp.internal.pi.plugin.model.IRecordable;
 import com.nokia.carbide.cpp.internal.pi.plugin.model.IReportable;
 import com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace;
+import com.nokia.carbide.cpp.internal.pi.plugin.model.ITraceSMP;
 import com.nokia.carbide.cpp.internal.pi.plugin.model.IViewMenu;
 import com.nokia.carbide.cpp.internal.pi.plugin.model.IVisualizable;
 import com.nokia.carbide.cpp.internal.pi.resolvers.SymbolFileFunctionResolver;
 import com.nokia.carbide.cpp.internal.pi.test.AnalysisInfoHandler;
 import com.nokia.carbide.cpp.internal.pi.utils.PIUtilities;
-import com.nokia.carbide.cpp.internal.pi.visual.Defines;
-import com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph;
 import com.nokia.carbide.cpp.internal.pi.visual.GraphDrawRequest;
 import com.nokia.carbide.cpp.internal.pi.visual.PIEvent;
 import com.nokia.carbide.cpp.pi.core.SessionPreferences;
 import com.nokia.carbide.cpp.pi.editors.PIPageEditor;
 import com.nokia.carbide.cpp.pi.importer.SampleImporter;
-import com.nokia.carbide.cpp.pi.util.ColorPalette;
 import com.nokia.carbide.cpp.pi.util.GeneralMessages;
 
 
@@ -82,17 +86,26 @@
  * The main plugin class to be used in the desktop.
  */
 public class AddressPlugin extends AbstractPiPlugin
-		implements ITrace, IViewMenu, IClassReplacer, //IExportItem,
-					IReportable, IRecordable, IVisualizable, IEventListener
+		implements ITrace, ITraceSMP, IViewMenu, IClassReplacer, //IExportItem,
+					IReportable, IRecordable, IVisualizable, IEventListener, IFinalizeTrace
 {
 	private static final String HELP_CONTEXT_ID = PIPageEditor.PI_ID + ".address";  //$NON-NLS-1$
+
+	public static final String ACTION_COMBINED_CPU_VIEW = "combined_cpu_view";//$NON-NLS-1$
+	public static final String ACTION_SEPARATE_CPU_VIEW = "separate_cpu_view";//$NON-NLS-1$
+	public static final int[] TRACE_IDS_SMP = new int[]{1, 21, 41, 62};
+
 	
 //	private static HashMap<Integer,Long> uidToAddrThreadPeriod = new HashMap<Integer,Long>();
 
 	// There will be three graphs - one each for editor pages 0, 1, 2
 	// This code assumes that page 0 has the threads graph, 1 the binaries, and 2 the functions
-	private final static int GRAPH_COUNT = 3;
+	//private final static int GRAPH_COUNT = 3;
+	private final static int PAGE_COUNT = 3;
 	private boolean pagesCreated = false;
+	
+	private IAction actionCombinedCpuView;
+	private IAction actionSeparateCpuView;
 
 	// The shared instance.
 	private static AddressPlugin plugin;
@@ -115,11 +128,17 @@
 		setPlugin(this);
 	}
 
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace#getTraceClass()
+	 */
 	public Class getTraceClass()
 	{
 		return GppTrace.class;
 	}
 
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.IClassReplacer#getReplacedClass(java.lang.String)
+	 */
 	public Class getReplacedClass(String className)
 	{
 		if (   className.indexOf("com.nokia.carbide.cpp.pi.address.GppTrace") != -1 //$NON-NLS-1$
@@ -172,14 +191,14 @@
 			samplingInterval = (int) (((GppSample) trace.samples.get(1)).sampleSynchTime - ((GppSample) trace.samples.get(0)).sampleSynchTime); 
 		}
 			
-		NpiInstanceRepository.getInstance().activeUidSetPersistState("com.nokia.carbide.cpp.pi.address.samplingInterval", new Integer(samplingInterval)); //$NON-NLS-1$
+		NpiInstanceRepository.getInstance().activeUidSetPersistState("com.nokia.carbide.cpp.pi.address.samplingInterval", Integer.valueOf(samplingInterval)); //$NON-NLS-1$
 		
 		// make sure that the sorted samples array exists
 		if (trace.getSortedGppSamples() == null)
 			trace.sortGppSamples();
 
-		GppTraceGraph.refreshDataFromTrace(trace);
-		PIPageEditor.setTime(0.0f, 0.0f);
+		trace.refreshDataFromTrace(this.getGraphCount());
+//		PIPageEditor.setTime(0.0f, 0.0f);
 		long lastSampleTime = trace.getSample(trace.samples.size() - 1).sampleSynchTime;
 		PIPageEditor.currentPageEditor().setMaxEndTime(((double)lastSampleTime) / 1000.0f);
 	}
@@ -189,7 +208,7 @@
 		return (GppTrace)NpiInstanceRepository.getInstance().activeUidGetTrace("com.nokia.carbide.cpp.pi.address"); //$NON-NLS-1$
 	}
 
-	public GenericTraceGraph getTraceGraph(int graphIndex)
+	public IGppTraceGraph getTraceGraph(int graphIndex)
 	{
 		GppTrace trace = (GppTrace)NpiInstanceRepository.getInstance().activeUidGetTrace("com.nokia.carbide.cpp.pi.address"); //$NON-NLS-1$
 		
@@ -205,16 +224,6 @@
 		return (GenericTrace)NpiInstanceRepository.getInstance().activeUidGetTrace("com.nokia.carbide.cpp.pi.address"); //$NON-NLS-1$
 	}
 	
-/*
-	public GenericTraceGraph getTraceGraph(int graphIndex, int uid)
-	{	
-		GppTrace trace = (GppTrace)NpiInstanceRepository.getInstance().activeUidGetTrace("com.nokia.carbide.cpp.pi.address"); //$NON-NLS-1$
-
-		// if we already had it, then we can pass in the formatted trace data
-		return trace.getTraceGraph(graphIndex, uid);
-	}
-*/
-	
 	public Integer getLastSample(int graphIndex)
 	{
 		GppTrace trace = (GppTrace)NpiInstanceRepository.getInstance().activeUidGetTrace("com.nokia.carbide.cpp.pi.address"); //$NON-NLS-1$
@@ -223,15 +232,19 @@
 			return null;
 
 	  	//this sets GPP thread list visible by default
-	  	((GppTraceGraph)trace.getTraceGraph(graphIndex)).piEventReceived(new PIEvent(null, PIEvent.MOUSE_PRESSED));
+	  	trace.getTraceGraph(graphIndex).piEventReceived(new PIEvent(null, PIEvent.MOUSE_PRESSED));
 
-	  	return new Integer(trace.getLastSampleNumber());
+	  	return Integer.valueOf(trace.getLastSampleNumber());
 	}
 
 	public GraphDrawRequest getDrawRequest(int graphIndex) {
 		return null;
 	}
 
+	/**
+	 * Converts the given event string into a PIEvent if necessary, and passes it to the appropriate graph
+	 * @param eventString the event string indicating the action to be executed
+	 */
 	public void receiveSelectionEvent(String eventString)
 	{
 		if (eventString == null)
@@ -249,68 +262,109 @@
 		if (eventString.equals("fillSelected")) //$NON-NLS-1$
 	    {
 	    	PIEvent be = new PIEvent(null, PIEvent.SET_FILL_SELECTED_THREAD);
-	    	((GppTraceGraph)trace.getTraceGraph(PIPageEditor.THREADS_PAGE)).piEventReceived(be);
-	    	((GppTraceGraph)trace.getTraceGraph(PIPageEditor.BINARIES_PAGE)).piEventReceived(be);
-	    	((GppTraceGraph)trace.getTraceGraph(PIPageEditor.FUNCTIONS_PAGE)).piEventReceived(be);
+	    	for (int i = 0; i < getGraphCount(); i++) {
+		    	trace.getTraceGraph(i).piEventReceived(be);				
+			}
 	    	
 	    	NpiInstanceRepository.getInstance().activeUidSetPersistState("com.nokia.carbide.cpp.pi.address.fillAll", Boolean.FALSE); //$NON-NLS-1$
 	    }
 		else if (eventString.equals("fillAll")) //$NON-NLS-1$
 		{
 			PIEvent be = new PIEvent(null, PIEvent.SET_FILL_ALL_THREADS);
-	    	((GppTraceGraph)trace.getTraceGraph(PIPageEditor.THREADS_PAGE)).piEventReceived(be);
-	    	((GppTraceGraph)trace.getTraceGraph(PIPageEditor.BINARIES_PAGE)).piEventReceived(be);
-	    	((GppTraceGraph)trace.getTraceGraph(PIPageEditor.FUNCTIONS_PAGE)).piEventReceived(be);
+	    	for (int i = 0; i < getGraphCount(); i++) {
+		    	trace.getTraceGraph(i).piEventReceived(be);				
+			}
 	    	
 	    	NpiInstanceRepository.getInstance().activeUidSetPersistState("com.nokia.carbide.cpp.pi.address.fillAll", Boolean.TRUE); //$NON-NLS-1$
 		}
 		else if (eventString.equals("fillNone")) //$NON-NLS-1$
 		{
 			PIEvent be = new PIEvent(null, PIEvent.SET_FILL_OFF);
-	    	((GppTraceGraph)trace.getTraceGraph(PIPageEditor.THREADS_PAGE)).piEventReceived(be);
-	    	((GppTraceGraph)trace.getTraceGraph(PIPageEditor.BINARIES_PAGE)).piEventReceived(be);
-	    	((GppTraceGraph)trace.getTraceGraph(PIPageEditor.FUNCTIONS_PAGE)).piEventReceived(be);
+	    	for (int i = 0; i < getGraphCount(); i++) {
+		    	trace.getTraceGraph(i).piEventReceived(be);				
+			}
 	    	
 	    	NpiInstanceRepository.getInstance().activeUidSetPersistState("com.nokia.carbide.cpp.pi.address.fillAll", Boolean.FALSE); //$NON-NLS-1$
 		}
 		else if (eventString.equals("setBarOn")) //$NON-NLS-1$
 		{
 			PIEvent be = new PIEvent(null, PIEvent.GPP_SET_BAR_GRAPH_ON);
-	    	((GppTraceGraph)trace.getTraceGraph(PIPageEditor.THREADS_PAGE)).piEventReceived(be);
-	    	((GppTraceGraph)trace.getTraceGraph(PIPageEditor.BINARIES_PAGE)).piEventReceived(be);
-	    	((GppTraceGraph)trace.getTraceGraph(PIPageEditor.FUNCTIONS_PAGE)).piEventReceived(be);
+	    	for (int i = 0; i < getGraphCount(); i++) {
+		    	trace.getTraceGraph(i).piEventReceived(be);				
+			}
 	    	
 	    	NpiInstanceRepository.getInstance().activeUidSetPersistState("com.nokia.carbide.cpp.pi.address.bar", Boolean.TRUE); //$NON-NLS-1$
 		}
 		else if (eventString.equals("setBarOff")) //$NON-NLS-1$
 		{
 			PIEvent be = new PIEvent(null, PIEvent.GPP_SET_BAR_GRAPH_OFF);
-	    	((GppTraceGraph)trace.getTraceGraph(PIPageEditor.THREADS_PAGE)).piEventReceived(be);
-	    	((GppTraceGraph)trace.getTraceGraph(PIPageEditor.BINARIES_PAGE)).piEventReceived(be);
-	    	((GppTraceGraph)trace.getTraceGraph(PIPageEditor.FUNCTIONS_PAGE)).piEventReceived(be);
+	    	for (int i = 0; i < getGraphCount(); i++) {
+		    	trace.getTraceGraph(i).piEventReceived(be);				
+			}
 	    	
 	    	NpiInstanceRepository.getInstance().activeUidSetPersistState("com.nokia.carbide.cpp.pi.address.bar", Boolean.FALSE); //$NON-NLS-1$
 		}
 	  	else if (eventString.equals("resetToCurrentMode")) //$NON-NLS-1$
 	  	{
-	  		((GppTraceGraph)trace.getTraceGraph(currentPage)).action(eventString);
-	  	}
+	  		trace.getTraceGraph(currentPage).action(eventString);
+	  	} else if (eventString.equals(ACTION_COMBINED_CPU_VIEW) || eventString.equals(ACTION_SEPARATE_CPU_VIEW)){
+	  		boolean showCombined = eventString.equals(ACTION_COMBINED_CPU_VIEW); 
+
+			if (currentPage == PIPageEditor.THREADS_PAGE){
+				trace.getGppGraph(PIPageEditor.THREADS_PAGE, -1).setVisible(showCombined);
+				for (int cpu = 0; cpu < trace.getCPUCount(); cpu++) {
+					trace.getGppGraph(PIPageEditor.FUNCTIONS_PAGE + 1 + cpu, -1).setVisible(!showCombined);
+				}
+
+				ArrayList<ProfileVisualiser> pages = NpiInstanceRepository.getInstance().activeUidGetProfilePages();
+				//hiding of graphs needs to take affect
+				pages.get(PIPageEditor.THREADS_PAGE).getTopComposite().getSashForm().layout();
+				if (actionCombinedCpuView != null && actionCombinedCpuView.isChecked() != showCombined){
+					actionCombinedCpuView.setChecked(showCombined);
+				}
+				if (actionSeparateCpuView != null && actionSeparateCpuView.isChecked() == showCombined){
+					actionSeparateCpuView.setChecked(!showCombined);
+				}
+			}
+			
+			
+			NpiInstanceRepository.getInstance().activeUidSetPersistState(NpiInstanceRepository.PERSISTED_SHOW_COMBINED_CPU_VIEW, showCombined);	//$NON-NLS-1$				
+			
+	  	} 
 	}
 
 	public String getTraceName() {
 		return "Address/Thread";	//$NON-NLS-1$
 	}
 
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace#getTraceTitle()
+	 */
+	public String getTraceTitle() {
+		return Messages.getString("AddressPlugin.21"); //$NON-NLS-1$
+	}
+
 	public int getTraceId() {
 		return 1;
 	}
 
-	public ParsedTraceData parseTraceFile(File file /*, ProgressBar progressBar*/) throws IOException
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace#getTraceIdsSMP()
+	 */
+	public int[] getTraceIdsSMP() {
+		return TRACE_IDS_SMP;
+	}
+
+	public ParsedTraceData parseTraceFile(File file /*, ProgressBar progressBar*/) throws IOException{
+		return parseTraceFiles(new File[]{file});
+	}
+
+	public ParsedTraceData parseTraceFiles(File[] files) throws IOException
 	{
 //		progressBar.setString("Parsing address and thread trace");
 
         GppTraceParser gppParser = new GppTraceParser();
-        ParsedTraceData parsed = gppParser.parse(file);
+        ParsedTraceData parsed = gppParser.parse(files);
         SymbolFileFunctionResolver sffp = this.resolveSymbolFileParser(/*progressBar*/);
 
         parsed.functionResolvers = new FunctionResolver[]{sffp};
@@ -353,7 +407,7 @@
 			ProfiledThread pt = (ProfiledThread)e.nextElement();
 			data.add(pt.getNameString());
 			data.add(pt.getAverageLoadValueString(currentPage));
-			summary.put(new Integer(pt.getThreadId()), data);
+			summary.put(Integer.valueOf(pt.getThreadId()), data);
 		}
 		return summary;
 	}
@@ -379,6 +433,9 @@
 		return sortTypes;
 	}
 
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.IReportable#getActiveInfo(java.lang.Object, double, double)
+	 */
 	public String getActiveInfo(Object key, double startTime, double endTime)
 	{
 		int threadId;
@@ -405,10 +462,10 @@
 
 			String functionName = Messages.getString("AddressPlugin.2");  //$NON-NLS-1$
 
-			if (sample.currentFunctionSym != null)
-				functionName = sample.currentFunctionSym.functionName;
-			else if (sample.currentFunctionItt != null)
-				functionName = sample.currentFunctionItt.functionName;
+			if (sample.getCurrentFunctionSym() != null)
+				functionName = sample.getCurrentFunctionSym().getFunctionName();
+			else if (sample.getCurrentFunctionItt() != null)
+				functionName = sample.getCurrentFunctionItt().getFunctionName();
 
 			if (sample.thread.threadId.intValue() == threadId)
 			{
@@ -416,11 +473,11 @@
 				if (load != null)
 				{
 					functionLoad.remove(functionName);
-					functionLoad.put(functionName, new Integer(load.intValue()+1));
+					functionLoad.put(functionName, Integer.valueOf(load.intValue()+1));
 				}
 				else
 				{
-					functionLoad.put(functionName, new Integer(1));
+					functionLoad.put(functionName, Integer.valueOf(1));
 				}
 				threadSampleAmount++;
 			}
@@ -437,7 +494,7 @@
 		}
 
 		ArrayList<Object> sortedFunctions = new ArrayList<Object>();
-//		functionsShown = new Integer(functionsShownField.getText()).intValue();
+//		functionsShown = Integer.valueOf(functionsShownField.getText()).intValue();
 		while (functionLoad.size() != 0 && sortedFunctions.size() <= (functionsShown * 2) - 1)
 		{
 			String maxFunction = null;
@@ -454,7 +511,7 @@
 				}
 			}
 			sortedFunctions.add(maxFunction);
-			sortedFunctions.add(new Integer(maxCount));
+			sortedFunctions.add(Integer.valueOf(maxCount));
 			functionLoad.remove(maxFunction);
 		}
 
@@ -574,13 +631,17 @@
 		return reportManager;
 	}
 
+	/**
+	 * Adds actions to the Investigator top-menu 
+	 */
 	public MenuManager getViewOptionManager()
 	{
 		Action action;
 		
 		MenuManager manager = new MenuManager(Messages.getString("AddressPlugin.5"));  //$NON-NLS-1$
 		
-		action = new Action(Messages.getString("AddressPlugin.7"), Action.AS_CHECK_BOX) {  //$NON-NLS-1$
+		action = new Action(Messages.getString("AddressPlugin.7"), IAction.AS_CHECK_BOX) {  //$NON-NLS-1$
+			@Override
 			public void run() {
 				if (this.isChecked())
 					receiveSelectionEvent("setBarOn"); //$NON-NLS-1$
@@ -617,7 +678,8 @@
 			// set the initial value
 			NpiInstanceRepository.getInstance().activeUidSetPersistState("com.nokia.carbide.cpp.pi.address.fillAll", fillAll); //$NON-NLS-1$
 
-		action = new Action(Messages.getString("AddressPlugin.9"), Action.AS_CHECK_BOX) {  //$NON-NLS-1$
+		action = new Action(Messages.getString("AddressPlugin.9"), IAction.AS_CHECK_BOX) {  //$NON-NLS-1$
+			@Override
 			public void run() {
 				if (this.isChecked()) {
 					receiveSelectionEvent("fillAll"); //$NON-NLS-1$
@@ -642,13 +704,56 @@
 		
 		manager.add(new Separator());
 		
-		action = new Action(Messages.getString("AddressPlugin.12"), Action.AS_PUSH_BUTTON) {  //$NON-NLS-1$
+		action = new Action(Messages.getString("AddressPlugin.12"), IAction.AS_PUSH_BUTTON) {  //$NON-NLS-1$
+			@Override
 			public void run() {
 				new SetThresholdsDialog(Display.getCurrent());
 			}
 		};
 		action.setToolTipText(Messages.getString("AddressPlugin.24"));  //$NON-NLS-1$
 		manager.add(action);
+		
+		manager.add(new Separator());	
+		
+		
+		GppTrace trace = (GppTrace)NpiInstanceRepository.getInstance().activeUidGetTrace("com.nokia.carbide.cpp.pi.address"); //$NON-NLS-1$
+		
+		if (trace != null && trace.getCPUCount() > 1){
+			//the following are SMP-related view options
+			manager.add(new Separator());
+
+			boolean showCombinedCPUView  = true;
+			
+			obj = NpiInstanceRepository.getInstance().activeUidGetPersistState(NpiInstanceRepository.PERSISTED_SHOW_COMBINED_CPU_VIEW);	
+			if ((obj != null) && (obj instanceof Boolean)){
+				showCombinedCPUView = (Boolean)obj;				
+			}
+			
+			actionCombinedCpuView = new Action(Messages.getString("AddressPlugin.14"), IAction.AS_RADIO_BUTTON) {  //$NON-NLS-1$
+				@Override
+				public void run() {
+					if (this.isChecked()){
+						receiveSelectionEvent(ACTION_COMBINED_CPU_VIEW); 						
+					}
+				}
+			};
+			actionCombinedCpuView.setChecked(showCombinedCPUView);
+			actionCombinedCpuView.setToolTipText(Messages.getString("AddressPlugin.18")); //$NON-NLS-1$
+			manager.add(actionCombinedCpuView);
+
+			actionSeparateCpuView = new Action(Messages.getString("AddressPlugin.19"), IAction.AS_RADIO_BUTTON) {  //$NON-NLS-1$
+				@Override
+				public void run() {
+					if (this.isChecked()){
+						receiveSelectionEvent(ACTION_SEPARATE_CPU_VIEW);  						
+					}
+				}
+			};
+			actionSeparateCpuView.setChecked(!showCombinedCPUView);
+			actionSeparateCpuView.setToolTipText(Messages.getString("AddressPlugin.20")); //$NON-NLS-1$
+			manager.add(actionSeparateCpuView);
+			
+		}
 
 		return manager;
 	}
@@ -673,7 +778,7 @@
 			ProfiledThread pt = (ProfiledThread)e.nextElement();
 			// backward compatibility with old Swing Color
 			java.awt.Color tmpAWTColor = new java.awt.Color(pt.getColor().getRed(),pt.getColor().getGreen(),pt.getColor().getBlue());
-			threadColors.put(new Integer(pt.getThreadId()), tmpAWTColor);
+			threadColors.put(Integer.valueOf(pt.getThreadId()), tmpAWTColor);
 		}
 		e = trace.getSortedBinariesElements();
 		while (e.hasMoreElements())
@@ -709,79 +814,8 @@
 		
 		try {
 			final GppTrace trace = (GppTrace)NpiInstanceRepository.getInstance().activeUidGetTrace("com.nokia.carbide.cpp.pi.address"); //$NON-NLS-1$
-
-			Vector<Object> tmpData = (Vector<Object>)data;
-			Hashtable<Integer,java.awt.Color> threadColors = (Hashtable<Integer,java.awt.Color>)tmpData.elementAt(0);
-			Hashtable<String,java.awt.Color> binaryColors = (Hashtable<String,java.awt.Color>)tmpData.elementAt(1);
-			Hashtable<String,java.awt.Color> functionColors = (Hashtable<String,java.awt.Color>)tmpData.elementAt(2);
-
-			boolean changed;
-			Enumeration<ProfiledGeneric> e;
-			
-			changed = false;
-			e = trace.getSortedThreadsElements();
-			while (e.hasMoreElements())
-			{
-				ProfiledThread pt = (ProfiledThread)e.nextElement();
-				// backward compatibility with old Swing Color
-				java.awt.Color tmpAWTColor = threadColors.get(new Integer(pt.getThreadId()));
-				if (tmpAWTColor != null) {
-					Color color = ColorPalette.getColor(new RGB(tmpAWTColor.getRed(), tmpAWTColor.getGreen(), tmpAWTColor.getBlue()));
-					if (color != null) {
-						pt.setColor(color);
-						changed = true;
-					}
-				}
-			}
-			
-			final int uid = NpiInstanceRepository.getInstance().activeUid();
-
-			if (changed) {
-				// need to provide new colors for the thread load table
-				trace.getGppGraph(PIPageEditor.THREADS_PAGE, uid).getThreadTable().addColor(Defines.THREADS);
-			}
-
-			changed = false;
-			e = trace.getSortedBinariesElements();
-			while (e.hasMoreElements())
-			{
-				ProfiledBinary pb = (ProfiledBinary)e.nextElement();
-				// backward compatibility with old Swing Color
-				java.awt.Color tmpAWTColor = binaryColors.get(pb.getNameString());
-				if (tmpAWTColor != null) {
-					Color color = ColorPalette.getColor(new RGB(tmpAWTColor.getRed(), tmpAWTColor.getGreen(), tmpAWTColor.getBlue()));
-					if (color != null) {
-						pb.setColor(color);
-						changed = true;
-					}
-				}
-			}
-
-			if (changed) {
-				// need to provide new colors for the binary load table
-				trace.getGppGraph(PIPageEditor.BINARIES_PAGE, uid).getBinaryTable().addColor(Defines.BINARIES);
-			}
-			
-			changed = false;
-			e = trace.getSortedFunctionsElements();
-			while (e.hasMoreElements())
-			{
-				ProfiledFunction pb = (ProfiledFunction)e.nextElement();
-				// backward compatibility with old Swing Color
-				java.awt.Color tmpAWTColor = functionColors.get(pb.getNameString());
-				if (tmpAWTColor != null) {
-					Color color = ColorPalette.getColor(new RGB(tmpAWTColor.getRed(), tmpAWTColor.getGreen(), tmpAWTColor.getBlue()));
-					if (color != null) {
-						pb.setColor(color);
-						changed = true;
-					}
-				}
-			}
-
-			if (changed) {
-				// need to provide new colors for the binary load table
-				trace.getGppGraph(PIPageEditor.FUNCTIONS_PAGE, uid).getFunctionTable().addColor(Defines.FUNCTIONS);
-			}
+			int uid = NpiInstanceRepository.getInstance().activeUid();
+			trace.setAdditionalData((Vector<Object>)data);
 			
 		} catch (Exception e) {
 			System.out.println("Could not load additional address/thread data!"); //$NON-NLS-1$
@@ -822,21 +856,35 @@
 		return AbstractPiPlugin.imageDescriptorFromPlugin("com.nokia.carbide.cpp.pi.address", path); //$NON-NLS-1$
 	}
 
-	// number of graphs supplied by this plugin
+	/**
+	 *  number of graphs supplied by this plugin
+	 */
 	public int getGraphCount() {
-		return GRAPH_COUNT;
+		final GppTrace trace = (GppTrace)NpiInstanceRepository.getInstance().activeUidGetTrace("com.nokia.carbide.cpp.pi.address"); //$NON-NLS-1$
+		int graphCount = trace.getCPUCount() > 1 ? PAGE_COUNT + trace.getCPUCount() : PAGE_COUNT;
+		return graphCount;
 	}
 
 	// page number of each graph supplied by this plugin
+	// in IVisualizable
 	public int getPageNumber(int graphIndex) {
+		return AddressPlugin.getPageIndex(graphIndex);
+	}
+	
+	/**
+	 * Returns the index of the page for the graph with this graphIndex
+	 * @param graphIndex the index of the graph
+	 * @return the page index, one of PIPageEditor.THREADS_PAGE, PIPageEditor.BINARIES_PAGE, PIPageEditor.FUNCTIONS_PAGE
+	 */
+	public static int getPageIndex(int graphIndex){
 		if (graphIndex == 0)
 			return PIPageEditor.THREADS_PAGE;
 		else if (graphIndex == 1)
 			return PIPageEditor.BINARIES_PAGE;
 		else if (graphIndex == 2)
 			return PIPageEditor.FUNCTIONS_PAGE;
-
-		return PIPageEditor.NEXT_AVAILABLE_PAGE;
+		else 
+			return PIPageEditor.THREADS_PAGE; //all SMP graphs go onto the threads page for now
 	}
 
 	// return whether this plugin's editor pages have been created
@@ -851,7 +899,7 @@
 
 	// number of editor pages to create
 	public int getCreatePageCount() {
-		return GRAPH_COUNT;
+		return PAGE_COUNT;
 	}
 
 	// editor page index for each created editor page
@@ -882,17 +930,16 @@
 			GeneralMessages.showErrorMessage("Address trace failed to create UI"); //$NON-NLS-1$
 			return null;
 		}
+		pageHelp = getPageHelpContextId(index);
 
 		if (index == 0) {
 			pageName = "Threads"; //$NON-NLS-1$
-			pageHelp = "threadsPageContext"; //$NON-NLS-1$
 		} else if (index == 1) {
 			pageName = "Binaries"; //$NON-NLS-1$
-			pageHelp = "binariesPageContext"; //$NON-NLS-1$
 		} else if (index == 2) {
 			pageName = "Functions"; //$NON-NLS-1$
-			pageHelp = "functionsPageContext"; //$NON-NLS-1$
-		} else {
+		}
+		else {
 			return null;
 		}
 
@@ -900,34 +947,42 @@
 		int uid = NpiInstanceRepository.getInstance().activeUid();
 		AnalysisInfoHandler infoHandler = NpiInstanceRepository.getInstance().activeUidGetAnalysisInfoHandler();
 		pV.getParserRepository().setPIAnalysisInfoHandler(infoHandler);
-		PlatformUI.getWorkbench().getHelpSystem().setHelp(pV.getContentPane(), HELP_CONTEXT_ID + "." + pageHelp); //$NON-NLS-1$
+		PlatformUI.getWorkbench().getHelpSystem().setHelp(pV.getContentPane(), pageHelp); //$NON-NLS-1$
 
 		return pV;
 	}
+	
+	/**
+	 * Returns the context help id for the given editor page index
+	 * @param pageIndex the editor page index to use
+	 * @return the context help id
+	 */
+	public static String getPageHelpContextId(int pageIndex){
+		if (pageIndex == 0) {
+			return HELP_CONTEXT_ID + "." + "threadsPageContext"; //$NON-NLS-1$
+		} else if (pageIndex == 1) {
+			return HELP_CONTEXT_ID + "." + "binariesPageContext"; //$NON-NLS-1$
+		} else if (pageIndex == 2) {
+			return HELP_CONTEXT_ID + "." + "functionsPageContext"; //$NON-NLS-1$
+		} else {
+			return null;
+		}
+	}
 
 	public void receiveEvent(String action, Event event) {
 		if (action.equals("scroll")) { //$NON-NLS-1$
-			if (   !(event.data instanceof String)
-				|| !((String)event.data).equals("FigureCanvas")) //$NON-NLS-1$
-				return;
 			
-			// the currently visible page has scrolled, so scroll the other pages
 			ArrayList<ProfileVisualiser> pages = NpiInstanceRepository.getInstance().activeUidGetProfilePages();
 			ProfileVisualiser pV;
 
-			int currentPV = PIPageEditor.currentPageIndex();
-			if (currentPV != PIPageEditor.THREADS_PAGE) {
-				pV = pages.get(PIPageEditor.THREADS_PAGE);
-				pV.getTopComposite().setScrolledOrigin(event.x, event.y);
-			}
-			if (currentPV != PIPageEditor.BINARIES_PAGE) {
-				pV = (ProfileVisualiser)pages.get(PIPageEditor.BINARIES_PAGE);
-				pV.getTopComposite().setScrolledOrigin(event.x, event.y);
-			}
-			if (currentPV != PIPageEditor.FUNCTIONS_PAGE) {
-				pV = (ProfileVisualiser)pages.get(PIPageEditor.FUNCTIONS_PAGE);
-				pV.getTopComposite().setScrolledOrigin(event.x, event.y);
-			}
+			// post the scroll event to all pages including the current page
+			// since there might be multiple graph components on each page even for the same plugin
+			pV = pages.get(PIPageEditor.THREADS_PAGE);
+			pV.getTopComposite().setScrolledOrigin(event.x, event.y, (FigureCanvas)event.data);
+			pV = (ProfileVisualiser)pages.get(PIPageEditor.BINARIES_PAGE);
+			pV.getTopComposite().setScrolledOrigin(event.x, event.y, (FigureCanvas)event.data);
+			pV = (ProfileVisualiser)pages.get(PIPageEditor.FUNCTIONS_PAGE);
+			pV.getTopComposite().setScrolledOrigin(event.x, event.y, (FigureCanvas)event.data);
 		} else if (action.equals("priority_init")) { //$NON-NLS-1$
 			// priority trace has been processed, so let the threads page know
 			Hashtable<Integer,String> priStringById = (Hashtable<Integer,String>)event.data;
@@ -935,20 +990,13 @@
 			if (getTrace() == null)
 				return;
 
-			GppTraceGraph addressGraph = ((GppTraceGraph) getTrace().getTraceGraph(PIPageEditor.THREADS_PAGE));
+			IGppTraceGraph addressGraph = ((IGppTraceGraph) getTrace().getTraceGraph(PIPageEditor.THREADS_PAGE));
 
 			if (addressGraph != null) {
 				addressGraph.updateThreadTablePriorities(priStringById);
 			}
 		}
 	}
-
-	/* (non-Javadoc)
-	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.IVisualizable#getGraphTitle(int)
-	 */
-	public String getGraphTitle(int graphIndex) {
-		return null;
-	}
 //	
 //	static public void putAddrThreadPeriod(long addrThreadPeriod) {
 //		uidToAddrThreadPeriod.put(NpiInstanceRepository.getInstance().activeUid(), addrThreadPeriod);
@@ -957,4 +1005,54 @@
 //	static public long getAddrThreadPeriod() {
 //		return uidToAddrThreadPeriod.get(NpiInstanceRepository.getInstance().activeUid());
 //	}
+	
+	/**
+	 * Returns a File corresponding to the given bundle relative path.
+	 * @param path the bundle relative path to resource to locate
+	 * @return the File corresponding to the given bundle relative path, or null
+	 * @throws IOException
+	 */
+	public File locateFileInBundle(final String path) throws IOException {
+		Bundle myBundle= getDefault().getBundle();
+		IPath ppath= new Path(path);
+		ppath= ppath.makeRelative();
+		URL[] urls= FileLocator.findEntries(myBundle, ppath);
+		if(urls.length != 1) {
+			return null;
+		}
+		return new File(FileLocator.toFileURL(urls[0]).getFile());
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.IFinalizeTrace#runOnDispose()
+	 */
+	public void runOnDispose() {
+		//no-op
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.IFinalizeTrace#runOnPartOpened()
+	 */
+	public void runOnPartOpened() {
+		//execute the initial action; since it affects the GIU, execute in UI thread
+		GppTrace trace = (GppTrace)NpiInstanceRepository.getInstance().activeUidGetTrace("com.nokia.carbide.cpp.pi.address"); //$NON-NLS-1$
+		
+		if (trace != null && trace.getCPUCount() > 1){
+			boolean showCombinedCPUView  = true;
+			
+			Object obj = NpiInstanceRepository.getInstance().activeUidGetPersistState(NpiInstanceRepository.PERSISTED_SHOW_COMBINED_CPU_VIEW);	
+			if ((obj != null) && (obj instanceof Boolean)){
+				showCombinedCPUView = (Boolean)obj;				
+			}
+			
+			final String actionRequest = showCombinedCPUView ? ACTION_COMBINED_CPU_VIEW : ACTION_SEPARATE_CPU_VIEW;
+			Display.getDefault().syncExec( new Runnable() {
+				public void run() {
+					receiveSelectionEvent(actionRequest);
+				}
+			});
+		}		
+		
+	}
+	
 }
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/pi/address/GenericAddrTable.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/pi/address/GenericAddrTable.java	Wed Apr 21 15:14:16 2010 +0300
@@ -49,12 +49,14 @@
 import org.eclipse.ui.actions.ActionFactory;
 import org.eclipse.ui.ide.IIDEActionConstants;
 
+import com.nokia.carbide.cpp.internal.pi.address.GppModelAdapter;
 import com.nokia.carbide.cpp.internal.pi.interfaces.ISaveSamples;
 import com.nokia.carbide.cpp.internal.pi.interfaces.ISaveTable;
 import com.nokia.carbide.cpp.internal.pi.model.ProfiledBinary;
 import com.nokia.carbide.cpp.internal.pi.model.ProfiledFunction;
 import com.nokia.carbide.cpp.internal.pi.model.ProfiledGeneric;
 import com.nokia.carbide.cpp.internal.pi.model.ProfiledThread;
+import com.nokia.carbide.cpp.internal.pi.model.ProfiledThreshold;
 import com.nokia.carbide.cpp.internal.pi.save.SaveTableWizard;
 import com.nokia.carbide.cpp.internal.pi.visual.Defines;
 import com.nokia.carbide.cpp.internal.pi.visual.GenericTable;
@@ -65,6 +67,7 @@
 {
 	protected GppTraceGraph myGraph;
 	protected Composite     parent;
+	protected GppModelAdapter adapter;
 
 	// sorting column and order
 	protected int     sortColumn = COLUMN_ID_SAMPLE_COUNT;
@@ -86,6 +89,13 @@
 	protected Action saveDrilldownAction;
 	
 	protected static int SAMPLES_AT_ONE_TIME = 1000;
+	
+	public GenericAddrTable(GppTraceGraph myGraph, Composite parent, GppModelAdapter adapter)
+	{
+		this.myGraph = myGraph;
+		this.parent  = parent;
+		this.adapter = adapter;
+	}
 
 	// class to pass sample data to the save wizard
     public class SaveSampleString implements ISaveSamples {
@@ -317,54 +327,55 @@
 		}
 	}
 
-	/*
-	 * Find if any threads with checkboxes checked
-	 */
-	protected boolean haveCheckedThread(GppTrace trace, int graphIndex)
-	{
-		ProfiledThread pThread;
-		for (ProfiledGeneric pGeneric: trace.getIndexedThreads()) {
-			if (pGeneric instanceof ProfiledThread) {
-				pThread = (ProfiledThread) pGeneric;
-				if (pThread.isEnabled(graphIndex))
-					return true;
-			}
-		}
-		return false;
-	}
-	
-
-	/*
-	 * Find if any binaries with checkboxes checked
-	 */
-	protected boolean haveCheckedBinary(GppTrace trace, int graphIndex)
-	{
-		ProfiledBinary pBinary;
-		for (ProfiledGeneric pGeneric: trace.getIndexedBinaries()) {
-			if (pGeneric instanceof ProfiledBinary) {
-				pBinary = (ProfiledBinary) pGeneric;
-				if (pBinary.isEnabled(graphIndex))
-					return true;
-			}
-		}
-		return false;
-	}
-
-	/*
-	 * Find if any functions with checkboxes checked
-	 */
-	protected boolean haveCheckedFunction(GppTrace trace, int graphIndex)
-	{
-		ProfiledFunction pFunction;
-		for (ProfiledGeneric pGeneric: trace.getIndexedFunctions()) {
-			if (pGeneric instanceof ProfiledFunction) {
-				pFunction = (ProfiledFunction) pGeneric;
-				if (pFunction.isEnabled(graphIndex))
-					return true;
-			}
-		}
-		return false;
-	}
+	//unused?
+//	/*
+//	 * Find if any threads with checkboxes checked
+//	 */
+//	protected boolean haveCheckedThread(GppTrace trace, int graphIndex)
+//	{
+//		ProfiledThread pThread;
+//		for (ProfiledGeneric pGeneric: trace.getIndexedThreads()) {
+//			if (pGeneric instanceof ProfiledThread) {
+//				pThread = (ProfiledThread) pGeneric;
+//				if (pThread.isEnabled(graphIndex))
+//					return true;
+//			}
+//		}
+//		return false;
+//	}
+//	
+//
+//	/*
+//	 * Find if any binaries with checkboxes checked
+//	 */
+//	protected boolean haveCheckedBinary(GppTrace trace, int graphIndex)
+//	{
+//		ProfiledBinary pBinary;
+//		for (ProfiledGeneric pGeneric: trace.getIndexedBinaries()) {
+//			if (pGeneric instanceof ProfiledBinary) {
+//				pBinary = (ProfiledBinary) pGeneric;
+//				if (pBinary.isEnabled(graphIndex))
+//					return true;
+//			}
+//		}
+//		return false;
+//	}
+//
+//	/*
+//	 * Find if any functions with checkboxes checked
+//	 */
+//	protected boolean haveCheckedFunction(GppTrace trace, int graphIndex)
+//	{
+//		ProfiledFunction pFunction;
+//		for (ProfiledGeneric pGeneric: trace.getIndexedFunctions()) {
+//			if (pGeneric instanceof ProfiledFunction) {
+//				pFunction = (ProfiledFunction) pGeneric;
+//				if (pFunction.isEnabled(graphIndex))
+//					return true;
+//			}
+//		}
+//		return false;
+//	}
 	
 	/* 
 	 * get list of matching samples based on draw mode 
@@ -372,9 +383,9 @@
 	private ArrayList<GppSample> getMatchingSamples(int drawMode, GppTrace trace, int startIndex, int endIndex, int graphIndex)
 	{
 		ArrayList<GppSample> samplesArray = new ArrayList<GppSample>(endIndex - startIndex > 1000 ? 1000 : endIndex - startIndex);
-		Vector<ProfiledGeneric> traceThreads   = trace.getIndexedThreads();
-		Vector<ProfiledGeneric> traceBinaries  = trace.getIndexedBinaries();
-		Vector<ProfiledGeneric> traceFunctions = trace.getIndexedFunctions();
+		Vector<ProfiledThread> traceThreads   = trace.getIndexedThreads();
+		Vector<ProfiledBinary> traceBinaries  = trace.getIndexedBinaries();
+		Vector<ProfiledFunction> traceFunctions = trace.getIndexedFunctions();
 		GppSample[] samples = trace.getSortedGppSamples();
 		GppSample sample;
 
@@ -516,7 +527,7 @@
 		String returnString = ""; //$NON-NLS-1$
 		
 		if (threads) {
-			Vector<ProfiledGeneric> traceThreads   = trace.getIndexedThreads();
+			Vector<ProfiledThread> traceThreads   = trace.getIndexedThreads();
 			if (startIndex == 0)
 				returnString = Messages.getString("GenericAddrTable.threadSampleHeading");  //$NON-NLS-1$
 			
@@ -1153,4 +1164,5 @@
 			fileMenuManager.remove("PISaveDrilldown");  //$NON-NLS-1$
 		}
 	}
+
 }
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/pi/address/GppSample.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/pi/address/GppSample.java	Wed Apr 21 15:14:16 2010 +0300
@@ -17,9 +17,10 @@
 
 package com.nokia.carbide.cpp.pi.address;
 
-import com.nokia.carbide.cpp.internal.pi.model.Function;
 import com.nokia.carbide.cpp.internal.pi.model.FunctionResolver;
 import com.nokia.carbide.cpp.internal.pi.model.GenericSampleWithFunctions;
+import com.nokia.carbide.cpp.internal.pi.model.IFunction;
+import com.nokia.carbide.cpp.internal.pi.model.UnresolvedFunction;
 
 public class GppSample extends GenericSampleWithFunctions
   {
@@ -32,11 +33,14 @@
     public GppThread   thread;
     public GppFunction function;
     public long programCounter;
-    public SomMapping somMapping;
+    //public SomMapping somMapping;
     
-    public Function currentFunctionSym;    
-    public Function currentFunctionItt;
+    private IFunction currentFunctionSym;    
+    private IFunction currentFunctionItt;
     
+    /** CPU core number */
+    public int cpuNumber;
+
     public void resolveFunction(FunctionResolver res)
     {
     	if (res.getResolverName().equals("Symbol"))  //$NON-NLS-1$
@@ -46,15 +50,68 @@
     	else if (res.getResolverName().equals("ITT"))  //$NON-NLS-1$
     	{
     		if (this.currentFunctionSym == null)
-    			this.currentFunctionItt = res.findFunctionForAddress(programCounter);
+    			this.currentFunctionItt = res.findFunctionForAddress(programCounter, sampleSynchTime);
     	}
     }
 
-    public String toString()
+
+	/**
+	 * @return the function resolved from symbol file
+	 */
+	public IFunction getCurrentFunctionSym() {
+		return currentFunctionSym;
+	}
+
+	/**
+	 * Setter for the function resolved from symbol file
+	 * @param currentFunctionSym the function to set
+	 */
+	public void setCurrentFunctionSym(IFunction currentFunctionSym) {
+		this.currentFunctionSym = currentFunctionSym;
+	}
+
+	/**
+	 * Getter
+	 * @return the function resolved from dynamic binary trace
+	 */
+	public IFunction getCurrentFunctionItt() {
+		if (currentFunctionItt == null && currentFunctionSym == null){
+			return new UnresolvedFunction(programCounter);
+		}
+		
+		return currentFunctionItt;
+	}
+
+	/**
+	 * Setter the function resolved from dynamic binary trace
+	 * @param currentFunctionItt the function to set
+	 */
+	public void setCurrentFunctionItt(IFunction currentFunctionItt) {
+		this.currentFunctionItt = currentFunctionItt;
+	}
+    
+	@Override
+    public String toString()    
 	  {
-	  	return "Gpp:#" + this.sampleSynchTime + " @0x"   //$NON-NLS-1$ //$NON-NLS-2$
-	  							  + Long.toHexString(this.programCounter) + " fS:"   //$NON-NLS-1$
-	  							  + this.currentFunctionSym != null ? this.currentFunctionSym.functionName : this.currentFunctionItt.functionName
-	  							  + " pr:" + this.thread.process.name + " th:"+ this.thread.threadName;  //$NON-NLS-1$ //$NON-NLS-2$
+  	StringBuilder sb = new StringBuilder("Gpp:#").append(this.sampleSynchTime);
+  	if (cpuNumber != -1){
+  		sb.append(" CPU: ").append(cpuNumber);
+  	}
+  	sb.append(" @0x").append(Long.toHexString(this.programCounter));   //$NON-NLS-1$ //$NON-NLS-2$
+  	if (currentFunctionSym != null){
+  		sb.append(" fS:").append(currentFunctionSym.getFunctionName());
+  	} else if (this.currentFunctionItt != null){
+  		sb.append(" fS:").append(currentFunctionItt.getFunctionName());
+  	}
+  	if (thread != null){
+  		if (thread.process != null && thread.process.name != null){
+  			sb.append(" pr:").append(this.thread.process.name);
+  		}
+  		if (thread.threadName != null){
+  			sb.append(" th:").append(this.thread.threadName);
+  		}
+  	}
+  	return sb.toString();
 	  }
+    
   }
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/pi/address/GppTableSorter.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/pi/address/GppTableSorter.java	Wed Apr 21 15:14:16 2010 +0300
@@ -220,10 +220,10 @@
 			tmp2 = (ProfiledThread)e.nextElement();
 			if (tmp1 != null)
 			{
-				Integer p1 = (Integer)priorities.get(new Integer(tmp1.getThreadId()));
-				Integer p2 = (Integer)priorities.get(new Integer(tmp2.getThreadId()));
-				p1 = (p1 == null) ? new Integer(Integer.MIN_VALUE) : p1;
-				p2 = (p2 == null) ? new Integer(Integer.MIN_VALUE) : p2;
+				Integer p1 = (Integer)priorities.get(Integer.valueOf(tmp1.getThreadId()));
+				Integer p2 = (Integer)priorities.get(Integer.valueOf(tmp2.getThreadId()));
+				p1 = (p1 == null) ? Integer.valueOf(Integer.MIN_VALUE) : p1;
+				p2 = (p2 == null) ? Integer.valueOf(Integer.MIN_VALUE) : p2;
 
 				if ((p1.compareTo(p2) != 0) && (p1.compareTo(p2) < 0) ^ sortAscending)
 				{
@@ -1246,8 +1246,8 @@
 		highToLowIndex = highIndex;
 		pivotIndex = (lowToHighIndex + highToLowIndex) / 2;
 		pivotValue = (ProfiledThread)elements.elementAt(pivotIndex);
-		Integer pivot = (Integer)priorities.get(new Integer(pivotValue.getThreadId()));
-		pivot = (pivot == null) ? new Integer(Integer.MIN_VALUE) : pivot;
+		Integer pivot = (Integer)priorities.get(Integer.valueOf(pivotValue.getThreadId()));
+		pivot = (pivot == null) ? Integer.valueOf(Integer.MIN_VALUE) : pivot;
 
 		newLowIndex = highIndex + 1;
 		newHighIndex = lowIndex - 1;
@@ -1256,29 +1256,29 @@
 		while ((newHighIndex + 1) < newLowIndex) // loop until partition complete
 		{
 			lowToHighValue = (ProfiledThread)elements.elementAt(lowToHighIndex);
-			Integer low = (Integer)priorities.get(new Integer(lowToHighValue.getThreadId()));
-			low = (low == null) ? new Integer(Integer.MIN_VALUE) : low;
+			Integer low = (Integer)priorities.get(Integer.valueOf(lowToHighValue.getThreadId()));
+			low = (low == null) ? Integer.valueOf(Integer.MIN_VALUE) : low;
 			while (lowToHighIndex < newLowIndex
 					&& ((low.compareTo(pivot) != 0) && ((low.compareTo(pivot) > 0) ^ sortAscending)))
 			{
 				newHighIndex = lowToHighIndex; // add element to lower part
 				lowToHighIndex ++;
 				lowToHighValue = (ProfiledThread)elements.elementAt(lowToHighIndex);
-				low = (Integer)priorities.get(new Integer(lowToHighValue.getThreadId()));
-				low = (low == null) ? new Integer(Integer.MIN_VALUE) : low;
+				low = (Integer)priorities.get(Integer.valueOf(lowToHighValue.getThreadId()));
+				low = (low == null) ? Integer.valueOf(Integer.MIN_VALUE) : low;
 			}
 
 			highToLowValue = (ProfiledThread)elements.elementAt(highToLowIndex);
-			Integer high = (Integer)priorities.get(new Integer(highToLowValue.getThreadId()));
-			high = (high == null) ? new Integer(Integer.MIN_VALUE) : high;
+			Integer high = (Integer)priorities.get(Integer.valueOf(highToLowValue.getThreadId()));
+			high = (high == null) ? Integer.valueOf(Integer.MIN_VALUE) : high;
 			while (newHighIndex <= highToLowIndex
 					&& ((high.compareTo(pivot) != 0) && ((high.compareTo(pivot) < 0) ^ sortAscending)))
 			{
 				newLowIndex = highToLowIndex; // add element to higher part
 				highToLowIndex --;
 				highToLowValue = (ProfiledThread)elements.elementAt(highToLowIndex);
-				high = (Integer)priorities.get(new Integer(highToLowValue.getThreadId()));
-			  	high = (high == null) ? new Integer(Integer.MIN_VALUE) : high;
+				high = (Integer)priorities.get(Integer.valueOf(highToLowValue.getThreadId()));
+			  	high = (high == null) ? Integer.valueOf(Integer.MIN_VALUE) : high;
 			}
 
 			// swap if needed
@@ -1288,10 +1288,10 @@
 			}
 			else if (lowToHighIndex < highToLowIndex) // not last element yet
 			{
-				high = (Integer)priorities.get(new Integer(highToLowValue.getThreadId()));
-				high = (high == null) ? new Integer(Integer.MIN_VALUE) : high;
-				low  = (Integer)priorities.get(new Integer(lowToHighValue.getThreadId()));
-				low  = (low == null) ? new Integer(Integer.MIN_VALUE) : low;
+				high = (Integer)priorities.get(Integer.valueOf(highToLowValue.getThreadId()));
+				high = (high == null) ? Integer.valueOf(Integer.MIN_VALUE) : high;
+				low  = (Integer)priorities.get(Integer.valueOf(lowToHighValue.getThreadId()));
+				low  = (low == null) ? Integer.valueOf(Integer.MIN_VALUE) : low;
 
 				compareResult = low.compareTo(high);
 				if ((compareResult == 0) || ((compareResult < 0) ^ sortAscending))
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/pi/address/GppTrace.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/pi/address/GppTrace.java	Wed Apr 21 15:14:16 2010 +0300
@@ -17,115 +17,127 @@
 
 package com.nokia.carbide.cpp.pi.address;
 
-import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Comparator;
 import java.util.Enumeration;
+import java.util.HashMap;
 import java.util.Hashtable;
+import java.util.List;
 import java.util.Vector;
 
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.SashForm;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.swt.widgets.TabItem;
+
+import com.nokia.carbide.cpp.internal.pi.address.GppModelAdapter;
+import com.nokia.carbide.cpp.internal.pi.address.GppTraceGraphSMP;
 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.FunctionResolver;
+import com.nokia.carbide.cpp.internal.pi.model.GenericSample;
 import com.nokia.carbide.cpp.internal.pi.model.GenericSampledTraceWithFunctions;
 import com.nokia.carbide.cpp.internal.pi.model.ProfiledBinary;
 import com.nokia.carbide.cpp.internal.pi.model.ProfiledFunction;
 import com.nokia.carbide.cpp.internal.pi.model.ProfiledGeneric;
 import com.nokia.carbide.cpp.internal.pi.model.ProfiledThread;
 import com.nokia.carbide.cpp.internal.pi.model.ProfiledThreshold;
-import com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph;
 import com.nokia.carbide.cpp.pi.editors.PIPageEditor;
 import com.nokia.carbide.cpp.pi.util.BinaryColorPalette;
+import com.nokia.carbide.cpp.pi.util.ColorPalette;
 import com.nokia.carbide.cpp.pi.util.FunctionColorPalette;
 import com.nokia.carbide.cpp.pi.util.ThreadColorPalette;
 
+/**
+ * Data model of the GPP trace (General Purpose Processor Trace). This class
+ * also creates the graphs and the ColorPalette that represent the trace.
+ * 
+ */
+public class GppTrace extends GenericSampledTraceWithFunctions {
+	private static final long serialVersionUID = -658505849351283165L;
 
-public class GppTrace extends GenericSampledTraceWithFunctions
-{
-	private static final long serialVersionUID = -658505849351283165L;
-	
-	// sample times start at a set interval, monotonically increase by that interval, and end at a
+	// sample times start at a set interval, monotonically increase by that
+	// interval, and end at a
 	// time equal to (number of elements - 1) times the interval
 	private boolean complete;
 	
+	private int graphCount = -1;
+
 	private transient GppSample[] sortedSamples = null;
 
 	// unchanging set of objects in the trace, ordered by total load
 	private transient Vector<ProfiledGeneric> sortedProfiledThreads;
 	private transient Vector<ProfiledGeneric> sortedProfiledBinaries;
 	private transient Vector<ProfiledGeneric> sortedProfiledFunctions;
-	
+
 	// unchanging set of objects in the trace, sorted by index
-	private transient Vector<ProfiledGeneric> profiledThreads;
-	private transient Vector<ProfiledGeneric> profiledBinaries;
-	private transient Vector<ProfiledGeneric> profiledFunctions;
-	
+	private transient Vector<ProfiledThread> profiledThreads;
+	private transient Vector<ProfiledBinary> profiledBinaries;
+	private transient Vector<ProfiledFunction> profiledFunctions;
+
 	// selection time based objects in the trace
-	private transient int startSampleIndex;	// first sample in the selection
-	private transient int endSampleIndex;		// last sample in the selection
-
-	// sample counts for the currently selected area of the graph 
-	private transient int[] threadSamples;
-	private transient int[] binarySamples;
-	private transient int[] functionSamples;
+	private transient int startSampleIndex; // first sample in the selection
+	private transient int endSampleIndex; // last sample in the selection
 
 	private transient GppTraceGraph[] graphs;
-	
-	// tie palette to a trace instead of graph since trace is the data it represents
+	private transient GppTraceGraphSMP[] smpGraph;
+
+	// TODO: This should be in the GppTraceGraph and not in the model!
+	// tie palette to a trace instead of graph since trace is the data it
+	// represents
 	private transient ThreadColorPalette threadColorPalette = null;
 	private transient BinaryColorPalette binaryColorPalette = null;
 	private transient FunctionColorPalette functionColorPalette = null;
-	
-	//protected int uid;
-	
-	public GppTrace() 
-	{
+
+	/** number of CPUs in the trace, should be 1 for non-SMP */
+	private int cpuCount;
+	/**
+	 * indicator whether this trace is SMP; false if cpuCount == 1, true if
+	 * greater
+	 */
+	private boolean isSMP;
+
+	// the following structures are for managing legend views in tabFolders
+	// this should really go into a GUI-related class but we haven't got 
+	// one with visibility of all graphs
+	//
+	/** tabFolders for the legend views, up to one per page */
+	private transient TabFolderWrapper[] legendTabFolders;
+
+	/**
+	 * Default constructor
+	 */
+	public GppTrace() {
+		cpuCount = 1; // default
 	}
-	
-	// for fast access, created a sorted array of samples
-	// this will remove duplicate times, find if times are missing, and
-	// find if times are increasing  
-	public void sortGppSamples()
-	{
+
+	/**
+	 * for fast access, created a sorted array of samples this will remove
+	 * duplicate times, find if times are missing, and find if times are
+	 * increasing
+	 */
+	public void sortGppSamples() {
 		// check if already sorted
 		if (this.sortedSamples != null)
 			return;
-		
-		int samplingInterval = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.samplingInterval"); //$NON-NLS-1$
-
-		complete = this.samples.size()*samplingInterval == this.getLastSampleNumber();
-		
-		this.sortedSamples = new GppSample[this.samples.size()];
-	
-		// fill the sorted array, assuming each sample time matches its (index+1)*samplingInterval
-		boolean sorted = true;
-		int arrayIndex = 0;
-		long lastTime = -1;
-		
-		for (int i = 0, sampleTime = 0; i < this.samples.size(); i++) {
-			Object o = this.samples.get(i);
-			if (o instanceof GppSample) {
-				  GppSample sample = (GppSample)o;
 
-				  // don't copy duplicates
-				  if (sample.sampleSynchTime == lastTime)
-					  continue;
+		complete = true;
+		List<GppSample> sortedSamplesList = new ArrayList<GppSample>();
+		int samplingInterval = (Integer) NpiInstanceRepository.getInstance()
+				.activeUidGetPersistState(
+						"com.nokia.carbide.cpp.pi.address.samplingInterval"); //$NON-NLS-1$
 
-				  this.sortedSamples[arrayIndex++] = sample;
-				  sampleTime += samplingInterval;
-				  
-				  // make sure times are in increasing order
-				  if (sample.sampleSynchTime < lastTime)
-					  sorted = false;
-				  
-				  lastTime = sample.sampleSynchTime;
-				  
-				  if (sample.sampleSynchTime != sampleTime) {
-					  this.complete = false;
-					  
-					  // find the time it does match, in case one is missing
-					  while (sample.sampleSynchTime > sampleTime)
-						  sampleTime += samplingInterval;
-				  }
+		// add samples to the list and sort the list
+		for (GenericSample sample : this.samples) {
+			if (sample instanceof GppSample) {
+				sortedSamplesList.add((GppSample) sample);
 			} else {
 				// error case
 				this.sortedSamples = new GppSample[1];
@@ -134,216 +146,328 @@
 				return;
 			}
 		}
-		
-		// if any duplicates, create a shorter array
-		if (arrayIndex != this.samples.size()) {
-			GppSample[] sampleObjects1 = new GppSample[this.samples.size()];
-			for (int i = 0; i < this.sortedSamples.length; i++)
-				sampleObjects1[i] = this.sortedSamples[i];
-			this.sortedSamples = sampleObjects1;
-		}
-		
-		if (!sorted) {
-			// now we have to actually sort
-			Arrays.sort(this.sortedSamples, new Comparator<Object>() {
-	
-				public int compare(Object arg0, Object arg1)
-				{
-					return (int) (((GppSample)arg0).sampleSynchTime - ((GppSample)arg1).sampleSynchTime);
-				}
-			});
+		Collections.sort(sortedSamplesList, new Comparator<Object>() {
+			public int compare(Object arg0, Object arg1) {
+				return (int) (((GppSample) arg0).sampleSynchTime - ((GppSample) arg1).sampleSynchTime);
+			}
+		});
 
-			// get rid of any duplicates and check for completeness
-			for (int i = 0, sampleTime = 0, length = this.sortedSamples.length; i < length; i++) {
-				GppSample sample = this.sortedSamples[i];
-
-				// don't copy duplicates
-				if (sample.sampleSynchTime == lastTime) {
-					for (int j = i; j < length - 1; j++) {
-						this.sortedSamples[j] = this.sortedSamples[j + 1];
-					}
-					length--;
-					this.complete = false;
-					continue;
+		// copy to array while ignoring any duplicates and checking for
+		// completeness
+		GppSample[] mySortedSamples = new GppSample[this.samples.size()];
+		long[] sampleTime = new long[cpuCount];
+		for (int cpu = 0; cpu < cpuCount; cpu++) {
+			sampleTime[cpu] = -1;
+		}
+		int i = 0;
+		for (GppSample gppSample : sortedSamplesList) {
+			int cpu = gppSample.cpuNumber < 0 ? 0 : gppSample.cpuNumber;
+			if (sampleTime[cpu] == -1
+					|| gppSample.sampleSynchTime > sampleTime[cpu]) {
+				if (sampleTime[cpu] != -1
+						&& gppSample.sampleSynchTime != sampleTime[cpu]
+								+ samplingInterval) {
+					complete = false;// gap to previous is larger than sampling
+										// interval
 				}
-				
-				sampleTime += samplingInterval;
-				
-				if (sample.sampleSynchTime != sampleTime) {
-					  this.complete = false;
-						  
-					  // find the time it does match, in case one is missing
-					  while (sample.sampleSynchTime > sampleTime)
-						  sampleTime += samplingInterval;
-			    }
+				sampleTime[cpu] = gppSample.sampleSynchTime;
+				mySortedSamples[i] = gppSample;
+				i++;
 			}
 		}
+		if (i < sortedSamplesList.size()) {
+			sortedSamples = new GppSample[i];
+			System.arraycopy(mySortedSamples, 0, sortedSamples, 0, i);
+			complete = false; // due to duplicates
+		} else {
+			sortedSamples = mySortedSamples;
+		}
 	}
-	
-	public boolean isGppSampleComplete()
-	{
+
+	/**
+	 * Returns true if the samples in the trace were complete, i.e. no
+	 * duplicates were found and samples adhered to the sampling interval
+	 * 
+	 * @return true if complete, false otherwise
+	 */
+	public boolean isGppSampleComplete() {
 		return this.complete;
 	}
-	
-	public GppSample[] getSortedGppSamples()
-	{
+
+	/**
+	 * Array of GppSamples sorted ascending by their sampling time
+	 * 
+	 * @return
+	 */
+	public GppSample[] getSortedGppSamples() {
 		return this.sortedSamples;
 	}
-	
-	public GppSample getGppSample(int number)
-	{
-		return (GppSample)this.samples.elementAt(number);
+
+	/**
+	 * Returns the sample at the given index from the raw collection of samples
+	 * (i.e. may not be not sorted)
+	 * 
+	 * @param number
+	 *            the index of the sample to return
+	 * @return
+	 */
+	public GppSample getGppSample(int number) {
+		return (GppSample) this.samples.elementAt(number);
 	}
-	
-	public GenericTraceGraph getTraceGraph(int graphIndex, int uid)
-	{	
-		return getGppGraph(graphIndex,uid);
+
+	/**
+	 * Returns the IGenericTraceGraph associated with the given graphIndex
+	 * 
+	 * @param graphIndex
+	 *            the graphIndex to use
+	 * @param uid
+	 *            the uid to use
+	 * @return
+	 */
+	public IGppTraceGraph getTraceGraph(int graphIndex, int uid) {
+		return getGppGraph(graphIndex, uid);
 	}
-	
-	public GppTraceGraph getGppGraph(int graphIndex, int uid)
-	{
+
+	/**
+	 * Returns the IGppTraceGraph associated with the given graphIndex. This
+	 * will create the IGppTraceGraph if it doesn't already exist.
+	 * 
+	 * @param graphIndex
+	 *            the graphIndex to use
+	 * @param uid
+	 *            the uid to use
+	 * @return
+	 */
+	public IGppTraceGraph getGppGraph(int graphIndex, int uid) {
 		if (graphs == null) {
 			graphs = new GppTraceGraph[3];
 		}
-			
+
 		// note that graphIndex needs not match the index sent to GppTraceGraph
-		if (   (graphIndex == PIPageEditor.THREADS_PAGE)
-			|| (graphIndex == PIPageEditor.BINARIES_PAGE)
-			|| (graphIndex == PIPageEditor.FUNCTIONS_PAGE)) {
-			if (graphs[graphIndex] == null)
+		if ((graphIndex == PIPageEditor.THREADS_PAGE)
+				|| (graphIndex == PIPageEditor.BINARIES_PAGE)
+				|| (graphIndex == PIPageEditor.FUNCTIONS_PAGE)) {
+			if (graphs[graphIndex] == null){
 				graphs[graphIndex] = new GppTraceGraph(graphIndex, this, uid);
+				graphs[graphIndex].init(GppTraceUtil.getPageIndex(graphIndex), this);
+				
+			}
 			return graphs[graphIndex];
+		} else if (isSingleCPUModeonSMP(graphIndex)
+				&& graphIndex <= PIPageEditor.FUNCTIONS_PAGE + cpuCount) {
+			
+			//a single-CPU threads graph on an SMP trace 
+			int cpuIndex = graphIndex - 3; // - PAGE_NUMBER
+			if (smpGraph == null) {
+				smpGraph = new GppTraceGraphSMP[cpuCount];
+			}
+			if (smpGraph[cpuIndex] == null){
+				smpGraph[cpuIndex] = new GppTraceGraphSMP(graphIndex, this, uid,
+						cpuIndex, PIPageEditor.THREADS_PAGE);	
+				smpGraph[cpuIndex].init(PIPageEditor.THREADS_PAGE, this);
+			}
+			return smpGraph[cpuIndex];
 		}
-	
 		return null;
 	}
-	
-	public GenericTraceGraph getTraceGraph(int graphIndex)
-	{
+
+
+	/**
+	 * Convenience method which will call {@link #getTraceGraph(int, int)} using
+	 * the activeUid()
+	 * 
+	 * @param graphIndex
+	 *            the graphIndex to use
+	 * @return IGenericTraceGraph for the given graphIndex and the active Uid
+	 */
+	public IGppTraceGraph getTraceGraph(int graphIndex) {
 		int uid = NpiInstanceRepository.getInstance().activeUid();
 		return getTraceGraph(graphIndex, uid);
 	}
-	
-	public void refineTrace(FunctionResolver resolver)
-	{
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.model.GenericSampledTraceWithFunctions
+	 * #refineTrace(com.nokia.carbide.cpp.internal.pi.model.FunctionResolver)
+	 */
+	@Override
+	public void refineTrace(FunctionResolver resolver) {
 		super.refineTrace(resolver);
 	}
 
-	public int getSortedThreadsCount()
-	{
+	/**
+	 * 
+	 * @return the number of ProfiledThreads in the trace
+	 */
+	public int getSortedThreadsCount() {
 		return this.sortedProfiledThreads.size();
 	}
-	
-	public Enumeration<ProfiledGeneric> getSortedThreadsElements()
-	{
+
+	/**
+	 * Returns the sorted ProfiledThreads in the trace
+	 * 
+	 * @return
+	 */
+	public Enumeration<ProfiledGeneric> getSortedThreadsElements() {
 		return this.sortedProfiledThreads.elements();
 	}
 
-	public Vector<ProfiledGeneric> getSortedThreads()
-	{
+	/**
+	 * Returns the sorted ProfiledThreads Vector
+	 * 
+	 * @return
+	 */
+	public Vector<ProfiledGeneric> getSortedThreads() {
 		if (this.sortedProfiledThreads == null)
 			this.sortedProfiledThreads = new Vector<ProfiledGeneric>();
 		return this.sortedProfiledThreads;
 	}
 
-	public Vector<ProfiledGeneric> getIndexedThreads()
-	{
+	/**
+	 * Returns the ProfiledThreads in the trace sorted by thread index (an
+	 * ordinal which gets set when ProfiledThreads are created).
+	 * 
+	 * @return
+	 */
+	public Vector<ProfiledThread> getIndexedThreads() {
 		if (this.profiledThreads == null)
-			this.profiledThreads = new Vector<ProfiledGeneric>();
+			this.profiledThreads = new Vector<ProfiledThread>();
 		return this.profiledThreads;
 	}
 
-	public int getSortedBinariesCount()
-	{
-	    return this.sortedProfiledBinaries.size();
+	public int getSortedBinariesCount() {
+		return this.sortedProfiledBinaries.size();
 	}
-	
-	public Enumeration<ProfiledGeneric> getSortedBinariesElements()
-	{
-	    return this.sortedProfiledBinaries.elements();
+
+	public Enumeration<ProfiledGeneric> getSortedBinariesElements() {
+		return this.sortedProfiledBinaries.elements();
 	}
-	
-	public Vector<ProfiledGeneric> getSortedBinaries()
-	{
+
+	public Vector<ProfiledGeneric> getSortedBinaries() {
 		if (this.sortedProfiledBinaries == null)
 			this.sortedProfiledBinaries = new Vector<ProfiledGeneric>();
-	    return this.sortedProfiledBinaries;
+		return this.sortedProfiledBinaries;
 	}
 
-	public Vector<ProfiledGeneric> getIndexedBinaries()
-	{
+	public Vector<ProfiledBinary> getIndexedBinaries() {
 		if (this.profiledBinaries == null)
-			this.profiledBinaries = new Vector<ProfiledGeneric>();
-	    return this.profiledBinaries;
+			this.profiledBinaries = new Vector<ProfiledBinary>();
+		return this.profiledBinaries;
 	}
 
-	public int getSortedFunctionsCount()
-	{
-	    return this.sortedProfiledFunctions.size();
+	public int getSortedFunctionsCount() {
+		return this.sortedProfiledFunctions.size();
 	}
-	
-	public Enumeration<ProfiledGeneric> getSortedFunctionsElements()
-	{
-        return this.sortedProfiledFunctions.elements();
+
+	public Enumeration<ProfiledGeneric> getSortedFunctionsElements() {
+		return this.sortedProfiledFunctions.elements();
 	}
-	
-	public Vector<ProfiledGeneric> getSortedFunctions()
-	{
+
+	public Vector<ProfiledGeneric> getSortedFunctions() {
 		if (this.sortedProfiledFunctions == null)
 			this.sortedProfiledFunctions = new Vector<ProfiledGeneric>();
 		return this.sortedProfiledFunctions;
 	}
-	
-	public Vector<ProfiledGeneric> getIndexedFunctions()
-	{
+
+	public Vector<ProfiledFunction> getIndexedFunctions() {
 		if (this.profiledFunctions == null)
-			this.profiledFunctions = new Vector<ProfiledGeneric>();
+			this.profiledFunctions = new Vector<ProfiledFunction>();
 		return this.profiledFunctions;
 	}
 
-	/*
-	 *	Determine the threads, binaries, and functions associated with a time period
-	 *  from the start time up to and including the end time. If the times are equal,
-	 *  do not include any samples.
+	/**
+	 * Determine the threads, binaries, and functions associated with a time
+	 * period from the start time up to and including the end time. If the times
+	 * are equal, do not include any samples.
+	 * <p>
+	 * Calculates and sets: <br>
+	 * - startSampleIndex <br>
+	 * - endSampleIndex
+	 * <p>
+	 * and for each ProfiledGeneric, calls <br>
+	 * - setSampleCount() <br>
+	 * - setLoadAndString()
+	 * 
+	 * @param startTime
+	 *            start time of the selected area in seconds
+	 * @param endTime
+	 *            end time of the selected area in seconds
 	 */
-	public void setSelectedArea() {
-		// create empty arrays to hold sample counts
-		this.threadSamples   = new int[this.profiledThreads.size()];
-		this.binarySamples   = new int[this.profiledBinaries.size()];
-		this.functionSamples = new int[this.profiledFunctions.size()];
+	public void setSelectedArea(final double startTime, final double endTime) {
 
-		double doubleStartTime = PIPageEditor.currentPageEditor().getStartTime();
-		double doubleEndTime   = PIPageEditor.currentPageEditor().getEndTime();
-
-		int samplingInterval = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.samplingInterval"); //$NON-NLS-1$
+		int samplingInterval = (Integer) NpiInstanceRepository.getInstance()
+				.activeUidGetPersistState(
+						"com.nokia.carbide.cpp.pi.address.samplingInterval"); //$NON-NLS-1$
 
 		GppSample[] sortedGppSamples = this.getSortedGppSamples();
 
 		// get the sample start time in integer multiples of milliseconds
-		startSampleIndex = ((int) ((doubleStartTime + 0.0005f)* 1000.0f))/samplingInterval;
-		if (startSampleIndex*samplingInterval < this.getFirstSampleNumber()) {
+		// the -1 is important, since sample.sampleSynchTime is one-based (not
+		// zero-based!)
+		startSampleIndex = ((((int) ((startTime + 0.0005f) * 1000.0f)) - 1)
+				* cpuCount / (samplingInterval));
+		if (startSampleIndex * samplingInterval < this.getFirstSampleNumber()) {
 			startSampleIndex = 0;
 		} else if (startSampleIndex > sortedGppSamples.length) {
 			startSampleIndex = sortedGppSamples.length - 1;
 		}
-			
+
 		// get the sample end time in integer multiples of milliseconds
-		// NOTE: endSampleIndex is one past the last allowed index, so that when no time
+		// NOTE: endSampleIndex is one past the last allowed index, so that when
+		// no time
 		// is selected startSampleIndex will equal end sample index
-		endSampleIndex = ((int) ((doubleEndTime + 0.0005f) * 1000.0f))/samplingInterval;
-		if (endSampleIndex*samplingInterval < this.getFirstSampleNumber()) {
+
+		// for SMP, endSampleIndex points to the first sample past this
+		// timestamp
+		endSampleIndex = (((int) ((endTime + 0.0005f) * 1000.0f)) * cpuCount / (samplingInterval));
+		if (endSampleIndex * samplingInterval < this.getFirstSampleNumber()) {
 			endSampleIndex = 0;
 		} else if (endSampleIndex > sortedGppSamples.length) {
-			endSampleIndex = sortedGppSamples.length - 1;
+			endSampleIndex = sortedGppSamples.length;
+		}
+
+		// TODO: CH: if the start and end index haven't changed (compared to
+		// previous), we could return here
+
+		// create empty arrays to hold total sample counts per index of
+		// ProfiledGeneric
+		int[] threadSamples = new int[this.profiledThreads.size()];
+		int[] binarySamples = new int[this.profiledBinaries.size()];
+		int[] functionSamples = new int[this.profiledFunctions.size()];
+
+		int[][] threadSamplesSMP = null;
+		int[][] binarySamplesSMP = null;
+		int[][] functionSamplesSMP = null;
+		int[] totalSamplesPerCPU = null;
+
+		if (isSMP) {
+			threadSamplesSMP = new int[cpuCount][];
+			binarySamplesSMP = new int[cpuCount][];
+			functionSamplesSMP = new int[cpuCount][];
+			for (int cpu = 0; cpu < cpuCount; cpu++) {
+				threadSamplesSMP[cpu] = new int[this.profiledThreads.size()];
+				binarySamplesSMP[cpu] = new int[this.profiledBinaries.size()];
+				functionSamplesSMP[cpu] = new int[this.profiledFunctions.size()];
+			}
+			totalSamplesPerCPU = new int[cpuCount];
 		}
 
 		if (this.isGppSampleComplete()) {
 			// find the sample counts in each category
 			// just use the start and end times as indices
 			for (int i = startSampleIndex; i < endSampleIndex; i++) {
-				threadSamples[sortedGppSamples[i].threadIndex]++;
-				binarySamples[sortedGppSamples[i].binaryIndex]++;
-				functionSamples[sortedGppSamples[i].functionIndex]++;
+				GppSample sample = sortedGppSamples[i];
+				threadSamples[sample.threadIndex]++;
+				binarySamples[sample.binaryIndex]++;
+				functionSamples[sample.functionIndex]++;
+				if (isSMP) {
+					threadSamplesSMP[sample.cpuNumber][sample.threadIndex]++;
+					binarySamplesSMP[sample.cpuNumber][sample.binaryIndex]++;
+					functionSamplesSMP[sample.cpuNumber][sample.functionIndex]++;
+					totalSamplesPerCPU[sample.cpuNumber]++;
+				}
 			}
 		} else {
 			// use a binary search to find the first sample
@@ -351,181 +475,202 @@
 			GppSample sample = null;
 			int lowerBound = 0;
 			int upperBound = sortedGppSamples.length;
-		    while (lowerBound <= upperBound) {
-		    	startIndex = (lowerBound + upperBound)/2;
+			while (lowerBound <= upperBound) {
+				startIndex = (lowerBound + upperBound) / 2;
 				sample = sortedGppSamples[startIndex];
-				if (startSampleIndex*samplingInterval == sample.sampleSynchTime) {
-		            break;
-				} else if (sample.sampleSynchTime > startSampleIndex*samplingInterval)
-		            upperBound = startIndex - 1;
-		        else
-		        	lowerBound = startIndex + 1;
-		    }
-		    
-		    // if there is no match, it's okay if the sample's time is larger than the
-		    // startTime, but not if the startTime is less
-		    if (sample.sampleSynchTime < startSampleIndex*samplingInterval)
-		    	startIndex++;
-	    	endSampleIndex = startIndex;
-		    
+				if (startSampleIndex * samplingInterval == sample.sampleSynchTime) {
+					break;
+				} else if (sample.sampleSynchTime > startSampleIndex
+						* samplingInterval)
+					upperBound = startIndex - 1;
+				else
+					lowerBound = startIndex + 1;
+			}
+
+			// if there is no match, it's okay if the sample's time is larger
+			// than the
+			// startTime, but not if the startTime is less
+			if (sample.sampleSynchTime < startSampleIndex * samplingInterval)
+				startIndex++;
+			endSampleIndex = startIndex;
+
 			// find the sample counts in each category
-	    	// use comparisons to find the end sample
-		    if (startIndex < this.samples.size()) {
-				while (sample.sampleSynchTime < endSampleIndex*samplingInterval) {
+			// use comparisons to find the end sample
+			if (startIndex < this.samples.size()) {
+				while (sample.sampleSynchTime < endSampleIndex
+						* samplingInterval) {
 					threadSamples[sample.threadIndex]++;
 					binarySamples[sample.binaryIndex]++;
 					functionSamples[sample.functionIndex]++;
-	
+					if (isSMP) {
+						threadSamplesSMP[sample.cpuNumber][sample.threadIndex]++;
+						binarySamplesSMP[sample.cpuNumber][sample.binaryIndex]++;
+						functionSamplesSMP[sample.cpuNumber][sample.functionIndex]++;
+						totalSamplesPerCPU[sample.cpuNumber]++;
+					}
+
 					endSampleIndex++;
 					if (endSampleIndex == sortedGppSamples.length)
 						break;
-	
+
 					sample = sortedGppSamples[endSampleIndex];
 				}
-				
-				if (   (endSampleIndex == this.samples.size())
-					|| (sample.sampleSynchTime > endSampleIndex*samplingInterval))
+
+				if ((endSampleIndex == this.samples.size())
+						|| (sample.sampleSynchTime > endSampleIndex
+								* samplingInterval))
 					endSampleIndex--;
-		    }
-		    endSampleIndex++;
+			}
+			endSampleIndex++;
 		}
-		
+
 		// set the sample counts and loads for all the trace-related graphs
 		// set the % load strings only for a tab's base table
-		// To optimise this, we could just set the main sample count and load per graph (e.g., thread stuff for page 0)
-		// To ptimise this, we could check drawMode and ignore sample counts when tables don't show them
+		// To optimise this, we could just set the main sample count and load
+		// per graph (e.g., thread stuff for page 0)
+		// To ptimise this, we could check drawMode and ignore sample counts
+		// when tables don't show them
 		// requires sample counts, a
 		double percentPerSample;
 		if (startSampleIndex == endSampleIndex)
 			percentPerSample = 0.0;
 		else
-			percentPerSample = 100.0 / ((double)(this.endSampleIndex - this.startSampleIndex));
+			percentPerSample = 100.0 / ((double) (this.endSampleIndex - this.startSampleIndex));
 
-		// NOTE: For slightly better performance, might have other functions rely on this one zeroing out sample counts
-		for (int i = 0; i < this.profiledThreads.size(); i++) {
+		// NOTE: For slightly better performance, might have other functions
+		// rely on this one zeroing out sample counts
+		for (int i = 0; i < profiledThreads.size(); i++) {
 			ProfiledGeneric pThread = this.profiledThreads.elementAt(i);
-			pThread.setSampleCount(PIPageEditor.THREADS_PAGE, this.threadSamples[i]);
-			pThread.setLoadAndString(PIPageEditor.THREADS_PAGE, (float)(this.threadSamples[i] * percentPerSample));
+			pThread.setSampleCount(PIPageEditor.THREADS_PAGE, threadSamples[i]);
+			pThread.setLoadAndString(PIPageEditor.THREADS_PAGE,
+					(float) (threadSamples[i] * percentPerSample));
+			if (isSMP) {
+				for (int cpu = 0; cpu < cpuCount; cpu++) {
+					//for now set this for the thread SMP graphs only
+					int graphIndex = cpu + 3;
+					pThread.setSampleCount(graphIndex, threadSamplesSMP[cpu][i]);
+					pThread.setLoadAndString(graphIndex, (float) threadSamplesSMP[cpu][i] * 100 / totalSamplesPerCPU[cpu]);
+				}
+			}
 		}
 
 		for (int i = 0; i < this.profiledBinaries.size(); i++) {
 			ProfiledGeneric pBinary = this.profiledBinaries.elementAt(i);
-			pBinary.setSampleCount(PIPageEditor.BINARIES_PAGE, this.binarySamples[i]);
-			pBinary.setLoadAndString(PIPageEditor.BINARIES_PAGE, (float)(this.binarySamples[i] * percentPerSample));
+			pBinary.setSampleCount(PIPageEditor.BINARIES_PAGE, binarySamples[i]);
+			pBinary.setLoadAndString(PIPageEditor.BINARIES_PAGE, (float) (binarySamples[i] * percentPerSample));
+			if (isSMP) {
+				//for now set this for the thread SMP graphs only
+				for (int cpu = 0; cpu < cpuCount; cpu++) {
+					int graphIndex = cpu + 3;
+					pBinary.setSampleCount(graphIndex, binarySamplesSMP[cpu][i]);
+					pBinary.setLoadAndString(graphIndex, (float) binarySamplesSMP[cpu][i] * 100	/ totalSamplesPerCPU[cpu]);
+				}
+			}
 		}
 
 		for (int i = 0; i < this.profiledFunctions.size(); i++) {
 			ProfiledGeneric pFunction = this.profiledFunctions.elementAt(i);
-			pFunction.setSampleCount(PIPageEditor.FUNCTIONS_PAGE, this.functionSamples[i]);
-			pFunction.setLoadAndString(PIPageEditor.FUNCTIONS_PAGE, (float)(this.functionSamples[i] * percentPerSample));
-		}		
-	}
-
-	/*
-	 * Based on a graph's set of enabled threads, produce a set of binaries, and
-	 * disable all other binaries for that graph
-	 */
-	public Vector<ProfiledGeneric> setThreadBinary(int graphIndex)
-	{
-		Vector<ProfiledGeneric>  graphBinaries = new Vector<ProfiledGeneric>();
-		Hashtable<String,String> foundBinaries = new Hashtable<String,String>();
-		
-		// disable all binaries for the given graph
-		for (int i = 0; i < this.profiledBinaries.size(); i++) {
-			ProfiledGeneric pBinary = this.profiledBinaries.elementAt(i);
-			pBinary.setEnabled(graphIndex, false);
-		}
-
-		// set up in case we find binaries below the threshold
-		boolean lowBinary;
-		ProfiledThreshold thresholdBinary = this.graphs[graphIndex].getThresholdBinary();
-		thresholdBinary.init(graphIndex);
-
-		// for each binary in the selected sample range, if its thread is enabled, add the binary
-		int binaryThreshold = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountBinary"); //$NON-NLS-1$
-		for (int i = this.startSampleIndex; i < this.endSampleIndex; i++) {
-			GppSample sample = this.sortedSamples[i];
-			ProfiledThread pThread = (ProfiledThread)
-							this.profiledThreads.elementAt(sample.threadIndex);
-
-			if (pThread.isEnabled(graphIndex)) {
-				ProfiledBinary pBinary = (ProfiledBinary) this.profiledBinaries.elementAt(sample.binaryIndex);
-				String binaryName = pBinary.getNameString();
-
-				lowBinary = pBinary.getTotalSampleCount() < binaryThreshold;
-
-				if (!foundBinaries.containsKey(binaryName)) {
-					pBinary.setEnabled(graphIndex, true);
-					foundBinaries.put(binaryName, binaryName);
-					if (lowBinary) {
-						thresholdBinary.addItem(graphIndex, pBinary, 1);
-					} else {
-						pBinary.setSampleCount(graphIndex, 1);
-						graphBinaries.add(pBinary);
-					}
-				} else {
-					if (lowBinary)
-						thresholdBinary.incSampleCount(graphIndex);
-					else
-						pBinary.incSampleCount(graphIndex);
+			pFunction.setSampleCount(PIPageEditor.FUNCTIONS_PAGE, functionSamples[i]);
+			pFunction.setLoadAndString(PIPageEditor.FUNCTIONS_PAGE, (float) (functionSamples[i] * percentPerSample));
+			if (isSMP) {
+				//for now set this for the thread SMP graphs only
+				for (int cpu = 0; cpu < cpuCount; cpu++) {
+					int graphIndex = cpu + 3;
+					pFunction.setSampleCount(graphIndex, functionSamplesSMP[cpu][i]);
+					pFunction.setLoadAndString(graphIndex, (float) functionSamplesSMP[cpu][i] * 100	/ totalSamplesPerCPU[cpu]);
 				}
 			}
 		}
+	}
+
+	/**
+	 * Based on a graph's set of enabled threads, produce a set of binaries, and
+	 * disable all other binaries for that graph
+	 * 
+	 * @param graphIndex
+	 *            index of the graph to operate on
+	 * @param adapter a GppModelAdapter encapsulating SMP or non-SMP specific model
+	 *            usage
+	 * @param binaries Collection of binaries with their sample count within selected
+	 *         area and filtered by selected threads in the given
+	 *         graph. This collection will be cleared and then updated.
+	 */
+	public void setThreadBinary(int graphIndex,
+			GppModelAdapter adapter, Vector<ProfiledGeneric> binaries) {
+		internalSetBinary(graphIndex, adapter, binaries, false, true);
 		
-		// since we are not converting float % load to string % load inside the table viewers, do it here
-		double percentPerSample;
-		if (startSampleIndex == endSampleIndex)
-			percentPerSample = 0.0;
-		else
-			percentPerSample = 100.0 / ((double)(this.endSampleIndex - this.startSampleIndex));
-
-		for (int i = 0; i < graphBinaries.size(); i++) {
-			ProfiledBinary pBinary = (ProfiledBinary) graphBinaries.elementAt(i);
-			pBinary.setLoadAndString(graphIndex, (float)(pBinary.getSampleCount(graphIndex) * percentPerSample));
-		}
-
-		return graphBinaries;
 	}
 
-	/*
-	 * Based on a graph's set of enabled threads and binaries, produce a set of functions, and
-	 * disable all other functions for that graph
+	/**
+	 * Internal implementation of {@link #setBinaryFunction(int)},
+	 * {@link #setBinaryThreadFunction(int, GppModelAdapter)},
+	 * {@link #setThreadBinaryFunction(int, GppModelAdapter)},
+	 * {@link #setThreadFunction(int, GppModelAdapter)}
+	 * 
+	 * @param graphIndex
+	 *            index of graph to use
+	 * @param adapter
+	 *            a GppModelAdapter encapsulating SMP or non-SMP specific model
+	 *            usage
+	 * @param graphFunctions Collection of functions with their sample count within selected
+	 *         area and filtered by selected threads and / or binaries in the
+	 *         given graph
+	 * @param noThreads
+	 * @param noBinaries
 	 */
-	public Vector<ProfiledGeneric> setThreadBinaryFunction(int graphIndex)
-	{
-		Vector<ProfiledGeneric>  graphFunctions = new Vector<ProfiledGeneric>();
-		Hashtable<String,String> foundFunctions = new Hashtable<String,String>();
-		
+	private void internalSetFunction(int graphIndex,
+			GppModelAdapter adapter, Vector<ProfiledGeneric> graphFunctions, boolean noThreads, boolean noBinaries) {
+		Hashtable<String, String> foundFunctions = new Hashtable<String, String>();
+
 		// disable all functions for the given graph
 		for (int i = 0; i < this.profiledFunctions.size(); i++) {
-			ProfiledFunction pFunction = (ProfiledFunction) this.profiledFunctions.elementAt(i);
+			ProfiledFunction pFunction = (ProfiledFunction) this.profiledFunctions
+					.elementAt(i);
 			pFunction.setEnabled(graphIndex, false);
 		}
+		graphFunctions.clear();
 
 		// set up in case we find functions below the threshold
 		boolean lowFunction;
-		ProfiledThreshold thresholdFunction = this.graphs[graphIndex].getThresholdFunction();
-		thresholdFunction.init(graphIndex);
+		ProfiledThreshold thresholdFunction = adapter.getThresholdItem(this, graphIndex, PIPageEditor.FUNCTIONS_PAGE);
+		adapter.init(thresholdFunction, graphIndex);
 
-		// for each function in the selected sample range, if its thread and binary are enabled,
+		// for each function in the selected sample range, if its thread and
+		// binary are enabled,
 		// add the function
-		int functionThreshold = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountFunction"); //$NON-NLS-1$
+		int functionThreshold = (Integer) NpiInstanceRepository
+				.getInstance()
+				.activeUidGetPersistState(
+						"com.nokia.carbide.cpp.pi.address.thresholdCountFunction"); //$NON-NLS-1$
+		int[] totalSamplesPerCPU = null;
+		if (isSingleCPUModeonSMP(graphIndex)) {
+			totalSamplesPerCPU = new int[cpuCount];
+		}
+
 		for (int i = this.startSampleIndex; i < this.endSampleIndex; i++) {
 			GppSample sample = this.sortedSamples[i];
-			ProfiledThread pThread = (ProfiledThread) this.profiledThreads.elementAt(sample.threadIndex);
-			ProfiledBinary pBinary = (ProfiledBinary) this.profiledBinaries.elementAt(sample.binaryIndex);
+			if (isSingleCPUModeonSMP(graphIndex)) {
+				totalSamplesPerCPU[sample.cpuNumber]++;
+				if (!adapter.matchingCPU(sample.cpuNumber)){
+					continue;
+				}
+			}
 
-			if (pThread.isEnabled(graphIndex) && pBinary.isEnabled(graphIndex)) {
-				ProfiledFunction pFunction = (ProfiledFunction) this.profiledFunctions.elementAt(sample.functionIndex);
+			if ((noThreads || ((ProfiledThread) this.profiledThreads
+					.elementAt(sample.threadIndex)).isEnabled(graphIndex))
+					&& (noBinaries || ((ProfiledBinary) this.profiledBinaries
+							.elementAt(sample.binaryIndex)).isEnabled(graphIndex))) {
+				ProfiledFunction pFunction = (ProfiledFunction) this.profiledFunctions
+						.elementAt(sample.functionIndex);
 				String functionName = pFunction.getNameString();
 
-				lowFunction = pFunction.getTotalSampleCount() < functionThreshold;
+				lowFunction = adapter.getTotalSampleCount(pFunction) < functionThreshold;
 
 				if (!foundFunctions.containsKey(functionName)) {
 					pFunction.setEnabled(graphIndex, true);
 					foundFunctions.put(functionName, functionName);
 					if (lowFunction) {
-						thresholdFunction.addItem(graphIndex, pFunction, 1);
+						adapter.addItem(thresholdFunction, graphIndex, pFunction, 1);
 					} else {
 						pFunction.setSampleCount(graphIndex, 1);
 						graphFunctions.add(pFunction);
@@ -538,131 +683,149 @@
 				}
 			}
 		}
-		
-		// since we are not converting float % load to string % load inside the table viewers, do it here
+
+		// since we are not converting float % load to string % load inside the
+		// table viewers, do it here
 		double percentPerSample;
 		if (startSampleIndex == endSampleIndex)
 			percentPerSample = 0.0;
-		else
-			percentPerSample = 100.0 / ((double)(this.endSampleIndex - this.startSampleIndex));
-
-		for (int i = 0; i < graphFunctions.size(); i++) {
-			ProfiledFunction pFunction = (ProfiledFunction) graphFunctions.elementAt(i);
-			pFunction.setLoadAndString(graphIndex, (float)(pFunction.getSampleCount(graphIndex)* percentPerSample));
-		}		
-
-		return graphFunctions;
-	}
-
-	public Vector<ProfiledGeneric> setBinaryThreadFunction(int graphIndex)
-	{
-		return setThreadBinaryFunction(graphIndex);
-	}
-	
-	/*
-	 * Based on a graph's set of enabled threads, produce a set of functions, and
-	 * disable all other functions for that graph
-	 */
-	public Vector<ProfiledGeneric> setThreadFunction(int graphIndex)
-	{
-		Vector<ProfiledGeneric>  graphFunctions = new Vector<ProfiledGeneric>();
-		Hashtable<String,String> foundFunctions = new Hashtable<String,String>();
-		
-		// disable all functions for the given graph
-		for (int i = 0; i < this.profiledFunctions.size(); i++) {
-			ProfiledFunction pFunction = (ProfiledFunction) this.profiledFunctions.elementAt(i);
-			pFunction.setEnabled(graphIndex, false);
+		else {
+			int total = isSingleCPUModeonSMP(graphIndex) ? adapter.getValueForCPU(totalSamplesPerCPU)
+					: (this.endSampleIndex - this.startSampleIndex);
+			percentPerSample = 100.0 / ((double) total);
 		}
 
-		// set up in case we find functions below the threshold
-		boolean lowFunction;
-		ProfiledThreshold thresholdFunction = this.graphs[graphIndex].getThresholdFunction();
-		thresholdFunction.init(graphIndex);
-
-		// for each function in the selected sample range, if its thread is enabled, add the function
-		int functionThreshold = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountFunction"); //$NON-NLS-1$
-		for (int i = this.startSampleIndex; i < this.endSampleIndex; i++) {
-			GppSample sample = this.sortedSamples[i];
-			ProfiledThread pThread = (ProfiledThread) this.profiledThreads.elementAt(sample.threadIndex);
-
-			if (pThread.isEnabled(graphIndex)) {
-				ProfiledFunction pFunction = (ProfiledFunction) this.profiledFunctions.elementAt(sample.functionIndex);
-				String functionName = pFunction.getNameString();
-
-				lowFunction = pFunction.getTotalSampleCount() < functionThreshold;
+		for (int i = 0; i < graphFunctions.size(); i++) {
+			ProfiledFunction pFunction = (ProfiledFunction) graphFunctions
+					.elementAt(i);
+			pFunction.setLoadAndString(graphIndex, (float) (pFunction.getSampleCount(graphIndex) * percentPerSample));
+		}
+	}
+	/**
+	 * Based on a graph's set of enabled threads and binaries, produce a set of
+	 * functions, and disable all other functions for that graph
+	 * 
+	 * @param graphIndex
+	 *            index of graph to use
+	 * @param adapter
+	 *            a GppModelAdapter encapsulating SMP or non-SMP specific model
+	 *            usage
+	 * @param functions The collection to clear and update. Collection of functions with their sample count within selected
+	 *         area and filtered by selected threads and binaries in the given
+	 *         graph
+	 */
+	public void setThreadBinaryFunction(int graphIndex,
+			GppModelAdapter adapter, Vector<ProfiledGeneric> functions) {
+		internalSetFunction(graphIndex, adapter, functions, false, false);		
+	}
 
-				if (!foundFunctions.containsKey(functionName)) {
-					pFunction.setEnabled(graphIndex, true);
-					foundFunctions.put(functionName, functionName);
-					if (lowFunction) {
-						thresholdFunction.addItem(graphIndex, pFunction, 1);
-					} else {
-						pFunction.setSampleCount(graphIndex, 1);
-						graphFunctions.add(pFunction);
-					}
-				} else {
-					if (lowFunction)
-						thresholdFunction.incSampleCount(graphIndex);
-					else
-						pFunction.incSampleCount(graphIndex);
-				}
-			}
-		}
-		
-		// since we are not converting float % load to string % load inside the table viewers, do it here
-		double percentPerSample;
-		if (startSampleIndex == endSampleIndex)
-			percentPerSample = 0.0;
-		else
-			percentPerSample = 100.0 / ((double)(this.endSampleIndex - this.startSampleIndex));
-
-		for (int i = 0; i < graphFunctions.size(); i++) {
-			ProfiledFunction pFunction = (ProfiledFunction) graphFunctions.elementAt(i);
-			pFunction.setLoadAndString(graphIndex, (float)(pFunction.getSampleCount(graphIndex) * percentPerSample));
-		}		
-		
-		return graphFunctions;
+	/**
+	 * Based on a graph's set of enabled threads and binaries, produce a set of
+	 * functions, and disable all other functions for that graph
+	 * 
+	 * @param graphIndex
+	 *            index of graph to use
+	 * @param adapter
+	 *            a GppModelAdapter encapsulating SMP or non-SMP specific model
+	 *            usage
+	 * @param functions The collection to clear and update. Collection of functions with their sample count within selected
+	 *         area and filtered by selected threads and binaries in the given
+	 *         graph
+	 */
+	public void setBinaryThreadFunction(int graphIndex, GppModelAdapter adapter, Vector<ProfiledGeneric> functions) {
+		internalSetFunction(graphIndex, adapter, functions, false, false);
 	}
 
-	/*
-	 * Based on a graph's set of enabled threads and functions, produce a set of binaries, and
-	 * disable all other binaries for that graph
+	/**
+	 * Based on a graph's set of enabled threads, produce a set of functions,
+	 * and disable all other functions for that graph
+
+	 * @param graphIndex
+	 *            index of graph to use
+	 * @param adapter
+	 *            a GppModelAdapter encapsulating SMP or non-SMP specific model
+	 *            usage
+	 * @param functions The collection to clear and update. Collection of functions with their sample count within selected
+	 *         area and filtered by selected threads in the given graph
 	 */
-	public Vector<ProfiledGeneric> setThreadFunctionBinary(int graphIndex)
-	{
-		Vector<ProfiledGeneric>  graphBinaries = new Vector<ProfiledGeneric>();
-		Hashtable<String,String> foundBinaries = new Hashtable<String,String>();
-		
+	public void setThreadFunction(int graphIndex, GppModelAdapter adapter, Vector<ProfiledGeneric> functions) {
+		internalSetFunction(graphIndex, adapter, functions, false, true);
+	}
+
+	/**
+	 * internal implementation for
+	 * {@link #setFunctionBinary(int, GppModelAdapter)},
+	 * {@link #setFunctionThreadBinary(int, GppModelAdapter)},
+	 * {@link #setThreadBinary(int, GppModelAdapter)},
+	 * {@link #setThreadFunctionBinary(int, GppModelAdapter)}
+	 * 
+	 * @param graphIndex
+	 *            index of the graph to use
+	 * @param adapter
+	 *            a GppModelAdapter encapsulating SMP or non-SMP specific model
+	 *            usage
+	 * @param graphBinaries the collection to update. Collection of ProfiledGeneric binaries filtered by selected
+	 *         threads and functions on the given graph in the selected time
+	 *         frame
+	 * @param noThreads
+	 *            ignore threads filtering
+	 * @param noFunctions
+	 *            ignore functions filtering
+	 */
+	private Vector<ProfiledGeneric> internalSetBinary(int graphIndex, GppModelAdapter adapter, Vector<ProfiledGeneric> graphBinaries, boolean noThreads, boolean noFunctions) {
+		graphBinaries.clear();
+		Hashtable<String, String> foundBinaries = new Hashtable<String, String>();
+
 		// disable all binaries for the given graph
 		for (int i = 0; i < this.profiledBinaries.size(); i++) {
-			ProfiledBinary pBinary = (ProfiledBinary) this.profiledBinaries.elementAt(i);
+			ProfiledBinary pBinary = (ProfiledBinary) this.profiledBinaries
+					.elementAt(i);
 			pBinary.setEnabled(graphIndex, false);
 		}
 
 		// set up in case we find binaries below the threshold
 		boolean lowBinary;
-		ProfiledThreshold thresholdBinary = this.graphs[graphIndex].getThresholdBinary();
-		thresholdBinary.init(graphIndex);
+		ProfiledThreshold thresholdBinary = adapter.getThresholdItem(this, graphIndex, PIPageEditor.BINARIES_PAGE);
+		adapter.init(thresholdBinary, graphIndex);
 
-		// for each binary in the selected sample range, if its thread and function are enabled,
+		// for each binary in the selected sample range, if its thread and
+		// function are enabled,
 		// add the binary
-		int binaryThreshold = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountBinary"); //$NON-NLS-1$
+		int binaryThreshold = (Integer) NpiInstanceRepository
+				.getInstance()
+				.activeUidGetPersistState(
+						"com.nokia.carbide.cpp.pi.address.thresholdCountBinary"); //$NON-NLS-1$
+
+		int[] totalSamplesPerCPU = null;
+		if (isSingleCPUModeonSMP(graphIndex)) {
+			totalSamplesPerCPU = new int[cpuCount];
+		}
+		
 		for (int i = this.startSampleIndex; i < this.endSampleIndex; i++) {
 			GppSample sample = this.sortedSamples[i];
-			ProfiledThread pThread = (ProfiledThread) this.profiledThreads.elementAt(sample.threadIndex);
-			ProfiledFunction pFunction = (ProfiledFunction) this.profiledFunctions.elementAt(sample.functionIndex);
 
-			if (pThread.isEnabled(graphIndex) && pFunction.isEnabled(graphIndex)) {
-				ProfiledBinary pBinary = (ProfiledBinary) this.profiledBinaries.elementAt(sample.binaryIndex);
+			if (isSingleCPUModeonSMP(graphIndex)) {
+				totalSamplesPerCPU[sample.cpuNumber]++;
+				if (!adapter.matchingCPU(sample.cpuNumber)){
+					continue;
+				}
+			}
+
+			if ((noThreads || (this.profiledThreads
+					.elementAt(sample.threadIndex)).isEnabled(graphIndex))
+					&& (noFunctions || (this.profiledFunctions
+							.elementAt(sample.functionIndex)).isEnabled(graphIndex))) {
+				ProfiledBinary pBinary = (ProfiledBinary) this.profiledBinaries
+						.elementAt(sample.binaryIndex);
 				String binaryName = pBinary.getNameString();
 
-				lowBinary = pBinary.getTotalSampleCount() < binaryThreshold;
+				lowBinary = adapter.getTotalSampleCount(pBinary) < binaryThreshold;
 
 				if (!foundBinaries.containsKey(binaryName)) {
 					pBinary.setEnabled(graphIndex, true);
 					foundBinaries.put(binaryName, binaryName);
 					if (lowBinary) {
-						thresholdBinary.addItem(graphIndex, pBinary, 1);
+						adapter.addItem(thresholdBinary, graphIndex, pBinary, 1);
 					} else {
 						pBinary.setSampleCount(graphIndex, 1);
 						graphBinaries.add(pBinary);
@@ -675,129 +838,167 @@
 				}
 			}
 		}
-		
-		// since we are not converting float % load to string % load inside the table viewers, do it here
+
+		// since we are not converting float % load to string % load inside the
+		// table viewers, do it here
 		double percentPerSample;
 		if (startSampleIndex == endSampleIndex)
 			percentPerSample = 0.0;
-		else
-			percentPerSample = 100.0 / ((double)(this.endSampleIndex - this.startSampleIndex));
+		else{
+			int total = isSingleCPUModeonSMP(graphIndex) ? adapter.getValueForCPU(totalSamplesPerCPU)
+					: (this.endSampleIndex - this.startSampleIndex);
+			percentPerSample = 100.0 / ((double) total);
+			
+		}
 
 		for (int i = 0; i < graphBinaries.size(); i++) {
-			ProfiledBinary pBinary = (ProfiledBinary) graphBinaries.elementAt(i);
-			pBinary.setLoadAndString(graphIndex, (float)(pBinary.getSampleCount(graphIndex) * percentPerSample));
+			ProfiledBinary pBinary = (ProfiledBinary) graphBinaries
+					.elementAt(i);
+			pBinary.setLoadAndString(graphIndex, (float) (pBinary.getSampleCount(graphIndex) * percentPerSample));
 		}
-		
+
 		return graphBinaries;
+	
+	}
+	/**
+	 * Based on a graph's set of enabled threads and functions, produce a set of
+	 * binaries, and disable all other binaries for that graph
+	 * 
+	 * @param graphIndex
+	 *            index of the graph to use
+	 * @param adapter
+	 *            a GppModelAdapter encapsulating SMP or non-SMP specific model
+	 *            usage
+	 * @param graphBinaries Collection of ProfiledGeneric binaries to be updated. The collection is filtered by selected
+	 *         threads and functions on the given graph in the selected
+	 *         time frame
+	 */
+	public void setThreadFunctionBinary(int graphIndex, GppModelAdapter adapter, Vector<ProfiledGeneric> graphBinaries) {
+		internalSetBinary(graphIndex, adapter, graphBinaries, false, false);		
+	}
+
+	/**
+	 * Based on a graph's set of enabled threads and functions, produce a set of
+	 * binaries, and disable all other binaries for that graph
+	 * 
+	 * @param graphIndex
+	 *            index of the graph to use
+	 * @param adapter
+	 *            a GppModelAdapter encapsulating SMP or non-SMP specific model
+	 *            usage
+	 * @param graphThreads Collection of ProfiledGeneric threads filtered by selected
+	 *         threads on the given graph in the selected
+	 *         time frame. This collection will be updated.
+	 */
+	public void setFunctionThreadBinary(int graphIndex, GppModelAdapter adapter, Vector<ProfiledGeneric> graphThreads) {
+		internalSetBinary(graphIndex, adapter, graphThreads, false, false);
 	}
 
-	public Vector<ProfiledGeneric> setFunctionThreadBinary(int graphIndex)
-	{
-		return setThreadFunctionBinary(graphIndex);
-	}
-
-	/*
+	/**
 	 * Based on a graph's set of enabled binaries, produce a set of threads, and
 	 * disable all other threads for that graph
+	 * 
+	 * @param graphIndex
+	 *            index of the graph to use
+	 * @param adapter
+	 *            a GppModelAdapter encapsulating SMP or non-SMP specific model
+	 *            usage
+	 * @param graphTreads Collection of ProfiledGeneric threads filtered by selected
+	 *         threads on the given graph in the selected
+	 *         time frame. This collection will be updated.
 	 */
-	public Vector<ProfiledGeneric> setBinaryThread(int graphIndex)
-	{
-		Vector<ProfiledGeneric>  graphThreads = new Vector<ProfiledGeneric>();
-		Hashtable<String,String> foundThreads = new Hashtable<String,String>();
-		
+	public void setBinaryThread(int graphIndex, GppModelAdapter adapter, Vector<ProfiledGeneric> graphThreads) {
+		internalSetThread(graphIndex, adapter, graphThreads, true, false);
+	}
+
+	/**
+	 * Based on a graph's set of enabled functions, produce a set of threads,
+	 * and disable all other threads for that graph
+	 * 
+	 * @param graphIndex
+	 *            index of the graph to use
+	 * @param adapter
+	 *            a GppModelAdapter encapsulating SMP or non-SMP specific model
+	 *            usage
+	 * @param graphThreads list of previous threads, will be updated
+	 * @return Collection of ProfiledGeneric threads filtered by selected
+	 *         functions on the given graph in the selected time frame
+	 */
+	public void setFunctionThread(int graphIndex, GppModelAdapter adapter, Vector<ProfiledGeneric> graphThreads) {
+		internalSetThread(graphIndex, adapter, graphThreads, false, true);
+	}
+
+	/**
+	 * Internal implementation for
+	 * {@link #setBinaryFunctionThread(int, GppModelAdapter)},
+	 * {@link #setFunctionBinaryThread(int, GppModelAdapter)},
+	 * {@link #setBinaryThread(int)},
+	 * {@link #setFunctionThread(int, GppModelAdapter)}
+	 * 
+	 * @param graphIndex
+	 *            index of graph to use
+	 * @param adapter
+	 *            a GppModelAdapter encapsulating SMP or non-SMP specific model
+	 *            usage
+	 * @param noFunctions
+	 *            if true omit functions, use for binaries -> threads
+	 * @param noBinaries
+	 *            if true omit binaries, use for functions -> threads
+	 * @param graphThreads Collection of threads to update with their sample count within selected
+	 *         area and filtered by selected functions and binaries (or
+	 *         functions only or binaries only) in the given graph
+	 */
+	private void internalSetThread(int graphIndex, GppModelAdapter adapter, Vector<ProfiledGeneric> graphThreads, boolean noFunctions, boolean noBinaries){
+		graphThreads.clear();
+		Hashtable<String, String> foundThreads = new Hashtable<String, String>();
+
 		// disable all threads for the given graph
 		for (int i = 0; i < this.profiledThreads.size(); i++) {
-			ProfiledThread pThread = (ProfiledThread) this.profiledThreads.elementAt(i);
+			ProfiledThread pThread = (ProfiledThread) this.profiledThreads
+					.elementAt(i);
 			pThread.setEnabled(graphIndex, false);
 		}
 
 		// set up in case we find threads below the threshold
 		boolean lowThread;
-		ProfiledThreshold thresholdThread = this.graphs[graphIndex].getThresholdThread();
-		thresholdThread.init(graphIndex);
+		ProfiledThreshold thresholdThread = adapter.getThresholdItem(this, graphIndex, PIPageEditor.THREADS_PAGE);
+		adapter.init(thresholdThread, graphIndex);
 
-		// for each thread in the selected sample range, if its binary is enabled, add the thread
-		int threadThreshold = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountThread"); //$NON-NLS-1$
+		// for each thread in the selected sample range, if its binary and
+		// function are enabled,
+		// add the thread
+		int threadThreshold = (Integer) NpiInstanceRepository
+				.getInstance()
+				.activeUidGetPersistState(
+						"com.nokia.carbide.cpp.pi.address.thresholdCountThread"); //$NON-NLS-1$
+		int[] totalSamplesPerCPU = null;
+		if (isSingleCPUModeonSMP(graphIndex)) {
+			totalSamplesPerCPU = new int[cpuCount];
+		}
 		for (int i = this.startSampleIndex; i < this.endSampleIndex; i++) {
 			GppSample sample = this.sortedSamples[i];
-			ProfiledBinary pBinary = (ProfiledBinary) this.profiledBinaries.elementAt(sample.binaryIndex);
+			if (isSingleCPUModeonSMP(graphIndex)) {
+				totalSamplesPerCPU[sample.cpuNumber]++;
+				if (!adapter.matchingCPU(sample.cpuNumber)){
+					continue;
+				}
+			}
 
-			if (pBinary.isEnabled(graphIndex)) {
-				ProfiledThread pThread = (ProfiledThread) this.profiledThreads.elementAt(sample.threadIndex);
+			if ((noBinaries || ((ProfiledBinary) this.profiledBinaries
+					.elementAt(sample.binaryIndex)).isEnabled(graphIndex))
+					&& (noFunctions || ((ProfiledFunction) this.profiledFunctions
+							.elementAt(sample.functionIndex)).isEnabled(graphIndex))) {
+				ProfiledThread pThread = (ProfiledThread) this.profiledThreads
+						.elementAt(sample.threadIndex);
 				String threadName = pThread.getNameString();
 
-				lowThread = pThread.getTotalSampleCount() < threadThreshold;
+				lowThread = adapter.getTotalSampleCount(pThread) < threadThreshold;
 
 				if (!foundThreads.containsKey(threadName)) {
 					pThread.setEnabled(graphIndex, true);
 					foundThreads.put(threadName, threadName);
 					if (lowThread) {
-						thresholdThread.addItem(graphIndex, pThread, 1);
-					} else {
-						pThread.setSampleCount(graphIndex, 1);
-						graphThreads.add(pThread);
-					}
-				} else {
-					if (lowThread)
-						thresholdThread.incSampleCount(graphIndex);
-					else
-						pThread.incSampleCount(graphIndex);
-				}
-			}
-		}
-		
-		// since we are not converting float % load to string % load inside the table viewers, do it here
-		double percentPerSample;
-		if (startSampleIndex == endSampleIndex)
-			percentPerSample = 0.0;
-		else
-			percentPerSample = 100.0 / ((double)(this.endSampleIndex - this.startSampleIndex));
-
-		for (int i = 0; i < graphThreads.size(); i++) {
-			ProfiledThread pThread = (ProfiledThread) graphThreads.elementAt(i);
-			pThread.setLoadAndString(graphIndex, (float)(pThread.getSampleCount(graphIndex) * percentPerSample));
-		}
-		
-		return graphThreads;
-	}
-
-	/*
-	 * Based on a graph's set of enabled functions, produce a set of threads, and
-	 * disable all other threads for that graph
-	 */
-	public Vector<ProfiledGeneric> setFunctionThread(int graphIndex)
-	{
-		Vector<ProfiledGeneric>  graphThreads = new Vector<ProfiledGeneric>();
-		Hashtable<String,String> foundThreads = new Hashtable<String,String>();
-		
-		// disable all threads for the given graph
-		for (int i = 0; i < this.profiledThreads.size(); i++) {
-			ProfiledThread pThread = (ProfiledThread) this.profiledThreads.elementAt(i);
-			pThread.setEnabled(graphIndex, false);
-		}
-
-		// set up in case we find threads below the threshold
-		boolean lowThread;
-		ProfiledThreshold thresholdThread = this.graphs[graphIndex].getThresholdThread();
-		thresholdThread.init(graphIndex);
-
-		// for each thread in the selected sample range, if its function is enabled, add the thread
-		int threadThreshold = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountThread"); //$NON-NLS-1$
-		for (int i = this.startSampleIndex; i < this.endSampleIndex; i++) {
-			GppSample sample = this.sortedSamples[i];
-			ProfiledFunction pFunction = (ProfiledFunction) this.profiledFunctions.elementAt(sample.functionIndex);
-
-			if (pFunction.isEnabled(graphIndex)) {
-				ProfiledThread pThread = (ProfiledThread) this.profiledThreads.elementAt(sample.threadIndex);
-				String threadName = pThread.getNameString();
-
-				lowThread = pThread.getTotalSampleCount() < threadThreshold;
-
-				if (!foundThreads.containsKey(threadName)) {
-					pThread.setEnabled(graphIndex, true);
-					foundThreads.put(threadName, threadName);
-					if (lowThread) {
-						thresholdThread.addItem(graphIndex, pThread, 1);
+						adapter.addItem(thresholdThread, graphIndex, pThread, 1);
 					} else {
 						pThread.setSampleCount(graphIndex, 1);
 						graphThreads.add(pThread);
@@ -810,269 +1011,109 @@
 				}
 			}
 		}
-		
-		// since we are not converting float % load to string % load inside the table viewers, do it here
+
+		// since we are not converting float % load to string % load inside the
+		// table viewers, do it here
 		double percentPerSample;
 		if (startSampleIndex == endSampleIndex)
 			percentPerSample = 0.0;
-		else
-			percentPerSample = 100.0 / ((double)(this.endSampleIndex - this.startSampleIndex));
-
-		for (int i = 0; i < graphThreads.size(); i++) {
-			ProfiledThread pThread = (ProfiledThread) graphThreads.elementAt(i);
-			pThread.setLoadAndString(graphIndex, (float)(pThread.getSampleCount(graphIndex) * percentPerSample));
-		}
-		
-		return graphThreads;
-	}
-
-	/*
-	 * Based on a graph's set of enabled binaries and functions, produce a set of threads, and
-	 * disable all other threads for that graph
-	 */
-	public Vector<ProfiledGeneric> setBinaryFunctionThread(int graphIndex)
-	{
-		Vector<ProfiledGeneric>  graphThreads = new Vector<ProfiledGeneric>();
-		Hashtable<String,String> foundThreads = new Hashtable<String,String>();
-		
-		// disable all threads for the given graph
-		for (int i = 0; i < this.profiledThreads.size(); i++) {
-			ProfiledThread pThread = (ProfiledThread) this.profiledThreads.elementAt(i);
-			pThread.setEnabled(graphIndex, false);
+		else {
+			int total = isSingleCPUModeonSMP(graphIndex) ? adapter.getValueForCPU(totalSamplesPerCPU)
+					: (this.endSampleIndex - this.startSampleIndex);
+			percentPerSample = 100.0 / ((double) total);
 		}
 
-		// set up in case we find threads below the threshold
-		boolean lowThread;
-		ProfiledThreshold thresholdThread = this.graphs[graphIndex].getThresholdThread();
-		thresholdThread.init(graphIndex);
-
-		// for each thread in the selected sample range, if its binary and function are enabled,
-		// add the thread
-		int threadThreshold = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountThread"); //$NON-NLS-1$
-		for (int i = this.startSampleIndex; i < this.endSampleIndex; i++) {
-			GppSample sample = this.sortedSamples[i];
-			ProfiledBinary pBinary = (ProfiledBinary) this.profiledBinaries.elementAt(sample.binaryIndex);
-			ProfiledFunction pFunction = (ProfiledFunction) this.profiledFunctions.elementAt(sample.functionIndex);
-
-			if (pBinary.isEnabled(graphIndex)
-	 		    && (pFunction.isEnabled(graphIndex))) {
-				ProfiledThread pThread = (ProfiledThread) this.profiledThreads.elementAt(sample.threadIndex);
-				String threadName = pThread.getNameString();
-
-				lowThread = pThread.getTotalSampleCount() < threadThreshold;
-
-				if (!foundThreads.containsKey(threadName)) {
-					pThread.setEnabled(graphIndex, true);
-					foundThreads.put(threadName, threadName);
-					if (lowThread) {
-						thresholdThread.addItem(graphIndex, pThread, 1);
-					} else {
-						pThread.setSampleCount(graphIndex, 1);
-						graphThreads.add(pThread);
-					}
-				} else {
-					if (lowThread)
-						thresholdThread.incSampleCount(graphIndex);
-					else
-						pThread.incSampleCount(graphIndex);
-				}
-			}
-		}
-		
-		// since we are not converting float % load to string % load inside the table viewers, do it here
-		double percentPerSample;
-		if (startSampleIndex == endSampleIndex)
-			percentPerSample = 0.0;
-		else
-			percentPerSample = 100.0 / ((double)(this.endSampleIndex - this.startSampleIndex));
-
 		for (int i = 0; i < graphThreads.size(); i++) {
 			ProfiledThread pThread = (ProfiledThread) graphThreads.elementAt(i);
-			pThread.setLoadAndString(graphIndex, (float)(pThread.getSampleCount(graphIndex) * percentPerSample));
+			pThread.setLoadAndString(graphIndex, (float) (pThread.getSampleCount(graphIndex) * percentPerSample));
 		}
-		
-		return graphThreads;
 	}
-
-	public Vector<ProfiledGeneric> setFunctionBinaryThread(int graphIndex)
-	{
-		return setBinaryFunctionThread(graphIndex);
+	/**
+	 * Based on a graph's set of enabled binaries and functions, produce a set
+	 * of threads, and disable all other threads for that graph
+	 * @param graphIndex
+	 *            index of graph to use
+	 * @param adapter
+	 *            a GppModelAdapter encapsulating SMP or non-SMP specific model
+	 *            usage
+	 * @param threads Collection of threads to update with their sample count within selected
+	 *         area and filtered by selected functions and binaries in the given
+	 *         graph
+	 */
+	public void setBinaryFunctionThread(int graphIndex, GppModelAdapter adapter, Vector<ProfiledGeneric> threads) {
+		internalSetThread(graphIndex, adapter, threads, false, false);
 	}
 
-	/*
-	 * Based on a graph's set of enabled functions, produce a set of binaries, and
-	 * disable all other binaries for that graph
+	/**
+	 * Based on a graph's set of enabled binaries and functions, produce a set
+	 * of threads, and disable all other threads for that graph
+	 * @param graphIndex
+	 *            index of graph to use
+	 * @param adapter
+	 *            a GppModelAdapter encapsulating SMP or non-SMP specific model
+	 *            usage
+	 * @param threads Collection of threads to update with their sample count within selected
+	 *         area and filtered by selected functions and binaries in the given
+	 *         graph
 	 */
-	public Vector<ProfiledGeneric> setFunctionBinary(int graphIndex)
-	{
-		Vector<ProfiledGeneric>  graphBinaries = new Vector<ProfiledGeneric>();
-		Hashtable<String,String> foundBinaries = new Hashtable<String,String>();
-		
-		// disable all binaries for the given graph
-		for (int i = 0; i < this.profiledBinaries.size(); i++) {
-			ProfiledBinary pBinary = (ProfiledBinary) this.profiledBinaries.elementAt(i);
-			pBinary.setEnabled(graphIndex, false);
-		}
-
-		// set up in case we find binaries below the threshold
-		boolean lowBinary;
-		ProfiledThreshold thresholdBinary = this.graphs[graphIndex].getThresholdBinary();
-		thresholdBinary.init(graphIndex);
-
-		// for each binary in the selected sample range, if its function is enabled, add the binary
-		int binaryThreshold = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountBinary"); //$NON-NLS-1$
-		for (int i = this.startSampleIndex; i < this.endSampleIndex; i++) {
-			GppSample sample = this.sortedSamples[i];
-			ProfiledFunction pFunction = (ProfiledFunction) this.profiledFunctions.elementAt(sample.functionIndex);
-
-			if (pFunction.isEnabled(graphIndex)) {
-				ProfiledBinary pBinary = (ProfiledBinary) this.profiledBinaries.elementAt(sample.binaryIndex);
-				String binaryName = pBinary.getNameString();
-
-				lowBinary = pBinary.getTotalSampleCount() < binaryThreshold;
-
-				if (!foundBinaries.containsKey(binaryName)) {
-					pBinary.setEnabled(graphIndex, true);
-					foundBinaries.put(binaryName, binaryName);
-					if (lowBinary) {
-						thresholdBinary.addItem(graphIndex, pBinary, 1);
-					} else {
-						pBinary.setSampleCount(graphIndex, 1);
-						graphBinaries.add(pBinary);
-					}
-				} else {
-					if (lowBinary)
-						thresholdBinary.incSampleCount(graphIndex);
-					else
-						pBinary.incSampleCount(graphIndex);
-				}
-			}
-		}
-		
-		// since we are not converting float % load to string % load inside the table viewers, do it here
-		double percentPerSample;
-		if (startSampleIndex == endSampleIndex)
-			percentPerSample = 0.0;
-		else
-			percentPerSample = 100.0 / ((double)(this.endSampleIndex - this.startSampleIndex));
-
-		for (int i = 0; i < graphBinaries.size(); i++) {
-			ProfiledBinary pBinary = (ProfiledBinary) graphBinaries.elementAt(i);
-			pBinary.setLoadAndString(graphIndex, (float)(pBinary.getSampleCount(graphIndex) * percentPerSample));
-		}
-		
-		return graphBinaries;
+	public void setFunctionBinaryThread(int graphIndex, GppModelAdapter adapter, Vector<ProfiledGeneric> threads) {
+		internalSetThread(graphIndex, adapter, threads, false, false);
 	}
 
-	/*
-	 * Based on a graph's set of enabled binaries, produce a set of functions, and
-	 * disable all other functions for that graph
+	/**
+	 * Based on a graph's set of enabled functions, produce a set of binaries,
+	 * and disable all other binaries for that graph
+	 * @param graphIndex
+	 *            index of the graph to operate on
+	 * @param adapter a GppModelAdapter encapsulating SMP or non-SMP specific model
+	 *            usage
+	 * @param binaries Collection of binaries to update with their sample count within selected
+	 *         area and filtered by selected functions in the given
+	 *         graph
 	 */
-	public Vector<ProfiledGeneric> setBinaryFunction(int graphIndex)
-	{
-		Vector<ProfiledGeneric>  graphFunctions = new Vector<ProfiledGeneric>();
-		Hashtable<String,String> foundFunctions = new Hashtable<String,String>();
-		
-		// disable all functions for the given graph
-		for (int i = 0; i < this.profiledFunctions.size(); i++) {
-			ProfiledFunction pFunction = (ProfiledFunction) this.profiledFunctions.elementAt(i);
-			pFunction.setEnabled(graphIndex, false);
-		}
-
-		// set up in case we find functions below the threshold
-		boolean lowFunction;
-		ProfiledThreshold thresholdFunction = this.graphs[graphIndex].getThresholdFunction();
-		thresholdFunction.init(graphIndex);
-
-		// for each function in the selected sample range, if its binary is enabled, add the function
-		int functionThreshold = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountFunction"); //$NON-NLS-1$
-		for (int i = this.startSampleIndex; i < this.endSampleIndex; i++) {
-			GppSample sample = this.sortedSamples[i];
-			ProfiledBinary pBinary = (ProfiledBinary) this.profiledBinaries.elementAt(sample.binaryIndex);
-
-			if (pBinary.isEnabled(graphIndex)) {
-				ProfiledFunction pFunction = (ProfiledFunction) this.profiledFunctions.elementAt(sample.functionIndex);
-				String functionName = pFunction.getNameString();
-
-				lowFunction = pFunction.getTotalSampleCount() < functionThreshold;
+	public void setFunctionBinary(int graphIndex, GppModelAdapter adapter, Vector<ProfiledGeneric> binaries) {
+		internalSetBinary(graphIndex, adapter, binaries,  true, false);
+	}
 
-				if (!foundFunctions.containsKey(functionName)) {
-					pFunction.setEnabled(graphIndex, true);
-					foundFunctions.put(functionName, functionName);
-					if (lowFunction) {
-						thresholdFunction.addItem(graphIndex, pFunction, 1);
-					} else {
-						pFunction.setSampleCount(graphIndex, 1);
-						graphFunctions.add(pFunction);
-					}
-				} else {
-					if (lowFunction)
-						thresholdFunction.incSampleCount(graphIndex);
-					else
-						pFunction.incSampleCount(graphIndex);
-				}
-			}
-		}
-		
-		// since we are not converting float % load to string % load inside the table viewers, do it here
-		double percentPerSample;
-		if (startSampleIndex == endSampleIndex)
-			percentPerSample = 0.0;
-		else
-			percentPerSample = 100.0 / ((double)(this.endSampleIndex - this.startSampleIndex));
+	/**
+	 * Based on a graph's set of enabled binaries, produce a set of functions,
+	 * and disable all other functions for that graph
+	 * @param graphIndex
+	 *            index of the graph to operate on
+	 * @param adapter a GppModelAdapter encapsulating SMP or non-SMP specific model
+	 *            usage
+	 * @param functions Collection of functions with their sample count within selected
+	 *         area and filtered by selected binaries in the given
+	 *         graph
+	 */
+	public void setBinaryFunction(int graphIndex, GppModelAdapter adapter, Vector<ProfiledGeneric> functions) {
+		internalSetFunction(graphIndex, adapter, functions, true, false);
+	}
 
-		for (int i = 0; i < graphFunctions.size(); i++) {
-			ProfiledFunction pFunction = (ProfiledFunction) graphFunctions.elementAt(i);
-			pFunction.setLoadAndString(graphIndex, (float)(pFunction.getSampleCount(graphIndex) * percentPerSample));
-		}		
-		
-		return graphFunctions;
-	}
-	
-	public int getStartSampleIndex()
-	{
+	/**
+	 * returns the first sample index within the time range
+	 * 
+	 * @return
+	 */
+	public int getStartSampleIndex() {
 		return this.startSampleIndex;
 	}
-	
-	public int getEndSampleIndex()
-	{
+
+	/**
+	 * Returns the first sample index just past the selected time range
+	 * 
+	 * @return
+	 */
+	public int getEndSampleIndex() {
 		return this.endSampleIndex;
 	}
-	
-	public int[] getThreadSampleCounts()
-	{
-		return this.threadSamples;
-	}
-	
-	public int[] getBinarySampleCounts()
-	{
-		return this.binarySamples;
-	}
-	
-	public int[] getFunctionSampleCounts()
-	{
-		return this.functionSamples;
-	}
 
-	public void setThreadSampleCounts(int[] sampleCounts)
-	{
-		this.threadSamples = sampleCounts;
-	}
-	
-	public void setBinarySampleCounts(int[] sampleCounts)
-	{
-		this.binarySamples = sampleCounts;
-	}
-	
-	public void setFunctionSampleCounts(int[] sampleCounts)
-	{
-		this.functionSamples = sampleCounts;
-	}
-	
-	public void setThreadColorPalette(ThreadColorPalette tableColorPalette) {
-		this.threadColorPalette = tableColorPalette;
-	}
-
+	/**
+	 * Getter for function color ThreadColorPalette. Will create the instance
+	 * if it doesn't already exist
+	 * 
+	 * @return threadColorPalette
+	 */
 	public ThreadColorPalette getThreadColorPalette() {
 		if (this.threadColorPalette == null) {
 			this.threadColorPalette = new ThreadColorPalette();
@@ -1080,10 +1121,12 @@
 		return this.threadColorPalette;
 	}
 
-	public void setBinaryColorPalette(BinaryColorPalette tableColorPalette) {
-		this.binaryColorPalette = tableColorPalette;
-	}
-
+	/**
+	 * Getter for function color BinaryColorPalette. Will create the instance
+	 * if it doesn't already exist
+	 * 
+	 * @return binaryColorPalette
+	 */
 	public BinaryColorPalette getBinaryColorPalette() {
 		if (this.binaryColorPalette == null) {
 			this.binaryColorPalette = new BinaryColorPalette();
@@ -1091,10 +1134,12 @@
 		return this.binaryColorPalette;
 	}
 
-	public void setFunctionColorPalette(FunctionColorPalette tableColorPalette) {
-		this.functionColorPalette = tableColorPalette;
-	}
-
+	/**
+	 * Getter for FunctionColorPalette. Will create the instance
+	 * if it doesn't already exist
+	 * 
+	 * @return functionColorPalette
+	 */
 	public FunctionColorPalette getFunctionColorPalette() {
 		if (this.functionColorPalette == null) {
 			this.functionColorPalette = new FunctionColorPalette();
@@ -1105,14 +1150,554 @@
 	@Override
 	public void finalizeTrace() {
 		samples.trimToSize();
-		for (int i = 0; i < samples.size(); i++) {
-			GppSample sample = (GppSample) samples.get(i);
-			
-			if (sample.currentFunctionItt == null && sample.currentFunctionSym == null) {
-				sample.currentFunctionItt = new Function(Messages.getString("GppTrace.functionNotFound1") + Long.toHexString(sample.programCounter) + Messages.getString("GppTrace.functionNotFound2"), //$NON-NLS-1$ //$NON-NLS-2$
-						new Long(sample.programCounter),
-						Messages.getString("GppTrace.binaryNotFound1") +  Long.toHexString(sample.programCounter) + Messages.getString("GppTrace.binarynotFound2")); //$NON-NLS-1$ //$NON-NLS-2$
+	}
+
+	/**
+	 * Builds up the model from trace. The following structures will be filled
+	 * with data: <br>
+	 * profiledThreads <br>
+	 * sortedProfiledThreads <br>
+	 * profiledBinaries <br>
+	 * sortedProfiledBinaries <br>
+	 * profiledFunctions <br>
+	 * sortedProfiledFunctions All Profiled objects in these structures will
+	 * have sample counts and sample percentages according to the given trace.
+	 * @param graphCount the number of graphs for which to prepare the model
+	 */
+	public void refreshDataFromTrace(int graphCount) {
+		// Loop through samples and
+		// - create ProfiledThread, ProfiledBinary, ProfiledFunction and save in
+		// this.profiledThreads, etc
+		// - increase sample counts appropriate in ProfiledThread,
+		// ProfiledBinary, ProfiledFunction
+		// After all samples have been processed
+		// - update percentage counts per bucket in ProfiledThread,
+		// ProfiledBinary, ProfiledFunction
+		// - sort ProfiledThread, ProfiledBinary, ProfiledFunction and save in
+		// this.sortedProfiledThreads, etc.
+		// - create/clear this.threadSamples etc, will contain selected areas of
+		// the graph later on
+
+		// each bucket has GppTraceGraph.GRANULARITY_VALUE number of samples
+		// (the last bucket might contain a few more)
+		// except in the SMP case, where we have
+		// <cpuNumber>*GppTraceGraph.GRANULARITY_VALUE number of samples per
+		// bucket
+
+		this.setGraphCount(graphCount);
+		int bucketDuration = getBucketDuration();
+		// assume samples are evenly distributed across buckets
+		int granularityValue = samples.size() / cpuCount > GppTraceGraph.GRANULARITY_VALUE ? GppTraceGraph.GRANULARITY_VALUE
+				: samples.size() / cpuCount;
+		int numberOfBuckets = GppTraceUtil.calculateNumberOfBuckets(
+				getLastSampleTime(), granularityValue);
+
+		HashMap<String, ProfiledThread> profiledThreadsMap = new HashMap<String, ProfiledThread>();
+		HashMap<String, ProfiledBinary> profiledBinariesMap = new HashMap<String, ProfiledBinary>();
+		HashMap<String, ProfiledFunction> profiledFunctionsMap = new HashMap<String, ProfiledFunction>();
+
+		createProfiledFromSamples(bucketDuration, numberOfBuckets,
+				profiledThreadsMap, profiledBinariesMap, profiledFunctionsMap);
+
+		// for sorting by increasing index
+		Comparator<ProfiledGeneric> indexComparator = new Comparator<ProfiledGeneric>() {
+			public int compare(ProfiledGeneric o1, ProfiledGeneric o2)
+					throws ClassCastException {
+				return o1.getIndex() - o2.getIndex();
+			}
+		};
+		// sort by increasing sample load
+		Comparator<ProfiledGeneric> loadComparator = new Comparator<ProfiledGeneric>() {
+			public int compare(ProfiledGeneric o1, ProfiledGeneric o2)
+					throws ClassCastException {
+				return o1.getTotalSampleCount() - o2.getTotalSampleCount();
+			}
+		};
+
+		// now create collections of the profiled elements in the trace
+
+		profiledThreads = new Vector<ProfiledThread>();
+		profiledThreads.addAll(profiledThreadsMap.values());
+		Collections.sort(profiledThreads, indexComparator);
+
+		profiledBinaries = new Vector<ProfiledBinary>();
+		profiledBinaries.addAll(profiledBinariesMap.values());
+		Collections.sort(profiledBinaries, indexComparator);
+
+		profiledFunctions = new Vector<ProfiledFunction>();
+		profiledFunctions.addAll(profiledFunctionsMap.values());
+		Collections.sort(profiledFunctions, indexComparator);
+
+		sortedProfiledThreads = new Vector<ProfiledGeneric>();
+		sortedProfiledThreads.addAll(profiledThreadsMap.values());
+		Collections.sort(sortedProfiledThreads, loadComparator);
+
+		sortedProfiledBinaries = new Vector<ProfiledGeneric>();
+		sortedProfiledBinaries.addAll(profiledBinariesMap.values());
+		Collections.sort(sortedProfiledBinaries, loadComparator);
+
+		sortedProfiledFunctions = new Vector<ProfiledGeneric>();
+		sortedProfiledFunctions.addAll(profiledFunctionsMap.values());
+		Collections.sort(sortedProfiledFunctions, loadComparator);
+
+	}
+
+	/**
+	 * Returns the duration for a bucket based on the sampling granularity
+	 * and the sampling interval
+	 * @return the bucket duration in milliseconds
+	 */
+	public int getBucketDuration() {
+		int samplingInterval = (Integer) NpiInstanceRepository.getInstance()
+				.activeUidGetPersistState(
+						"com.nokia.carbide.cpp.pi.address.samplingInterval"); //$NON-NLS-1$
+		return getGranularity() * samplingInterval;
+	}
+
+	/**
+	 * Returns the granularity value, i.e. the number of samples per bucket
+	 * @return granularity
+	 */
+	public int getGranularity(){
+		return  (samples.size() / cpuCount) > GppTraceGraph.GRANULARITY_VALUE ? GppTraceGraph.GRANULARITY_VALUE
+				: (samples.size() / cpuCount);
+		
+	}
+	/**
+	 * Loops through the given samples and: <br>
+	 * - Creates ProfiledThread, ProfiledBinary, ProfiledFunction as needed
+	 * which are saved in the passed maps <br>
+	 * - Increases sample counts in appropriate ProfiledThread, ProfiledBinary,
+	 * ProfiledFunction <br>
+	 * - Updates each sample with the index of the ProfiledThread,
+	 * ProfiledBinary, ProfiledFunction
+	 * 
+	 * @param bucketDuration
+	 *            length of a bucket in milliseconds
+	 * @param numberOfBuckets
+	 *            Number of buckets to use
+	 * @param profiledThreadsMap
+	 *            Map to store the ProfiledThreads keyed by thread name
+	 * @param profiledBinariesMap
+	 *            Map to store the ProfiledBinaries keyed by binary name
+	 * @param profiledFunctionsMap
+	 *            Map to store the ProfiledFunctions keyed by function name
+	 */
+	private void createProfiledFromSamples(final int bucketDuration,
+			int numberOfBuckets,
+			HashMap<String, ProfiledThread> profiledThreadsMap,
+			HashMap<String, ProfiledBinary> profiledBinariesMap,
+			HashMap<String, ProfiledFunction> profiledFunctionsMap) {
+
+		int threadCount = 0; // used for thread index
+		int binaryCount = 0; // used for binary index
+		int functionCount = 0; // used for function index
+		char threadSymbol = 'A'; // each thread has a unique character as
+									// symbol; the character value increases as
+									// threads are created
+		int[] bucketTotalArr = new int[numberOfBuckets];
+		int[][] bucketTotalArrSMP = null;
+		if (isSMP) {
+			bucketTotalArrSMP = new int[cpuCount][numberOfBuckets];
+		}
+
+		for (GenericSample genericSample : samples) {
+			GppSample sample = (GppSample) genericSample;
+			String threadName = sample.thread.process.name
+					+ "::" + sample.thread.threadName + "_" + sample.thread.threadId; //$NON-NLS-1$ //$NON-NLS-2$
+			String binaryName = GppTraceUtil.getBinaryName(sample);
+			String functionName = GppTraceUtil.getFunctionName(sample);
+			int bucket = (int) sample.sampleSynchTime / bucketDuration;
+			bucketTotalArr[bucket]++;
+			if (isSMP) {
+				bucketTotalArrSMP[sample.cpuNumber][bucket]++;
+			}
+
+			// process thread information
+			ProfiledThread pThread = profiledThreadsMap.get(threadName);
+			if (pThread == null) {
+				pThread = new ProfiledThread(cpuCount, graphCount);
+
+				pThread.setIndex(threadCount++);
+				pThread.setNameValues(threadSymbol++, threadName);
+				pThread.setColor(getThreadColorPalette().getColor(threadName));
+
+				pThread.setThreadId(sample.thread.threadId.intValue());
+
+				pThread.createBuckets(numberOfBuckets);
+				pThread.initialiseBuckets(bucketDuration);
+				profiledThreadsMap.put(threadName, pThread);
+			}
+			pThread.increaseSampleCount(bucket, (int) sample.sampleSynchTime,
+					sample.cpuNumber);
+			sample.threadIndex = pThread.getIndex();
+
+			// process binary information
+			ProfiledBinary pBinary = profiledBinariesMap.get(binaryName);
+			if (pBinary == null) {
+				pBinary = new ProfiledBinary(cpuCount, graphCount);
+
+				pBinary.setIndex(binaryCount++);
+				pBinary.setNameString(binaryName);
+				pBinary.setColor(getBinaryColorPalette().getColor(binaryName));
+
+				pBinary.createBuckets(numberOfBuckets);
+				pBinary.initialiseBuckets(bucketDuration);
+				profiledBinariesMap.put(binaryName, pBinary);
+			}
+			pBinary.increaseSampleCount(bucket, (int) sample.sampleSynchTime,
+					sample.cpuNumber);
+			sample.binaryIndex = pBinary.getIndex();
+
+			// process function information
+			ProfiledFunction pFunction = profiledFunctionsMap.get(functionName);
+			if (pFunction == null) {
+				pFunction = new ProfiledFunction(cpuCount, graphCount);
+
+				pFunction.setIndex(functionCount++);
+				pFunction.setNameString(functionName);
+				pFunction.setFunctionAddress(GppTraceUtil
+						.getFunctionAddress(sample));
+				pFunction.setFunctionBinaryName(binaryName);
+				pFunction.setColor(getFunctionColorPalette().getColor(
+						functionName));
+
+				pFunction.createBuckets(numberOfBuckets);
+				pFunction.initialiseBuckets(bucketDuration);
+				profiledFunctionsMap.put(functionName, pFunction);
+			}
+			pFunction.increaseSampleCount(bucket, (int) sample.sampleSynchTime,
+					sample.cpuNumber);
+			sample.functionIndex = pFunction.getIndex();
+		}
+
+		// update bucket percentages now
+		for (ProfiledThread thread : profiledThreadsMap.values()) {
+			thread
+					.calculateBucketPercentages(bucketTotalArr,
+							bucketTotalArrSMP);
+		}
+		for (ProfiledBinary binary : profiledBinariesMap.values()) {
+			binary
+					.calculateBucketPercentages(bucketTotalArr,
+							bucketTotalArrSMP);
+		}
+		for (ProfiledFunction function : profiledFunctionsMap.values()) {
+			function.calculateBucketPercentages(bucketTotalArr,
+					bucketTotalArrSMP);
+		}
+	}
+
+	/**
+	 * Sets the CPU count
+	 * 
+	 * @param cpuCount
+	 *            the number of CPUs encountered in the data
+	 */
+	public void setCPUCount(int cpuCount) {
+		this.cpuCount = cpuCount < 1 ? 1 : cpuCount;
+		this.isSMP = cpuCount > 1;
+	}
+
+	/**
+	 * Returns the number of CPUs encountered. If the number is greater than 1,
+	 * it is SMP data
+	 * 
+	 * @return number of CPUs
+	 */
+	public int getCPUCount() {
+		return cpuCount;
+	}
+
+	/**
+	 * Sets additional data when trace is loaded from .bup file
+	 * 
+	 * @param data
+	 *            The data to set
+	 */
+	public void setAdditionalData(Vector<Object> data) {
+		Vector<Object> tmpData = (Vector<Object>) data;
+		Hashtable<Integer, java.awt.Color> threadColors = (Hashtable<Integer, java.awt.Color>) tmpData
+				.elementAt(0);
+		Hashtable<String, java.awt.Color> binaryColors = (Hashtable<String, java.awt.Color>) tmpData
+				.elementAt(1);
+		Hashtable<String, java.awt.Color> functionColors = (Hashtable<String, java.awt.Color>) tmpData
+				.elementAt(2);
+
+		boolean changed;
+		Enumeration<ProfiledGeneric> e;
+
+		changed = false;
+		e = getSortedThreadsElements();
+		while (e.hasMoreElements()) {
+			ProfiledThread pt = (ProfiledThread) e.nextElement();
+			// backward compatibility with old Swing Color
+			java.awt.Color tmpAWTColor = threadColors.get(pt.getThreadId());
+			if (tmpAWTColor != null) {
+				Color color = ColorPalette.getColor(new RGB(tmpAWTColor
+						.getRed(), tmpAWTColor.getGreen(), tmpAWTColor
+						.getBlue()));
+				if (color != null) {
+					pt.setColor(color);
+					changed = true;
+				}
 			}
 		}
+
+		final int uid = NpiInstanceRepository.getInstance().activeUid();
+
+		if (changed) {
+			// need to provide new colors for the thread load table
+			getGppGraph(PIPageEditor.THREADS_PAGE, uid)
+					.refreshColoursFromTrace();
+		}
+
+		changed = false;
+		e = getSortedBinariesElements();
+		while (e.hasMoreElements()) {
+			ProfiledBinary pb = (ProfiledBinary) e.nextElement();
+			// backward compatibility with old Swing Color
+			java.awt.Color tmpAWTColor = binaryColors.get(pb.getNameString());
+			if (tmpAWTColor != null) {
+				Color color = ColorPalette.getColor(new RGB(tmpAWTColor
+						.getRed(), tmpAWTColor.getGreen(), tmpAWTColor
+						.getBlue()));
+				if (color != null) {
+					pb.setColor(color);
+					changed = true;
+				}
+			}
+		}
+
+		if (changed) {
+			// need to provide new colors for the binary load table
+			getGppGraph(PIPageEditor.BINARIES_PAGE, uid)
+					.refreshColoursFromTrace();
+		}
+
+		changed = false;
+		e = getSortedFunctionsElements();
+		while (e.hasMoreElements()) {
+			ProfiledFunction pb = (ProfiledFunction) e.nextElement();
+			// backward compatibility with old Swing Color
+			java.awt.Color tmpAWTColor = functionColors.get(pb.getNameString());
+			if (tmpAWTColor != null) {
+				Color color = ColorPalette.getColor(new RGB(tmpAWTColor
+						.getRed(), tmpAWTColor.getGreen(), tmpAWTColor
+						.getBlue()));
+				if (color != null) {
+					pb.setColor(color);
+					changed = true;
+				}
+			}
+		}
+
+		if (changed) {
+			// need to provide new colors for the binary load table
+			getGppGraph(PIPageEditor.FUNCTIONS_PAGE, uid)
+					.refreshColoursFromTrace();
+		}
+
 	}
+	
+	/**
+	 * Returns true if this is a single-CPU graph on an SMP trace.
+	 * @param graphIndex the index of the graph to check
+	 * @return true, if single-CPU graph on an SMP trace, false otherwise
+	 */
+	private boolean isSingleCPUModeonSMP(int graphIndex){
+		return isSMP && graphIndex > PIPageEditor.FUNCTIONS_PAGE;
+	}
+
+	/**
+	 * Sets the number of graphs to be used. This is necessary because all ProfiledGenerics
+	 * hold values per graph. 
+	 * 
+	 * <p>Value is only set when called for the first time. 
+	 * @param graphCount the graphCount to set
+	 */
+	public void setGraphCount(int graphCount) {
+		if (this.graphCount == -1){
+			this.graphCount = graphCount;
+		}
+	}
+	
+	/**
+	 * Returns the number of graphs for this trace. This includes the 3 basic
+	 * graphs as well as one extra graph per CPU in the SMP case.
+	 * 
+	 * @return
+	 */
+	public int getGraphCount(){
+		if (graphCount == -1){
+			throw new IllegalStateException();
+		}
+		return this.graphCount;
+	}
+
+	/**
+	 * Returns the TabFolder for the legend views for this page.
+	 * 
+	 * TODO: Ideally, this should be in a GUI-related class, but right now
+	 * we don't have any class that has visibility of all graphs
+	 * 
+	 * 
+	 * @param pageIndex
+	 *            Index of the page to use (PIPageEditor.THREADS_PAGE,
+	 *            PIPageEditor.BINARIES_PAGE, PIPageEditor.FUNCTIONS_PAGE)
+	 * @param parent
+	 *            The parent composite to put the TabFolder in
+	 * @return the TabFolder
+	 */
+	private TabFolderWrapper getTabFolder(int pageIndex, Composite parent) {
+		if (pageIndex < PIPageEditor.THREADS_PAGE
+				|| pageIndex > PIPageEditor.FUNCTIONS_PAGE
+				|| !needTabFolder(pageIndex)) {
+			throw new IllegalArgumentException();
+		}
+		
+		if (legendTabFolders == null){
+			legendTabFolders = new TabFolderWrapper[3];
+		}
+		if (legendTabFolders[pageIndex] == null){
+			legendTabFolders[pageIndex] = new TabFolderWrapper(new TabFolder(parent, SWT.NONE));
+			
+		}
+		return legendTabFolders[pageIndex];
+	}
+	
+	/**
+	 * Create and return the main Composite for the legend view. This methods manages whether to
+	 * create the legend on a simple Composite (for single graphs on one page) or to put
+	 * the legend composite on a tabbed legend (for multiple CPU graphs on one pages)
+	 * @param pageIndex page index 
+	 * @param graphIndex graph index
+	 * @param parent the parent composite for the legend
+	 * @param title the title to display - typically the title of the graph
+	 * @return the newly created legend Composite
+	 */
+	public Composite createLegendComposite(int pageIndex, int graphIndex, Composite parent, String title){
+		Composite legendComposite = null;
+		
+		if (needTabFolder(pageIndex)){
+			
+			TabFolderWrapper legendTabFolder = getTabFolder(pageIndex, parent);
+			legendComposite = legendTabFolder.createTabItem(graphIndex);
+		} else {
+
+			// create a wrapper composite so we can add a title in addition to the table viewers
+			//
+			Composite legendWrapperComposite = new Composite(parent, SWT.NONE);		
+			legendWrapperComposite.setLayout(GridLayoutFactory.fillDefaults().numColumns(1).spacing(0, 0).create());
+
+			Label label = new Label(legendWrapperComposite, SWT.CENTER);
+			label.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_WHITE));
+			label.setText(title);
+			label.setLayoutData(GridDataFactory.fillDefaults().align(SWT.FILL, SWT.BEGINNING).grab(true, false).create());
+			
+			legendComposite = new Composite(legendWrapperComposite, SWT.NONE);	
+			legendComposite.setLayoutData(GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).grab(true, true).create());
+		}
+		return legendComposite;
+	}
+
+	/**
+	 * Returns true if multiple CPU load graphs are on the given page
+	 * @param pageIndex one of PIPageEditor.THREADS_PAGE, PIPageEditor.BINARIES_PAGE, PIPageEditor.FUNCTIONS_PAGE
+	 * @return true for multiple CPU load graphs on page, false otherwise
+	 */
+	public boolean needTabFolder(int pageIndex) {
+		return graphCount > 3 && pageIndex == PIPageEditor.THREADS_PAGE;
+	}
+
+	/**
+	 * Changes visibility of the graph legend with the given graph index 
+	 * @param graphIndex Index of the graph for which to 
+	 * @param visible true to make visible, false to hide
+	 * @param legend the main Composite of the legend view
+	 */
+	public void setLegendVisible(int graphIndex, boolean visible, Composite legend){
+		int pageIndex = AddressPlugin.getPageIndex(graphIndex);
+		if (needTabFolder(pageIndex)){
+			TabFolderWrapper legendTabFolder = legendTabFolders[pageIndex];
+			legendTabFolder.setVisible(graphIndex, visible);
+		} else {
+			legend.getParent().setVisible(visible);
+		}
+	}
+	/**
+	 * Sets the graph legend with the given graph index to maximised (or restored) 
+	 * @param graphIndex Index of the graph for which to 
+	 * @param maximised true to set maximised, false to restore
+	 * @param legend the main Composite of the legend view
+	 */
+	public void setLegendMaximised(int graphIndex, boolean maximised, Composite legend){
+		int pageIndex = AddressPlugin.getPageIndex(graphIndex);
+		if (needTabFolder(pageIndex)){
+			legendTabFolders[pageIndex].setMaximised(graphIndex, maximised);
+		} else {
+			((SashForm)legend.getParent().getParent()).setMaximizedControl(maximised ? legend.getParent() : null);
+		}
+	}
+	
+	/**
+	 * Class to wrap TabFolders for legend management
+	 * This should really go into a GUI-related class but we haven't got 
+	 * one with visibility of all graphs
+	 *
+	 */
+	class TabFolderWrapper{
+		
+		private TabFolder tabFolder;
+		/** indicates which legends are enabled; one per graphIndex */
+		private boolean[] legendsVisible;
+		/** the Composites for each tabItem; one per graphIndex */
+		private Composite[] legendComposites;
+		
+		public TabFolderWrapper(TabFolder tabFolder) {
+			this.tabFolder = tabFolder;
+			legendsVisible = new boolean[graphCount];
+			legendComposites = new Composite[graphCount];
+		}
+
+		public void setVisible(int graphIndex, boolean visible) {
+			if (legendsVisible[graphIndex] != visible){
+				
+				//dispose all tabItems and recreate them so that the correct order is preserved
+				//
+				legendsVisible[graphIndex] = visible;
+				for (TabItem tabItem : tabFolder.getItems()) {
+					tabItem.dispose();
+				}
+				for (int i = 0; i < legendsVisible.length; i++) {
+					boolean isVisible = legendsVisible[i];
+					if (isVisible){
+						TabItem legendTabItem = new TabItem (tabFolder, SWT.NONE);
+						legendTabItem.setText(getTraceGraph(i).getShortTitle());
+						legendTabItem.setControl(legendComposites[i]);							
+					}
+				}
+			}
+		}
+		
+		public void setMaximised(int graphIndex, boolean maximised){
+			if (maximised){
+				setVisible(graphIndex, maximised);	//in case it was minimised before			
+			}
+			((SashForm)tabFolder.getParent()).setMaximizedControl(maximised ? tabFolder : null);
+		}
+
+		public Composite createTabItem(int graphIndex) {
+			TabItem legendTabItem = new TabItem (tabFolder, SWT.NONE);
+			legendTabItem.setText(getTraceGraph(graphIndex).getShortTitle());
+			Composite legendComposite = new Composite(tabFolder, SWT.NONE);
+			legendTabItem.setControl(legendComposite);	
+
+			legendsVisible[graphIndex] = true;
+			legendComposites[graphIndex] = legendComposite;
+			return legendComposite;
+		}
+	}
+
+	
 }
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/pi/address/GppTraceCsvPrinter.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/pi/address/GppTraceCsvPrinter.java	Wed Apr 21 15:14:16 2010 +0300
@@ -119,7 +119,7 @@
     
     private void formCsvPrint(Enumeration profiledThreads, File threadFile)
     {
-    	Hashtable<String,int[]> activityByName = new Hashtable<String,int[]>();
+    	Hashtable<String,float[]> activityByName = new Hashtable<String,float[]>();
     	Vector fixedThreads = getFixedThreadTable(threadFile);
     	Vector<ObjectMap> resultVector = new Vector<ObjectMap>();
     	boolean nullListFormed = false;
@@ -136,8 +136,8 @@
     		String name = formatThreadName(pt.getNameString());
     		if (activityByName.containsKey(name))
     		{
-    			int[] existingList = activityByName.get(name);
-    			int[] combinedList = combineLists(pt.getActivityList(), existingList);
+    			float[] existingList = activityByName.get(name);
+    			float[] combinedList = combineLists(pt.getActivityList(), existingList);
     			activityByName.put(name, combinedList);
     		}
     		else
@@ -214,11 +214,11 @@
     	
     }
     
-    private int[] combineLists(int[] p1List, int[] p2List)
+    private float[] combineLists(float[] p1List, float[] p2List)
     {
     	if (p1List.length < p2List.length)
     		return null;
-    	int[] combinedList = new int[p2List.length];
+    	float[] combinedList = new float[p2List.length];
     	for (int i = 0; i < p2List.length; i++)
     	{
     		combinedList[i] = p2List[i] + p1List[i];
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/pi/address/GppTraceGraph.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/pi/address/GppTraceGraph.java	Wed Apr 21 15:14:16 2010 +0300
@@ -24,11 +24,8 @@
 import java.awt.event.ActionListener;
 import java.awt.event.FocusEvent;
 import java.awt.event.FocusListener;
-import java.util.Collection;
 import java.util.Enumeration;
 import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.LinkedList;
 import java.util.Vector;
 
 import org.eclipse.draw2d.FigureCanvas;
@@ -37,9 +34,11 @@
 import org.eclipse.draw2d.MouseListener;
 import org.eclipse.draw2d.MouseMotionListener;
 import org.eclipse.draw2d.Panel;
-import org.eclipse.jface.viewers.CheckboxTableViewer;
+import org.eclipse.jface.action.Action;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.MouseMoveListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
 import org.eclipse.swt.graphics.Color;
 import org.eclipse.swt.graphics.GC;
 import org.eclipse.swt.graphics.Point;
@@ -47,754 +46,871 @@
 import org.eclipse.swt.graphics.Rectangle;
 import org.eclipse.swt.layout.FormLayout;
 import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
 import org.eclipse.swt.widgets.Sash;
 
+import com.nokia.carbide.cpp.internal.pi.address.GppModelAdapter;
+import com.nokia.carbide.cpp.internal.pi.address.GppTraceGraphSMP;
 import com.nokia.carbide.cpp.internal.pi.analyser.NpiInstanceRepository;
 import com.nokia.carbide.cpp.internal.pi.analyser.ProfileVisualiser;
-import com.nokia.carbide.cpp.internal.pi.model.GenericSampledTrace;
 import com.nokia.carbide.cpp.internal.pi.model.ProfiledBinary;
 import com.nokia.carbide.cpp.internal.pi.model.ProfiledFunction;
 import com.nokia.carbide.cpp.internal.pi.model.ProfiledGeneric;
 import com.nokia.carbide.cpp.internal.pi.model.ProfiledThread;
 import com.nokia.carbide.cpp.internal.pi.model.ProfiledThreshold;
+import com.nokia.carbide.cpp.internal.pi.plugin.model.IContextMenu;
+import com.nokia.carbide.cpp.internal.pi.plugin.model.ITitleBarMenu;
 import com.nokia.carbide.cpp.internal.pi.visual.Defines;
 import com.nokia.carbide.cpp.internal.pi.visual.GenericTable;
 import com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph;
 import com.nokia.carbide.cpp.internal.pi.visual.GraphComposite;
 import com.nokia.carbide.cpp.internal.pi.visual.PIEvent;
-import com.nokia.carbide.cpp.internal.pi.visual.PIEventListener;
-import com.nokia.carbide.cpp.internal.pi.visual.PIVisualSharedData;
 import com.nokia.carbide.cpp.pi.editors.PIPageEditor;
 import com.nokia.carbide.cpp.pi.util.ColorPalette;
+import com.nokia.carbide.cpp.pi.visual.IGenericTraceGraph;
 
+/**
+ * Each instance of this class represents one trace graph for profiling
+ * CPU activity. 
+ *
+ */
+public class GppTraceGraph extends GenericTraceGraph implements IGppTraceGraph,
+		ActionListener, FocusListener, MouseMotionListener, MouseListener,
+		MouseMoveListener, ITitleBarMenu, IContextMenu {
 
-public class GppTraceGraph extends GenericTraceGraph implements ActionListener, 
-																FocusListener, 
-																PIEventListener,
-																MouseMotionListener,
-																MouseListener,
-																MouseMoveListener
-{
-	private GppTraceGraph thisTraceGraph;
+	/**
+	 * amount of space at bottom of graph to contain things like x-axis units
+	 * and button icons
+	 */
+	public static final int X_LEGEND_HEIGHT = 50;
+
+	/**
+	 * When the graph is drawn, this is the finest granularity drawn. E.g.,
+	 * assume a granularity of 100, and a sample every ms. If the 1st function
+	 * draw appears in 5 samples from 101ms to 200ms and 10 samples from 200ms
+	 * to 300ms then the graph will show a point at height 5 at time 200
+	 * connected by a line to a point at height 10 at time 300.
+	 */
+	static final int GRANULARITY_VALUE = 100;
 	
-	// amount of space at bottom of graph to contain things like x-axis units and button icons
-	public static final int xLegendHeight = 50;
-	
-	// When the graph is drawn, this is the finest granularity drawn. E.g., assume
-	// a granularity of 100, and a sample every ms. If the 1st function draw appears
-	// in 5 samples from 101ms to 200ms and 10 samples from 200ms to 300ms then the
-	// graph will show a point at height 5 at time 200 connected by a line to a
-	// point at height 10 at time 300.
-	private static int granularityValue = 100;
-	
-	private GppVisualiserPanel vPanel;
+	/** constant to indicate graph is a bar graph */
+	public static final int BAR_MODE_ON = 3;
+	/** constant to indicate graph is stacked-area graph */
+	public static final int BAR_MODE_OFF = 4;
+
+	private static final String EMPTY_STRING = "";//$NON-NLS-1$ 
+
+	protected GppVisualiserPanel vPanel;
+	protected String title;
+	protected String shortTitle;
 
 	/*
-	 *  Depending on this trace graph's graphIndex, one of these will be
-	 *  the base table, and others will be derived from its selections.
-	 *  The other tables will appear and disappear based on drawMode.
-	 *  
-	 *  E.g., say that for graphIndex = 0, the base table is threadTable.
-	 *  Then this graph can represent the draw modes of:
-	 *  	THREADS
-	 *  	THREADS_BINARIES
-	 *  	THREADS_BINARIES_FUNCTIONS
-	 *  	THREADS_FUNCTIONS
-	 *  	THREADS_FUNCTIONS_BINARIES
+	 * Depending on this trace graph's graphIndex, one of these will be the base
+	 * table, and others will be derived from its selections. The other tables
+	 * will appear and disappear based on drawMode.
+	 * 
+	 * E.g., say that for graphIndex = 0, the base table is threadTable. Then
+	 * this graph can represent the draw modes of: THREADS THREADS_BINARIES
+	 * THREADS_BINARIES_FUNCTIONS THREADS_FUNCTIONS THREADS_FUNCTIONS_BINARIES
 	 */
-	private AddrThreadTable   threadTable;
-	private AddrBinaryTable   binaryTable;
-	private AddrFunctionTable functionTable;
-
+	protected AddrThreadTable threadTable;
+	protected AddrBinaryTable binaryTable;
+	protected AddrFunctionTable functionTable;
+	
 	/*
-	 *	Depending on this trace graph's graphIndex, one of these will match
-	 *	the entire trace's profiled vector, while the others will be derived
-	 *	from drilldown selections. The other vectors will only be meaningful
-	 *  depending on the drawMode.
+	 * Depending on this trace graph's graphIndex, one of these will match the
+	 * entire trace's profiled vector, while the others will be derived from
+	 * drilldown selections. The other vectors will only be meaningful depending
+	 * on the drawMode.
 	 */
-	private Vector<ProfiledGeneric> profiledThreads   = new Vector<ProfiledGeneric>();
-	private Vector<ProfiledGeneric> profiledBinaries  = new Vector<ProfiledGeneric>();
-	private Vector<ProfiledGeneric> profiledFunctions = new Vector<ProfiledGeneric>();
-	
-	private Vector<ProfiledGeneric> sortedProfiledThreads   = new Vector<ProfiledGeneric>();
-	private Vector<ProfiledGeneric> sortedProfiledBinaries  = new Vector<ProfiledGeneric>();
+	protected Vector<ProfiledGeneric> profiledThreads = new Vector<ProfiledGeneric>();
+	protected Vector<ProfiledGeneric> profiledBinaries = new Vector<ProfiledGeneric>();
+	protected Vector<ProfiledGeneric> profiledFunctions = new Vector<ProfiledGeneric>();
+
+	private Vector<ProfiledGeneric> sortedProfiledThreads = new Vector<ProfiledGeneric>();
+	private Vector<ProfiledGeneric> sortedProfiledBinaries = new Vector<ProfiledGeneric>();
 	private Vector<ProfiledGeneric> sortedProfiledFunctions = new Vector<ProfiledGeneric>();
-	
-	private ProfiledThreshold thresholdThread   = new ProfiledThreshold("dummy[0]::dummy_0"); //$NON-NLS-1$
-	private ProfiledThreshold thresholdBinary   = new ProfiledThreshold("\\dummy"); //$NON-NLS-1$
-	private ProfiledThreshold thresholdFunction = new ProfiledThreshold("dummy::dummy()"); //$NON-NLS-1$
+
+	protected ProfiledThreshold thresholdThread;
+	private ProfiledThreshold thresholdBinary;
+	private ProfiledThreshold thresholdFunction;
 
 	// when multiple tables are visible, they are separated by sashes
 	private Sash leftSash;
 	private Sash rightSash;
 
-	public static final int NOFILL       = 0;
-	public static final int FILLSELECTED = 1;
-	public static final int FILLALL      = 2;
-	public static final int BAR_MODE_ON  = 3;
-	public static final int BAR_MODE_OFF = 4;
-		
-	private int drawMode = Defines.THREADS;
-	public int barMode   = BAR_MODE_OFF;
+	protected int drawMode = Defines.THREADS;
 	
-	private int uid;
-	
-	private static class BarGraphData
-	{
+	/** current graph drawing mode: either bar or stacked-area graph */
+	public int barMode = BAR_MODE_OFF;
+
+	protected int uid;
+
+	private static class BarGraphData {
 		public int x;
 		public Color color;
 	}
-	
+
 	private Vector<BarGraphData> barGraphData;
-	
-	public GppTraceGraph(int graphIndex, GppTrace trace, int uid)
-	{
-		super((GenericSampledTrace)trace);
-		
-		int granularityValue = trace.samples.size() > GppTraceGraph.granularityValue ? GppTraceGraph.granularityValue : trace.samples.size();  
-		
-		this.thisTraceGraph = this;
-		this.graphIndex     = graphIndex;
-		
-		// create the graph's 3 table objects - without any table items yet
-		ProfileVisualiser pV = NpiInstanceRepository.getInstance().getProfilePage(uid, graphIndex);
-		Composite holdTables = new Composite(pV.getBottomComposite(), SWT.NONE);
-		holdTables.setLayout(new FormLayout());
+
+	/**
+	 * The model adapter hides some of the SMP specifics. It must be created
+	 * during initialisation of this graph.
+	 */
+	protected GppModelAdapter adapter;
+
+	/** main Composite of legend view */
+	private Composite holdTablesComposite;
+
 
-		this.threadTable   = new AddrThreadTable(this, holdTables);
-		this.binaryTable   = new AddrBinaryTable(this, holdTables);
-		this.functionTable = new AddrFunctionTable(this, holdTables);
-		
+	/**
+	 * Constructor
+	 * 
+	 * @param graphIndex
+	 *            the unique index of this graph
+	 * @param trace
+	 *            the trace data model to use
+	 * @param uid
+	 *            the Uid of the editor session
+	 */
+	public GppTraceGraph(int graphIndex, GppTrace trace, int uid) {
+		super(trace);
+		this.graphIndex = graphIndex;
 		this.uid = uid;
 
-		Label graphTitle = pV.getTitle();
-		Label graphTitle2 = pV.getTitle2();
-		if 	(graphTitle2 != null)
-			graphTitle2.setText(""); //$NON-NLS-1$
+	}
+
+	/**
+	 * Initialises the graph.
+	 * 
+	 * @param pageIndex
+	 *            page index of the page which displays the graph
+	 * @param trace
+	 *            the trace model
+	 */
+	public void init(int pageIndex, GppTrace trace) {
+		doCreateAdapter();
+		doSetTitle();
+		int granularityValue = trace.samples.size() > GppTraceGraph.GRANULARITY_VALUE ? GppTraceGraph.GRANULARITY_VALUE
+				: trace.samples.size();
+
+		// create the graph's 3 table objects - without any table items yet
+		ProfileVisualiser pV = NpiInstanceRepository.getInstance()
+				.getProfilePage(uid, pageIndex);
+		holdTablesComposite = trace.createLegendComposite(pageIndex, graphIndex, pV.getBottomComposite(), getShortTitle());
+		holdTablesComposite.setLayout(new FormLayout());
+
+		createLegendTables(holdTablesComposite);
 
 		// initialize the threshold counts
 		int totalSampleCount = trace.getSampleAmount();
-		NpiInstanceRepository.getInstance().setPersistState(uid, "com.nokia.carbide.cpp.pi.address.thresholdCountThread", new Integer(new Double(totalSampleCount * (Double)NpiInstanceRepository.getInstance().getPersistState(uid, "com.nokia.carbide.cpp.pi.address.thresholdLoadThread") + 0.5).intValue())); //$NON-NLS-1$ //$NON-NLS-2$
-		NpiInstanceRepository.getInstance().setPersistState(uid, "com.nokia.carbide.cpp.pi.address.thresholdCountBinary", new Integer(new Double(totalSampleCount * (Double)NpiInstanceRepository.getInstance().getPersistState(uid, "com.nokia.carbide.cpp.pi.address.thresholdLoadBinary") + 0.5).intValue())); //$NON-NLS-1$ //$NON-NLS-2$
-		NpiInstanceRepository.getInstance().setPersistState(uid, "com.nokia.carbide.cpp.pi.address.thresholdCountFunction", new Integer(new Double(totalSampleCount * (Double)NpiInstanceRepository.getInstance().getPersistState(uid, "com.nokia.carbide.cpp.pi.address.thresholdLoadFunction") + 0.5).intValue())); //$NON-NLS-1$ //$NON-NLS-2$
-		
-		int samplingInterval = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.samplingInterval"); //$NON-NLS-1$
+
+		// CH: this is called too many times (those values are global for the
+		// whole trace) -> can we move it to GppTrace?
+		NpiInstanceRepository
+				.getInstance()
+				.setPersistState(
+						uid,
+						"com.nokia.carbide.cpp.pi.address.thresholdCountThread", Integer.valueOf(new Double(totalSampleCount * (Double) NpiInstanceRepository.getInstance().getPersistState(uid, "com.nokia.carbide.cpp.pi.address.thresholdLoadThread") + 0.5).intValue())); //$NON-NLS-1$ //$NON-NLS-2$
+		NpiInstanceRepository
+				.getInstance()
+				.setPersistState(
+						uid,
+						"com.nokia.carbide.cpp.pi.address.thresholdCountBinary", Integer.valueOf(new Double(totalSampleCount * (Double) NpiInstanceRepository.getInstance().getPersistState(uid, "com.nokia.carbide.cpp.pi.address.thresholdLoadBinary") + 0.5).intValue())); //$NON-NLS-1$ //$NON-NLS-2$
+		NpiInstanceRepository
+				.getInstance()
+				.setPersistState(
+						uid,
+						"com.nokia.carbide.cpp.pi.address.thresholdCountFunction", Integer.valueOf(new Double(totalSampleCount * (Double) NpiInstanceRepository.getInstance().getPersistState(uid, "com.nokia.carbide.cpp.pi.address.thresholdLoadFunction") + 0.5).intValue())); //$NON-NLS-1$ //$NON-NLS-2$
+
+		int samplingInterval = (Integer) NpiInstanceRepository.getInstance()
+				.activeUidGetPersistState(
+						"com.nokia.carbide.cpp.pi.address.samplingInterval"); //$NON-NLS-1$
 
 		// initialize the threshold items
-		thresholdThread.setColor(trace.getThreadColorPalette().getColor(thresholdThread.getNameString()));
-		thresholdThread.setActivityMarkCount((trace.samples.size() + granularityValue) / granularityValue + 1);
-		for (int i = 0; i < trace.samples.size() + granularityValue; i += granularityValue)
-		{
-			thresholdThread.zeroActivityMarkValues(i * samplingInterval);
-		}
-		thresholdBinary.setColor(trace.getBinaryColorPalette().getColor(thresholdBinary.getNameString()));
-		thresholdBinary.setActivityMarkCount((trace.samples.size() + granularityValue) / granularityValue + 1);
-		for (int i = 0; i < trace.samples.size() + granularityValue; i += granularityValue)
-		{
-			thresholdBinary.zeroActivityMarkValues(i * samplingInterval);
-		}
-		thresholdFunction.setColor(trace.getFunctionColorPalette().getColor(thresholdFunction.getNameString()));
-		thresholdFunction.setActivityMarkCount((trace.samples.size() + granularityValue) / granularityValue + 1);
-		for (int i = 0; i < trace.samples.size() + granularityValue; i += granularityValue)
-		{
-			thresholdFunction.zeroActivityMarkValues(i * samplingInterval);
-		}
+		int bucketDuration = granularityValue * samplingInterval;
+		int numberOfBuckets = GppTraceUtil.calculateNumberOfBuckets(trace
+				.getLastSampleTime(), granularityValue);
 
-		// all the trace data is known, and you have it sorted 3 different ways
-		// so set the drawmode, create the page's base table, and set the graph title
-		if (graphIndex == PIPageEditor.THREADS_PAGE) {
-			this.drawMode = Defines.THREADS;
+		thresholdThread = new ProfiledThreshold(
+				"dummy[0]::dummy_0", trace.getCPUCount(), trace.getGraphCount()); //$NON-NLS-1$
+		thresholdBinary = new ProfiledThreshold(
+				"\\dummy", trace.getCPUCount(), trace.getGraphCount()); //$NON-NLS-1$
+		thresholdFunction = new ProfiledThreshold(
+				"dummy::dummy()", trace.getCPUCount(), trace.getGraphCount()); //$NON-NLS-1$
+		thresholdThread.setColor(trace.getThreadColorPalette().getColor(
+				thresholdThread.getNameString()));
+		thresholdThread.createBuckets(numberOfBuckets);
+		thresholdThread.initialiseBuckets(bucketDuration);
+		thresholdBinary.setColor(trace.getBinaryColorPalette().getColor(
+				thresholdBinary.getNameString()));
+		thresholdBinary.createBuckets(numberOfBuckets);
+		thresholdBinary.initialiseBuckets(bucketDuration);
+		thresholdFunction.setColor(trace.getFunctionColorPalette().getColor(
+				thresholdFunction.getNameString()));
+		thresholdFunction.createBuckets(numberOfBuckets);
+		thresholdFunction.initialiseBuckets(bucketDuration);
+
+		int graphType = adapter.getGraphType();
 
-			// tables will show threads in decreasing total sample order, but
-			// then put them back in increasing sample order so that the graph
-			// shows most common (e.g., EKern) threads on top
-			this.profiledThreads.clear();
-			for (int i = trace.getSortedThreads().size() - 1; i >= 0; i--)
-				this.profiledThreads.add(trace.getSortedThreads().get(i));
-			filterSortedByThreshold(graphIndex, 
-									(Integer)NpiInstanceRepository.getInstance().getPersistState(uid, "com.nokia.carbide.cpp.pi.address.thresholdCountThread"), //$NON-NLS-1$
-									thresholdThread, this.profiledThreads);
+		if (graphType == PIPageEditor.THREADS_PAGE) {
+			this.drawMode = Defines.THREADS;
+			int threshold = (Integer)NpiInstanceRepository.getInstance().getPersistState(uid, "com.nokia.carbide.cpp.pi.address.thresholdCountThread"); //$NON-NLS-1$
+
+			for (ProfiledGeneric profiled : trace.getSortedThreads()) {
+				if (adapter.getTotalSampleCount(profiled) > 0){
+					if (adapter.getTotalSampleCount(profiled) < threshold){//check below threshold
+						adapter.addItem(thresholdThread, graphIndex, profiled, adapter.getTotalSampleCount(profiled));
+					} else {
+						profiledThreads.add(profiled);
+					}
+				}
+			}
+
 			this.threadTable.setTableViewer(Defines.THREADS);
-
 			this.profiledThreads = trace.getSortedThreads();
-			graphTitle.setText(Messages.getString("GppTraceGraph.threadLoad"));  //$NON-NLS-1$
-		} else
-		if (graphIndex == PIPageEditor.BINARIES_PAGE) {
+		} else if (graphType == PIPageEditor.BINARIES_PAGE) {
 			this.drawMode = Defines.BINARIES;
+			int threshold = (Integer)NpiInstanceRepository.getInstance().getPersistState(uid, "com.nokia.carbide.cpp.pi.address.thresholdCountBinary"); //$NON-NLS-1$
 
-			// tables will show binaries in decreasing total sample order, but
-			// then put them back in increasing sample order so that the graph
-			// shows most common (e.g., EKern) binaries on top
-			this.profiledBinaries.clear();
-			for (int i = trace.getSortedBinaries().size() - 1; i >= 0; i--)
-				this.profiledBinaries.add(trace.getSortedBinaries().get(i));
-			filterSortedByThreshold(graphIndex, (Integer)NpiInstanceRepository.getInstance().getPersistState(uid, "com.nokia.carbide.cpp.pi.address.thresholdCountBinary"), //$NON-NLS-1$
-								thresholdBinary, this.profiledBinaries);
+			for (ProfiledGeneric profiled : trace.getSortedBinaries()) {
+				if (adapter.getTotalSampleCount(profiled) > 0){
+					if (adapter.getTotalSampleCount(profiled) < threshold){//check below threshold
+						adapter.addItem(thresholdBinary, graphIndex, profiled, adapter.getTotalSampleCount(profiled));
+					} else {
+						profiledBinaries.add(profiled);
+					}
+					
+				}
+			}
+
 			this.binaryTable.setTableViewer(Defines.BINARIES);
 
 			this.profiledBinaries = trace.getSortedBinaries();
-			graphTitle.setText(Messages.getString("GppTraceGraph.binaryLoad"));  //$NON-NLS-1$
-		} else
-		if (graphIndex == PIPageEditor.FUNCTIONS_PAGE) {
+		} else if (graphType == PIPageEditor.FUNCTIONS_PAGE) {
 			this.drawMode = Defines.FUNCTIONS;
+			int threshold = (Integer)NpiInstanceRepository.getInstance().getPersistState(uid, "com.nokia.carbide.cpp.pi.address.thresholdCountFunction"); //$NON-NLS-1$
 
-			// tables will show functions in decreasing total sample order, but
-			// then put them back in increasing sample order so that the graph
-			// shows most common (e.g., EKern) functions on top
-			this.profiledFunctions.clear();
-			for (int i = trace.getSortedFunctions().size() - 1; i >= 0; i--)
-				this.profiledFunctions.add(trace.getSortedFunctions().get(i));
-			filterSortedByThreshold(graphIndex, (Integer)NpiInstanceRepository.getInstance().getPersistState(uid, "com.nokia.carbide.cpp.pi.address.thresholdCountFunction"), //$NON-NLS-1$
-								thresholdFunction, this.profiledFunctions);
+			for (ProfiledGeneric profiled : trace.getSortedFunctions()) {
+				if (adapter.getTotalSampleCount(profiled) > 0){
+					if (adapter.getTotalSampleCount(profiled) < threshold){//check below threshold
+						adapter.addItem(thresholdFunction, graphIndex, profiled, adapter.getTotalSampleCount(profiled));
+					} else {
+						profiledFunctions.add(profiled);
+					}
+				}
+			}
 			this.functionTable.setTableViewer(Defines.FUNCTIONS);
 
 			this.profiledFunctions = trace.getSortedFunctions();
-			graphTitle.setText(Messages.getString("GppTraceGraph.FunctionLoad"));  //$NON-NLS-1$
-		} else
-		{
-			try {
-				throw new Exception(Messages.getString("GppTraceGraph.traceGraphInternalErrorIn"));  //$NON-NLS-1$
-			} catch (Exception e) {
-				e.printStackTrace();
-			}
+		} else {
+			throw new IllegalStateException(Messages
+					.getString("GppTraceGraph.traceGraphInternalErrorIn")); //$NON-NLS-1$
 		}
-		
+
+
 		// since the trace can be shown any of 3 ways (by thread, by binary, or
 		// by function), make sure that all 3 are ready for display
-		// Sse sorted vector to be consistent with other call to genericRefreshCumulativeThreadTable()
-		// fix issue with wrong color on newly opened npi file before a change in the table
+		// Sse sorted vector to be consistent with other call to
+		// genericRefreshCumulativeThreadTable()
+		// fix issue with wrong color on newly opened npi file before a change
+		// in the table
 		if (this.profiledThreads.size() > 0) {
 			genericRefreshCumulativeThreadTable(this.profiledThreads.elements());
-			genericRefreshCumulativeThreadTable(this.sortedProfiledThreads.elements());
+			genericRefreshCumulativeThreadTable(this.sortedProfiledThreads
+					.elements());
 		}
 		if (this.profiledBinaries.size() > 0) {
-			genericRefreshCumulativeThreadTable(this.profiledBinaries.elements());
-			genericRefreshCumulativeThreadTable(this.sortedProfiledBinaries.elements());
+			genericRefreshCumulativeThreadTable(this.profiledBinaries
+					.elements());
+			genericRefreshCumulativeThreadTable(this.sortedProfiledBinaries
+					.elements());
 		}
 		if (this.profiledFunctions.size() > 0) {
-			genericRefreshCumulativeThreadTable(this.profiledFunctions.elements());
-			genericRefreshCumulativeThreadTable(this.sortedProfiledFunctions.elements());
+			genericRefreshCumulativeThreadTable(this.profiledFunctions
+					.elements());
+			genericRefreshCumulativeThreadTable(this.sortedProfiledFunctions
+					.elements());
 		}
-		
-		if (   this.profiledThreads.size() <= 0
-			&& this.profiledBinaries.size() <= 0
-			&& this.profiledFunctions.size() <= 0) {
+
+		if (this.profiledThreads.size() <= 0
+				&& this.profiledBinaries.size() <= 0
+				&& this.profiledFunctions.size() <= 0) {
 			try {
-				throw new Exception(Messages.getString("GppTraceGraph.traceGraphInternalErrorAt"));  //$NON-NLS-1$
+				throw new Exception(Messages
+						.getString("GppTraceGraph.traceGraphInternalErrorAt")); //$NON-NLS-1$
 			} catch (Exception e) {
 				e.printStackTrace();
 			}
 		}
 
 		this.vPanel = new GppVisualiserPanel(this);
+
 	}
-	
+
+	/**
+	 * Sets the graph-specific title
+	 */
+	protected void doSetTitle() {
+		title = Messages.getString("GppTraceGraph.1");		 //$NON-NLS-1$
+		shortTitle = Messages.getString("GppTraceGraph.0"); //$NON-NLS-1$
+	}
+
+	/**
+	 * Creates a GppModelAdapter
+	 */
+	protected void doCreateAdapter() {
+		adapter = new GppModelAdapter(this.graphIndex);
+	}
+
+	/**
+	 * Creates the three legend tables for this graph (for threads, binaries,
+	 * functions)
+	 * 
+	 * @param holdTablesComposite
+	 */
+	protected void createLegendTables(Composite holdTablesComposite) {
+		this.threadTable = new AddrThreadTable(this, holdTablesComposite, adapter);
+		this.binaryTable = new AddrBinaryTable(this, holdTablesComposite, adapter);
+		this.functionTable = new AddrFunctionTable(this, holdTablesComposite, adapter);
+	}
+
 	/*
-	 * Combine all vectors elements that are below the threshold into a single
-	 * vector element. Assumes that the input vector is sorted by decreasing sample count.
+	 * (non-Javadoc)
+	 * 
+	 * @see com.nokia.carbide.cpp.pi.address.IGppTraceGraph#getGppTrace()
+	 */
+	public GppTrace getGppTrace() {
+		return (GppTrace) this.getTrace();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.visual.PIEventListener#piEventReceived
+	 * (com.nokia.carbide.cpp.internal.pi.visual.PIEvent)
 	 */
-	private void filterSortedByThreshold(int graphIndex, int thresholdCount, ProfiledThreshold pThreshold, Vector<ProfiledGeneric> pGenerics)
-	{
-		// count and remove items below the threshold 
-		for (int i = pGenerics.size() - 1; i >= 0; i--) {
-			if (pGenerics.elementAt(i).getTotalSampleCount() < thresholdCount) {
-				pThreshold.addItem(graphIndex, pGenerics.elementAt(i), 0);
-				pGenerics.removeElementAt(i);
-			} else {
+	public void piEventReceived(PIEvent be) {
+		switch (be.getType()) {
+		// determine the threads that can be shown, and get rid of all
+		// drilldowns
+		case PIEvent.THRESHOLD_THREAD_CHANGED:
+			if (this.getGraphIndex() == PIPageEditor.THREADS_PAGE)
+				this.getThreadTable().action("changeThresholdThread"); //$NON-NLS-1$
+			switch (this.drawMode) {
+			case Defines.THREADS:
+			case Defines.THREADS_FUNCTIONS:
+			case Defines.THREADS_FUNCTIONS_BINARIES:
+			case Defines.THREADS_BINARIES:
+			case Defines.THREADS_BINARIES_FUNCTIONS:
+			case Defines.BINARIES_THREADS:
+			case Defines.BINARIES_THREADS_FUNCTIONS:
+			case Defines.BINARIES_FUNCTIONS_THREADS:
+			case Defines.FUNCTIONS_THREADS:
+			case Defines.FUNCTIONS_THREADS_BINARIES:
+			case Defines.FUNCTIONS_BINARIES_THREADS:
+				this.setGraphImageChanged(true);
+			default:
+				break;
+			}
+			break;
+		case PIEvent.THRESHOLD_BINARY_CHANGED:
+			if (this.getGraphIndex() == PIPageEditor.BINARIES_PAGE)
+				this.getBinaryTable().action("changeThresholdBinary"); //$NON-NLS-1$
+			switch (this.drawMode) {
+			case Defines.THREADS_FUNCTIONS_BINARIES:
+			case Defines.THREADS_BINARIES:
+			case Defines.THREADS_BINARIES_FUNCTIONS:
+			case Defines.BINARIES:
+			case Defines.BINARIES_THREADS:
+			case Defines.BINARIES_THREADS_FUNCTIONS:
+			case Defines.BINARIES_FUNCTIONS:
+			case Defines.BINARIES_FUNCTIONS_THREADS:
+			case Defines.FUNCTIONS_THREADS_BINARIES:
+			case Defines.FUNCTIONS_BINARIES:
+			case Defines.FUNCTIONS_BINARIES_THREADS:
+				this.setGraphImageChanged(true);
+			default:
+				break;
+			}
+			break;
+		case PIEvent.THRESHOLD_FUNCTION_CHANGED:
+			if (this.getGraphIndex() == PIPageEditor.FUNCTIONS_PAGE)
+				this.getFunctionTable().action("changeThresholdFunction"); //$NON-NLS-1$
+			switch (this.drawMode) {
+			case Defines.THREADS_FUNCTIONS:
+			case Defines.THREADS_FUNCTIONS_BINARIES:
+			case Defines.THREADS_BINARIES_FUNCTIONS:
+			case Defines.BINARIES_THREADS_FUNCTIONS:
+			case Defines.BINARIES_FUNCTIONS:
+			case Defines.BINARIES_FUNCTIONS_THREADS:
+			case Defines.FUNCTIONS:
+			case Defines.FUNCTIONS_THREADS:
+			case Defines.FUNCTIONS_THREADS_BINARIES:
+			case Defines.FUNCTIONS_BINARIES:
+			case Defines.FUNCTIONS_BINARIES_THREADS:
+				this.setGraphImageChanged(true);
+			default:
+				break;
+			}
+			break;
+		// when the selection area changes, change the percent loads
+		// and the sample counts in all tables of this GPP graph
+		case PIEvent.SELECTION_AREA_CHANGED:
+			// this is the first GPP graph to be told of the selection area
+			// change,
+			// so it gathers the overall trace information
+			double doubleStartTime = PIPageEditor.currentPageEditor()
+					.getStartTime();
+			double doubleEndTime = PIPageEditor.currentPageEditor()
+					.getEndTime();
+			GppTrace trace = (GppTrace) this.getTrace();
+			trace.setSelectedArea(doubleStartTime, doubleEndTime);
+
+			// take care of the threshold members
+			int sampleCount = 0;
+			int thresholdCount;
+
+			if (graphIndex == PIPageEditor.THREADS_PAGE) {
+				thresholdCount = (Integer) NpiInstanceRepository
+						.getInstance()
+						.getPersistState(uid,
+								"com.nokia.carbide.cpp.pi.address.thresholdCountThread"); //$NON-NLS-1$
+				if (thresholdCount > 0) {
+					for (int i = 0; i < profiledThreads.size(); i++)
+						if (profiledThreads.elementAt(i).getTotalSampleCount() < thresholdCount)
+							sampleCount += profiledThreads.elementAt(i)
+									.getSampleCount(graphIndex);
+					thresholdThread
+							.setSampleCount(this.graphIndex, sampleCount);
+				}
+			} else if (graphIndex == PIPageEditor.BINARIES_PAGE) {
+				thresholdCount = (Integer) NpiInstanceRepository
+						.getInstance()
+						.getPersistState(uid,
+								"com.nokia.carbide.cpp.pi.address.thresholdCountBinary"); //$NON-NLS-1$
+				if (thresholdCount > 0) {
+					for (int i = 0; i < profiledBinaries.size(); i++)
+						if (profiledBinaries.elementAt(i).getTotalSampleCount() < thresholdCount)
+							sampleCount += profiledBinaries.elementAt(i)
+									.getSampleCount(graphIndex);
+					thresholdBinary
+							.setSampleCount(this.graphIndex, sampleCount);
+				}
+			} else if (graphIndex == PIPageEditor.FUNCTIONS_PAGE) {
+				thresholdCount = (Integer) NpiInstanceRepository
+						.getInstance()
+						.getPersistState(uid,
+								"com.nokia.carbide.cpp.pi.address.thresholdCountFunction"); //$NON-NLS-1$
+				if (thresholdCount > 0) {
+					for (int i = 0; i < profiledFunctions.size(); i++)
+						if (profiledFunctions.elementAt(i)
+								.getTotalSampleCount() < thresholdCount)
+							sampleCount += profiledFunctions.elementAt(i)
+									.getSampleCount(graphIndex);
+					thresholdFunction.setSampleCount(this.graphIndex,
+							sampleCount);
+				}
+			}
+
+			double startTime = PIPageEditor.currentPageEditor().getStartTime();
+			double endTime = PIPageEditor.currentPageEditor().getEndTime();
+
+			// send this message to the other GPP graphs
+			PIEvent be2 = new PIEvent(be.getValueObject(),
+					PIEvent.SELECTION_AREA_CHANGED2);
+
+			// update the selection area shown
+			for (int i = 0; i < trace.getGraphCount(); i++) {
+				IGppTraceGraph graph = trace.getGppGraph(i, getUid());
+
+				if (graph != this) {
+					graph.piEventReceived(be2);
+					// once per graph, update the selection interval shown
+					graph.getCompositePanel().getVisualiser().updateStatusBarTimeInterval(startTime, endTime);
+				}
+
+				// change the graph's selected time interval
+				graph.setSelectionStart(startTime * 1000);
+				graph.setSelectionEnd(endTime * 1000);
+				graph.getCompositePanel().setSelectionFields(
+						(int) (startTime * 1000), (int) (endTime * 1000));
+			}
+
+			this.parentComponent.getSashForm().redraw();
+			be = be2;
+			// FALL THROUGH
+		case PIEvent.SELECTION_AREA_CHANGED2: {
+			// this code lets each graph's base thread/binary/function table
+			// update the other tables
+			switch (drawMode) {
+			case Defines.THREADS:
+			case Defines.THREADS_FUNCTIONS:
+			case Defines.THREADS_FUNCTIONS_BINARIES:
+			case Defines.THREADS_BINARIES:
+			case Defines.THREADS_BINARIES_FUNCTIONS: {
+				this.threadTable.piEventReceived(be);
+				break;
+			}
+			case Defines.BINARIES:
+			case Defines.BINARIES_THREADS:
+			case Defines.BINARIES_THREADS_FUNCTIONS:
+			case Defines.BINARIES_FUNCTIONS:
+			case Defines.BINARIES_FUNCTIONS_THREADS: {
+				this.binaryTable.piEventReceived(be);
+				break;
+			}
+			case Defines.FUNCTIONS:
+			case Defines.FUNCTIONS_THREADS:
+			case Defines.FUNCTIONS_THREADS_BINARIES:
+			case Defines.FUNCTIONS_BINARIES:
+			case Defines.FUNCTIONS_BINARIES_THREADS: {
+				this.functionTable.piEventReceived(be);
 				break;
 			}
+			}
+
+			this.vPanel.refreshCumulativeThreadTable();
+			this.setGraphImageChanged(true); // any selection change to drill
+			// down will change graph
+			this.repaint();
+			break;
+		}
+
+			// in the graph, show all values from the rightmost table
+		case PIEvent.SET_FILL_ALL_THREADS:
+			this.setGraphImageChanged(true); // any selection change to drill
+			// down will change graph
+			this.vPanel.piEventReceived(be);
+			break;
+
+		// in the graph, don't fill between the lines will the color of
+		// the line above
+		case PIEvent.SET_FILL_OFF:
+			this.setGraphImageChanged(true); // any selection change to drill
+			// down will change graph
+			this.vPanel.piEventReceived(be);
+			break;
+
+		// in the graph, show bars
+		case PIEvent.GPP_SET_BAR_GRAPH_ON:
+			this.vPanel.piEventReceived(be);
+			break;
+
+		// in the graph, show polylines
+		case PIEvent.GPP_SET_BAR_GRAPH_OFF:
+			this.vPanel.piEventReceived(be);
+			break;
+
+		// in the graph, show only the values from selected rows in the
+		// rightmost table
+		case PIEvent.SET_FILL_SELECTED_THREAD:
+			this.setGraphImageChanged(true); // any selection change to drill
+			// down will change graph
+			this.vPanel.piEventReceived(be);
+			break;
+
+		// Redraw the graph because the thread table's selected values have
+		// changed.
+		// The thread table is handled (setting of array of selected threads
+		// and table redraw) by the table selection listener or mouse listener.
+		case PIEvent.CHANGED_THREAD_TABLE:
+			switch (drawMode) {
+			case Defines.THREADS_BINARIES:
+			case Defines.THREADS_BINARIES_FUNCTIONS:
+			case Defines.THREADS_FUNCTIONS:
+			case Defines.THREADS_FUNCTIONS_BINARIES: {
+				this.threadTable.piEventReceived(be);
+				break;
+			}
+			case Defines.BINARIES_THREADS_FUNCTIONS: {
+				this.binaryTable.piEventReceived(be);
+				break;
+			}
+			case Defines.FUNCTIONS_THREADS_BINARIES: {
+				this.functionTable.piEventReceived(be);
+				break;
+			}
+			case Defines.THREADS:
+			case Defines.BINARIES:
+			case Defines.BINARIES_THREADS:
+			case Defines.BINARIES_FUNCTIONS:
+			case Defines.BINARIES_FUNCTIONS_THREADS:
+			case Defines.FUNCTIONS:
+			case Defines.FUNCTIONS_THREADS:
+			case Defines.FUNCTIONS_BINARIES:
+			case Defines.FUNCTIONS_BINARIES_THREADS:
+			default:
+				break;
+			}
+
+			this.vPanel.refreshCumulativeThreadTable();
+			this.repaint();
+			// if fill selected, the graph is drawn again
+			this.vPanel.piEventReceived(be);
+			break;
+
+		// Redraw the graph because the binary table's selected values have
+		// changed.
+		// The binary table is handled (setting of array of selected binaries
+		// and table redraw) by the table selection listener or mouse listener.
+		case PIEvent.CHANGED_BINARY_TABLE:
+			switch (drawMode) {
+			case Defines.BINARIES_THREADS:
+			case Defines.BINARIES_THREADS_FUNCTIONS:
+			case Defines.BINARIES_FUNCTIONS:
+			case Defines.BINARIES_FUNCTIONS_THREADS: {
+				this.binaryTable.piEventReceived(be);
+				break;
+			}
+			case Defines.THREADS_BINARIES_FUNCTIONS: {
+				this.threadTable.piEventReceived(be);
+				break;
+			}
+			case Defines.FUNCTIONS_BINARIES_THREADS: {
+				this.functionTable.piEventReceived(be);
+				break;
+			}
+			case Defines.THREADS:
+			case Defines.THREADS_BINARIES:
+			case Defines.THREADS_FUNCTIONS:
+			case Defines.THREADS_FUNCTIONS_BINARIES:
+			case Defines.BINARIES:
+			case Defines.FUNCTIONS:
+			case Defines.FUNCTIONS_THREADS:
+			case Defines.FUNCTIONS_THREADS_BINARIES:
+			case Defines.FUNCTIONS_BINARIES:
+			default:
+				break;
+			}
+
+			this.vPanel.refreshCumulativeThreadTable();
+			this.repaint();
+			// if fill selected, the graph is drawn again
+			this.vPanel.piEventReceived(be);
+			break;
+
+		// Redraw the graph because the function table's selected values have
+		// changed.
+		// The function table is handled (setting of array of selected functions
+		// and table redraw) by the table selection listener or mouse listener.
+		case PIEvent.CHANGED_FUNCTION_TABLE:
+			switch (drawMode) {
+			case Defines.FUNCTIONS_THREADS:
+			case Defines.FUNCTIONS_THREADS_BINARIES:
+			case Defines.FUNCTIONS_BINARIES:
+			case Defines.FUNCTIONS_BINARIES_THREADS: {
+				this.functionTable.piEventReceived(be);
+				break;
+			}
+			case Defines.THREADS_FUNCTIONS_BINARIES: {
+				this.threadTable.piEventReceived(be);
+				break;
+			}
+			case Defines.BINARIES_FUNCTIONS_THREADS: {
+				this.binaryTable.piEventReceived(be);
+				break;
+			}
+			case Defines.THREADS:
+			case Defines.THREADS_BINARIES:
+			case Defines.THREADS_BINARIES_FUNCTIONS:
+			case Defines.THREADS_FUNCTIONS:
+			case Defines.BINARIES:
+			case Defines.BINARIES_THREADS:
+			case Defines.BINARIES_THREADS_FUNCTIONS:
+			case Defines.BINARIES_FUNCTIONS:
+			case Defines.FUNCTIONS:
+			default:
+				break;
+			}
+
+			this.vPanel.refreshCumulativeThreadTable();
+			this.repaint();
+			this.vPanel.piEventReceived(be);
+			break;
+
+		case PIEvent.MOUSE_PRESSED:
+			switch (drawMode) {
+			case Defines.THREADS: {
+				break;
+			}
+			case Defines.BINARIES: {
+				break;
+			}
+			case Defines.FUNCTIONS: {
+				break;
+			}
+			default: {
+				break;
+			}
+			}
+			this.parentComponent.setActive(this);
+			break;
+
+		case PIEvent.SCALE_CHANGED:
+			this.setGraphImageChanged(true);
+			break;
+			
+		default:
+			break;
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
+	 */
+	public void actionPerformed(ActionEvent ae) {
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph#action(java
+	 * .lang.String)
+	 */
+	@Override
+	public void action(String actionString) {
+		System.out
+				.println(Messages.getString("GppTraceGraph.actionString") + actionString); //$NON-NLS-1$
+
+		if (actionString.equals("resetToCurrentMode")) //$NON-NLS-1$
+		{
+			if (drawMode == Defines.THREADS_FUNCTIONS)
+				this.setDrawMode(Defines.THREADS);
+			else if (drawMode == Defines.BINARIES_FUNCTIONS)
+				this.setDrawMode(Defines.BINARIES);
+			else
+				System.out
+						.println(Messages.getString("GppTraceGraph.drawMode") + drawMode); //should not print this ever  //$NON-NLS-1$
+		} else {
+			switch (drawMode) {
+			case Defines.THREADS:
+			case Defines.THREADS_FUNCTIONS:
+			case Defines.THREADS_FUNCTIONS_BINARIES:
+			case Defines.THREADS_BINARIES:
+			case Defines.THREADS_BINARIES_FUNCTIONS: {
+				this.threadTable.action(actionString);
+				break;
+			}
+			case Defines.BINARIES:
+			case Defines.BINARIES_THREADS:
+			case Defines.BINARIES_THREADS_FUNCTIONS:
+			case Defines.BINARIES_FUNCTIONS:
+			case Defines.BINARIES_FUNCTIONS_THREADS: {
+				this.binaryTable.action(actionString);
+				break;
+			}
+			case Defines.FUNCTIONS:
+			case Defines.FUNCTIONS_THREADS:
+			case Defines.FUNCTIONS_THREADS_BINARIES:
+			case Defines.FUNCTIONS_BINARIES:
+			case Defines.FUNCTIONS_BINARIES_THREADS: {
+				this.functionTable.action(actionString);
+				break;
+			}
+			}
 		}
 	}
 
-	public GppTrace getGppTrace() {
-		return (GppTrace)this.getTrace();
-	}
-
-	public int getGraphIndex()
-	{
-		return this.graphIndex;
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see java.awt.event.FocusListener#focusGained(java.awt.event.FocusEvent)
+	 */
+	public void focusGained(FocusEvent fe) {
 	}
 
-	public void piEventReceived(PIEvent be)
-	{
-		switch (be.getType())
-		{
-			// determine the threads that can be shown, and get rid of all drilldowns
-			case PIEvent.THRESHOLD_THREAD_CHANGED:
-				if (this.getGraphIndex() == PIPageEditor.THREADS_PAGE)
-					this.getThreadTable().action("changeThresholdThread"); //$NON-NLS-1$
-				switch (this.drawMode) {
-				case Defines.THREADS:
-				case Defines.THREADS_FUNCTIONS:
-				case Defines.THREADS_FUNCTIONS_BINARIES:
-				case Defines.THREADS_BINARIES:
-				case Defines.THREADS_BINARIES_FUNCTIONS:
-				case Defines.BINARIES_THREADS:
-				case Defines.BINARIES_THREADS_FUNCTIONS:
-				case Defines.BINARIES_FUNCTIONS_THREADS:
-				case Defines.FUNCTIONS_THREADS:
-				case Defines.FUNCTIONS_THREADS_BINARIES:
-				case Defines.FUNCTIONS_BINARIES_THREADS:
-					this.setGraphImageChanged(true);
-				default:
-					break;
-			}
-				break;
-			case PIEvent.THRESHOLD_BINARY_CHANGED:
-				if (this.getGraphIndex() == PIPageEditor.BINARIES_PAGE)
-					this.getBinaryTable().action("changeThresholdBinary"); //$NON-NLS-1$
-				switch (this.drawMode) {
-				case Defines.THREADS_FUNCTIONS_BINARIES:
-				case Defines.THREADS_BINARIES:
-				case Defines.THREADS_BINARIES_FUNCTIONS:
-				case Defines.BINARIES:
-				case Defines.BINARIES_THREADS:
-				case Defines.BINARIES_THREADS_FUNCTIONS:
-				case Defines.BINARIES_FUNCTIONS:
-				case Defines.BINARIES_FUNCTIONS_THREADS:
-				case Defines.FUNCTIONS_THREADS_BINARIES:
-				case Defines.FUNCTIONS_BINARIES:
-				case Defines.FUNCTIONS_BINARIES_THREADS:
-					this.setGraphImageChanged(true);
-				default:
-					break;
-			}
-				break;
-			case PIEvent.THRESHOLD_FUNCTION_CHANGED:
-				if (this.getGraphIndex() == PIPageEditor.FUNCTIONS_PAGE)
-					this.getFunctionTable().action("changeThresholdFunction"); //$NON-NLS-1$
-				switch (this.drawMode) {
-				case Defines.THREADS_FUNCTIONS:
-				case Defines.THREADS_FUNCTIONS_BINARIES:
-				case Defines.THREADS_BINARIES_FUNCTIONS:
-				case Defines.BINARIES_THREADS_FUNCTIONS:
-				case Defines.BINARIES_FUNCTIONS:
-				case Defines.BINARIES_FUNCTIONS_THREADS:
-				case Defines.FUNCTIONS:
-				case Defines.FUNCTIONS_THREADS:
-				case Defines.FUNCTIONS_THREADS_BINARIES:
-				case Defines.FUNCTIONS_BINARIES:
-				case Defines.FUNCTIONS_BINARIES_THREADS:
-					this.setGraphImageChanged(true);
-				default:
-					break;
-			}
-				break;
-			// when the selection area changes, change the percent loads
-			// and the sample counts in all tables of this GPP graph
-			case PIEvent.SELECTION_AREA_CHANGED:
-				// this is the first GPP graph to be told of the selection area change,
-				// so it gathers the overall trace information
-				GppTrace trace = (GppTrace)this.getTrace();
-				trace.setSelectedArea();
-				
-				// take care of the threshold members
-				int sampleCount = 0;
-				int thresholdCount;
-				
-				if (graphIndex == PIPageEditor.THREADS_PAGE) {
-					thresholdCount = (Integer)NpiInstanceRepository.getInstance().getPersistState(uid, "com.nokia.carbide.cpp.pi.address.thresholdCountThread"); //$NON-NLS-1$
-					if (thresholdCount > 0) {
-						for (int i = 0; i < profiledThreads.size(); i++)
-							if (profiledThreads.elementAt(i).getTotalSampleCount() < thresholdCount)
-								sampleCount += profiledThreads.elementAt(i).getSampleCount(graphIndex);
-						thresholdThread.setSampleCount(this.graphIndex, sampleCount);
-					}
-				} else if (graphIndex == PIPageEditor.BINARIES_PAGE) {
-					thresholdCount = (Integer)NpiInstanceRepository.getInstance().getPersistState(uid, "com.nokia.carbide.cpp.pi.address.thresholdCountBinary"); //$NON-NLS-1$
-					if (thresholdCount > 0) {
-						for (int i = 0; i < profiledBinaries.size(); i++)
-							if (profiledBinaries.elementAt(i).getTotalSampleCount() < thresholdCount)
-								sampleCount += profiledBinaries.elementAt(i).getSampleCount(graphIndex);
-						thresholdBinary.setSampleCount(this.graphIndex, sampleCount);
-					}
-				} else if (graphIndex == PIPageEditor.FUNCTIONS_PAGE) {
-					thresholdCount = (Integer)NpiInstanceRepository.getInstance().getPersistState(uid, "com.nokia.carbide.cpp.pi.address.thresholdCountFunction"); //$NON-NLS-1$
-					if (thresholdCount > 0) {
-						for (int i = 0; i < profiledFunctions.size(); i++)
-							if (profiledFunctions.elementAt(i).getTotalSampleCount() < thresholdCount)
-								sampleCount += profiledFunctions.elementAt(i).getSampleCount(graphIndex);
-						thresholdFunction.setSampleCount(this.graphIndex, sampleCount);
-					}
-				}
-
-				double startTime = PIPageEditor.currentPageEditor().getStartTime();
-				double endTime   = PIPageEditor.currentPageEditor().getEndTime();
-				
-				// send this message to the 2 other GPP graphs
-				PIEvent be2 = new PIEvent(be.getValueObject(),
-						PIEvent.SELECTION_AREA_CHANGED2);
-				
-				// update the selection area shown
-				for (int i = 0; i < 3; i++)
-				{
-					GppTraceGraph graph = trace.getGppGraph(i, getUid());
-
-					if (graph != this) {
-						graph.piEventReceived(be2);
-						// once per graph, update the selection interval shown
-						graph.getCompositePanel().getVisualiser().getTimeString().setText(ProfileVisualiser.getTimeInterval(startTime, endTime));
-					}
-					
-					// change the graph's selected time interval
-					graph.setSelectionStart((double) startTime * 1000);
-					graph.setSelectionEnd((double) endTime * 1000);
-					graph.parentComponent.setSelectionFields((int)(startTime * 1000), (int)(endTime * 1000));
-				}
-
-				this.parentComponent.getSashForm().redraw();
-				be = be2;
-				// FALL THROUGH
-			case PIEvent.SELECTION_AREA_CHANGED2:
-			{
-				// this code lets each graph's base thread/binary/function table update the other tables
-				switch (drawMode)
-				{
-					case Defines.THREADS:
-					case Defines.THREADS_FUNCTIONS:
-					case Defines.THREADS_FUNCTIONS_BINARIES:
-					case Defines.THREADS_BINARIES:
-					case Defines.THREADS_BINARIES_FUNCTIONS:
-				    {
-				        this.threadTable.piEventReceived(be);
-				        break;
-				    }
-					case Defines.BINARIES:
-					case Defines.BINARIES_THREADS:
-					case Defines.BINARIES_THREADS_FUNCTIONS:
-					case Defines.BINARIES_FUNCTIONS:
-					case Defines.BINARIES_FUNCTIONS_THREADS:
-					{
-				        this.binaryTable.piEventReceived(be);
-						break;
-					}
-					case Defines.FUNCTIONS:
-					case Defines.FUNCTIONS_THREADS:
-					case Defines.FUNCTIONS_THREADS_BINARIES:
-					case Defines.FUNCTIONS_BINARIES:
-					case Defines.FUNCTIONS_BINARIES_THREADS:
-					{
-				        this.functionTable.piEventReceived(be);
-						break;
-					}
-				}
-
-				this.vPanel.refreshCumulativeThreadTable();
-				this.setGraphImageChanged(true);	// any selection change to drill down will change graph
-				this.repaint();
-				break;
-			}
-			
-			// in the graph, show all values from the rightmost table
-			case PIEvent.SET_FILL_ALL_THREADS:
-				this.setGraphImageChanged(true);	// any selection change to drill down will change graph
-				this.vPanel.piEventReceived(be);
-				break;
-
-			// in the graph, don't fill between the lines will the color of
-			// the line above
-			case PIEvent.SET_FILL_OFF:
-				this.setGraphImageChanged(true);	// any selection change to drill down will change graph
-				this.vPanel.piEventReceived(be);
-				break;
-
-			// in the graph, show bars
-			case PIEvent.GPP_SET_BAR_GRAPH_ON:
-				this.vPanel.piEventReceived(be);
-				break;
-
-			// in the graph, show polylines 
-			case PIEvent.GPP_SET_BAR_GRAPH_OFF:
-				this.vPanel.piEventReceived(be);
-				break;
-
-			// in the graph, show only the values from selected rows in the
-			// rightmost table
-			case PIEvent.SET_FILL_SELECTED_THREAD:
-				this.setGraphImageChanged(true);	// any selection change to drill down will change graph
-				this.vPanel.piEventReceived(be);
-				break;
-
-			// Redraw the graph because the thread table's selected values have changed.
-			// The thread table is handled (setting of array of selected threads
-			// and table redraw) by the table selection listener or mouse listener.
-			case PIEvent.CHANGED_THREAD_TABLE:
-				switch (drawMode)
-				{
-					case Defines.THREADS_BINARIES:
-					case Defines.THREADS_BINARIES_FUNCTIONS:
-					case Defines.THREADS_FUNCTIONS:
-					case Defines.THREADS_FUNCTIONS_BINARIES:
-					{
-						this.threadTable.piEventReceived(be);
-						break;
-					}
-					case Defines.BINARIES_THREADS_FUNCTIONS:
-					{
-						this.binaryTable.piEventReceived(be);
-						break;
-					}
-					case Defines.FUNCTIONS_THREADS_BINARIES:
-					{
-						this.functionTable.piEventReceived(be);
-						break;
-					}
-					case Defines.THREADS:
-					case Defines.BINARIES:
-					case Defines.BINARIES_THREADS:
-					case Defines.BINARIES_FUNCTIONS:
-					case Defines.BINARIES_FUNCTIONS_THREADS:
-					case Defines.FUNCTIONS:
-					case Defines.FUNCTIONS_THREADS:
-					case Defines.FUNCTIONS_BINARIES:
-					case Defines.FUNCTIONS_BINARIES_THREADS:
-					default:
-						break;
-				}
-
-				this.vPanel.refreshCumulativeThreadTable();
-				this.repaint();
-			    //if fill selected, the graph is drawn again
-				this.vPanel.piEventReceived(be);
-				break;
-
-			// Redraw the graph because the binary table's selected values have changed.
-			// The binary table is handled (setting of array of selected binaries
-			// and table redraw) by the table selection listener or mouse listener.
-			case PIEvent.CHANGED_BINARY_TABLE:
-				switch(drawMode)
-				{
-					case Defines.BINARIES_THREADS:
-					case Defines.BINARIES_THREADS_FUNCTIONS:
-					case Defines.BINARIES_FUNCTIONS:
-					case Defines.BINARIES_FUNCTIONS_THREADS:
-					{
-						this.binaryTable.piEventReceived(be);
-						break;
-					}
-					case Defines.THREADS_BINARIES_FUNCTIONS:
-					{
-						this.threadTable.piEventReceived(be);
-						break;
-					}
-					case Defines.FUNCTIONS_BINARIES_THREADS:
-					{
-						this.functionTable.piEventReceived(be);
-						break;
-					}
-					case Defines.THREADS:
-					case Defines.THREADS_BINARIES:
-					case Defines.THREADS_FUNCTIONS:
-					case Defines.THREADS_FUNCTIONS_BINARIES:
-					case Defines.BINARIES:
-					case Defines.FUNCTIONS:
-					case Defines.FUNCTIONS_THREADS:
-					case Defines.FUNCTIONS_THREADS_BINARIES:
-					case Defines.FUNCTIONS_BINARIES:
-					default:
-						break;
-				}
-
-				this.vPanel.refreshCumulativeThreadTable();
-				this.repaint();
-			    //if fill selected, the graph is drawn again
-				this.vPanel.piEventReceived(be);
-				break;
-
-			// Redraw the graph because the function table's selected values have changed.
-			// The function table is handled (setting of array of selected functions
-			// and table redraw) by the table selection listener or mouse listener.
-			case PIEvent.CHANGED_FUNCTION_TABLE:
-				switch(drawMode)
-				{
-					case Defines.FUNCTIONS_THREADS:
-					case Defines.FUNCTIONS_THREADS_BINARIES:
-					case Defines.FUNCTIONS_BINARIES:
-					case Defines.FUNCTIONS_BINARIES_THREADS:
-					{
-						this.functionTable.piEventReceived(be);
-						break;
-					}
-					case Defines.THREADS_FUNCTIONS_BINARIES:
-					{
-						this.threadTable.piEventReceived(be);
-						break;
-					}
-					case Defines.BINARIES_FUNCTIONS_THREADS:
-					{
-						this.binaryTable.piEventReceived(be);
-						break;
-					}
-					case Defines.THREADS:
-					case Defines.THREADS_BINARIES:
-					case Defines.THREADS_BINARIES_FUNCTIONS:
-					case Defines.THREADS_FUNCTIONS:
-					case Defines.BINARIES:
-					case Defines.BINARIES_THREADS:
-					case Defines.BINARIES_THREADS_FUNCTIONS:
-					case Defines.BINARIES_FUNCTIONS:
-					case Defines.FUNCTIONS:
-					default:
-						break;
-				}
-
-				this.vPanel.refreshCumulativeThreadTable();
-				this.repaint();
-				this.vPanel.piEventReceived(be);
-				break;
-
-			case PIEvent.MOUSE_PRESSED:
-				switch (drawMode) {
-					case Defines.THREADS:
-					{
-						break;
-					}
-					case Defines.BINARIES:
-					{
-						break;
-					}
-					case Defines.FUNCTIONS:
-					{
-						break;
-					}
-					default:
-					{
-						break;
-					}
-				}
-			    this.parentComponent.setActive(this);
-				break;
-				
-			default:
-				break;
-		}
-	}
-	
-	public void actionPerformed(ActionEvent ae)
-	{
-	}
-	
-	public void action(String actionString)
-	{
-	    System.out.println(Messages.getString("GppTraceGraph.actionString")+actionString);  //$NON-NLS-1$
-	    
-	    if (actionString.equals("resetToCurrentMode")) //$NON-NLS-1$
-	    {
-	        if (drawMode == Defines.THREADS_FUNCTIONS)
-	            this.setDrawMode(Defines.THREADS);
-	        else if (drawMode == Defines.BINARIES_FUNCTIONS)
-	            this.setDrawMode(Defines.BINARIES);
-	        else
-	            System.out.println(Messages.getString("GppTraceGraph.drawMode") + drawMode); //should not print this ever  //$NON-NLS-1$
-	    }
-	    else
-	    {
-			switch (drawMode)
-			{
-				case Defines.THREADS:
-				case Defines.THREADS_FUNCTIONS:
-				case Defines.THREADS_FUNCTIONS_BINARIES:
-				case Defines.THREADS_BINARIES:
-				case Defines.THREADS_BINARIES_FUNCTIONS:
-			    {
-					this.threadTable.action(actionString);
-			        break;
-			    }
-				case Defines.BINARIES:
-				case Defines.BINARIES_THREADS:
-				case Defines.BINARIES_THREADS_FUNCTIONS:
-				case Defines.BINARIES_FUNCTIONS:
-				case Defines.BINARIES_FUNCTIONS_THREADS:
-				{
-					this.binaryTable.action(actionString);
-					break;
-				}
-				case Defines.FUNCTIONS:
-				case Defines.FUNCTIONS_THREADS:
-				case Defines.FUNCTIONS_THREADS_BINARIES:
-				case Defines.FUNCTIONS_BINARIES:
-				case Defines.FUNCTIONS_BINARIES_THREADS:
-				{
-					this.functionTable.action(actionString);
-					break;
-				}
-			}
-	    }
-	}
-	
-	public void focusGained(FocusEvent fe)
-	{
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see java.awt.event.FocusListener#focusLost(java.awt.event.FocusEvent)
+	 */
+	public void focusLost(FocusEvent fe) {
 	}
 
-	public void focusLost(FocusEvent fe)
-	{
-	}
-
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.draw2d.MouseMotionListener#mouseDragged(org.eclipse.draw2d
+	 * .MouseEvent)
+	 */
 	public void mouseDragged(MouseEvent me) {
 	}
 
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.draw2d.MouseMotionListener#mouseEntered(org.eclipse.draw2d
+	 * .MouseEvent)
+	 */
 	public void mouseEntered(MouseEvent me) {
 	}
 
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.draw2d.MouseMotionListener#mouseExited(org.eclipse.draw2d
+	 * .MouseEvent)
+	 */
 	public void mouseExited(MouseEvent me) {
 	}
 
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.draw2d.MouseMotionListener#mouseHover(org.eclipse.draw2d.
+	 * MouseEvent)
+	 */
 	public void mouseHover(MouseEvent me) {
 	}
 
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.draw2d.MouseListener#mousePressed(org.eclipse.draw2d.MouseEvent
+	 * )
+	 */
 	public void mousePressed(MouseEvent me) {
 	}
 
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.draw2d.MouseListener#mouseReleased(org.eclipse.draw2d.MouseEvent
+	 * )
+	 */
 	public void mouseReleased(MouseEvent me) {
 	}
 
-	public void mouseDoubleClicked(MouseEvent me)
-	{
-	    Object[] result = this.getProfiledGenericUnderMouse(me);
-		if ((result == null)) 
-		{
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.draw2d.MouseListener#mouseDoubleClicked(org.eclipse.draw2d
+	 * .MouseEvent)
+	 */
+	public void mouseDoubleClicked(MouseEvent me) {
+		Object[] result = this.getProfiledGenericUnderMouseImproved(me, false);
+		if ((result == null)) {
 			return;
 		}
-		
-		ProfiledGeneric pg = (ProfiledGeneric)result[0];
-		GenericTable gtu = null;
 
-		switch (drawMode)
-		{
-			case Defines.THREADS:
-			case Defines.BINARIES_THREADS:
-			case Defines.FUNCTIONS_THREADS:
-			case Defines.BINARIES_FUNCTIONS_THREADS:
-			case Defines.FUNCTIONS_BINARIES_THREADS:
-			{
-			    gtu = this.threadTable;
-			    break;
-			}
-			case Defines.BINARIES:
-			case Defines.THREADS_BINARIES:
-			case Defines.THREADS_FUNCTIONS_BINARIES:
-			case Defines.FUNCTIONS_BINARIES:
-			case Defines.FUNCTIONS_THREADS_BINARIES:
-			{
-			    gtu = this.binaryTable;
-				break;
-			}
-			case Defines.FUNCTIONS:
-			case Defines.THREADS_FUNCTIONS:
-			case Defines.BINARIES_FUNCTIONS:
-			case Defines.THREADS_BINARIES_FUNCTIONS:
-			case Defines.BINARIES_THREADS_FUNCTIONS:
-			{
-			    gtu = this.functionTable;
-			    break;
-			}
-			default:
-				break;
-		}
+		ProfiledGeneric pg = (ProfiledGeneric) result[0];
+		GenericTable gtu = getLegendTableForGraph();
 
-		if (pg != null)
-		{
+		if (pg != null) {
 			if (gtu.getIndex(pg) == null)
 				return;
 			int[] index = new int[1];
@@ -803,514 +919,640 @@
 		}
 	}
 
-	private Object[] getProfiledGenericUnderMouse(MouseEvent me)
-	{		
+	/**
+	 * For a stacked-area chart, this method retrieves the ProfiledGeneric
+	 * currently pointed to by the mouse. It also determines the percentage
+	 * activity load of this ProfiledGeneric in the current bucket. The load
+	 * will also be determined if no ProfiledGeneric is currently pointed to
+	 * (unresolved items).
+	 * 
+	 * 
+	 * @param me
+	 * @return Object[2] of which [0] is the ProfiledGeneric (may be null) and
+	 *         [1] is a String containing the load
+	 */
+	private Object[] getProfiledGenericUnderMouseImproved(MouseEvent me, boolean includeLoadString) {
 		Object[] result = new Object[2];
-		double x = me.x * this.getScale();
+
+		int adjustedX = me.x;
+		if (me.x >= (this.getSize().width)) {
+			adjustedX = this.getSize().width - 1;
+		}
+		double x = getTimeForXCoordinate(adjustedX, this.getScale());
+		if (x > PIPageEditor.currentPageEditor().getMaxEndTime() * 1000) {
+			return result;
+		}
+
 		double y = me.y;
-		
-		y = y * 100 / (this.getVisualSize().height - GppTraceGraph.xLegendHeight);
+
+		y = y * 100	/ (this.getVisualSize().height - GppTraceGraph.X_LEGEND_HEIGHT);
 		y = 100 - y;
-		if (y <= 0)
-			return null;
+		if (y <= 0){
+			return result;
+		}
+		
+		int samplingInterval = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState(
+				"com.nokia.carbide.cpp.pi.address.samplingInterval"); //$NON-NLS-1$
+		int granularityValue = ((GppTrace) (this.getTrace())).getGranularity();
+
+		int bucket = getBucketForTime(x);
+
+		//since the value is drawn at bucket mid-point, we need to work out whether
+		//x is to the left or right of the midpoint, in other words
+		//whether we need to take into account the gradient from the previous
+		//bucket or the next bucket
+		int offset = ((int)(x / samplingInterval)) % granularityValue; //offset into the bucket
+		int d = offset - (int)(granularityValue/2); //distance in samples off bucket mid-point, negative for left
+		double prt = Math.abs(d / (granularityValue * 1d)); //expressed as proportion
+		double saveLastPeak = 0f;
 		
-		// mouse event may return out of range X, that may 
-		// crash when we use it to index data array
-		x = x >= 0 ? x : 0;
+		for (ProfiledGeneric p : getSortedProfiledsForGraph()) {
+			if (!p.isEnabled(graphIndex)){
+				continue;
+			}
+			float[] cum = p.getCumulativeList(graphIndex);
+			float[] val = adapter.getActivityList(p);
+			if (cum == null || val == null || bucket >= cum.length){
+				return result;			
+			}
+
+			float lowCur = cum[bucket];
+			float topCur = cum[bucket] + val[bucket];
+
+			float lowNext = 0;
+			float topNext = 0;
+
+			double lowDiff = 0;
+			double topDiff = 0;
+
+			if (d < 0 && bucket > 0) {
+				// use gradient of previous bucket
+				lowNext = cum[bucket - 1];
+				topNext = cum[bucket - 1] + val[bucket - 1];
+
+			} else if (d > 0 && bucket < cum.length - 2) {
+				// use gradient of next bucket
+				lowNext = cum[bucket + 1];
+				topNext = cum[bucket + 1] + val[bucket + 1];
+
+			}
+			lowDiff = (lowNext - lowCur) * prt;
+			topDiff = (topNext - topCur) * prt;
+
+			// check whether y is in the profiled's value range
+			if (y >= lowCur + lowDiff && y < topCur + topDiff) {
+				result[0] = p;
+				if (includeLoadString){
+					//round to 2 dec places
+					result[1] = String.format("%.2f", (topCur + topDiff - lowCur - lowDiff));//$NON-NLS-1$
+				}
+				return result;
+			}
+			saveLastPeak = topCur + topDiff;
+		}
 		
-		if (x > PIPageEditor.currentPageEditor().getMaxEndTime() * 1000)
-			return null;
-
-		if (me.x >= (int)(this.getSize().width)) {
-			x = (this.getSize().width - 1) * this.getScale();
+		if (includeLoadString){
+			// within the area of not shown profiled items
+			result[0] = null;
+			result[1] = String.format("%.2f", (100 - saveLastPeak));//$NON-NLS-1$
 		}
 		
-		GppTrace gppTrace = (GppTrace) (this.getTrace());
+		return result;
+	}
+	
+	/**
+	 * Returns the bucket index for the given time
+	 * @param time
+	 * @return
+	 */
+	private int getBucketForTime(double time) {
+		return ((int) (time / ((GppTrace) (this.getTrace())).getBucketDuration()));
+	}
+
+	/**
+	 * @return the sorted collection of ProfiledGeneric appropriate for the
+	 *         current draw mode of the graph
+	 */
+	public Vector<ProfiledGeneric> getSortedProfiledsForGraph() {
+		switch (drawMode) {
+		case Defines.THREADS:
+		case Defines.BINARIES_THREADS:
+		case Defines.FUNCTIONS_THREADS:
+		case Defines.BINARIES_FUNCTIONS_THREADS:
+		case Defines.FUNCTIONS_BINARIES_THREADS: {
+			return sortedProfiledThreads ;
+		}
+		case Defines.BINARIES:
+		case Defines.THREADS_BINARIES:
+		case Defines.THREADS_FUNCTIONS_BINARIES:
+		case Defines.FUNCTIONS_BINARIES:
+		case Defines.FUNCTIONS_THREADS_BINARIES: {
+			return sortedProfiledBinaries;
+		}
+		case Defines.FUNCTIONS:
+		case Defines.THREADS_FUNCTIONS:
+		case Defines.BINARIES_FUNCTIONS:
+		case Defines.THREADS_BINARIES_FUNCTIONS:
+		case Defines.BINARIES_THREADS_FUNCTIONS: {
+			return sortedProfiledFunctions;
+		}
+		}
+		throw new IllegalArgumentException();
+		}
+
+	/**
+	 * @return the sorted collection of ProfiledGeneric appropriate for the
+	 *         current draw mode of the graph
+	 */
+	private GenericAddrTable getLegendTableForGraph() {
 
-		Enumeration<ProfiledGeneric> enumer = null;
-		switch (drawMode)
-		{
+		switch (drawMode) {
+		case Defines.THREADS:
+		case Defines.BINARIES_THREADS:
+		case Defines.FUNCTIONS_THREADS:
+		case Defines.BINARIES_FUNCTIONS_THREADS:
+		case Defines.FUNCTIONS_BINARIES_THREADS: {
+			return this.threadTable;
+		}
+		case Defines.BINARIES:
+		case Defines.THREADS_BINARIES:
+		case Defines.THREADS_FUNCTIONS_BINARIES:
+		case Defines.FUNCTIONS_BINARIES:
+		case Defines.FUNCTIONS_THREADS_BINARIES: {
+			return this.binaryTable;
+		}
+		case Defines.FUNCTIONS:
+		case Defines.THREADS_FUNCTIONS:
+		case Defines.BINARIES_FUNCTIONS:
+		case Defines.THREADS_BINARIES_FUNCTIONS:
+		case Defines.BINARIES_THREADS_FUNCTIONS: {
+			return this.functionTable;
+		}
+		}
+		throw new IllegalArgumentException();
+	}
+
+	/**
+	 * Converts the passed X-coordiate into a time value (in milliseconds) using
+	 * the scale provided. Makes sure the return value is non-negative.
+	 * 
+	 * @param x
+	 *            the x coordinate to use
+	 * @param scale
+	 *            the scale to use
+	 * @return time in milliseconds
+	 */
+	protected double getTimeForXCoordinate(int x, double scale) {
+		double time = x * scale;
+		// mouse event may return out of range X, that may
+		// crash when we use it to index data array
+		time = time >= 0 ? time : 0;
+		return time;
+
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.draw2d.MouseMotionListener#mouseMoved(org.eclipse.draw2d.
+	 * MouseEvent)
+	 */
+	public void mouseMoved(MouseEvent me) {
+		double x = getTimeForXCoordinate(me.x, this.getScale());
+		double y = me.y;
+
+		if (y >= this.getVisualSizeY() - GppTraceGraph.X_LEGEND_HEIGHT
+				|| x >= PIPageEditor.currentPageEditor().getMaxEndTime() * 1000) {
+			//don't set the tooltip to null here since it might affect other plugins, such as button plugin
+			return;
+		}
+
+		if (NpiInstanceRepository.getInstance() == null
+				|| NpiInstanceRepository
+						.getInstance()
+						.activeUidGetPersistState(
+								"com.nokia.carbide.cpp.pi.address.samplingInterval") == null) //$NON-NLS-1$)
+			return;
+
+		int samplingInterval = (Integer) NpiInstanceRepository.getInstance()
+				.activeUidGetPersistState(
+						"com.nokia.carbide.cpp.pi.address.samplingInterval"); //$NON-NLS-1$
+
+		if (this.barMode == GppTraceGraph.BAR_MODE_ON) {
+			GppSample samp = getSampleUnderMouse(me.x, this.getScale(),
+					samplingInterval);
+			if (samp == null) {
+				this.setToolTipText(null);
+				return;
+			}
+			switch (drawMode) {
 			case Defines.THREADS:
 			case Defines.BINARIES_THREADS:
 			case Defines.FUNCTIONS_THREADS:
 			case Defines.BINARIES_FUNCTIONS_THREADS:
-			case Defines.FUNCTIONS_BINARIES_THREADS:
-			{
-				enumer = gppTrace.getSortedThreadsElements();
-			    break;
+			case Defines.FUNCTIONS_BINARIES_THREADS: {
+				try {
+					this.setToolTipText(samp.sampleSynchTime + "ms @" + //$NON-NLS-1$
+							Long.toHexString(samp.programCounter) + " " + //$NON-NLS-1$
+							samp.thread.process.name + "::" + //$NON-NLS-1$
+							samp.thread.threadName + "_" + //$NON-NLS-1$
+							samp.thread.threadId);
+				} catch (NullPointerException e2) {
+					this
+							.setToolTipText(Messages
+									.getString("GppTraceGraph.cannotResolveThreadName")); //$NON-NLS-1$
+				}
+				break;
 			}
 			case Defines.BINARIES:
 			case Defines.THREADS_BINARIES:
 			case Defines.THREADS_FUNCTIONS_BINARIES:
 			case Defines.FUNCTIONS_BINARIES:
-			case Defines.FUNCTIONS_THREADS_BINARIES:
-			{
-				enumer = gppTrace.getSortedBinariesElements();
+			case Defines.FUNCTIONS_THREADS_BINARIES: {
+				try {
+					if (samp.getCurrentFunctionSym().getFunctionBinary().getBinaryName()
+							.endsWith(Messages
+									.getString("GppTraceGraph.NotFound"))) //$NON-NLS-1$
+						throw new NullPointerException();
+					this.setToolTipText(samp.sampleSynchTime + "ms @" + //$NON-NLS-1$
+							Long.toHexString(samp.programCounter) + " " + //$NON-NLS-1$
+							samp.getCurrentFunctionSym().getFunctionBinary().getBinaryName());
+				} catch (NullPointerException e) {
+					try {
+						this
+								.setToolTipText(samp.sampleSynchTime + "ms @" + //$NON-NLS-1$
+										Long.toHexString(samp.programCounter)
+										+ " " + //$NON-NLS-1$
+										samp.getCurrentFunctionItt().getFunctionBinary().getBinaryName());
+					} catch (NullPointerException e2) {
+						this
+								.setToolTipText(Messages
+										.getString("GppTraceGraph.cannotResolveBinaryName")); //$NON-NLS-1$
+					}
+				}
 				break;
 			}
 			case Defines.FUNCTIONS:
 			case Defines.THREADS_FUNCTIONS:
 			case Defines.BINARIES_FUNCTIONS:
 			case Defines.THREADS_BINARIES_FUNCTIONS:
-			case Defines.BINARIES_THREADS_FUNCTIONS:
-			{
-		        enumer = gppTrace.getSortedFunctionsElements();
-			    break;
+			case Defines.BINARIES_THREADS_FUNCTIONS: {
+				try {
+					if (samp.getCurrentFunctionSym().getFunctionBinary().getBinaryName()
+							.endsWith(Messages
+									.getString("GppTraceGraph.notFound"))) //$NON-NLS-1$
+						throw new NullPointerException();
+
+					this.setToolTipText(samp.sampleSynchTime + "ms @" + //$NON-NLS-1$
+							Long.toHexString(samp.programCounter) + " " + //$NON-NLS-1$
+							samp.getCurrentFunctionSym().getFunctionName());
+				} catch (NullPointerException e) {
+					try {
+						this.setToolTipText(samp.sampleSynchTime + "ms @" + //$NON-NLS-1$
+								Long.toHexString(samp.programCounter) + " " + //$NON-NLS-1$
+								samp.getCurrentFunctionItt().getFunctionName());
+					} catch (NullPointerException e2) {
+						this
+								.setToolTipText(Messages
+										.getString("GppTraceGraph.cannotResolveFunctionName")); //$NON-NLS-1$
+					}
+				}
+				break;
 			}
 			default:
-				break;
+				return;
+			}
+
+			return; // return for barMode == GppTraceGraph.BAR_MODE_ON
 		}
 
-		if (enumer == null)
-			return null;
-
-		Vector<ProfiledGeneric> activeThreads = new Vector<ProfiledGeneric>();
-		while(enumer.hasMoreElements())
-		{
-			ProfiledGeneric pg = (ProfiledGeneric)enumer.nextElement();
-			if (pg.isEnabled(this.graphIndex))		
-			{		
-				activeThreads.add(pg);
-			}
-		}
-		
-		int cumPrev = 0;
-		int cumNext = 0;
-		
-		int topPrev = 0;
-		int topNext = 0;
-
-		double cumDiff = 0;
-		double topDiff = 0;
-		
-		ProfiledGeneric currentProfiled = null;
-		
-		enumer = activeThreads.elements();
-		if (enumer.hasMoreElements())
-		    currentProfiled = enumer.nextElement();
-		
-		int samplingInterval = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.samplingInterval"); //$NON-NLS-1$
-		int granularityValue = gppTrace.samples.size() > GppTraceGraph.granularityValue ? GppTraceGraph.granularityValue : gppTrace.samples.size();  
-
-		while (true)
-		{
-			if (currentProfiled != null)
-			{
-				int[] cum = currentProfiled.getCumulativeList(graphIndex);
-				int[] val = currentProfiled.getActivityList();
-				if (cum == null || val == null)
-					return null;
-				
-				int current = ((int)(x / samplingInterval)) / granularityValue;
-				
-				if ((current >= cum.length) || (current + 1 >= cum.length)) 
-					return null;
-					
-				cumPrev = cum[current];	
-				cumNext = cum[current + 1];
-
-				topPrev = val[current];
-				topNext = val[current + 1];
+		// barMode == GppTraceGraph.BAR_MODE_OFF
 
-				cumDiff = (cumNext - cumPrev) * ((double)((x / samplingInterval) % granularityValue) / (granularityValue * 1d));
-				topDiff = (topNext - topPrev) * ((double)((x / samplingInterval) % granularityValue) / (granularityValue * 1d));
-			}
-			else
-			{
-				if (y >= cumPrev + topPrev + topDiff + cumDiff) 
-				{
-				    currentProfiled = null;
-					break;
-				}
-				else
-				{
-					break;
-				}
-			}
-			
-			if (y >= cumPrev + cumDiff && y < cumPrev + topPrev + topDiff + cumDiff ) 
-			{
-				break;
-			}
-			else
-			{
-				if (enumer.hasMoreElements())
-				{
-				    currentProfiled = (ProfiledGeneric)enumer.nextElement();
-				}
-				else
-				{
-				    currentProfiled = null;
-				}
-			}
-		}
-		
-		if (currentProfiled != null)
-		{
-			String loadString = "" + (topPrev + topDiff); //$NON-NLS-1$
-			int index = loadString.indexOf('.');
-			
-			if (index > 0 && ((index + 2) < loadString.length()))
-				loadString = loadString.substring(0, index + 2); 
-			
-			result[0] = currentProfiled;
-			result[1] = loadString;				
-		}
-		else
-		{
-			String totalString = "" + (100 - (cumPrev + topPrev + topDiff + cumDiff)); //$NON-NLS-1$
-			int index = totalString.indexOf('.');
-			
-			if (index > 0 && ((index + 2) < totalString.length()))
-				totalString = totalString.substring(0, index + 2);
-
-			result[0] = null;
-			result[1] = totalString;
-		}
-		return result;
-	}
-
-	public void mouseMoved(MouseEvent me)
-	{
-		double x = me.x * this.getScale();
-		double y = me.y;
-		
-		// mouse event may return out of range X, that may 
-		// crash when we use it to index data array
-		x = x >= 0 ? x : 0;
-		
-		if (   y >= this.getVisualSizeY() - GppTraceGraph.xLegendHeight
-			|| x >= PIPageEditor.currentPageEditor().getMaxEndTime() * 1000)
-		{
+		Object[] result = this.getProfiledGenericUnderMouseImproved(me, true);
+		if (result == null || (result[0] == null && result[1] == null)) {
 			this.setToolTipText(null);
 			return;
 		}
 
-		if (   NpiInstanceRepository.getInstance() == null
-			|| NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.samplingInterval") == null) //$NON-NLS-1$)
-			return;
-		
-		int samplingInterval = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.samplingInterval"); //$NON-NLS-1$
-
-		if (this.barMode == GppTraceGraph.BAR_MODE_ON) {
-			GppSample samp = (GppSample)((GenericSampledTrace)this.getTrace()).getSample(((int)(x + .0005))/samplingInterval);
-			switch (drawMode)
-			{
-				case Defines.THREADS:
-				case Defines.BINARIES_THREADS:
-				case Defines.FUNCTIONS_THREADS:
-				case Defines.BINARIES_FUNCTIONS_THREADS:
-				case Defines.FUNCTIONS_BINARIES_THREADS:
-				{
-					try {
-						this.setToolTipText(samp.sampleSynchTime+"ms @"+  //$NON-NLS-1$
-											Long.toHexString(samp.programCounter)+" "+  //$NON-NLS-1$
-											samp.thread.process.name+"::"+  //$NON-NLS-1$
-											samp.thread.threadName+"_"+  //$NON-NLS-1$
-											samp.thread.threadId);}
-					catch (NullPointerException e2)
-					{
-						this.setToolTipText(Messages.getString("GppTraceGraph.cannotResolveThreadName"));  //$NON-NLS-1$
-					}
-					break;
-				}
-				case Defines.BINARIES:
-				case Defines.THREADS_BINARIES:
-				case Defines.THREADS_FUNCTIONS_BINARIES:
-				case Defines.FUNCTIONS_BINARIES:
-				case Defines.FUNCTIONS_THREADS_BINARIES:
-				{
-					try {
-						if (samp.currentFunctionSym.functionBinary.binaryName.endsWith(Messages.getString("GppTraceGraph.NotFound")))  //$NON-NLS-1$
-							throw new NullPointerException();
-						this.setToolTipText(samp.sampleSynchTime+"ms @"+  //$NON-NLS-1$
-											Long.toHexString(samp.programCounter)+" "+  //$NON-NLS-1$
-											samp.currentFunctionSym.functionBinary.binaryName);
-					} catch (NullPointerException e)
-					{
-						try {
-							this.setToolTipText(samp.sampleSynchTime+"ms @"+  //$NON-NLS-1$
-												Long.toHexString(samp.programCounter)+" "+  //$NON-NLS-1$
-												samp.currentFunctionItt.functionBinary.binaryName);}
-						catch (NullPointerException e2)
-						{
-							this.setToolTipText(Messages.getString("GppTraceGraph.cannotResolveBinaryName"));  //$NON-NLS-1$
-						}
-					}
-					break;
-				}
-				case Defines.FUNCTIONS:
-				case Defines.THREADS_FUNCTIONS:
-				case Defines.BINARIES_FUNCTIONS:
-				case Defines.THREADS_BINARIES_FUNCTIONS:
-				case Defines.BINARIES_THREADS_FUNCTIONS:
-				{
-					try {
-						if (samp.currentFunctionSym.functionBinary.binaryName.endsWith(Messages.getString("GppTraceGraph.notFound")))  //$NON-NLS-1$
-							throw new NullPointerException();
-						
-						this.setToolTipText(samp.sampleSynchTime+"ms @"+  //$NON-NLS-1$
-											Long.toHexString(samp.programCounter)+" "+  //$NON-NLS-1$
-											samp.currentFunctionSym.functionName);}
-					catch (NullPointerException e)
-					{
-						try{this.setToolTipText(samp.sampleSynchTime+"ms @"+  //$NON-NLS-1$
-												Long.toHexString(samp.programCounter)+" "+  //$NON-NLS-1$
-												samp.currentFunctionItt.functionName);}
-						catch (NullPointerException e2)
-						{
-							this.setToolTipText(Messages.getString("GppTraceGraph.cannotResolveFunctionName"));  //$NON-NLS-1$
-						}
-					}
-					break;
-				}
-				default:
-					return;
-			}
-
-			return;  // return for barMode == GppTraceGraph.BAR_MODE_ON
+		if (me.x >= (this.getSize().width)) {
+			x = (this.getSize().width - 1) * this.getScale();
 		}
 
-		// barMode == GppTraceGraph.BAR_MODE_OFF
+		ProfiledGeneric pg = (ProfiledGeneric) result[0];
 
-    	Object[] result = this.getProfiledGenericUnderMouse(me);
-		if (result == null)
-		{
-			this.setToolTipText(null);
-			return;
-		}
-		
-		if (me.x >= (int)(this.getSize().width)) {
-			x = (this.getSize().width - 1) * this.getScale();
-		}
-		
-		ProfiledGeneric pg = null;
-		switch (drawMode)
-		{
+		String string = (String) result[1];
+		if (pg == null) {
+			switch (drawMode) {
 			case Defines.THREADS:
 			case Defines.BINARIES_THREADS:
 			case Defines.FUNCTIONS_THREADS:
 			case Defines.BINARIES_FUNCTIONS_THREADS:
-			case Defines.FUNCTIONS_BINARIES_THREADS:
-			{
-			    pg = (ProfiledThread)result[0];
-			    break;
+			case Defines.FUNCTIONS_BINARIES_THREADS: {
+				this
+						.setToolTipText(string
+								+ "% " + Messages.getString("GppTraceGraph.unknownOrExcludedThreads")); //$NON-NLS-1$ //$NON-NLS-2$
+				break;
 			}
 			case Defines.BINARIES:
 			case Defines.THREADS_BINARIES:
 			case Defines.THREADS_FUNCTIONS_BINARIES:
 			case Defines.FUNCTIONS_BINARIES:
-			case Defines.FUNCTIONS_THREADS_BINARIES:
-			{
-			    pg = (ProfiledBinary)result[0];
+			case Defines.FUNCTIONS_THREADS_BINARIES: {
+				this
+						.setToolTipText(string
+								+ "% " + Messages.getString("GppTraceGraph.unknownOrExcludedBinaries")); //$NON-NLS-1$ //$NON-NLS-2$
 				break;
 			}
 			case Defines.FUNCTIONS:
 			case Defines.THREADS_FUNCTIONS:
 			case Defines.BINARIES_FUNCTIONS:
 			case Defines.THREADS_BINARIES_FUNCTIONS:
-			case Defines.BINARIES_THREADS_FUNCTIONS:
-			{
-			    pg = (ProfiledFunction)result[0];
-			    break;
+			case Defines.BINARIES_THREADS_FUNCTIONS: {
+				this
+						.setToolTipText(string
+								+ "% " + Messages.getString("GppTraceGraph.unknownOrExcludedFunctions")); //$NON-NLS-1$ //$NON-NLS-2$
+				break;
 			}
 			default:
 				break;
+			}
+		} else {
+			this.setToolTipText(string + "% " + pg.getNameString()); //$NON-NLS-1$
+		}
+	}
+
+	/**
+	 * Returns the closest matching sample with the given x-coordinate. May
+	 * return null if there isn't a matching sample in the immediate vicinity of
+	 * x. This method is typically used in bar mode.
+	 * 
+	 * @param xPoint
+	 * @param scale
+	 * @param samplingInterval
+	 * @return
+	 */
+	protected GppSample getSampleUnderMouse(int xPoint, double scale,
+			int samplingInterval) {
+		GppTrace trace = (GppTrace)this.getTrace();
+		GppSample match = null;
+		double x = xPoint * scale;
+		x = x >= 0 ? x : 0;
+		double xStart = (xPoint -5 ) * scale;
+		double xEnd = (xPoint +5) * scale;
+		
+		int start =  ((int)(xStart + .0005) * trace.getCPUCount())/samplingInterval;
+		if (start < 0){
+			start = 0;
+		} else if (start >= trace.getSampleAmount()){
+			start = trace.getSampleAmount()-1;
 		}
 
-		String string = (String)result[1];
-		if (pg == null)
-		{
-			switch (drawMode)
-			{
-				case Defines.THREADS:
-				case Defines.BINARIES_THREADS:
-				case Defines.FUNCTIONS_THREADS:
-				case Defines.BINARIES_FUNCTIONS_THREADS:
-				case Defines.FUNCTIONS_BINARIES_THREADS:
-				{
-				    this.setToolTipText(string + "% " + Messages.getString("GppTraceGraph.unknownOrExcludedThreads"));  //$NON-NLS-1$ //$NON-NLS-2$
-				    break;
-				}
-				case Defines.BINARIES:
-				case Defines.THREADS_BINARIES:
-				case Defines.THREADS_FUNCTIONS_BINARIES:
-				case Defines.FUNCTIONS_BINARIES:
-				case Defines.FUNCTIONS_THREADS_BINARIES:
-				{
-				    this.setToolTipText(string + "% " + Messages.getString("GppTraceGraph.unknownOrExcludedBinaries"));  //$NON-NLS-1$ //$NON-NLS-2$
-					break;
-				}
-				case Defines.FUNCTIONS:
-				case Defines.THREADS_FUNCTIONS:
-				case Defines.BINARIES_FUNCTIONS:
-				case Defines.THREADS_BINARIES_FUNCTIONS:
-				case Defines.BINARIES_THREADS_FUNCTIONS:
-				{
-				    this.setToolTipText(string + "% " + Messages.getString("GppTraceGraph.unknownOrExcludedFunctions"));  //$NON-NLS-1$ //$NON-NLS-2$
-				    break;
-				}
-				default:
-					break;
+		int end =  ((int)(xEnd + .0005) * trace.getCPUCount())/samplingInterval;
+		if (end >= trace.getSampleAmount()){
+			end = trace.getSampleAmount()-1;
+		}
+
+		//loop through samples with the correct CPU id in close vicinity, and find the closest one to the given x-coordinate 
+		for (int i = start; i <= end; i++) {
+			GppSample tmp = trace.getSortedGppSamples()[i];
+			if (doCheckSampleMatch(tmp) && (match == null || Math.abs(tmp.sampleSynchTime - x) < Math.abs(match.sampleSynchTime - x)) && isSampleEnabled(tmp)){
+				match = tmp;
 			}
 		}
-		else
-		{
-			this.setToolTipText(string + "% " + pg.getNameString());  //$NON-NLS-1$
-		}
+		
+		return match;
 	}
 	
-	public GenericTable getTableUtils()
-	{
-		switch (drawMode)
-		{
-			case Defines.THREADS:
-			case Defines.BINARIES_THREADS:
-			case Defines.FUNCTIONS_THREADS:
-			case Defines.BINARIES_FUNCTIONS_THREADS:
-			case Defines.FUNCTIONS_BINARIES_THREADS:
-			{
-			    return this.threadTable;
-			}
-			case Defines.BINARIES:
-			case Defines.THREADS_BINARIES:
-			case Defines.THREADS_FUNCTIONS_BINARIES:
-			case Defines.FUNCTIONS_BINARIES:
-			case Defines.FUNCTIONS_THREADS_BINARIES:
-			{
-			    return this.binaryTable;
-			}
-			case Defines.FUNCTIONS:
-			case Defines.THREADS_FUNCTIONS:
-			case Defines.BINARIES_FUNCTIONS:
-			case Defines.THREADS_BINARIES_FUNCTIONS:
-			case Defines.BINARIES_THREADS_FUNCTIONS:
-			{
-			    return this.functionTable;
-			}
-			default:
-				break;
+	/**
+	 * According to current graph index and drawing mode, check whether this 
+	 * sample is enabled  
+	 * @param sample the sample to use
+	 * @return true, if enabled, false if disabled or cannot be determined
+	 */
+	private boolean isSampleEnabled(GppSample sample) {
+		
+		switch (drawMode) {
+		case Defines.THREADS:
+			return isSampleEnabled(sample, true, false, false);			
+		case Defines.BINARIES:
+			return isSampleEnabled(sample, false, true, false);			
+		case Defines.FUNCTIONS:
+			return isSampleEnabled(sample, false, false, true);			
+		case Defines.BINARIES_THREADS:
+		case Defines.THREADS_BINARIES:
+			return isSampleEnabled(sample, true, true, false);			
+		case Defines.FUNCTIONS_THREADS:
+		case Defines.THREADS_FUNCTIONS:
+			return isSampleEnabled(sample, true, false, true);			
+		case Defines.FUNCTIONS_BINARIES:
+		case Defines.BINARIES_FUNCTIONS:
+			return isSampleEnabled(sample, false, true, true);	
+		case Defines.BINARIES_FUNCTIONS_THREADS:
+		case Defines.FUNCTIONS_BINARIES_THREADS: 
+		case Defines.THREADS_FUNCTIONS_BINARIES:
+		case Defines.FUNCTIONS_THREADS_BINARIES: 
+		case Defines.THREADS_BINARIES_FUNCTIONS:
+		case Defines.BINARIES_THREADS_FUNCTIONS: 
+			return isSampleEnabled(sample, true, true, true);	
+		}
+		throw new IllegalArgumentException();
+	}
+
+	/**
+	 * Check whether a combination of thread / function / binary for this sample
+	 * is enabled in the current graph. 
+	 * @param sample
+	 * @param checkThreads
+	 * @param checkBinaries
+	 * @param checkFunctions
+	 * @return
+	 */
+	private boolean isSampleEnabled(GppSample sample, boolean checkThreads, boolean checkBinaries,
+			boolean checkFunctions) {
+		
+		boolean ret = true;
+		GppTrace trace = (GppTrace) this.getTrace();
+		
+		if (checkThreads){
+			ret &= trace.getIndexedThreads().get(sample.threadIndex).isEnabled(graphIndex);
+		}
+		if (checkBinaries){
+			ret &= trace.getIndexedBinaries().get(sample.binaryIndex).isEnabled(graphIndex);			
+		}
+		if (checkFunctions){
+			ret &= trace.getIndexedFunctions().get(sample.functionIndex).isEnabled(graphIndex);			
+		}
+		return ret;
+	}
+
+	/**
+	 * Check the sample fulfils conditions for getSampleUnderMouse()
+	 * @return true if it fulfils matching conditions, false otherwise
+	 */
+	protected boolean doCheckSampleMatch(GppSample sample){
+		return true;
+	}
+
+	public GenericTable getTableUtils() {
+		switch (drawMode) {
+		case Defines.THREADS:
+		case Defines.BINARIES_THREADS:
+		case Defines.FUNCTIONS_THREADS:
+		case Defines.BINARIES_FUNCTIONS_THREADS:
+		case Defines.FUNCTIONS_BINARIES_THREADS: {
+			return this.threadTable;
+		}
+		case Defines.BINARIES:
+		case Defines.THREADS_BINARIES:
+		case Defines.THREADS_FUNCTIONS_BINARIES:
+		case Defines.FUNCTIONS_BINARIES:
+		case Defines.FUNCTIONS_THREADS_BINARIES: {
+			return this.binaryTable;
+		}
+		case Defines.FUNCTIONS:
+		case Defines.THREADS_FUNCTIONS:
+		case Defines.BINARIES_FUNCTIONS:
+		case Defines.THREADS_BINARIES_FUNCTIONS:
+		case Defines.BINARIES_THREADS_FUNCTIONS: {
+			return this.functionTable;
+		}
+		default:
+			break;
 		}
 
-		System.out.println(Messages.getString("GppTraceGraph.debugDrawMode") + drawMode);  //$NON-NLS-1$
-	    return null;
+		System.out
+				.println(Messages.getString("GppTraceGraph.debugDrawMode") + drawMode); //$NON-NLS-1$
+		return null;
 	}
-	
-	public GppVisualiserPanel getVisualiserPanel()
-	{
+
+	public GppVisualiserPanel getVisualiserPanel() {
 		return this.vPanel;
 	}
-	
-	public AddrThreadTable  getThreadTable() {
+
+	public AddrThreadTable getThreadTable() {
 		return this.threadTable;
 	}
-	
+
 	public AddrBinaryTable getBinaryTable() {
 		return this.binaryTable;
 	}
-	
+
 	public AddrFunctionTable getFunctionTable() {
 		return this.functionTable;
 	}
 
-	public void setThreadTableViewer(CheckboxTableViewer tableViewer) {
-		this.threadTable.setTableViewer(tableViewer);
-	}
-	
-	public void setBinaryTableViewer(CheckboxTableViewer tableViewer) {
-		this.binaryTable.setTableViewer(tableViewer);;
-	}
-	
-	public void setFunctionTableViewer(CheckboxTableViewer tableViewer) {
-		this.functionTable.setTableViewer(tableViewer);
-	}
-
-	public void paint(Panel panel, Graphics graphics)
-	{
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph#paint(org.
+	 * eclipse.draw2d.Panel, org.eclipse.draw2d.Graphics)
+	 */
+	@Override
+	public void paint(Panel panel, Graphics graphics) {
 		this.setSize(panel.getClientArea().width, panel.getClientArea().height);
 		this.vPanel.paintComponent(panel, graphics);
 	}
 
-	public void paintLeftLegend(FigureCanvas figureCanvas, GC gc)
-	{
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph#paintLeftLegend
+	 * (org.eclipse.draw2d.FigureCanvas, org.eclipse.swt.graphics.GC)
+	 */
+	@Override
+	public void paintLeftLegend(FigureCanvas figureCanvas, GC gc) {
 		GC localGC = gc;
-		
+
 		if (gc == null)
 			gc = new GC(PIPageEditor.currentPageEditor().getSite().getShell());
 
-		Rectangle rect = ((GraphComposite) figureCanvas.getParent()).figureCanvas.getClientArea();
-		
+		Rectangle rect = ((GraphComposite) figureCanvas.getParent()).figureCanvas
+				.getClientArea();
+
 		int visY = rect.height;
-		
-		float visYfloat = visY - GppTraceGraph.xLegendHeight;
-		
+
+		float visYfloat = visY - GppTraceGraph.X_LEGEND_HEIGHT;
+
 		if (visYfloat < 0f)
 			visYfloat = 0f;
-		
+
 		gc.setForeground(ColorPalette.getColor(new RGB(100, 100, 100)));
 		gc.setBackground(ColorPalette.getColor(new RGB(255, 255, 255)));
-		
+
 		// write each next number if there is space
 		// float values will be slightly smaller than the actual result
 		// and they will be incremented by one, since rounding to int
 		// discards the remaining decimals
 		int percent = 100;
-		int previousBottom = 0;		// bottom of the previous legend drawn
-		for (float y = 0f; percent >= 0; y += visYfloat * 10000f / 100001f, percent -= 10)
-		{
+		int previousBottom = 0; // bottom of the previous legend drawn
+		for (float y = 0f; percent >= 0; y += visYfloat * 10000f / 100001f, percent -= 10) {
 			String legend = "" + percent + "%"; //$NON-NLS-1$ //$NON-NLS-2$
 			Point extent = gc.stringExtent(legend);
-			
-			gc.drawLine(GenericTraceGraph.yLegendWidth - 3, (int)y + 1, GenericTraceGraph.yLegendWidth, (int)y + 1);
+
+			gc.drawLine(IGenericTraceGraph.Y_LEGEND_WIDTH - 3, (int) y + 1,
+					IGenericTraceGraph.Y_LEGEND_WIDTH, (int) y + 1);
 
-			if ((int)y >= previousBottom)
-			{
-				gc.drawString(legend, GenericTraceGraph.yLegendWidth - extent.x - 4, (int)y);
-				previousBottom = (int)y + extent.y;
+			if ((int) y >= previousBottom) {
+				gc.drawString(legend, IGenericTraceGraph.Y_LEGEND_WIDTH
+						- extent.x - 4, (int) y);
+				previousBottom = (int) y + extent.y;
 			}
 		}
-		
+
 		if (localGC == null) {
 			gc.dispose();
 			figureCanvas.redraw();
 		}
 	}
-	
-	public void repaint()
-	{
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph#repaint()
+	 */
+	@Override
+	public void repaint() {
 		this.parentComponent.repaintComponent();
 	}
-	
-	public void drawBarsGpp(Vector<ProfiledGeneric> profiledGenerics, Graphics graphics, Object[] selection)
-	{
-		if (   this.updateCumulativeThreadTableIsNeeded
-			|| this.barGraphData == null)
-		{
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.pi.address.IGppTraceGraph#drawBarsGpp(java.util
+	 * .Vector, org.eclipse.draw2d.Graphics, java.lang.Object[])
+	 */
+	public void drawBarsGpp(Vector<ProfiledGeneric> profiledGenerics,
+			Graphics graphics, Object[] selection) {
+		if (this.updateCumulativeThreadTableIsNeeded
+				|| this.barGraphData == null) {
 			this.updateBarGraphData(profiledGenerics);
 		}
-		
+
 		this.updateIfNeeded(profiledGenerics);
-		
+
 		Enumeration<BarGraphData> barEnum = this.barGraphData.elements();
 
 		int drawX = -1;
 		int lastDrawX = -10;
 		double scale = this.getScale();
 		int y = this.getVisualSizeY() - 51;
-		org.eclipse.draw2d.geometry.Rectangle visibleArea = this.getVisibleArea(graphics);
+		org.eclipse.draw2d.geometry.Rectangle visibleArea = this
+				.getVisibleArea(graphics);
 
-		while(barEnum.hasMoreElements())
-		{
+		while (barEnum.hasMoreElements()) {
 			BarGraphData bgd = barEnum.nextElement();
-			drawX = (int)(((double)bgd.x) / scale);
-			
-			if (   drawX >= visibleArea.x
-				&& drawX < visibleArea.x + visibleArea.width )
-			{
+			drawX = (int) ((bgd.x) / scale);
+
+			if (drawX >= visibleArea.x
+					&& drawX < visibleArea.x + visibleArea.width) {
 				if (debug)
-					System.out.println(Messages.getString("GppTraceGraph.draw") + drawX + " " + scale + " " + bgd.x);    //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-				if (drawX != lastDrawX)
-				{
+					System.out
+							.println(Messages.getString("GppTraceGraph.draw") + drawX + " " + scale + " " + bgd.x); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+				if (drawX != lastDrawX) {
 					graphics.setForegroundColor(bgd.color);
 					graphics.drawLine(drawX, 0, drawX, y);
 					lastDrawX = drawX;
@@ -1319,985 +1561,577 @@
 		}
 	}
 
-	public void updateBarGraphData(Vector profiledGenerics)
-	{
+	/**
+	 * Updates this.barGraphData.
+	 * 
+	 * @param profiledGenerics
+	 *            Vector of either sortedThreads / sortedBinaries /
+	 *            sortedFunctions
+	 */
+	private void updateBarGraphData(Vector<ProfiledGeneric> profiledGenerics) {
 		if (this.barGraphData == null)
 			this.barGraphData = new Vector<BarGraphData>();
 		this.barGraphData.clear();
 
 		int x = 0;
-		
+
 		// find the first enabled profiled generic
 		int firstEnabled;
 		for (firstEnabled = 0; firstEnabled < profiledGenerics.size(); firstEnabled++)
-			if (((ProfiledGeneric)profiledGenerics.get(firstEnabled)).isEnabled(this.graphIndex))
+			if (((ProfiledGeneric) profiledGenerics.get(firstEnabled))
+					.isEnabled(this.graphIndex))
 				break;
-		
+
 		// return if there are no enabled profiled generics
 		if (firstEnabled == profiledGenerics.size())
 			return;
-		
-		int samplingInterval = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.samplingInterval"); //$NON-NLS-1$
-		Enumeration samples = ((GenericSampledTrace)this.getTrace()).getSamples();
-		while (samples.hasMoreElements())
-		{
-			GppSample gs = (GppSample)samples.nextElement();
-			
-			// for each of the tens of thousands of samples, loop through each of the
-			// perhaps thousands of functions, hundreds of binaries, or tens of threads
-			for (int i = firstEnabled; i < profiledGenerics.size(); i++)
-			{
+
+		int samplingInterval = (Integer) NpiInstanceRepository.getInstance()
+				.activeUidGetPersistState(
+						"com.nokia.carbide.cpp.pi.address.samplingInterval"); //$NON-NLS-1$
+		for (GppSample gs : ((GppTrace) this
+				.getTrace()).getSortedGppSamples()) {
+			if (!sampleInChart(gs)) {
+				continue;
+			}
+
+			// for each of the tens of thousands of samples, loop through each
+			// of the
+			// perhaps thousands of functions, hundreds of binaries, or tens of
+			// threads
+			// CH: the following is inefficient and needs refactoring (GppTrace
+			// has a Vector<ProfiledThread> profiledThreads etc. which are
+			// already sorted by index)
+			for (int i = firstEnabled; i < profiledGenerics.size(); i++) {
 				// find the next enabled profiled generic, if any
-				while (   (i < profiledGenerics.size()
-					   && !((ProfiledGeneric)profiledGenerics.get(i)).isEnabled(this.graphIndex)))
+				while ((i < profiledGenerics.size() && !((ProfiledGeneric) profiledGenerics
+						.get(i)).isEnabled(this.graphIndex)))
 					i++;
 				if (i >= profiledGenerics.size())
 					break;
 
-				ProfiledGeneric pg = (ProfiledGeneric)profiledGenerics.get(i);
+				ProfiledGeneric pg = (ProfiledGeneric) profiledGenerics.get(i);
 
-				if (   ((pg instanceof ProfiledThread)   && (pg.getIndex() == gs.threadIndex))
-				    || ((pg instanceof ProfiledBinary)   && (pg.getIndex() == gs.binaryIndex))
-				    || ((pg instanceof ProfiledFunction) && (pg.getIndex() == gs.functionIndex))) {
+				if (((pg instanceof ProfiledThread) && (pg.getIndex() == gs.threadIndex))
+						|| ((pg instanceof ProfiledBinary) && (pg.getIndex() == gs.binaryIndex))
+						|| ((pg instanceof ProfiledFunction) && (pg.getIndex() == gs.functionIndex))) {
 					BarGraphData bgd = new BarGraphData();
 					bgd.color = pg.getColor();
-					bgd.x = x;
+					//bgd.x = x;
+					bgd.x = (int)gs.sampleSynchTime;
 					this.barGraphData.add(bgd);
 					break;
 				}
 			}
 			x += samplingInterval;
+			
 		}
-	}	
+
+	}
+
+	/**
+	 * Returns true if this sample is applicable to this chart. This method is
+	 * intended to be overridden, for example for SMP charts where samples
+	 * belong to the chart with the matching CPU number.
+	 * 
+	 * @param gs
+	 *            the sample to check
+	 * @return true, if sample belongs to chart, false otherwise
+	 */
+	protected boolean sampleInChart(GppSample gs) {
+		return true;
+	}
 
-	public void refreshDataFromTrace()
-	{
-		refreshDataFromTrace((GppTrace)this.getTrace());
+	// /*
+	// * Because a table to the left of a function table has changed, update
+	// * the function table.
+	// * If there is no table to the right of this one, redraw the graph based
+	// * on the changed data.
+	// */
+	// public void refreshProfiledThreadData(int drawMode)
+	// {
+	// // Must have a table to its left
+	// if ( (drawMode != Defines.BINARIES_THREADS)
+	// && (drawMode != Defines.BINARIES_THREADS_FUNCTIONS)
+	// && (drawMode != Defines.BINARIES_FUNCTIONS_THREADS)
+	// && (drawMode != Defines.FUNCTIONS_THREADS)
+	// && (drawMode != Defines.FUNCTIONS_THREADS_BINARIES)
+	// && (drawMode != Defines.FUNCTIONS_BINARIES_THREADS)
+	// )
+	// {
+	//	        System.out.println(Messages.getString("GppTraceGraph.wrongDrawMode"));  //$NON-NLS-1$
+	// return;
+	// }
+	//
+	// // boolean to use inside loops (should trust a compiler to optimize this
+	// out of the loop...)
+	// boolean basedOnBinaries = (drawMode == Defines.BINARIES_THREADS)
+	// || (drawMode == Defines.BINARIES_THREADS_FUNCTIONS)
+	// || (drawMode == Defines.FUNCTIONS_BINARIES_THREADS);
+	//
+	// Hashtable<String,ProfiledThread> profiledThreads = new
+	// Hashtable<String,ProfiledThread>();
+	//		
+	// GenericSampledTrace trace = (GenericSampledTrace)this.getTrace();
+	// int granularityValue = trace.samples.size() >
+	// GppTraceGraph.GRANULARITY_VALUE ? GppTraceGraph.GRANULARITY_VALUE :
+	// trace.samples.size();
+	//		
+	// String[] selectedItems;
+	// int[] selectedFunctionHashCodes = null;
+	// int[] selectedBinaryHashCodes = null;
+	// int count = 0;
+	// int timeStamp = 0;
+	// int stepValue = granularityValue;
+	//		int samplingInterval = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.samplingInterval"); //$NON-NLS-1$
+	// boolean exit = false;
+	//		
+	// Hashtable<ProfiledThread,Integer> percentages = new
+	// Hashtable<ProfiledThread,Integer>();
+	// PIVisualSharedData shared = this.getSharedDataInstance();
+	//		
+	// if (basedOnBinaries)
+	// {
+	// selectedItems = shared.GPP_SelectedBinaryNames;
+	// if (selectedItems == null)
+	// {
+	// selectedItems = new String[0];
+	// }
+	// int[] tmpHashCodes = new int[selectedItems.length];
+	// for (int i = 0; i < selectedItems.length; i++)
+	// {
+	// String tmp = selectedItems[i];
+	// tmpHashCodes[i] = tmp.hashCode();
+	// }
+	// selectedBinaryHashCodes = tmpHashCodes;
+	// }
+	// else
+	// {
+	// selectedItems = shared.GPP_SelectedFunctionNames;
+	// if (selectedItems == null)
+	// {
+	// selectedItems = new String[0];
+	// }
+	// int[] tmpHashCodes = new int[selectedItems.length];
+	// for (int i = 0; i < selectedItems.length; i++)
+	// {
+	// String tmp = selectedItems[i];
+	// tmpHashCodes[i] = tmp.hashCode();
+	// }
+	// selectedFunctionHashCodes = tmpHashCodes;
+	// }
+	//		
+	// for (Enumeration enumer = trace.getSamples(); !exit;)
+	// {
+	// exit = !enumer.hasMoreElements();
+	// if (exit)
+	// {
+	// // for the final samples, modify the step value
+	// // so that they will also be included
+	// // now there are no new samples, so proceed directly to
+	// // adding the final values to the percent list
+	// stepValue = count;
+	// }
+	// else
+	// {
+	// count++;
+	// int compareValue = 0;
+	// boolean match = false;
+	// GppSample sample = (GppSample)enumer.nextElement();
+	// if (basedOnBinaries)
+	// {
+	// compareValue = GppTraceGraphUtil.getBinaryName(sample).hashCode();
+	// for (int i = 0; i < selectedBinaryHashCodes.length; i++)
+	// {
+	// if (compareValue == selectedBinaryHashCodes[i])
+	// {
+	// match = true;
+	// break;
+	// }
+	// }
+	// }
+	// else
+	// {
+	// compareValue = GppTraceGraphUtil.getFunctionName(sample).hashCode();
+	// for (int i = 0; i < selectedFunctionHashCodes.length; i++)
+	// {
+	// if (compareValue == selectedFunctionHashCodes[i])
+	// {
+	// match = true;
+	// break;
+	// }
+	// }
+	// }
+	//			    
+	// if (match)
+	// {
+	// ProfiledThread pt = null;
+	// String name = sample.thread.threadName;
+	// if (profiledThreads.containsKey(name))
+	// {
+	// pt = profiledThreads.get(name);
+	// }
+	//				
+	// if (pt == null)
+	// {
+	// pt = new ProfiledThread();
+	//					
+	// pt.setNameString(name);
+	// pt.setColor(((GppTrace)this.getTrace()).getThreadColorPalette().getColor(name));
+	// pt.setThreadId(sample.thread.threadId.intValue());
+	//						
+	// pt.setActivityMarkCount((trace.samples.size() + granularityValue) /
+	// granularityValue + 1);
+	// for (int i = 0; i < timeStamp + stepValue * samplingInterval; i +=
+	// stepValue * samplingInterval)
+	// {
+	// pt.zeroActivityMarkValues(i);
+	// }
+	// pt.setEnabled(this.graphIndex, true);
+	// profiledThreads.put(name, pt);
+	// }
+	//	
+	// if (percentages.containsKey(pt))
+	// {
+	// Integer value = percentages.get(pt);
+	// value = Integer.valueOf(value.intValue()+1);
+	// percentages.remove(pt);
+	// percentages.put(pt,value);
+	// }
+	// else
+	// {
+	// percentages.put(pt,Integer.valueOf(1));
+	// }
+	// }
+	// }
+	//
+	// if (stepValue != 0 && count == stepValue)
+	// {
+	// Vector<ProfiledGeneric> v = new
+	// Vector<ProfiledGeneric>(profiledThreads.values());
+	// Enumeration<ProfiledGeneric> pfEnum = v.elements();
+	// while (pfEnum.hasMoreElements())
+	// {
+	// ProfiledThread updatePt = (ProfiledThread)pfEnum.nextElement();
+	// if (percentages.containsKey(updatePt))
+	// {
+	// int samples = ((percentages.get(updatePt))).intValue();
+	// int finalPerc = (samples * 100) / stepValue;
+	// updatePt.addActivityMarkValues(timeStamp + stepValue * samplingInterval,
+	// finalPerc, samples);
+	// }
+	// else
+	// {
+	// updatePt.zeroActivityMarkValues(timeStamp + stepValue *
+	// samplingInterval);
+	// }
+	// }
+	//				
+	// percentages.clear();
+	// count = 0;
+	// timeStamp += stepValue * samplingInterval;
+	// }
+	// }
+	//
+	// this.threadTable.getTable().deselectAll();
+	// this.threadTable.updateProfiledAndItemData(true);
+	// this.threadTable.getTable().redraw();
+	//
+	// // if this is not the last table, set the selected names to set up
+	// // the next table
+	// if ( (drawMode == Defines.BINARIES_THREADS_FUNCTIONS)
+	// || (drawMode == Defines.FUNCTIONS_THREADS_BINARIES))
+	// {
+	// this.threadTable.setSelectedNames();
+	// }
+	// else
+	// {
+	// // This may not be needed needed
+	// shared.GPP_SelectedThreadNames = new String[0];
+	// }
+	// }
+	//
+	// /*
+	// * Because a table to the left of a binary table has changed, update
+	// * the binary table.
+	// * If there is no table to the right of this one, redraw the graph based
+	// * on the changed data.
+	// */
+	// public void refreshProfiledBinaryData(int drawMode)
+	// {
+	// // Must have a table to its left
+	// if ( (drawMode != Defines.THREADS_BINARIES)
+	// && (drawMode != Defines.THREADS_BINARIES_FUNCTIONS)
+	// && (drawMode != Defines.THREADS_FUNCTIONS_BINARIES)
+	// && (drawMode != Defines.FUNCTIONS_BINARIES)
+	// && (drawMode != Defines.FUNCTIONS_BINARIES_THREADS)
+	// && (drawMode != Defines.FUNCTIONS_THREADS_BINARIES)
+	// )
+	// {
+	//	        System.out.println(Messages.getString("GppTraceGraph.wrongDrawMode"));  //$NON-NLS-1$
+	// return;
+	// }
+	//
+	// // boolean to use inside loops (never trust a compiler...)
+	// boolean basedOnThreads = (drawMode == Defines.THREADS_BINARIES)
+	// || (drawMode == Defines.THREADS_BINARIES_FUNCTIONS)
+	// || (drawMode == Defines.FUNCTIONS_THREADS_BINARIES);
+	//
+	// Hashtable<String,ProfiledBinary> profiledBinaries = new
+	// Hashtable<String,ProfiledBinary>();
+	//		
+	// GenericSampledTrace trace = (GenericSampledTrace)this.getTrace();
+	// int granularityValue = trace.samples.size() >
+	// GppTraceGraph.GRANULARITY_VALUE ? GppTraceGraph.GRANULARITY_VALUE :
+	// trace.samples.size();
+	//
+	// String[] selectedItems;
+	// int[] selectedThreadIds = null;
+	// int[] selectedFunctionHashCodes = null;
+	// int count = 0;
+	// int timeStamp = 0;
+	// int stepValue = granularityValue;
+	//		int samplingInterval = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.samplingInterval"); //$NON-NLS-1$
+	// boolean exit = false;
+	//		
+	// Hashtable<ProfiledBinary,Integer> percentages = new
+	// Hashtable<ProfiledBinary,Integer>();
+	// PIVisualSharedData shared = this.getSharedDataInstance();
+	//		
+	// if (basedOnThreads)
+	// {
+	// selectedItems = shared.GPP_SelectedThreadNames;
+	// if (selectedItems == null)
+	// {
+	// selectedItems = new String[0];
+	// }
+	// int[] tmpThreadIds = new int[selectedItems.length];
+	// for (int i = 0; i < selectedItems.length; i++)
+	// {
+	// String tmp = selectedItems[i].substring(selectedItems[i].lastIndexOf('_')
+	// + 1,
+	// selectedItems[i].length());
+	// tmpThreadIds[i] = Integer.parseInt(tmp);
+	// }
+	// selectedThreadIds = tmpThreadIds;
+	// }
+	// else
+	// {
+	// selectedItems = shared.GPP_SelectedFunctionNames;
+	// if (selectedItems == null)
+	// {
+	// selectedItems = new String[0];
+	// }
+	// int[] tmpHashCodes = new int[selectedItems.length];
+	// for (int i = 0; i < selectedItems.length; i++)
+	// {
+	// String tmp = selectedItems[i];
+	// tmpHashCodes[i] = tmp.hashCode();
+	// }
+	// selectedFunctionHashCodes = tmpHashCodes;
+	// }
+	//		
+	// for (Enumeration enumer = trace.getSamples(); !exit;)
+	// {
+	// exit = !enumer.hasMoreElements();
+	// if (exit)
+	// {
+	// // for the final samples, modify the step value
+	// // so that they will also be included
+	// // now there are no new samples, so proceed directly to
+	// // adding the final values to the percent list
+	// stepValue = count;
+	// }
+	// else
+	// {
+	// count++;
+	// int compareValue = 0;
+	// boolean match = false;
+	// GppSample sample = (GppSample)enumer.nextElement();
+	// if (basedOnThreads)
+	// {
+	// compareValue = sample.thread.threadId.intValue();
+	// for (int i = 0; i < selectedThreadIds.length; i++)
+	// {
+	// if (compareValue == selectedThreadIds[i])
+	// {
+	// match = true;
+	// break;
+	// }
+	// }
+	// }
+	// else
+	// {
+	// compareValue = GppTraceGraphUtil.getFunctionName(sample).hashCode();
+	// for (int i = 0; i < selectedFunctionHashCodes.length; i++)
+	// {
+	// if (compareValue == selectedFunctionHashCodes[i])
+	// {
+	// match = true;
+	// break;
+	// }
+	// }
+	// }
+	//			    
+	// if (match)
+	// {
+	// ProfiledBinary pb = null;
+	// String name = GppTraceGraphUtil.getFunctionName(sample);
+	// if (profiledBinaries.containsKey(name))
+	// {
+	// pb = profiledBinaries.get(name);
+	// }
+	//				
+	// if (pb == null)
+	// {
+	// pb = new ProfiledBinary();
+	//						
+	// pb.setNameString(name);
+	// pb.setColor(((GppTrace)this.getTrace()).getBinaryColorPalette().getColor(name));
+	//						
+	// pb.setActivityMarkCount((trace.samples.size() + granularityValue) /
+	// granularityValue + 1);
+	// for (int i = 0; i < timeStamp + stepValue * samplingInterval; i +=
+	// stepValue * samplingInterval)
+	// {
+	// pb.zeroActivityMarkValues(i);
+	// }
+	// profiledBinaries.put(name, pb);
+	// }
+	//	
+	// if (percentages.containsKey(pb))
+	// {
+	// Integer value = percentages.get(pb);
+	// value = Integer.valueOf(value.intValue()+1);
+	// percentages.remove(pb);
+	// percentages.put(pb,value);
+	// }
+	// else
+	// {
+	// percentages.put(pb,Integer.valueOf(1));
+	// }
+	// }
+	// }
+	//
+	// if (stepValue != 0 && count == stepValue)
+	// {
+	// Vector<ProfiledGeneric> v = new
+	// Vector<ProfiledGeneric>(profiledBinaries.values());
+	// Enumeration<ProfiledGeneric> pfEnum = v.elements();
+	// while (pfEnum.hasMoreElements())
+	// {
+	// ProfiledFunction updatePf = (ProfiledFunction)pfEnum.nextElement();
+	// if (percentages.containsKey(updatePf))
+	// {
+	// int samples = ((percentages.get(updatePf))).intValue();
+	// int finalPerc = (samples * 100) / stepValue;
+	// updatePf.addActivityMarkValues(timeStamp + stepValue * samplingInterval,
+	// finalPerc, samples);
+	// }
+	// else
+	// {
+	// updatePf.zeroActivityMarkValues(timeStamp + stepValue *
+	// samplingInterval);
+	// }
+	// }
+	//				
+	// percentages.clear();
+	// count = 0;
+	// timeStamp += stepValue * samplingInterval;
+	// }
+	// }
+	//
+	// this.binaryTable.getTable().deselectAll();
+	// this.binaryTable.updateProfiledAndItemData(true);
+	// this.binaryTable.getTable().redraw();
+	//
+	// // if this is not the last table, set the selected names to set up
+	// // the next table
+	// if ( (drawMode == Defines.THREADS_BINARIES_FUNCTIONS)
+	// || (drawMode == Defines.FUNCTIONS_BINARIES_THREADS))
+	// {
+	// this.binaryTable.setSelectedNames();
+	// }
+	// else
+	// {
+	// // This may not be needed
+	// shared.GPP_SelectedBinaryNames = new String[0];
+	// }
+	// }
 
-	    if (this.vPanel != null)
-		{
-			this.vPanel.refreshCumulativeThreadTable();
+	// public void updateGraph()
+	// {
+	// if (drawMode == Defines.BINARIES)
+	// {
+	// vPanel.refreshCumulativeThreadTable();
+	// }
+	// else if (drawMode == Defines.THREADS)
+	// {
+	// vPanel.refreshCumulativeThreadTable();
+	// }
+	//
+	// this.repaint();
+	// }
+
+	public void updateThreadTablePriorities(
+			Hashtable<Integer, String> priorities) {
+		this.threadTable.addPriorityColumn(priorities);
+	}
+
+	public int getDrawMode() {
+		return drawMode;
+	}
+
+	public void setDrawMode(int drawMode) {
+		if ((drawMode == Defines.THREADS)
+				|| (drawMode == Defines.THREADS_FUNCTIONS)
+				|| (drawMode == Defines.THREADS_FUNCTIONS_BINARIES)
+				|| (drawMode == Defines.THREADS_BINARIES)
+				|| (drawMode == Defines.THREADS_BINARIES_FUNCTIONS)
+				|| (drawMode == Defines.BINARIES)
+				|| (drawMode == Defines.BINARIES_THREADS)
+				|| (drawMode == Defines.BINARIES_THREADS_FUNCTIONS)
+				|| (drawMode == Defines.BINARIES_FUNCTIONS)
+				|| (drawMode == Defines.BINARIES_FUNCTIONS_THREADS)
+				|| (drawMode == Defines.FUNCTIONS)
+				|| (drawMode == Defines.FUNCTIONS_THREADS)
+				|| (drawMode == Defines.FUNCTIONS_THREADS_BINARIES)
+				|| (drawMode == Defines.FUNCTIONS_BINARIES)
+				|| (drawMode == Defines.FUNCTIONS_BINARIES_THREADS)) {
+			if (this.drawMode != drawMode) {
+				this.setGraphImageChanged(true);
+				this.drawMode = drawMode;
+				refreshMode();
+				if (this.graphChangeListener != null){
+					graphChangeListener.onTitleChange(getTitle());
+				}
+			}
+		} else {
+			throw new IllegalArgumentException(Messages
+					.getString("GppTraceGraph.unknownDrawMode")); //$NON-NLS-1$
 		}
 	}
 
-	public static void refreshDataFromTrace(GppTrace gppTrace)
-	{
-		Enumeration enumer = gppTrace.getSamples();
-		
-		int granularityValue = gppTrace.samples.size() > GppTraceGraph.granularityValue ? GppTraceGraph.granularityValue : gppTrace.samples.size();  
-
-		Hashtable<String,ProfiledGeneric> profiledThreads   = new Hashtable<String,ProfiledGeneric>();
-		Hashtable<String,ProfiledGeneric> profiledBinaries  = new Hashtable<String,ProfiledGeneric>();
-		Hashtable<String,ProfiledGeneric> profiledFunctions = new Hashtable<String,ProfiledGeneric>();
-		
-		Hashtable<ProfiledGeneric,Integer> threadPercentages   = new Hashtable<ProfiledGeneric,Integer>();
-		Hashtable<ProfiledGeneric,Integer> binaryPercentages   = new Hashtable<ProfiledGeneric,Integer>();
-		Hashtable<ProfiledGeneric,Integer> functionPercentages = new Hashtable<ProfiledGeneric,Integer>();
-		
-		int threadCount = 0;
-		int binaryCount = 0;
-		int functionCount = 0;
-		int count = 0;
-		int timeStamp = 0;
-		int stepValue = granularityValue;
-		char threadSymbol = 'A';
-		int samplingInterval = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.samplingInterval"); //$NON-NLS-1$
-
-		Vector<ProfiledGeneric> sortedProfiledThreads   = gppTrace.getSortedThreads();
-		Vector<ProfiledGeneric> sortedProfiledBinaries  = gppTrace.getSortedBinaries();
-		Vector<ProfiledGeneric> sortedProfiledFunctions = gppTrace.getSortedFunctions();
-
-		Vector<ProfiledGeneric> unsortedProfiledThreads   = gppTrace.getIndexedThreads();
-		Vector<ProfiledGeneric> unsortedProfiledBinaries  = gppTrace.getIndexedBinaries();
-		Vector<ProfiledGeneric> unsortedProfiledFunctions = gppTrace.getIndexedFunctions();
-		
-		// reset these list so we can call refreshDataFromTrace mulitple times (e.g. import) while keeping size consistent
-		sortedProfiledThreads.clear();
-		sortedProfiledBinaries.clear();
-		sortedProfiledFunctions.clear();
-
-		unsortedProfiledThreads.clear();
-		unsortedProfiledBinaries.clear();
-		unsortedProfiledFunctions.clear();
-
-		boolean exit = false;
-		while (exit == false)
-		{
-			exit = !enumer.hasMoreElements();
-			if (exit == true) 
-			{
-				// for the final samples, modify the step value
-				// so that they will also be included
-				// now there are no new samples, so proceed directly to
-				// adding the final values to the percent list
-				stepValue = count;
-			}
-			else
-			{
-				count++;
-				
-				// there is at least one new sample in the enumeration, so resolve it 
-				GppSample sample = (GppSample)enumer.nextElement();
-				String threadName   = sample.thread.process.name + "::" + sample.thread.threadName + "_" + sample.thread.threadId;   //$NON-NLS-1$ //$NON-NLS-2$
-				String binaryName   = getBinaryName(sample);
-				String functionName = getFunctionName(sample);
-
-				ProfiledThread   pThread = null;
-				ProfiledBinary   pBinary = null;
-				ProfiledFunction pFunction = null;
-				
-				// handle new thread names
-				if (profiledThreads.containsKey(threadName))
-				{
-					pThread = (ProfiledThread)profiledThreads.get(threadName);
-					if (pThread.getThreadId() != sample.thread.threadId.intValue())
-					{
-						// this was not the same thread, even though the
-						// name was the same
-						pThread = null;
-					}
-				}
-			
-				if (pThread == null)
-				{
-					pThread = new ProfiledThread();
-					
-					pThread.setIndex(threadCount++);
-					pThread.setNameValues(threadSymbol++, threadName);
-					pThread.setColor(gppTrace.getThreadColorPalette().getColor(threadName));
-					
-					pThread.setThreadId(sample.thread.threadId.intValue());
-					
-					pThread.setActivityMarkCount((gppTrace.samples.size() + granularityValue) / granularityValue + 1);
-					for (int i = 0; i < timeStamp + stepValue * samplingInterval; i += stepValue * samplingInterval)
-					{
-						pThread.zeroActivityMarkValues(i);
-					}
-					profiledThreads.put(threadName, pThread);
-					sortedProfiledThreads.add((ProfiledGeneric)pThread);			
-					unsortedProfiledThreads.add((ProfiledGeneric)pThread);			
-				}
-				
-				pThread.incTotalSampleCount();
-				sample.threadIndex = pThread.getIndex();
-
-				if (threadPercentages.containsKey(pThread))
-				{
-					Integer value = (Integer)threadPercentages.get(pThread);
-					value = new Integer(value.intValue()+1);
-					threadPercentages.remove(pThread);
-					threadPercentages.put(pThread, value);
-				}
-				else
-				{
-					threadPercentages.put(pThread, new Integer(1));
-				}
-				
-				// handle new binary names
-				if (profiledBinaries.containsKey(binaryName))
-				{
-					pBinary = (ProfiledBinary)profiledBinaries.get(binaryName);
-				}
-			
-				if (pBinary == null)
-				{
-					pBinary = new ProfiledBinary();
-
-					pBinary.setIndex(binaryCount++);
-					pBinary.setNameString(binaryName);
-					pBinary.setColor(gppTrace.getBinaryColorPalette().getColor(binaryName));
-					
-					pBinary.setActivityMarkCount((gppTrace.samples.size() + granularityValue) / granularityValue + 1);
-					for (int i = 0; i < timeStamp + stepValue * samplingInterval; i += stepValue * samplingInterval)
-					{
-						pBinary.zeroActivityMarkValues(i);
-					}
-					profiledBinaries.put(binaryName,pBinary);
-					sortedProfiledBinaries.add((ProfiledGeneric)pBinary);			
-					unsortedProfiledBinaries.add((ProfiledGeneric)pBinary);			
-				}
-				
-				pBinary.incTotalSampleCount();
-				sample.binaryIndex = pBinary.getIndex();
-
-				if (binaryPercentages.containsKey(pBinary))
-				{
-					Integer value = (Integer)binaryPercentages.get(pBinary);
-					value = new Integer(value.intValue()+1);
-					binaryPercentages.remove(pBinary);
-					binaryPercentages.put(pBinary,value);
-				}
-				else
-				{
-					binaryPercentages.put(pBinary, new Integer(1));
-				}														
-				
-				// handle new function names
-				if (profiledFunctions.containsKey(functionName))
-				{
-					pFunction = (ProfiledFunction)profiledFunctions.get(functionName);
-				}
-			
-				if (pFunction == null)
-				{
-					pFunction = new ProfiledFunction();
-
-					pFunction.setIndex(functionCount++);
-					pFunction.setNameString(functionName);
-					pFunction.setFunctionAddress(getFunctionAddress(sample));
-					pFunction.setFunctionBinaryName(binaryName);
-					pFunction.setColor(gppTrace.getFunctionColorPalette().getColor(functionName));
-					
-					pFunction.setActivityMarkCount((gppTrace.samples.size() + granularityValue) / granularityValue + 1);
-					for (int i = 0; i < timeStamp + stepValue * samplingInterval; i += stepValue * samplingInterval)
-					{
-						pFunction.zeroActivityMarkValues(i);
-					}
-					profiledFunctions.put(functionName,pFunction);
-					sortedProfiledFunctions.add((ProfiledGeneric)pFunction);			
-					unsortedProfiledFunctions.add((ProfiledGeneric)pFunction);			
-				}
-
-				pFunction.incTotalSampleCount();
-				sample.functionIndex = pFunction.getIndex();
-
-				if (functionPercentages.containsKey(pFunction))
-				{
-					Integer value = (Integer)functionPercentages.get(pFunction);
-					value = new Integer(value.intValue()+1);
-					functionPercentages.remove(pFunction);
-					functionPercentages.put(pFunction,value);
-				}
-				else
-				{
-					functionPercentages.put(pFunction, new Integer(1));
-				}														
-			}
-			
-			// for each stepValue (or final values) samples
-			// add the data to the profiled threads, binaries, functions
-			if (stepValue != 0 && count == stepValue)
-			{
-				Vector<ProfiledGeneric> tmpVector;
-				
-				tmpVector = new Vector<ProfiledGeneric>(profiledThreads.values());
-				Enumeration<ProfiledGeneric> ptEnum = tmpVector.elements();
-				while (ptEnum.hasMoreElements())
-				{
-					ProfiledThread updatePt = (ProfiledThread)ptEnum.nextElement();
-					if (threadPercentages.containsKey(updatePt))
-					{
-						int samples = ((Integer)(threadPercentages.get(updatePt))).intValue();
-						int finalPerc = (samples * 100) / stepValue;
-						updatePt.addActivityMarkValues(timeStamp + stepValue * samplingInterval, finalPerc, samples);
-					}
-					else
-					{
-						updatePt.zeroActivityMarkValues(timeStamp + stepValue * samplingInterval);
-					}					
-				}
-				
-				tmpVector = new Vector<ProfiledGeneric>(profiledBinaries.values());
-				Enumeration<ProfiledGeneric> pbEnum = tmpVector.elements();
-				while (pbEnum.hasMoreElements())
-				{
-					ProfiledBinary updatePb = (ProfiledBinary)pbEnum.nextElement();
-					if (binaryPercentages.containsKey(updatePb))
-					{
-						int samples = ((Integer)(binaryPercentages.get(updatePb))).intValue();
-						int finalPerc = (samples * 100) / stepValue;
-						updatePb.addActivityMarkValues(timeStamp + stepValue * samplingInterval, finalPerc, samples);
-					}
-					else
-					{
-						updatePb.zeroActivityMarkValues(timeStamp + stepValue * samplingInterval);
-					}					
-				}
-				
-				tmpVector = new Vector<ProfiledGeneric>(profiledFunctions.values());
-				Enumeration<ProfiledGeneric> pfEnum = tmpVector.elements();
-				while (pfEnum.hasMoreElements())
-				{
-					ProfiledFunction updatePf = (ProfiledFunction)pfEnum.nextElement();
-					if (functionPercentages.containsKey(updatePf))
-					{
-						int samples = ((Integer)(functionPercentages.get(updatePf))).intValue();
-						int finalPerc = (samples * 100) / stepValue;
-						updatePf.addActivityMarkValues(timeStamp + stepValue * samplingInterval, finalPerc, samples);
-					}
-					else
-					{
-						updatePf.zeroActivityMarkValues(timeStamp + stepValue * samplingInterval);
-					}					
-				}
-
-				threadPercentages.clear();
-				binaryPercentages.clear();
-				functionPercentages.clear();
-				count = 0;
-				timeStamp += stepValue * samplingInterval;
-			}
-		}
-		
-		// if there is no end point for a profiled element with samples, set the end to the last sample in the trace 
-		for (Enumeration<ProfiledGeneric> e = profiledThreads.elements(); e.hasMoreElements(); ) {
-			ProfiledGeneric pg = e.nextElement();
-			
-			if (pg.getRealLastSample() == -1 && pg.getTotalSampleCount() != 0)
-				pg.setLastSample(gppTrace.samples.size() * samplingInterval);
-		}
-
-		for (Enumeration<ProfiledGeneric> e = profiledBinaries.elements(); e.hasMoreElements(); ) {
-			ProfiledGeneric pg = e.nextElement();
-			
-			if (pg.getRealLastSample() == -1 && pg.getTotalSampleCount() != 0)
-				pg.setLastSample(gppTrace.samples.size() * samplingInterval);
-		}
-
-		for (Enumeration<ProfiledGeneric> e = profiledFunctions.elements(); e.hasMoreElements(); ) {
-			ProfiledGeneric pg = e.nextElement();
-			
-			if (pg.getRealLastSample() == -1 && pg.getTotalSampleCount() != 0)
-				pg.setLastSample(gppTrace.samples.size() * samplingInterval);
-		}
-
-		// sort the thread, binary, and function vectors by load
-		sortProfiledGenerics(profiledThreads, gppTrace);
-		sortProfiledGenerics(profiledBinaries, gppTrace);
-		sortProfiledGenerics(profiledFunctions, gppTrace);
-		
-		// the trace-level count arrays are initialized to 0
-		gppTrace.setThreadSampleCounts(new int[profiledThreads.size()]);
-		gppTrace.setBinarySampleCounts(new int[profiledBinaries.size()]);
-		gppTrace.setFunctionSampleCounts(new int[profiledFunctions.size()]);
+	private void refreshMode() {
+		this.vPanel.refreshCumulativeThreadTable();
 	}
-	
-	/*
-	 * Because a table to the left of a function table has changed, update
-	 * the function table.
-	 * If there is no table to the right of this one, redraw the graph based
-	 * on the changed data.
-	 */
-	public void refreshProfiledThreadData(int drawMode)
-	{
-		// Must have a table to its left
-	    if (   (drawMode != Defines.BINARIES_THREADS)
-	    	&& (drawMode != Defines.BINARIES_THREADS_FUNCTIONS)
-	    	&& (drawMode != Defines.BINARIES_FUNCTIONS_THREADS)
-	    	&& (drawMode != Defines.FUNCTIONS_THREADS)
-	    	&& (drawMode != Defines.FUNCTIONS_THREADS_BINARIES)
-	    	&& (drawMode != Defines.FUNCTIONS_BINARIES_THREADS)
-	    	)
-	    {
-	        System.out.println(Messages.getString("GppTraceGraph.wrongDrawMode"));  //$NON-NLS-1$
-	        return;
-	    }
-
-	    // boolean to use inside loops (should trust a compiler to optimize this out of the loop...)
-	    boolean basedOnBinaries = (drawMode == Defines.BINARIES_THREADS)
-	    					   || (drawMode == Defines.BINARIES_THREADS_FUNCTIONS)
-	    					   || (drawMode == Defines.FUNCTIONS_BINARIES_THREADS); 
-
-	    Hashtable<String,ProfiledThread> profiledThreads = new Hashtable<String,ProfiledThread>();
-		
-	    GenericSampledTrace trace = (GenericSampledTrace)this.getTrace();
-		int granularityValue = trace.samples.size() > GppTraceGraph.granularityValue ? GppTraceGraph.granularityValue : trace.samples.size();  
-		
-	    String[] selectedItems;
-		int[] selectedFunctionHashCodes = null;
-		int[] selectedBinaryHashCodes   = null;
-		int count = 0;
-		int timeStamp = 0;
-		int stepValue = granularityValue;
-		int samplingInterval = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.samplingInterval"); //$NON-NLS-1$
-		boolean exit = false;
-		
-		Hashtable<ProfiledThread,Integer> percentages = new Hashtable<ProfiledThread,Integer>();
-		PIVisualSharedData shared = this.getSharedDataInstance();
-		
-	    if (basedOnBinaries)
-		{
-		    selectedItems = shared.GPP_SelectedBinaryNames;
-		    if (selectedItems == null) 
-	        {
-		        selectedItems = new String[0];
-	        }
-		    int[] tmpHashCodes = new int[selectedItems.length];
-		    for (int i = 0; i < selectedItems.length; i++)
-		    {
-		        String tmp = selectedItems[i];
-		        tmpHashCodes[i] = tmp.hashCode();
-		    }
-		    selectedBinaryHashCodes = tmpHashCodes;
-		}
-		else
-		{
-		    selectedItems = shared.GPP_SelectedFunctionNames;
-		    if (selectedItems == null) 
-	        {
-		        selectedItems = new String[0];
-	        }
-		    int[] tmpHashCodes = new int[selectedItems.length];
-		    for (int i = 0; i < selectedItems.length; i++)
-		    {
-		        String tmp = selectedItems[i];
-		        tmpHashCodes[i] = tmp.hashCode();
-		    }
-		    selectedFunctionHashCodes = tmpHashCodes;
-		}
-		
-		for (Enumeration enumer = trace.getSamples(); !exit;)
-		{
-		    exit = !enumer.hasMoreElements();
-			if (exit)
-			{
-				// for the final samples, modify the step value
-				// so that they will also be included
-				// now there are no new samples, so proceed directly to
-				// adding the final values to the percent list
-				stepValue = count;
-			}
-			else
-			{
-			    count++;
-			    int compareValue = 0;
-			    boolean match = false;
-			    GppSample sample = (GppSample)enumer.nextElement();
-			    if (basedOnBinaries)
-				{
-				    compareValue = getBinaryName(sample).hashCode();
-				    for (int i = 0; i < selectedBinaryHashCodes.length; i++)
-				    {
-				        if (compareValue == selectedBinaryHashCodes[i])
-				        {
-				            match = true;
-				            break;
-				        }
-				    }
-				}
-			    else
-			    {
-				    compareValue = getFunctionName(sample).hashCode();
-				    for (int i = 0; i < selectedFunctionHashCodes.length; i++)
-				    {
-				        if (compareValue == selectedFunctionHashCodes[i])
-				        {
-				            match = true;
-				            break;
-				        }
-				    }
-			    }
-			    
-			    if (match)
-			    {
-			        ProfiledThread pt = null;
-			        String name = sample.thread.threadName;
-					if (profiledThreads.containsKey(name))
-					{
-						pt = (ProfiledThread)profiledThreads.get(name);
-					}
-				
-					if (pt == null)
-					{
-						pt = new ProfiledThread();
-					
-						pt.setNameString(name);
-						pt.setColor(((GppTrace)this.getTrace()).getThreadColorPalette().getColor(name));
-						pt.setThreadId(sample.thread.threadId.intValue());
-						
-						pt.setActivityMarkCount((trace.samples.size() + granularityValue) / granularityValue + 1);
-						for (int i = 0; i < timeStamp + stepValue * samplingInterval; i += stepValue * samplingInterval)
-						{
-							pt.zeroActivityMarkValues(i);
-						}
-						pt.setEnabled(this.graphIndex, true);
-						profiledThreads.put(name, pt);
-					}
-	
-					if (percentages.containsKey(pt))
-					{
-						Integer value = (Integer)percentages.get(pt);
-						value = new Integer(value.intValue()+1);
-						percentages.remove(pt);
-						percentages.put(pt,value);
-					}
-					else
-					{
-						percentages.put(pt,new Integer(1));
-					}
-			    }
-			}
-
-			if (stepValue != 0 && count == stepValue)
-			{	
-				Vector<ProfiledGeneric> v = new Vector<ProfiledGeneric>(profiledThreads.values());
-				Enumeration<ProfiledGeneric> pfEnum = v.elements();
-				while (pfEnum.hasMoreElements())
-				{
-					ProfiledThread updatePt = (ProfiledThread)pfEnum.nextElement();
-					if (percentages.containsKey(updatePt))
-					{
-						int samples = ((Integer)(percentages.get(updatePt))).intValue();
-						int finalPerc = (samples * 100) / stepValue;
-						updatePt.addActivityMarkValues(timeStamp + stepValue * samplingInterval, finalPerc, samples);
-					}
-					else
-					{
-						updatePt.zeroActivityMarkValues(timeStamp + stepValue * samplingInterval);
-					}					
-				}
-				
-				percentages.clear();
-				count = 0;
-				timeStamp += stepValue * samplingInterval;
-			}
-		}
-
-		this.threadTable.getTable().deselectAll();
-		this.threadTable.updateProfiledAndItemData(true);
-		this.threadTable.getTable().redraw();
-
-		// if this is not the last table, set the selected names to set up
-		// the next table
-	    if (   (drawMode == Defines.BINARIES_THREADS_FUNCTIONS)
-	    	|| (drawMode == Defines.FUNCTIONS_THREADS_BINARIES))
-	    {
-	    	this.threadTable.setSelectedNames();
-	    }
-	    else
-	    {
-	    	// This may not be needed needed
-			shared.GPP_SelectedThreadNames = new String[0];
-	    }
-	}
-
-	/*
-	 * Because a table to the left of a binary table has changed, update
-	 * the binary table.
-	 * If there is no table to the right of this one, redraw the graph based
-	 * on the changed data.
-	 */
-	public void refreshProfiledBinaryData(int drawMode)
-	{
-		// Must have a table to its left
-	    if (   (drawMode != Defines.THREADS_BINARIES)
-	    	&& (drawMode != Defines.THREADS_BINARIES_FUNCTIONS)
-	    	&& (drawMode != Defines.THREADS_FUNCTIONS_BINARIES)
-	    	&& (drawMode != Defines.FUNCTIONS_BINARIES)
-	    	&& (drawMode != Defines.FUNCTIONS_BINARIES_THREADS)
-	    	&& (drawMode != Defines.FUNCTIONS_THREADS_BINARIES)
-	       )
-	    {
-	        System.out.println(Messages.getString("GppTraceGraph.wrongDrawMode"));  //$NON-NLS-1$
-	        return;
-	    }
-
-	    // boolean to use inside loops (never trust a compiler...)
-	    boolean basedOnThreads = (drawMode == Defines.THREADS_BINARIES)
-	    					  || (drawMode == Defines.THREADS_BINARIES_FUNCTIONS)
-	    					  || (drawMode == Defines.FUNCTIONS_THREADS_BINARIES); 
-
-	    Hashtable<String,ProfiledBinary> profiledBinaries = new Hashtable<String,ProfiledBinary>();
-		
-	    GenericSampledTrace trace = (GenericSampledTrace)this.getTrace();
-		int granularityValue = trace.samples.size() > GppTraceGraph.granularityValue ? GppTraceGraph.granularityValue : trace.samples.size();  
-
-		String[] selectedItems;
-		int[] selectedThreadIds = null;
-		int[] selectedFunctionHashCodes = null;
-		int count = 0;
-		int timeStamp = 0;
-		int stepValue = granularityValue;
-		int samplingInterval = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.samplingInterval"); //$NON-NLS-1$
-		boolean exit = false;
-		
-		Hashtable<ProfiledBinary,Integer> percentages = new Hashtable<ProfiledBinary,Integer>();
-		PIVisualSharedData shared = this.getSharedDataInstance();
-		
-	    if (basedOnThreads)
-	    {
-	    	selectedItems = shared.GPP_SelectedThreadNames;
-		    if (selectedItems == null)
-		    {
-		        selectedItems = new String[0];
-		    }
-		    int[] tmpThreadIds = new int[selectedItems.length];
-		    for (int i = 0; i < selectedItems.length; i++)
-		    {
-		        String tmp = selectedItems[i].substring(selectedItems[i].lastIndexOf('_') + 1,
-		                selectedItems[i].length());
-		        tmpThreadIds[i] = Integer.parseInt(tmp);
-		    }
-		    selectedThreadIds = tmpThreadIds;
-		}
-		else
-		{
-		    selectedItems = shared.GPP_SelectedFunctionNames;
-		    if (selectedItems == null) 
-	        {
-		        selectedItems = new String[0];
-	        }
-		    int[] tmpHashCodes = new int[selectedItems.length];
-		    for (int i = 0; i < selectedItems.length; i++)
-		    {
-		        String tmp = selectedItems[i];
-		        tmpHashCodes[i] = tmp.hashCode();
-		    }
-		    selectedFunctionHashCodes = tmpHashCodes;
-		}
-		
-		for (Enumeration enumer = trace.getSamples(); !exit;)
-		{
-		    exit = !enumer.hasMoreElements();
-			if (exit) 
-			{
-				// for the final samples, modify the step value
-				// so that they will also be included
-				// now there are no new samples, so proceed directly to
-				// adding the final values to the percent list
-				stepValue = count;
-			}
-			else
-			{
-			    count++;
-			    int compareValue = 0;
-			    boolean match = false;
-			    GppSample sample = (GppSample)enumer.nextElement();
-			    if (basedOnThreads)
-			    {
-				    compareValue = sample.thread.threadId.intValue();
-				    for (int i = 0; i < selectedThreadIds.length; i++)
-				    {
-				        if (compareValue == selectedThreadIds[i])
-				        {
-				            match = true;
-				            break;
-				        }
-				    }
-			    }
-				else
-				{
-				    compareValue = getFunctionName(sample).hashCode();
-				    for (int i = 0; i < selectedFunctionHashCodes.length; i++)
-				    {
-				        if (compareValue == selectedFunctionHashCodes[i])
-				        {
-				            match = true;
-				            break;
-				        }
-				    }
-				}
-			    
-			    if (match)
-			    {
-			        ProfiledBinary pb = null;
-			        String name = getFunctionName(sample);
-					if (profiledBinaries.containsKey(name))
-					{
-						pb = (ProfiledBinary)profiledBinaries.get(name);
-					}
-				
-					if (pb == null)
-					{
-						pb = new ProfiledBinary();
-						
-						pb.setNameString(name);
-						pb.setColor(((GppTrace)this.getTrace()).getBinaryColorPalette().getColor(name));
-						
-						pb.setActivityMarkCount((trace.samples.size() + granularityValue) / granularityValue + 1);
-						for (int i = 0; i < timeStamp + stepValue * samplingInterval; i += stepValue * samplingInterval)
-						{
-							pb.zeroActivityMarkValues(i);
-						}
-						profiledBinaries.put(name, pb);
-					}
-	
-					if (percentages.containsKey(pb))
-					{
-						Integer value = (Integer)percentages.get(pb);
-						value = new Integer(value.intValue()+1);
-						percentages.remove(pb);
-						percentages.put(pb,value);
-					}
-					else
-					{
-						percentages.put(pb,new Integer(1));
-					}
-			    }
-			}
-
-			if (stepValue != 0 && count == stepValue)
-			{	
-				Vector<ProfiledGeneric> v = new Vector<ProfiledGeneric>(profiledBinaries.values());
-				Enumeration<ProfiledGeneric> pfEnum = v.elements();
-				while (pfEnum.hasMoreElements())
-				{
-					ProfiledFunction updatePf = (ProfiledFunction)pfEnum.nextElement();
-					if (percentages.containsKey(updatePf))
-					{
-						int samples = ((Integer)(percentages.get(updatePf))).intValue();
-						int finalPerc = (samples * 100) / stepValue;
-						updatePf.addActivityMarkValues(timeStamp + stepValue * samplingInterval, finalPerc, samples);
-					}
-					else
-					{
-						updatePf.zeroActivityMarkValues(timeStamp + stepValue * samplingInterval);
-					}					
-				}
-				
-				percentages.clear();
-				count = 0;
-				timeStamp += stepValue * samplingInterval;
-			}
-		}
-
-		this.binaryTable.getTable().deselectAll();
-		this.binaryTable.updateProfiledAndItemData(true);
-		this.binaryTable.getTable().redraw();
-
-		// if this is not the last table, set the selected names to set up
-		// the next table
-	    if (   (drawMode == Defines.THREADS_BINARIES_FUNCTIONS)
-	    	|| (drawMode == Defines.FUNCTIONS_BINARIES_THREADS))
-	    {
-	    	this.binaryTable.setSelectedNames();
-	    }
-	    else
-	    {
-	    	// This may not be needed
-			shared.GPP_SelectedBinaryNames = new String[0];
-	    }
-	}
-	
-	// sort profiled generics by decreasing total sample count
-	private static void sortProfiledGenerics(Hashtable<String,ProfiledGeneric> prof, GppTrace gppTrace)
-	{
-		// use an insertion sort to create a sorted linked list
-		// from the hashtable values
-		Collection<ProfiledGeneric> values = prof.values();
-		Vector<ProfiledGeneric> unsorted =   new Vector<ProfiledGeneric>(values);
-		LinkedList<ProfiledGeneric> sorted = new LinkedList<ProfiledGeneric>();
-
-		Enumeration<ProfiledGeneric> prEnum = unsorted.elements();
-		while (prEnum.hasMoreElements())
-		{
-			ProfiledGeneric pg = prEnum.nextElement();
-			if (sorted.size() == 0)
-			{
-				sorted.addFirst(pg);
-			}
-			else 
-			{
-				Iterator i = sorted.iterator();
-				boolean ok = false;
-				while (i.hasNext())
-				{
-					ProfiledGeneric next = (ProfiledGeneric)i.next();
-					if (next.getTotalSampleCount() < pg.getTotalSampleCount())
-					{
-						sorted.add(sorted.indexOf(next), pg);
-						ok = true;
-						break;
-					}
-				}
-				if (!ok)
-					sorted.addLast(pg);
-			}
-		}
-		
-		// Add the sorted data 
-		Iterator<ProfiledGeneric> iterator = sorted.iterator();
-		if (sorted.size() > 0)
-		{
-			Vector<ProfiledGeneric> v = null;
-			if (sorted.get(0) instanceof ProfiledThread)
-			{
-				v = gppTrace.getSortedThreads();
-			}
-			else if (sorted.get(0) instanceof ProfiledBinary)
-			{
-				v = gppTrace.getSortedBinaries();
-			}
-			else if (sorted.get(0) instanceof ProfiledFunction)
-			{
-				v = gppTrace.getSortedFunctions();
-			}
-			if (v != null)
-			{
-				v.clear();
-				while (iterator.hasNext())
-					v.add(0, iterator.next());
-			}
-		}
-	}
-	
-	public void updateGraph()
-	{
-	    if (drawMode == Defines.BINARIES)
-	    {
-	        vPanel.refreshCumulativeThreadTable();
-	    }
-	    else if (drawMode == Defines.THREADS)
-	    {
-	        vPanel.refreshCumulativeThreadTable();
-	    }
-
-		this.repaint();
-	}
-	
-	public void updateThreadTablePriorities(Hashtable<Integer,String> priorities)
-	{
-		this.threadTable.addPriorityColumn(priorities);
-	}
-	
-	static private String stringNotFound = Messages.getString("GppTraceGraph.notFound");  //$NON-NLS-1$
-
-	static private String stringBinaryAt         = Messages.getString("GppTraceGraph.binaryAt");  //$NON-NLS-1$
-	static private String stringBinaryForAddress = Messages.getString("GppTraceGraph.binaryForAddress");  //$NON-NLS-1$
-	static private String stringBinaryNotFound   = Messages.getString("GppTraceGraph.binaryNotFound");  //$NON-NLS-1$
-
-	static private String stringFunctionAt         = Messages.getString("GppTraceGraph.functionAt"); //$NON-NLS-1$
-	static private String stringFunctionForAddress = Messages.getString("GppTraceGraph.functionForAddress"); //$NON-NLS-1$
-	static private String stringFunctionNotFound   = Messages.getString("GppTraceGraph.functionNotFound"); //$NON-NLS-1$
-	
-	public static String getBinaryName(GppSample s)
-	{
-	    String name = null;
-	    
-	    if (s.currentFunctionSym != null)
-	    	name = s.currentFunctionSym.functionBinary.binaryName;
-
-        if (   (s.currentFunctionItt != null)
-           	&& ((name == null) || name.endsWith(stringNotFound)))
-        {
-            name = s.currentFunctionItt.functionBinary.binaryName;
-        }
-	    
-	    if (   name == null
-	    	|| name.startsWith(stringBinaryAt)
-	    	|| name.startsWith(stringBinaryForAddress))
-	    {
-	        name = stringBinaryNotFound;
-	    }
-	    return name;
-	}
-	
-	public static String getFunctionName(GppSample s)
-	{
-	    String name = null;
-	    if (s.currentFunctionSym != null)
-	    	name = s.currentFunctionSym.functionName;
-	    
-        if (   (s.currentFunctionItt != null)
-        	&& ((name == null) || name.endsWith(stringNotFound)))
-        {
-        	name = s.currentFunctionItt.functionName;
-        }
-
-	    if (   (name == null)
-	    	|| (name.startsWith(stringFunctionAt))
-	    	|| (name.startsWith(stringFunctionForAddress)))
-	    {
-	        name = stringFunctionNotFound;
-	    }
-	    
-	    return name;
-	}
-	
-	public static long getFunctionAddress(GppSample s)
-	{
-	    if (s.currentFunctionSym != null)
-	    {
-	        String name = s.currentFunctionSym.functionName;
-	        if (   (s.currentFunctionItt != null)
-	        	&& (name == null || name.endsWith(Messages.getString("GppTraceGraph.notFound"))))  //$NON-NLS-1$
-	        {
-        		return s.currentFunctionItt.startAddress.longValue();
-	        }
-	        else
-	        {
-	        	return s.currentFunctionSym.startAddress.longValue();
-	        }
-	    }
-	    else if (s.currentFunctionItt != null)
-	    {
-	        if (s.currentFunctionItt.functionName == null)
-	        {
-	        	if (s.currentFunctionSym != null)
-	        		return s.currentFunctionSym.startAddress.longValue();
-	        }
-	        else
-	        {
-        		return s.currentFunctionItt.startAddress.longValue();
-	        }
-	    }
-
-	    return 0;
-	}
-
-	public int getDrawMode()
-    {
-        return drawMode;
-    }
-
-    public void setDrawMode(int drawMode)
-    {
-    	if (
-    		   (drawMode == Defines.THREADS)
-    		|| (drawMode == Defines.THREADS_FUNCTIONS)
-    		|| (drawMode == Defines.THREADS_FUNCTIONS_BINARIES)
-    		|| (drawMode == Defines.THREADS_BINARIES)
-    		|| (drawMode == Defines.THREADS_BINARIES_FUNCTIONS)
-    		|| (drawMode == Defines.BINARIES)
-    		|| (drawMode == Defines.BINARIES_THREADS)
-    		|| (drawMode == Defines.BINARIES_THREADS_FUNCTIONS)
-    		|| (drawMode == Defines.BINARIES_FUNCTIONS)
-    		|| (drawMode == Defines.BINARIES_FUNCTIONS_THREADS)
-    		|| (drawMode == Defines.FUNCTIONS)
-    		|| (drawMode == Defines.FUNCTIONS_THREADS)
-    		|| (drawMode == Defines.FUNCTIONS_THREADS_BINARIES)
-    		|| (drawMode == Defines.FUNCTIONS_BINARIES)
-    		|| (drawMode == Defines.FUNCTIONS_BINARIES_THREADS))
-    	{
-    		if (this.drawMode != drawMode) {
-    			this.setGraphImageChanged(true);
-    		}
-	        this.drawMode = drawMode;
-	        refreshMode();
-        }
-        else
-        {
-            System.out.println(Messages.getString("GppTraceGraph.unknownDrawMode"));  //$NON-NLS-1$
-            this.drawMode = Defines.THREADS;
-            refreshMode();
-        }
-    }
-    
-    private void refreshMode()
-    {
-    	this.vPanel.refreshCumulativeThreadTable();
-    }
 
 	public int getUid() {
 		return this.uid;
 	}
-	
-	public GppTraceGraph getTraceGraph() {
-		return this.thisTraceGraph;
-	}
-	
+
 	public void setLeftSash(Sash leftSash) {
 		this.leftSash = leftSash;
 	}
-	
+
 	public Sash getLeftSash() {
 		return this.leftSash;
 	}
-	
+
 	public void setRightSash(Sash rightSash) {
 		this.rightSash = rightSash;
 	}
-	
+
 	public Sash getRightSash() {
 		return this.rightSash;
 	}
@@ -2305,11 +2139,11 @@
 	public void setProfiledThreads(Vector<ProfiledGeneric> profiledThreads) {
 		this.profiledThreads = profiledThreads;
 	}
-	
+
 	public Vector<ProfiledGeneric> getProfiledThreads() {
 		return this.profiledThreads;
 	}
-	
+
 	public Vector<ProfiledGeneric> getSortedThreads() {
 		return this.sortedProfiledThreads;
 	}
@@ -2317,11 +2151,11 @@
 	public void setProfiledBinaries(Vector<ProfiledGeneric> profiledBinaries) {
 		this.profiledBinaries = profiledBinaries;
 	}
-	
+
 	public Vector<ProfiledGeneric> getProfiledBinaries() {
 		return this.profiledBinaries;
 	}
-	
+
 	public Vector<ProfiledGeneric> getSortedBinaries() {
 		return this.sortedProfiledBinaries;
 	}
@@ -2329,27 +2163,206 @@
 	public void setProfiledFunctions(Vector<ProfiledGeneric> profiledFunctions) {
 		this.profiledFunctions = profiledFunctions;
 	}
-	
+
 	public Vector<ProfiledGeneric> getProfiledFunctions() {
 		return this.profiledFunctions;
 	}
-	
+
 	public Vector<ProfiledGeneric> getSortedFunctions() {
 		return this.sortedProfiledFunctions;
 	}
-	
+
 	public ProfiledThreshold getThresholdThread() {
 		return thresholdThread;
 	}
-	
+
 	public ProfiledThreshold getThresholdBinary() {
 		return thresholdBinary;
 	}
-	
+
 	public ProfiledThreshold getThresholdFunction() {
 		return thresholdFunction;
 	}
 
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.swt.events.MouseMoveListener#mouseMove(org.eclipse.swt.events
+	 * .MouseEvent)
+	 */
 	public void mouseMove(org.eclipse.swt.events.MouseEvent e) {
 	}
+	
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph#graphVisibilityChanged(boolean)
+	 */
+	@Override
+	public void graphVisibilityChanged(boolean visible){
+		getGppTrace().setLegendVisible(graphIndex, visible, holdTablesComposite);	
+	}
+	
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph#graphMaximized(boolean)
+	 */
+	@Override
+	public void graphMaximized(boolean value){
+		//TODO this needs to be re-implemented probably using setVisible() on all graphs (rather than calling max on one graph)
+		getGppTrace().setLegendMaximised(graphIndex, value, holdTablesComposite);	
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph#graphMaximized(boolean)
+	 */
+	public void refreshColoursFromTrace() {
+		if (graphIndex == PIPageEditor.THREADS_PAGE) {
+			getThreadTable().addColor(Defines.THREADS);
+		} else if (graphIndex == PIPageEditor.BINARIES_PAGE) {
+			getBinaryTable().addColor(Defines.BINARIES);
+		} else if (graphIndex == PIPageEditor.FUNCTIONS_PAGE) {
+			getFunctionTable().addColor(Defines.FUNCTIONS);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph#doGetActivityList(com.nokia.carbide.cpp.internal.pi.model.ProfiledGeneric)
+	 */
+	@Override
+	protected float[] doGetActivityList(ProfiledGeneric pg) {
+		return adapter.getActivityList(pg);
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.pi.visual.IGenericTraceGraph#getTitle()
+	 */
+	@Override
+	public String getTitle() {
+		return String.format(Messages.getString("GppTraceGraph.2"), title, getTranslatedDrawMode()); //$NON-NLS-1$
+	}
+
+	private String getTranslatedDrawMode() {
+		String s = EMPTY_STRING;
+
+		switch (this.drawMode) {
+		case Defines.THREADS: {
+			s = Messages.getString("GppTraceGraph.3"); //$NON-NLS-1$
+			break;
+		}
+		case Defines.THREADS_FUNCTIONS: {
+			s = Messages.getString("GppTraceGraph.4"); //$NON-NLS-1$
+			break;
+		}
+		case Defines.THREADS_FUNCTIONS_BINARIES: {
+			s = Messages.getString("GppTraceGraph.5"); //$NON-NLS-1$
+			break;
+		}
+		case Defines.THREADS_BINARIES: {
+			s = Messages.getString("GppTraceGraph.6"); //$NON-NLS-1$
+			break;
+		}
+		case Defines.THREADS_BINARIES_FUNCTIONS: {
+			s = Messages.getString("GppTraceGraph.7"); //$NON-NLS-1$
+			break;
+		}
+		case Defines.BINARIES: {
+			s = Messages.getString("GppTraceGraph.8"); //$NON-NLS-1$
+			break;
+		}
+		case Defines.BINARIES_THREADS: {
+			s = Messages.getString("GppTraceGraph.9"); //$NON-NLS-1$
+			break;
+		}
+		case Defines.BINARIES_THREADS_FUNCTIONS: {
+			s = Messages.getString("GppTraceGraph.10"); //$NON-NLS-1$
+			break;
+		}
+		case Defines.BINARIES_FUNCTIONS: {
+			s = Messages.getString("GppTraceGraph.11"); //$NON-NLS-1$
+			break;
+		}
+		case Defines.BINARIES_FUNCTIONS_THREADS: {
+			s = Messages.getString("GppTraceGraph.12"); //$NON-NLS-1$
+			break;
+		}
+		case Defines.FUNCTIONS: {
+			s = Messages.getString("GppTraceGraph.13"); //$NON-NLS-1$
+			break;
+		}
+		case Defines.FUNCTIONS_THREADS: {
+			s = Messages.getString("GppTraceGraph.14"); //$NON-NLS-1$
+			break;
+		}
+		case Defines.FUNCTIONS_THREADS_BINARIES: {
+			s = Messages.getString("GppTraceGraph.15"); //$NON-NLS-1$
+			break;
+		}
+		case Defines.FUNCTIONS_BINARIES: {
+			s = Messages.getString("GppTraceGraph.16"); //$NON-NLS-1$
+			break;
+		}
+		case Defines.FUNCTIONS_BINARIES_THREADS: {
+			s = Messages.getString("GppTraceGraph.17"); //$NON-NLS-1$
+			break;
+		}
+		default:
+			break;
+		}
+		return s;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph#getShortTitle()
+	 */
+	@Override
+	public String getShortTitle() {
+		return shortTitle;
+	}
+
+	public Action[] addTitleBarMenuItems() {
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.ITitleBarMenu#getContextHelpId()
+	 */
+	public String getContextHelpId() {
+		return AddressPlugin.getPageHelpContextId(GppTraceUtil.getPageIndex(graphIndex));
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph#setVisible(boolean)
+	 */
+	@Override
+	public void setVisible(boolean show) {
+		super.setVisible(show); //this sets visibility of the graph component
+	}
+	
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph#isGraphMinimizedWhenOpened()
+	 */
+	@Override
+	public boolean isGraphMinimizedWhenOpened(){
+		// CPU load graph is shown when view is opened
+		return false;
+	}
+
+	public void addContextMenuItems(Menu menu,
+			org.eclipse.swt.events.MouseEvent me) {
+		if (getGppTrace() != null && getGppTrace().getCPUCount() > 1){
+			new MenuItem(menu, SWT.SEPARATOR);
+			
+			final boolean isSeparate = this instanceof GppTraceGraphSMP; 
+
+			MenuItem changeViewAction = new MenuItem(menu, SWT.PUSH);
+			changeViewAction.setText(isSeparate ? Messages.getString("GppTraceGraph.18") : Messages.getString("GppTraceGraph.19"));  //$NON-NLS-1$ //$NON-NLS-2$
+			changeViewAction.addSelectionListener(new SelectionAdapter() {
+				public void widgetSelected(SelectionEvent e) {
+					AddressPlugin.getDefault().receiveSelectionEvent(isSeparate ? AddressPlugin.ACTION_COMBINED_CPU_VIEW : AddressPlugin.ACTION_SEPARATE_CPU_VIEW);
+				}
+			});			
+		}
+		
+	}
+	
 }
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/pi/address/GppTraceParser.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/pi/address/GppTraceParser.java	Wed Apr 21 15:14:16 2010 +0300
@@ -23,15 +23,14 @@
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
-import java.util.Collection;
-import java.util.Enumeration;
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.Hashtable;
-import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
 import java.util.StringTokenizer;
-import java.util.Vector;
 
 import com.nokia.carbide.cpp.internal.pi.analyser.NpiInstanceRepository;
-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.Parser;
 import com.nokia.carbide.cpp.internal.pi.model.TraceDataContainer;
@@ -45,19 +44,65 @@
   private String samplerVersion;
   private Hashtable<Integer,GppProcess> processes;
   private Hashtable<Integer,GppThread> threads;
-  private GppSample[] traceData;
-  private GppThread[] sortedThreads;
-  private TraceDataContainer container; 
-  private Hashtable<Long,String> threadAddressToName;
+  private HashMap<Long,String> threadAddressToName;
+
+  // smp specific
+  private int currentCpuNumber = 0;
+  private int cpuCount = 0;
+
 
   public GppTraceParser() throws IOException
   {
     this.processes = new Hashtable<Integer,GppProcess>();
     this.threads   = new Hashtable<Integer,GppThread>();
-    this.threadAddressToName = new Hashtable<Long,String>();
+    this.threadAddressToName = new HashMap<Long,String>();
   }
 
-  public ParsedTraceData parse(File traceInput) throws IOException
+	/**
+	 * Parses all given input trace files and returns the resulting ParsedTraceData. 
+	 * @param traceInputs the trace data files to parse
+	 * @return ParsedTraceData containing parsed trace
+	 * @throws IOException
+	 */
+	public ParsedTraceData parse(File[] traceInputs) throws IOException {
+		List<GppSample> samples = new ArrayList<GppSample>();
+		
+		for (File traceInput : traceInputs) {
+			//each part of the trace file is independent of each other 
+			//so clear previous state
+			processes.clear();
+			threads.clear();
+			internalParse(traceInput, samples);			
+		}
+
+		ParsedTraceData pd = new ParsedTraceData();
+		pd.traceData = this.getTrace(samples);
+		pd.staticData = createTraceContainer();
+		return pd;
+	}
+
+	private TraceDataContainer createTraceContainer() {
+		TraceDataContainer container = new TraceDataContainer("GPP_address2threadname",new String[]{"address","threadname"}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		for (Map.Entry<Long, String> entry : threadAddressToName.entrySet()) {
+	    	container.addDataToColumn("threadname",entry.getKey()); //$NON-NLS-1$
+	    	container.addDataToColumn("address",entry.getValue()); //$NON-NLS-1$			
+		}
+	    this.threadAddressToName = null;
+		return container;
+	}
+
+	/**
+	 * Parses the given input trace file and returns the resulting ParsedTraceData. 
+	 * @param traceInput the trace data file to parse
+	 * @return ParsedTraceData containing parsed trace
+	 * @throws IOException
+	 */
+	@Override
+	public ParsedTraceData parse(File traceInput) throws IOException {
+		return parse(new File[]{traceInput});
+	}
+	
+  private void internalParse(File traceInput, List<GppSample> gppSamples) throws IOException
   {
     if (!traceInput.exists())
     	throw new IOException(Messages.getString("GppTraceParser.0"));  //$NON-NLS-1$
@@ -74,8 +119,6 @@
     int samples = 0;
     long time = 0;
 
-    Vector<GppSample> intermediateTraceData = new Vector<GppSample>();
-    
     // determine the base sampling period (address/thread sampling period) 
     int addrThreadPeriod = 1;
     
@@ -89,7 +132,7 @@
 	// initialize the address/thread base sampling rate
 	NpiInstanceRepository.getInstance().activeUidSetPersistState(
 								"com.nokia.carbide.cpp.pi.address.samplingInterval", //$NON-NLS-1$
-								new Integer(addrThreadPeriod)); //$NON-NLS-1$
+								Integer.valueOf(addrThreadPeriod)); //$NON-NLS-1$
     
     while (dis.available() > 0)
     {
@@ -115,9 +158,9 @@
           samples++;
           time += addrThreadPeriod;
           
-          if (samples == 1 && thread == null)
+          if (samples < 3 && thread == null)
           {
-	       	// the first sample may be recorded before its thread's name
+	       	// the first sample (or couple of samples for SMP) may be recorded before its thread's name
 
         	// create a new sample object for this sample
             GppSample gppSample = new GppSample();
@@ -143,7 +186,9 @@
             this.threads.put(-1,unknownThread);
 
             gppSample.thread = unknownThread;
-            intermediateTraceData.add(gppSample);
+        	gppSample.cpuNumber = currentCpuNumber;
+            
+        	gppSamples.add(gppSample);
           }
           else if (thread.index >= -1)
 	      {
@@ -164,8 +209,9 @@
             
             gppSample.sampleSynchTime = time;
             gppSample.thread = thread;
+        	gppSample.cpuNumber = currentCpuNumber;
             thread.samples++;
-            intermediateTraceData.add(gppSample);
+            gppSamples.add(gppSample);
           }
         }
       }
@@ -173,76 +219,6 @@
     }
     if (debug) System.out.println(Messages.getString("GppTraceParser.2"));  //$NON-NLS-1$
     // all samples have been parsed
-    this.traceData = new GppSample[intermediateTraceData.size()];
-
-    // store the trace data into an array
-    intermediateTraceData.toArray(this.traceData);
-
-    // sort the threads into an ordered array
-    this.sortThreads();
-    
-    container = new TraceDataContainer("GPP_address2threadname",new String[]{"address","threadname"}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-    Enumeration<Long> ke = this.threadAddressToName.keys();
-    Iterator<String>  vi = this.threadAddressToName.values().iterator();
-    
-    while(ke.hasMoreElements())
-    {
-    	Long address = ke.nextElement();
-    	String name = vi.next();
-    	container.addDataToColumn("threadname",name); //$NON-NLS-1$
-    	container.addDataToColumn("address",address); //$NON-NLS-1$
-    }
-    this.threadAddressToName.clear();
-    this.threadAddressToName = null;
-    
-    ParsedTraceData pd = new ParsedTraceData();
-    pd.traceData = this.getTrace();
-        
-    return pd;
-  }
-  
-  private void sortThreads()
-  {
-    if (this.threads != null)
-    {
-      boolean sorted = false;
-
-      GppThread[] tArray = new GppThread[this.threads.size()];
-      Collection<GppThread> threadCollection = this.threads.values();
-      threadCollection.toArray(tArray);
-
-      // set initial sort order to the order in which
-      // the threads appear in the array
-      for (int i = 0; i < tArray.length; i++)
-      {
-        tArray[i].sortOrder = i;
-      }
-
-      // sort threads using bubble sort
-      while (sorted == false)
-      {
-        sorted = true;
-        for (int i = 0; i < tArray.length - 1; i++)
-        {
-          if (tArray[i].samples < tArray[i + 1].samples)
-          {
-              // switch the sort order
-              GppThread store = tArray[i];
-              tArray[i] = tArray[i + 1];
-              tArray[i + 1] = store;
-              sorted = false;
-          }
-        }
-      }
-
-      // finally, store the ordered array
-      this.sortedThreads = tArray;
-      for (int i=0;i<this.sortedThreads.length;i++)
-      {
-        this.sortedThreads[i].sortOrder = i;
-      }
-
-    }
   }
 
   private boolean validate(DataInputStream dis) throws IOException
@@ -276,12 +252,19 @@
     		{
     			this.samplerVersion = st.nextToken();
     		}
+    		else if(id.equals("CPU"))
+    		{
+    			
+    			this.currentCpuNumber = Integer.parseInt(st.nextToken());
+    			cpuCount++;
+    		}
     	}
                
-        System.out.println(Messages.getString("GppTraceParser.4")+traceVersion+Messages.getString("GppTraceParser.5")+profilerVersion+Messages.getString("GppTraceParser.6")+samplerVersion);    //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        System.out.println(Messages.getString("GppTraceParser.4")+traceVersion+Messages.getString("GppTraceParser.5")+profilerVersion+Messages.getString("GppTraceParser.6")+samplerVersion+" CPU: "+currentCpuNumber);    //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
 		
 		if (   (traceVersion.indexOf("V1.10") != -1)	//$NON-NLS-1$
 			|| (traceVersion.indexOf("V1.64") != -1)	//$NON-NLS-1$
+			|| (traceVersion.indexOf("V2.00") != -1)	//$NON-NLS-1$
 			|| (traceVersion.indexOf("V2.01") != -1))	//$NON-NLS-1$
             return true;
       	else
@@ -291,7 +274,7 @@
     return false;
   }
 
-  	public static void encodeInt(int number, DataOutputStream dos) throws IOException
+  private static void encodeInt(int number, DataOutputStream dos) throws IOException
 	{
 		int digit;
 		for (;;) {
@@ -306,7 +289,7 @@
 		dos.flush();
 	}
 	
-	public static void encodeUInt(int number, DataOutputStream dos) throws IOException
+  private static void encodeUInt(int number, DataOutputStream dos) throws IOException
 	{
 		int digit;
 		for (;;) {
@@ -319,7 +302,7 @@
 		dos.write(digit | 0x80);		
 	}
   
-  public static long decodeInt(DataInputStream dis) throws IOException
+  private static long decodeInt(DataInputStream dis) throws IOException
   {
     //System.out.println("DECODING INT");
 
@@ -347,7 +330,7 @@
   }
 
 
-  public static long decodeUInt(DataInputStream dis) throws IOException
+  private static long decodeUInt(DataInputStream dis) throws IOException
   {
     //System.out.println("DECODING UINT");
     long val = 0;
@@ -383,7 +366,7 @@
   private GppProcess decodeProcess(DataInputStream dis) throws IOException
   {
     //System.out.println("DECODING PROCESS");
-    Integer pid = new Integer((int)decodeUInt(dis));
+    Integer pid = Integer.valueOf((int)decodeUInt(dis));
 
     if (this.processes.containsKey(pid))
     {
@@ -402,7 +385,7 @@
   private GppThread decodeThread(DataInputStream dis) throws IOException
   {
     //System.out.println("DECODING THREAD");
-    Integer tid = new Integer((int)decodeUInt(dis));
+    Integer tid = Integer.valueOf((int)decodeUInt(dis));
 
     if (this.threads.containsKey(tid))
     {
@@ -418,7 +401,8 @@
     	{
     		String l = name.substring(name.lastIndexOf("[")+1,name.lastIndexOf("]")); //$NON-NLS-1$ //$NON-NLS-2$
     		Long threadAddress = Long.decode("0x"+l); //$NON-NLS-1$
-    		this.threadAddressToName.put(threadAddress,name);
+//    		this.threadAddressToName.put(threadAddress,name);
+    		this.threadAddressToName.put(threadAddress,p.name+"::"+name);
     		name = name.substring(0,name.lastIndexOf("[")); //$NON-NLS-1$
     	}
 	}
@@ -438,13 +422,13 @@
     return nt;
   }
   
-  private GenericTrace getTrace()
+  private GppTrace getTrace(List<GppSample> samples)
   {
   	GppTrace trace = new GppTrace();
-  	for (int i = 0; i < traceData.length; i++)
-  	{
-  		trace.addSample(this.traceData[i]);
-  	}
+  	for (GppSample gppSample : samples) {
+  		trace.addSample(gppSample);
+	}
+  	trace.setCPUCount(cpuCount == 0 ? 1 : cpuCount);
   	return trace;
   }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/pi/address/GppTraceUtil.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,139 @@
+/*
+ * 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: 
+ *
+ */
+package com.nokia.carbide.cpp.pi.address;
+
+import com.nokia.carbide.cpp.pi.editors.PIPageEditor;
+
+/**
+ * Utility class for functionality associated with GppTraceGraph
+ *
+ */
+public final class GppTraceUtil {
+	static private final String STRING_NOT_FOUND = Messages.getString("GppTraceGraph.notFound"); //$NON-NLS-1$
+
+	static private final String STRING_BINARY_AT = Messages.getString("GppTraceGraph.binaryAt"); //$NON-NLS-1$
+	static private final String STRING_BINARY_FOR_ADDRESS = Messages.getString("GppTraceGraph.binaryForAddress"); //$NON-NLS-1$
+	static private final String STRING_BINARY_NOT_FOUND = Messages.getString("GppTraceGraph.binaryNotFound"); //$NON-NLS-1$
+
+	static private final String STRING_FUNCTION_AT = Messages.getString("GppTraceGraph.functionAt"); //$NON-NLS-1$
+	static private final String STRING_FUNCTION_FOR_ADDRESS = Messages.getString("GppTraceGraph.functionForAddress"); //$NON-NLS-1$
+	static private final String STRING_FUNCTION_NOT_FOUND = Messages.getString("GppTraceGraph.functionNotFound"); //$NON-NLS-1$
+
+	/**
+	 * Private constructor to avoid instantiation
+	 */
+	private GppTraceUtil() {
+	}
+
+	/**
+	 * Returns the name of the binary from the given sample's function
+	 * @param s the sample to use
+	 * @return the binary's name
+	 */
+	public static String getBinaryName(GppSample s) {
+		String name = null;
+
+		if (s.getCurrentFunctionSym() != null)
+			name = s.getCurrentFunctionSym().getFunctionBinary().getBinaryName();
+
+		if ((s.getCurrentFunctionItt() != null)
+				&& ((name == null) || name.endsWith(STRING_NOT_FOUND))) {
+			name = s.getCurrentFunctionItt().getFunctionBinary().getBinaryName();
+		}
+
+		if (name == null || name.startsWith(STRING_BINARY_AT)
+				|| name.startsWith(STRING_BINARY_FOR_ADDRESS)) {
+			name = STRING_BINARY_NOT_FOUND;
+		}
+		return name;
+	}
+
+	/**
+	 * Returns the function name found within the given sample
+	 * @param s The sample to use
+	 * @return the function name
+	 */
+	public static String getFunctionName(GppSample s) {
+		String name = null;
+		if (s.getCurrentFunctionSym() != null)
+			name = s.getCurrentFunctionSym().getFunctionName();
+
+		if ((s.getCurrentFunctionItt() != null)
+				&& ((name == null) || name.endsWith(STRING_NOT_FOUND))) {
+			name = s.getCurrentFunctionItt().getFunctionName();
+		}
+
+		if ((name == null) || (name.startsWith(STRING_FUNCTION_AT))
+				|| (name.startsWith(STRING_FUNCTION_FOR_ADDRESS))) {
+			name = STRING_FUNCTION_NOT_FOUND;
+		}
+
+		return name;
+	}
+
+	/**
+	 * Returns the address of the function from the sample
+	 * @param s the sample to use
+	 * @return the function's address, or 0 if no function is given 
+	 */
+	public static long getFunctionAddress(GppSample s) {
+		if (s.getCurrentFunctionSym() != null) {
+			String name = s.getCurrentFunctionSym().getFunctionName();
+			if ((s.getCurrentFunctionItt() != null)
+					&& (name == null || name.endsWith(Messages
+							.getString("GppTraceGraph.notFound")))) //$NON-NLS-1$
+			{
+				return s.getCurrentFunctionItt().getStartAddress().longValue();
+			} else {
+				return s.getCurrentFunctionSym().getStartAddress().longValue();
+			}
+		} else if (s.getCurrentFunctionItt() != null) {
+			if (s.getCurrentFunctionItt().getFunctionName() == null) {
+				if (s.getCurrentFunctionSym() != null)
+					return s.getCurrentFunctionSym().getStartAddress().longValue();
+			} else {
+				return s.getCurrentFunctionItt().getStartAddress().longValue();
+			}
+		}
+
+		return 0;
+	}
+
+	/**
+	 * Calculates and returns the number of buckets required to accommodate all samples
+	 * @param lastSampleTime highest-possible timestamp in the set of samples
+	 * @param granularityValue number of samples per bucket
+	 * @return number of buckets
+	 */
+	public static int calculateNumberOfBuckets(final long lastSampleTime, final int granularityValue){
+		return (int)(lastSampleTime / granularityValue) +1; 
+	}
+
+	/**
+	 * From the given graph index, works out which page it goes on. 
+	 * In SMP, all single-CPU graphs go onto the threads page.
+	 * @param graphIndex the graph index to use
+	 * @return the page index the graph is on
+	 */
+	public static int getPageIndex(int graphIndex) {
+		return graphIndex < 3 ? graphIndex : PIPageEditor.THREADS_PAGE;
+	}
+	
+	
+
+
+}
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/pi/address/GppVisualiserPanel.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/pi/address/GppVisualiserPanel.java	Wed Apr 21 15:14:16 2010 +0300
@@ -20,7 +20,6 @@
  */
 package com.nokia.carbide.cpp.pi.address;
 
-import java.util.Enumeration;
 import java.util.Vector;
 
 import org.eclipse.draw2d.Graphics;
@@ -45,7 +44,7 @@
 	      
 	     //sets the percentage scale for y-coordinates
 	    this.myGppGraph.setScale(0,100);
-	    this.myGppGraph.fillFlag = SessionPreferences.getInstance().getFillAllEnabled();
+	    this.myGppGraph.setFillFlag(SessionPreferences.getInstance().getFillAllEnabled());
 	    
 	  	this.myGppVisualiser = myGppGraphIn.getVisualiserPanel();
 	} //constructor
@@ -60,20 +59,20 @@
 		switch (be.getType())
 		{
 			case PIEvent.SET_FILL_ALL_THREADS:
-				this.myGppGraph.fillSelected = false;
-				this.myGppGraph.fillFlag     = true;
+				this.myGppGraph.setFillSelected(false);
+				this.myGppGraph.setFillFlag(true);
 				this.myGppGraph.repaint();
 				break;
 			
 			case PIEvent.SET_FILL_OFF:
-				this.myGppGraph.fillSelected = false;
-				this.myGppGraph.fillFlag     = false;
+				this.myGppGraph.setFillSelected(false);
+				this.myGppGraph.setFillFlag(false);
 				this.myGppGraph.repaint();
 				break;
 			
 			case PIEvent.SET_FILL_SELECTED_THREAD:
-				this.myGppGraph.fillSelected = true;
-				this.myGppGraph.fillFlag     = true;
+				this.myGppGraph.setFillSelected(true);
+				this.myGppGraph.setFillFlag(true);
 				this.myGppGraph.repaint();
 				break;
 				
@@ -89,7 +88,7 @@
 				
 			case PIEvent.CHANGED_THREAD_TABLE:
 				this.myGppGraph.setGraphImageChanged(true);
-				if (this.myGppGraph.fillFlag && this.myGppGraph.fillSelected)
+				if (this.myGppGraph.isFillFlag() && this.myGppGraph.isFillSelected())
 				{
 				    this.myGppGraph.repaint();
 				}
@@ -97,7 +96,7 @@
 				
 			case PIEvent.CHANGED_BINARY_TABLE:
 				this.myGppGraph.setGraphImageChanged(true);
-			    if (this.myGppGraph.fillFlag)
+			    if (this.myGppGraph.isFillFlag())
 			    {
 			        this.myGppGraph.repaint();
 			    }
@@ -105,7 +104,7 @@
 				
 			case PIEvent.CHANGED_FUNCTION_TABLE:
 				this.myGppGraph.setGraphImageChanged(true);
-			    if (this.myGppGraph.fillFlag)
+			    if (this.myGppGraph.isFillFlag())
 			    {
 			        this.myGppGraph.repaint();
 			    }
@@ -116,42 +115,11 @@
 		}
 	}
   
-	private Vector getItemsInVector(int drawMode)
-	{
-		Vector v = null;
-		
-		if (   (drawMode == Defines.THREADS)
-			|| (drawMode == Defines.BINARIES_THREADS)
-			|| (drawMode == Defines.BINARIES_FUNCTIONS_THREADS)
-			|| (drawMode == Defines.FUNCTIONS_THREADS)
-			|| (drawMode == Defines.FUNCTIONS_BINARIES_THREADS))
-		{
-		    v = this.myGppGraph.getSortedThreads();
-		}
-		else if ((drawMode == Defines.BINARIES)
-			  || (drawMode == Defines.THREADS_BINARIES)
-			  || (drawMode == Defines.THREADS_FUNCTIONS_BINARIES)
-			  || (drawMode == Defines.FUNCTIONS_BINARIES)
-			  || (drawMode == Defines.FUNCTIONS_THREADS_BINARIES))
-		{
-		    v = this.myGppGraph.getSortedBinaries();
-		}
-		else if ((drawMode == Defines.FUNCTIONS)
-			  || (drawMode == Defines.THREADS_FUNCTIONS)
-			  || (drawMode == Defines.THREADS_BINARIES_FUNCTIONS)
-			  || (drawMode == Defines.BINARIES_FUNCTIONS)
-			  || (drawMode == Defines.BINARIES_THREADS_FUNCTIONS))
-		{
-			v = this.myGppGraph.getSortedFunctions();
-		}
-		
-		return v;
-	}
 
 	// draw the graph based on the rightmost table displayed
   	private void drawCumulativeGraphLines(Graphics graphics)
 	{	
-		Vector v = getItemsInVector(this.myGppGraph.getDrawMode());
+		Vector<ProfiledGeneric> v = this.myGppGraph.getSortedProfiledsForGraph();
 		
 		if (v == null) 
 		    return;
@@ -161,7 +129,7 @@
 	
 	private void drawBarGraph(Graphics graphics)
 	{
-		Vector v = getItemsInVector(this.myGppGraph.getDrawMode());
+		Vector<ProfiledGeneric> v = this.myGppGraph.getSortedProfiledsForGraph();
 		
 		if (v == null) 
 		    return;
@@ -169,72 +137,73 @@
 		this.myGppGraph.drawBarsGpp(v, graphics, myGppGraph.getTableUtils().getSelectedValues());	  			
 	}
 
-	//updates values in current profiled generic items
-	public void updateThreadAverages()
-	{
-	    //System.out.println("Refreshing average values");
-		Enumeration enumer = null;
-		int drawMode   = this.myGppGraph.getDrawMode();
-		int graphIndex = this.myGppGraph.getGraphIndex();
-
-		if (   (drawMode == Defines.THREADS)
-				|| (drawMode == Defines.BINARIES_THREADS)
-				|| (drawMode == Defines.BINARIES_FUNCTIONS_THREADS)
-				|| (drawMode == Defines.FUNCTIONS_THREADS)
-				|| (drawMode == Defines.FUNCTIONS_BINARIES_THREADS))
-		{
-		    enumer = ((GppTrace) (this.myGppGraph.getTrace())).getSortedThreadsElements();
-		}
-		else if ((drawMode == Defines.BINARIES)
-			  || (drawMode == Defines.THREADS_BINARIES)
-			  || (drawMode == Defines.THREADS_FUNCTIONS_BINARIES)
-			  || (drawMode == Defines.FUNCTIONS_BINARIES)
-			  || (drawMode == Defines.FUNCTIONS_THREADS_BINARIES))
-		{
-		    enumer = ((GppTrace) (this.myGppGraph.getTrace())).getSortedBinariesElements();
-		}
-		else if ((drawMode == Defines.FUNCTIONS)
-			  || (drawMode == Defines.THREADS_FUNCTIONS)
-			  || (drawMode == Defines.THREADS_BINARIES_FUNCTIONS)
-			  || (drawMode == Defines.BINARIES_FUNCTIONS)
-			  || (drawMode == Defines.BINARIES_THREADS_FUNCTIONS))
-		{
-		    enumer = ((GppTrace) (this.myGppGraph.getTrace())).getSortedFunctionsElements();
-		}
-
-		if (enumer == null) 
-		    return;
-
-	  	// update the average load strings
-		if (   (myGppGraph.getSelectionStart() == -1)
-			|| (myGppGraph.getSelectionEnd()   == -1))
-		{
-		  	while(enumer.hasMoreElements())
-		  		((ProfiledGeneric) enumer.nextElement()).
-		  				setAverageLoadValueString(graphIndex, "  0.000"); //$NON-NLS-1$
-		} else {
-		  	while(enumer.hasMoreElements())
-		  	{
-		  	    updateThreadAverage(graphIndex, (ProfiledGeneric) enumer.nextElement());
-		  	}
-		}
-	}
-	
-	private void updateThreadAverage(int graphIndex, ProfiledGeneric pg)
-	{
-        float averageLoad = pg.getAverageLoad(
-				myGppGraph.getSelectionStart(),
-				myGppGraph.getSelectionEnd());
-			
-		if (averageLoad >= 0.001)
-		{
-			pg.setAverageLoadValueString(graphIndex, averageLoad);
-		}
-	  	else
-	  	{
-			pg.setAverageLoadValueString(graphIndex, "  0.000"); //$NON-NLS-1$
-	  	}
-	}
+	//unused?
+//	//updates values in current profiled generic items
+//	public void updateThreadAverages()
+//	{
+//	    //System.out.println("Refreshing average values");
+//		Enumeration enumer = null;
+//		int drawMode   = this.myGppGraph.getDrawMode();
+//		int graphIndex = this.myGppGraph.getGraphIndex();
+//
+//		if (   (drawMode == Defines.THREADS)
+//				|| (drawMode == Defines.BINARIES_THREADS)
+//				|| (drawMode == Defines.BINARIES_FUNCTIONS_THREADS)
+//				|| (drawMode == Defines.FUNCTIONS_THREADS)
+//				|| (drawMode == Defines.FUNCTIONS_BINARIES_THREADS))
+//		{
+//		    enumer = ((GppTrace) (this.myGppGraph.getTrace())).getSortedThreadsElements();
+//		}
+//		else if ((drawMode == Defines.BINARIES)
+//			  || (drawMode == Defines.THREADS_BINARIES)
+//			  || (drawMode == Defines.THREADS_FUNCTIONS_BINARIES)
+//			  || (drawMode == Defines.FUNCTIONS_BINARIES)
+//			  || (drawMode == Defines.FUNCTIONS_THREADS_BINARIES))
+//		{
+//		    enumer = ((GppTrace) (this.myGppGraph.getTrace())).getSortedBinariesElements();
+//		}
+//		else if ((drawMode == Defines.FUNCTIONS)
+//			  || (drawMode == Defines.THREADS_FUNCTIONS)
+//			  || (drawMode == Defines.THREADS_BINARIES_FUNCTIONS)
+//			  || (drawMode == Defines.BINARIES_FUNCTIONS)
+//			  || (drawMode == Defines.BINARIES_THREADS_FUNCTIONS))
+//		{
+//		    enumer = ((GppTrace) (this.myGppGraph.getTrace())).getSortedFunctionsElements();
+//		}
+//
+//		if (enumer == null) 
+//		    return;
+//
+//	  	// update the average load strings
+//		if (   (myGppGraph.getSelectionStart() == -1)
+//			|| (myGppGraph.getSelectionEnd()   == -1))
+//		{
+//		  	while(enumer.hasMoreElements())
+//		  		((ProfiledGeneric) enumer.nextElement()).
+//		  				setAverageLoadValueString(graphIndex, "  0.000"); //$NON-NLS-1$
+//		} else {
+//		  	while(enumer.hasMoreElements())
+//		  	{
+//		  	    updateThreadAverage(graphIndex, (ProfiledGeneric) enumer.nextElement());
+//		  	}
+//		}
+//	}
+//	
+//	private void updateThreadAverage(int graphIndex, ProfiledGeneric pg)
+//	{
+//        float averageLoad = pg.getAverageLoad(
+//				myGppGraph.getSelectionStart(),
+//				myGppGraph.getSelectionEnd());
+//			
+//		if (averageLoad >= 0.001)
+//		{
+//			pg.setAverageLoadValueString(graphIndex, averageLoad);
+//		}
+//	  	else
+//	  	{
+//			pg.setAverageLoadValueString(graphIndex, "  0.000"); //$NON-NLS-1$
+//	  	}
+//	}
   
 	public void paintComponent(Panel panel, Graphics graphics)
 	{		
@@ -249,8 +218,8 @@
 			this.drawBarGraph(graphics);
 		}
 		
-		this.myGppGraph.drawDottedLineBackground(graphics, GppTraceGraph.xLegendHeight);
-		this.myGppGraph.drawSelectionSection(graphics, GppTraceGraph.xLegendHeight);
+		this.myGppGraph.drawDottedLineBackground(graphics, GppTraceGraph.X_LEGEND_HEIGHT);
+		this.myGppGraph.drawSelectionSection(graphics, GppTraceGraph.X_LEGEND_HEIGHT);
 	}
  
 } //class VisualiserPanel
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/pi/address/IGppTraceGraph.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,237 @@
+/*
+ * 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: 
+ *
+ */
+package com.nokia.carbide.cpp.pi.address;
+
+import java.util.Hashtable;
+import java.util.Vector;
+
+import org.eclipse.draw2d.Graphics;
+import org.eclipse.swt.widgets.Sash;
+
+import com.nokia.carbide.cpp.internal.pi.model.ProfiledGeneric;
+import com.nokia.carbide.cpp.internal.pi.model.ProfiledThreshold;
+import com.nokia.carbide.cpp.internal.pi.visual.Defines;
+import com.nokia.carbide.cpp.internal.pi.visual.GenericTable;
+import com.nokia.carbide.cpp.internal.pi.visual.PIEventListener;
+import com.nokia.carbide.cpp.pi.visual.IGenericTraceGraph;
+
+/**
+ * Interface for GppTraceGraph functionality
+ *
+ */
+public interface IGppTraceGraph extends IGenericTraceGraph, PIEventListener{
+	/** Constant for Change-Threshold-Thread action */
+	public static final String ACTION_CHANGE_THRESHOLD_THREAD = "changeThresholdThread";//$NON-NLS-1$ 
+	/**
+	 * Executes action according to given request. Valid requests include
+	 * <br>resetToCurrentMode
+	 * <br>add
+	 * <br>remove
+	 * <br>addall
+	 * <br>removeall
+	 * <br>recolor
+	 * <br>copy
+	 * <br>copyTable
+	 * <br>copyDrilldown
+	 * <br>saveTable
+	 * <br>saveDrilldown
+	 * <br>saveSamples
+	 * <br>savePrioritySamples
+	 * <br>selectAll
+	 * <br>doubleClick
+	 * <br>changeThresholdThread
+	 * <br>saveTableTest
+	 * <br>saveDrilldownTest
+	 * <br>thread-only
+	 * <br>thread-binary
+	 * <br>thread-binary-function
+	 * <br>thread-function
+	 * <br>thread-function-binary
+	 * <br>binary-only
+	 * <br>...several more see {@link AddrThreadTable.action()}
+	 * @param actionString the action to perform.
+	 */
+	public void action(String actionString);
+
+	/**
+	 * Draws the bar graph. Called on a paint request. 
+	 * @param profiledGenerics Collection of affected ProfiledGeneric
+	 * @param graphics the Graphics to use
+	 * @param selection - Not used in code?
+	 */
+	public void drawBarsGpp(Vector<ProfiledGeneric> profiledGenerics, Graphics graphics, Object[] selection);
+	
+	/**
+	 * Returns the Binaries address table, which manages the legend for Binaries
+	 * @return AddrBinaryTable
+	 */
+	public AddrBinaryTable getBinaryTable();
+	
+	/**
+	 * returns the currently active drawMode as defined in {@link Defines}
+	 * @return int value of the draw mode
+	 */
+	public int getDrawMode();	
+	
+	/**
+	 * Returns the Functions address table, which manages the legend for Functions
+	 * @return AddrFunctionTable
+	 */
+	public AddrFunctionTable getFunctionTable();	
+	
+	/**
+	 * Getter for the GppTrace model 
+	 * @return GppTrace 
+	 */
+	public GppTrace getGppTrace();
+		
+	/**
+	 * Returns the left sash of the graph. This is used when switching drawing modes.
+	 * @return the left Sash
+	 */
+	public Sash getLeftSash();
+	
+	/**
+	 * Setter for leftShash. This is used when switching drawing modes.
+	 * @param leftSash
+	 */
+	public void setLeftSash(Sash leftSash);
+	
+	/**
+	 * Setter for right sash of the graph.
+	 * @param rightSash The Sash to set
+	 */
+	public void setRightSash(Sash rightSash);
+	
+	/**
+	 * Getter for rightSash. This is used when switching drawing modes.
+	 * @return rightSash
+	 */
+	public Sash getRightSash();	
+	/**
+	 * Getter for profiledBinaries
+	 * @return profiledBinaries
+	 */
+	public Vector<ProfiledGeneric> getProfiledBinaries();	
+	
+	/**
+	 * Getter for profiledFunctions
+	 * @return profiledFunctions
+	 */
+	public Vector<ProfiledGeneric> getProfiledFunctions();
+	
+	/**
+	 * Getter for sortedBinaries
+	 * @return sortedBinaries
+	 */
+	public Vector<ProfiledGeneric> getSortedBinaries();
+	
+	/**
+	 * Getter for profiledThread
+	 * @return profiledThread
+	 */
+	public Vector<ProfiledGeneric> getProfiledThreads();
+	
+	/**
+	 * Getter for sortedFunctions
+	 * @return sortedFunctions
+	 */
+	public Vector<ProfiledGeneric> getSortedFunctions();
+	
+	/**
+	 * Getter for sortedThreads
+	 * @return sortedThreads
+	 */
+	public Vector<ProfiledGeneric> getSortedThreads();	
+	
+	/**
+	 * Getter for thresholdThread
+	 * @return thresholdThread
+	 */
+	public ProfiledThreshold getThresholdThread();
+	
+	/**
+	 * Getter for thresholdBinary
+	 * @return thresholdBinary
+	 */
+	public ProfiledThreshold getThresholdBinary();
+	
+	/**
+	 * Getter for thresholdFunction
+	 * @return thresholdFunction
+	 */
+	public ProfiledThreshold getThresholdFunction();
+	
+	/**
+	 * @return the correct GenericTable for the currently active drawing mode
+	 */
+	public GenericTable getTableUtils();
+	
+	/**
+	 * Getter for threadsTable
+	 * @return AddrThreadTable
+	 */
+	public AddrThreadTable  getThreadTable();
+	
+	/**
+	 * Returns the UId that this graph page was created with
+	 * @return the uid
+	 */
+	public int getUid();
+
+	/**
+	 * Getter for graph page's GppVisualiserPanel
+	 * @return GppVisualiserPanel
+	 */
+	public GppVisualiserPanel getVisualiserPanel();
+
+	/**
+	 * Changes the draw mode
+	 * @param drawMode the new draw mode to set
+	 */
+    public void setDrawMode(int drawMode);
+
+    /**
+	 * Setter for collection of profiledBinaries this graph page uses
+     * @param profiledBinaries
+     */
+    public void setProfiledBinaries(Vector<ProfiledGeneric> profiledBinaries);
+    /**
+	 * Setter for collection of profiledFunctions this graph page uses
+     * @param profiledFunctions
+     */
+	public void setProfiledFunctions(Vector<ProfiledGeneric> profiledFunctions);
+    /**
+	 * Setter for collection of profiledThreads this graph page uses
+     * @param profiledThreads
+     */
+	public void setProfiledThreads(Vector<ProfiledGeneric> profiledThreads);
+	
+	/**
+	 * Update the thread table with thread priorities. 
+	 * Called after processing the thread priority trace.
+	 * @param priorities the priorities data to use
+	 */
+	public void updateThreadTablePriorities(Hashtable<Integer,String> priorities);
+
+	/**
+	 * Reload table colours from Profiled objects.
+	 * 
+	 */
+	public void refreshColoursFromTrace();
+	
+}
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/pi/address/messages.properties	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/pi/address/messages.properties	Wed Apr 21 15:14:16 2010 +0300
@@ -3,6 +3,26 @@
 GppTrace.functionNotFound1=Function at 0x
 GppTrace.functionNotFound2=\ not found
 GppTraceParser.0=Address/thread trace file not found
+GppTraceGraph.0=CPU Load
+GppTraceGraph.1=CPU
+GppTraceGraph.10=Binary -> Thread -> Function Load
+GppTraceGraph.11=Binary -> Function Load
+GppTraceGraph.12=Binary -> Function -> Thread Load
+GppTraceGraph.13=Function Load
+GppTraceGraph.14=Function -> Thread Load
+GppTraceGraph.15=Function -> Thread -> Binary Load
+GppTraceGraph.16=Function -> Binary Load
+GppTraceGraph.17=Function -> Binary -> Thread Load
+GppTraceGraph.18=Show Combined CPU Graph
+GppTraceGraph.19=Show Separate CPU Graphs
+GppTraceGraph.2=%s %s
+GppTraceGraph.3=Thread Load
+GppTraceGraph.4=Thread -> Function Load
+GppTraceGraph.5=Thread -> Function -> Binary Load
+GppTraceGraph.6=Thread -> Binary Load
+GppTraceGraph.7=Thread -> Binary -> Function Load
+GppTraceGraph.8=Binary Load
+GppTraceGraph.9=Binary -> Thread Load
 GppTraceGraph.cannotResolveThreadName=Cannot resolve thread name
 GppTraceGraph.cannotResolveBinaryName=Cannot resolve binary name
 GppTraceCsvPrinter.1=CSV print mode couldn't be solved
@@ -63,10 +83,15 @@
 AddressPlugin.11=Comma-Separated Value Files
 AddressPlugin.12=Change Threshold Limits...
 AddressPlugin.13=Save CPU Load as comma-separated values
+AddressPlugin.14=Show Combined CPU Graph
 AddressPlugin.15=Maximum number of functions to display
 AddressPlugin.16=Not an integer number\!\!
 AddressPlugin.17=Maximum number of functions to display
+AddressPlugin.18=Show samples of all CPUs in the same graph
+AddressPlugin.19=Show Separate CPU Graphs
 AddressPlugin.2=Unknown
+AddressPlugin.20=Show samples for different CPUs in separate graphs
+AddressPlugin.21=CPU load
 AddressPlugin.22=Fill in all graph loads
 AddressPlugin.24=Set minimum CPU load or sample count a thread, binary, or function needs so it is displayed
 AddressPlugin.3=CPU load graph
@@ -76,6 +101,7 @@
 AddressPlugin.7=Show Individual Samples
 AddressPlugin.8=No functions in the time period for 
 AddressPlugin.9=Fill in Graph Loads
+AddressPlugin.25=CPU Load
 AddrFunctionTable.threshold1=\ functions < 
 AddrFunctionTable.threshold2=\ function < 
 AddrFunctionTable.threshold3=% load (< 
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.button/META-INF/MANIFEST.MF	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.button/META-INF/MANIFEST.MF	Wed Apr 21 15:14:16 2010 +0300
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: Carbide.c++ Performance Investigator Buttons
 Bundle-SymbolicName: com.nokia.carbide.cpp.pi.button;singleton:=true
-Bundle-Version: 1.5.0.qualifier
+Bundle-Version: 2.3.0.qualifier
 Bundle-Activator: com.nokia.carbide.cpp.pi.button.ButtonPlugin
 Bundle-Vendor: Nokia
 Bundle-Localization: plugin
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.button/src/com/nokia/carbide/cpp/internal/pi/button/ui/BupMapTableViewer.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.button/src/com/nokia/carbide/cpp/internal/pi/button/ui/BupMapTableViewer.java	Wed Apr 21 15:14:16 2010 +0300
@@ -98,7 +98,7 @@
 			TableColumn tableColumn = ((TableViewer)viewer).getTable().getSortColumn();
 			int result = 0;
 			if (tableColumn == columnKeyCode) {
-				result = new Integer(((BupMapEntry)o1).keyCode).compareTo(((BupMapEntry)o2).keyCode);
+				result = Integer.valueOf(((BupMapEntry)o1).keyCode).compareTo(((BupMapEntry)o2).keyCode);
 				if (dirKeyCode != SWT.UP) {
 					result *= -1;
 				}
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.button/src/com/nokia/carbide/cpp/internal/pi/button/ui/ModifyCachedBupEventMap.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.button/src/com/nokia/carbide/cpp/internal/pi/button/ui/ModifyCachedBupEventMap.java	Wed Apr 21 15:14:16 2010 +0300
@@ -142,7 +142,7 @@
 		TableEntry entry = cachedMap.get(keyCode);
 		if (entry == null) {	
 			entry = new TableEntry();
-			cachedMap.put(new Integer(keyCode), entry);
+			cachedMap.put(Integer.valueOf(keyCode), entry);
 		}
 		entry.enumString = enumString;
 		entry.label = label;
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.button/src/com/nokia/carbide/cpp/internal/pi/button/ui/messages.properties	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.button/src/com/nokia/carbide/cpp/internal/pi/button/ui/messages.properties	Wed Apr 21 15:14:16 2010 +0300
@@ -51,13 +51,13 @@
 ButtonTabPage.cannotRemoveProfile=Cannot Remove Profile
 ButtonTabPage.isStillOpen=\ is still being used by one of the opened files, it cannot be removed.
 ButtonTabPage.profile=Profile 
-ExportBupMapGetXmlTask.selectProfile=Select Key Press Profile
+ExportBupMapGetXmlTask.selectProfile=Select Output File
 ExportBupMapGetXmlTask.enterFileName=Please enter a file name.
-ExportBupMapGetXmlTask.profilerFiles=Profiler Key Press Profile (*.xml)
+ExportBupMapGetXmlTask.profilerFiles=Key Press Profile Output File(*.xml)
 ExportBupMapGetXmlTask.allFiles=All Files (*.*)
-ExportBupMapGetXmlTask.exportProfileExplained=Select the Carbide Profiler key press profile (.xml) for export from workspace preference.
-ExportBupMapGetXmlTask.exportThisProfile=&Export the following key press profile:
-ExportBupMapGetXmlTask.keyPressProfile=Key Press Profile...
+ExportBupMapGetXmlTask.exportProfileExplained=Select the output file (.xml) for exporting the Carbide Profiler key press profile from workspace preference.
+ExportBupMapGetXmlTask.exportThisProfile=&Export the key press profile to the following .xml file :
+ExportBupMapGetXmlTask.keyPressProfile=Browse...
 ExportBupMapGetXmlTask.extensionMustBeXML=Carbide.c++ Profiler key press profile extension must be "xml".
 ExportBupMapGetXmlTask.directory=Directory 
 ExportBupMapGetXmlTask.doesNotExist=\ does not exist.
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.button/src/com/nokia/carbide/cpp/pi/button/BupEventMapManager.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.button/src/com/nokia/carbide/cpp/pi/button/BupEventMapManager.java	Wed Apr 21 15:14:16 2010 +0300
@@ -226,7 +226,7 @@
 			MapEntry entry = keyCodeMap.get(keyCode);	// support override of mapping
 			if (entry == null) {
 				entry = new MapEntry();
-				keyCodeMap.put(new Integer(keyCode), entry);
+				keyCodeMap.put(Integer.valueOf(keyCode), entry);
 			}
 			entry.enumString = enumString;
 			entry.label = label;
@@ -235,7 +235,7 @@
 		public void removeMapping(int keyCode) {
 			MapEntry entry = keyCodeMap.get(keyCode);
 			if (entry != null) {
-				keyCodeMap.remove(new Integer(keyCode));
+				keyCodeMap.remove(Integer.valueOf(keyCode));
 			}
 		}
 		
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.button/src/com/nokia/carbide/cpp/pi/button/BupTrace.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.button/src/com/nokia/carbide/cpp/pi/button/BupTrace.java	Wed Apr 21 15:14:16 2010 +0300
@@ -40,7 +40,7 @@
 	public GenericTraceGraph getTraceGraph(int graphIndex)
 	{
 		if (graphs == null) {
-			graphs = new BupTraceGraph[3];
+			graphs = new BupTraceGraph[4];
 			
 			BupUpdater.getInstance().convertToLatest(this.samples);
 			
@@ -87,11 +87,6 @@
 		synchValue = aSynchValue;
 	}
 
-	public void addSample(BupSample sample)
-	{
-		this.samples.add(sample);
-	}
-
 	public BupSample getBupSample(int number)
 	{
 		return (BupSample)this.samples.elementAt(number);
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.button/src/com/nokia/carbide/cpp/pi/button/BupTraceGraph.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.button/src/com/nokia/carbide/cpp/pi/button/BupTraceGraph.java	Wed Apr 21 15:14:16 2010 +0300
@@ -46,6 +46,7 @@
 import com.nokia.carbide.cpp.internal.pi.actions.SaveSamples;
 import com.nokia.carbide.cpp.internal.pi.analyser.NpiInstanceRepository;
 import com.nokia.carbide.cpp.internal.pi.interfaces.ISaveSamples;
+import com.nokia.carbide.cpp.internal.pi.model.GenericSample;
 import com.nokia.carbide.cpp.internal.pi.model.GenericSampledTrace;
 import com.nokia.carbide.cpp.internal.pi.plugin.model.IContextMenu;
 import com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph;
@@ -178,6 +179,7 @@
 		double scale = this.getScale();
 		int height = this.getVisualSize().height;
 		String eventName;
+		int lastXLabelEnd = -1; //the x coordinate at which the last drawn label ended
 
 		while (samples.hasMoreElements())
 		{
@@ -196,12 +198,16 @@
 			Point point = gc.stringExtent(eventName);
 			gc.dispose();
 
-			if (sa.isLabelModified()) {
-				graphics.setForegroundColor(ColorConstants.blue);
-			} else {
-				graphics.setForegroundColor(ColorConstants.red);
+			int xLabelStart = x - (point.x / 2);
+			if (xLabelStart > lastXLabelEnd){ //only draw label if it doesn't overlap with previous
+				if (sa.isLabelModified()) {
+					graphics.setForegroundColor(ColorConstants.blue);
+				} else {
+					graphics.setForegroundColor(ColorConstants.red);
+				}
+				graphics.drawString(eventName, xLabelStart, height - EVENT_BOTTOMOFLINE + 3 + EVENT_RECTHEIGHT);
+				lastXLabelEnd = x + (point.x / 2);				
 			}
-			graphics.drawString(eventName, x - (point.x / 2), height - EVENT_BOTTOMOFLINE + 3 + EVENT_RECTHEIGHT);
 
 			// events with comments will have blue rectangles; otherwise, red triangles
 			if ((sa.getComment() != null) && (!sa.getComment().equals(""))) //$NON-NLS-1$
@@ -223,10 +229,6 @@
 	{
 	}
 
-	public void refreshDataFromTrace()
-	{
-	}
-
 	public void action(String action)
 	{
 		// do/don't show events in graph
@@ -441,8 +443,9 @@
 			}
 			
 			if (eventDialog.getNewSamePropagate()) {
-				Vector<BupSample> allSamples = (Vector<BupSample>)((GenericSampledTrace)this.getTrace()).samples;
-				for (BupSample currentSample : allSamples) {
+				Vector<GenericSample> allSamples = ((GenericSampledTrace)this.getTrace()).samples;
+				for (GenericSample genericSample : allSamples) {
+					BupSample currentSample = (BupSample)genericSample;
 					if (currentSample.getKeyCode() == sample.getKeyCode()) {
 						currentSample.setLabel(eventDialog.getNewName());
 					}
@@ -501,8 +504,9 @@
 		}
 			
 		if (eventDialog.getNewSamePropagate()) {
-			Vector<BupSample> allSamples = (Vector<BupSample>)bupTrace.samples;
-			for (BupSample currentSample : allSamples) {
+			Vector<GenericSample> allSamples = bupTrace.samples;
+			for (GenericSample genericSample : allSamples) {
+				BupSample currentSample = (BupSample)genericSample;
 				if (currentSample.getKeyCode() == sample.getKeyCode()) {
 					currentSample.setLabel(eventDialog.getNewName());
 				}
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.button/src/com/nokia/carbide/cpp/pi/button/ButtonPlugin.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.button/src/com/nokia/carbide/cpp/pi/button/ButtonPlugin.java	Wed Apr 21 15:14:16 2010 +0300
@@ -33,6 +33,7 @@
 import com.nokia.carbide.cpp.internal.pi.analyser.NpiInstanceRepository;
 import com.nokia.carbide.cpp.internal.pi.analyser.ProfileVisualiser;
 import com.nokia.carbide.cpp.internal.pi.button.ui.SwitchBupMapDialog;
+import com.nokia.carbide.cpp.internal.pi.model.GenericSample;
 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.plugin.model.AbstractPiPlugin;
@@ -60,6 +61,7 @@
 public class ButtonPlugin extends AbstractPiPlugin
 			implements ITrace, IViewMenu, IEventListener, IClassReplacer, IVisualizable, IFinalizeTrace, IProvideTraceAdditionalInfo
 {
+
 	public static final String PLUGIN_ID = PIPageEditor.PI_ID + ".button";  //$NON-NLS-1$
 
 	// There will be three graphs - one each for editor pages 0, 1, 2
@@ -120,10 +122,24 @@
 		return "Button"; //$NON-NLS-1$
 	}
 
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace#getTraceTitle()
+	 */
+	public String getTraceTitle() {
+		return Messages.getString("ButtonPlugin.0"); //$NON-NLS-1$
+	}
+
 	public int getTraceId() {
 		return 7;
 	}
 
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace#parseTraceFiles(java.io.File[])
+	 */
+	public ParsedTraceData parseTraceFiles(File[] files) throws Exception {
+		throw new UnsupportedOperationException();
+	}
+
 	public ParsedTraceData parseTraceFile(File file) throws Exception 
 	{
 		try
@@ -322,13 +338,6 @@
 	public void setPageIndex(int index, int pageIndex) {
 		return;
 	}
-
-	/* (non-Javadoc)
-	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.IVisualizable#getGraphTitle(int)
-	 */
-	public String getGraphTitle(int graphIndex) {
-		return null;
-	}
 	
 	/**
 	 * Returns the shared preference store of this plugin
@@ -350,6 +359,13 @@
 			BupEventMapManager.getInstance().releaseMap(bupTrace.getCurrentBupMapInUse());
 		}
 	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.IFinalizeTrace#runOnPartOpened()
+	 */
+	public void runOnPartOpened() {
+		//no-op
+	}
 	
 	public void switchMap() {
 		BupTrace bupTrace = (BupTrace)NpiInstanceRepository.getInstance().activeUidGetTrace("com.nokia.carbide.cpp.pi.button"); //$NON-NLS-1$
@@ -360,8 +376,9 @@
 			IBupEventMap newMap = BupEventMapManager.getInstance().captureMap(dialog.getNewProfile());
 			if (bupTrace != null) {
 				boolean resetAll = dialog.resetAll();
-				Vector<BupSample> samples = bupTrace.samples;
-				for (BupSample sample : samples) {
+				Vector<GenericSample> samples = bupTrace.samples;
+				for (GenericSample genericSample : samples) {
+					BupSample sample = (BupSample)genericSample;
 					if (resetAll || !sample.isLabelModified()) {
 						sample.resetLabelToMapDefault(newMap);
 					}
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.button/src/com/nokia/carbide/cpp/pi/button/messages.properties	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.button/src/com/nokia/carbide/cpp/pi/button/messages.properties	Wed Apr 21 15:14:16 2010 +0300
@@ -49,6 +49,7 @@
 BupTraceGraph.saveSamplesForInterval=Save All Event Samples for Interval...
 BupTraceGraph.saveSamplesHeading=Time (ms),Event Name,Event Comment\n
 BupTraceParser.traceFileParsed=Button capture trace file parsed, size: 
+ButtonPlugin.0=Button and touch event
 ButtonPlugin.applyProfile=Apply New Key Press Profile
 ButtonPlugin.InternalError=Internal error in additional info
 ButtonPlugin.keyMapRemoved=Key map for this file was removed, workspace profile selection is used
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.call/META-INF/MANIFEST.MF	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.call/META-INF/MANIFEST.MF	Wed Apr 21 15:14:16 2010 +0300
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: Carbide.c++ Performance Investigator Function Calls
 Bundle-SymbolicName: com.nokia.carbide.cpp.pi.call;singleton:=true
-Bundle-Version: 1.5.0.qualifier
+Bundle-Version: 2.3.0.qualifier
 Bundle-Activator: com.nokia.carbide.cpp.pi.call.CallPlugin
 Bundle-Vendor: Nokia
 Bundle-Localization: plugin
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.call/src/com/nokia/carbide/cpp/pi/call/CallPlugin.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.call/src/com/nokia/carbide/cpp/pi/call/CallPlugin.java	Wed Apr 21 15:14:16 2010 +0300
@@ -152,6 +152,13 @@
 		return "Function Call"; //$NON-NLS-1$
 	}
 
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace#getTraceTitle()
+	 */
+	public String getTraceTitle() {
+		return Messages.getString("CallPlugin.1"); //$NON-NLS-1$
+	}
+
 	public int getTraceId() {
 		return 2;
 	}
@@ -245,16 +252,7 @@
 
 		PIPageEditor pageEditor = PIPageEditor.currentPageEditor();
 		
-		this.callVisualiser = new CallVisualiser(pageEditor, pageIndex, profileVisualiser.getTopComposite().getSashForm(), this.trace);
-	    
-		this.profileVisualiser.getTitle().setText(Messages.getString("CallPlugin.functionCallAnalysis")); //$NON-NLS-1$
-		this.profileVisualiser.getTitle().setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_WHITE));
-		this.profileVisualiser.getTitle().setFont(PIPageEditor.helvetica_12);
-
-		this.profileVisualiser.getTitle2().setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_WHITE));
-
-		this.profileVisualiser.getTimeString().setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_WHITE));
-		this.profileVisualiser.getTimeString().setFont(PIPageEditor.helvetica_10);
+		this.callVisualiser = new CallVisualiser(pageEditor, pageIndex, profileVisualiser.getTopComposite().getSashForm(), this.trace, this.profileVisualiser.getContentPane());
 
 		Object objCallList = NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.call.CallPlugin.callVisualiserList"); //$NON-NLS-1$
 		ArrayList<CallVisualiser> callVisualiserList = (ArrayList<CallVisualiser>) objCallList;
@@ -324,19 +322,12 @@
 					callVisualiserList.get(i).setStartAndEnd(event.start, event.end);
 					double startTime = PIPageEditor.currentPageEditor().getStartTime();
 					double endTime   = PIPageEditor.currentPageEditor().getEndTime();
-					profileVisualiserList.get(i).getTimeString().setText(ProfileVisualiser.getTimeInterval(startTime, endTime));
+					profileVisualiserList.get(i).updateStatusBarTimeInterval(startTime, endTime);
 				}
 			}
 		}
 	}
 
-	/* (non-Javadoc)
-	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.IVisualizable#getGraphTitle(int)
-	 */
-	public String getGraphTitle(int graphIndex) {
-		return null;
-	}
-
 	public void setActions(boolean entering, int pageIndex) {
 		if (pageIndex != this.pageIndex)
 			return;
@@ -353,4 +344,11 @@
 			PIPageEditor.getZoomToTraceAction().setEnabled(true);
 		}
 	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace#parseTraceFiles(java.io.File[])
+	 */
+	public ParsedTraceData parseTraceFiles(File[] files) throws Exception {
+		throw new UnsupportedOperationException();
+	}
 }
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.call/src/com/nokia/carbide/cpp/pi/call/CallTraceGraph.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.call/src/com/nokia/carbide/cpp/pi/call/CallTraceGraph.java	Wed Apr 21 15:14:16 2010 +0300
@@ -44,9 +44,6 @@
 	public void repaint() {
 	}
 
-	public void refreshDataFromTrace() {
-	}
-
 	public void action(String action) {
 	}
 
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.call/src/com/nokia/carbide/cpp/pi/call/CallVisualiser.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.call/src/com/nokia/carbide/cpp/pi/call/CallVisualiser.java	Wed Apr 21 15:14:16 2010 +0300
@@ -28,12 +28,20 @@
 import java.text.DecimalFormat;
 import java.util.Vector;
 
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.IJobChangeEvent;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.core.runtime.jobs.JobChangeAdapter;
 import org.eclipse.jface.action.Action;
 import org.eclipse.jface.action.ActionContributionItem;
 import org.eclipse.jface.action.IAction;
 import org.eclipse.jface.action.IContributionManager;
 import org.eclipse.jface.action.IMenuManager;
 import org.eclipse.jface.action.SubMenuManager;
+import org.eclipse.jface.dialogs.IPageChangedListener;
+import org.eclipse.jface.dialogs.PageChangedEvent;
 import org.eclipse.jface.viewers.ArrayContentProvider;
 import org.eclipse.jface.viewers.ITableLabelProvider;
 import org.eclipse.jface.viewers.LabelProvider;
@@ -44,6 +52,8 @@
 import org.eclipse.jface.wizard.WizardDialog;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.SashForm;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
 import org.eclipse.swt.events.FocusListener;
 import org.eclipse.swt.events.MouseListener;
 import org.eclipse.swt.events.SelectionAdapter;
@@ -53,6 +63,7 @@
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.Menu;
 import org.eclipse.swt.widgets.MenuItem;
@@ -60,6 +71,8 @@
 import org.eclipse.swt.widgets.TableColumn;
 import org.eclipse.swt.widgets.TableItem;
 import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IPartListener;
+import org.eclipse.ui.IWorkbenchPart;
 import org.eclipse.ui.PlatformUI;
 import org.eclipse.ui.actions.ActionFactory;
 import org.eclipse.ui.ide.IIDEActionConstants;
@@ -137,6 +150,15 @@
 	// trace associated with this display
 	private GfcTrace myTrace;
 	
+	/** the editor page this is sitting on */
+	private Composite curPage;
+	protected boolean isPageActive;
+	protected boolean needsRefresh;
+	
+	//start and end of the timeframe at the last selection event
+	private int curStart;
+	private int curEnd;
+	
 	// lists of functions, function callers, and function callees
 	private GfcFunctionItem[]  functionArray;
 	private CallerCalleeItem[] callerList;
@@ -150,6 +172,7 @@
 	protected Action functionSaveFunctionAction;
 	
 	protected static int SAMPLES_AT_ONE_TIME = 1000;
+	private Job setTimeframeJob = null;
 	
 	// class to pass sample data to the save wizard
     public class SaveSampleString implements ISaveSamples {
@@ -206,23 +229,23 @@
 			returnString +=   sample.sampleSynchTime + ",0x" //$NON-NLS-1$
 							+ Long.toHexString(sample.linkRegister)
 							+ ",\"" //$NON-NLS-1$
-							+ (sample.callerFunctionItt != null
-								? sample.callerFunctionItt.functionName
-								: sample.callerFunctionSym.functionName)
+							+ (sample.getCallerFunctionItt() != null
+								? sample.getCallerFunctionItt().getFunctionName()
+								: sample.getCallerFunctionSym().getFunctionName())
 							+ "\"," //$NON-NLS-1$
-							+ (sample.callerFunctionItt != null
-								? sample.callerFunctionItt.functionBinary.binaryName
-								: sample.callerFunctionSym.functionBinary.binaryName)
+							+ (sample.getCallerFunctionItt() != null
+								? sample.getCallerFunctionItt().getFunctionBinary().getBinaryName()
+								: sample.getCallerFunctionSym().getFunctionBinary().getBinaryName())
 							+ ",0x" //$NON-NLS-1$
 							+ Long.toHexString(sample.programCounter)
 							+ ",\"" //$NON-NLS-1$
-							+ (sample.currentFunctionItt != null
-								? sample.currentFunctionItt.functionName
-								: sample.currentFunctionSym.functionName)
+							+ (sample.getCurrentFunctionItt() != null
+								? sample.getCurrentFunctionItt().getFunctionName()
+								: sample.getCurrentFunctionSym().getFunctionName())
 							+ "\"," //$NON-NLS-1$
-							+ (sample.currentFunctionItt != null
-								? sample.currentFunctionItt.functionBinary.binaryName
-								: sample.currentFunctionSym.functionBinary.binaryName)
+							+ (sample.getCurrentFunctionItt() != null
+								? sample.getCurrentFunctionItt().getFunctionBinary().getBinaryName()
+								: sample.getCurrentFunctionSym().getFunctionBinary().getBinaryName())
 							+ "\n"; //$NON-NLS-1$
 		}
 
@@ -246,20 +269,27 @@
 		return saveSamplesItem;
 	}
 
-	public CallVisualiser(PIPageEditor pageEditor, int pageIndex, SashForm parent, GfcTrace trace)
+	public CallVisualiser(PIPageEditor pageEditor, int pageIndex, SashForm parent, GfcTrace trace, Composite curPage)
 	{
 		this.pageEditor = pageEditor;
 		this.pageIndex  = pageIndex;
 		this.parent     = parent;
 		this.myTrace    = trace;
+		this.curPage = curPage;
+		isPageActive = true;
+		needsRefresh = false;
 		
 		// let the trace know about the CallVisualiser so that unit tests can find it
 		trace.setCallVisualiser(this);
 
 		// create the 3 table viewers: caller functions, selected function, callee functions
 		createTableViewers(parent);
+		
+		createSetTimeframeJob();
+		createPageListeners();
 	}
 
+
 	public void createTableViewers(SashForm parent)
 	{
 		if (parent == null)
@@ -362,7 +392,7 @@
 		column = new TableColumn(table, SWT.RIGHT);
 		column.setText(COLUMN_HEAD_IS_CALLED);
 		column.setWidth(COLUMN_WIDTH_IS_CALLED);
-		column.setData(new Integer(COLUMN_ID_IS_CALLED));
+		column.setData(Integer.valueOf(COLUMN_ID_IS_CALLED));
 		column.setMoveable(true);
 		column.setResizable(true);
 		column.addSelectionListener(new CheckboxColumnSelectionHandler());
@@ -371,7 +401,7 @@
 		column = new TableColumn(table, SWT.RIGHT);
 		column.setText(COLUMN_HEAD_IS_CALLER);
 		column.setWidth(COLUMN_WIDTH_IS_CALLER);
-		column.setData(new Integer(COLUMN_ID_IS_CALLER));
+		column.setData(Integer.valueOf(COLUMN_ID_IS_CALLER));
 		column.setMoveable(true);
 		column.setResizable(true);
 		column.addSelectionListener(new CheckboxColumnSelectionHandler());
@@ -380,7 +410,7 @@
 		column = new TableColumn(table, SWT.LEFT);
 		column.setText(COLUMN_HEAD_FUNCTION);
 		column.setWidth(COLUMN_WIDTH_FUNCTION_NAME);
-		column.setData(new Integer(COLUMN_ID_FUNCTION));
+		column.setData(Integer.valueOf(COLUMN_ID_FUNCTION));
 		column.setMoveable(true);
 		column.setResizable(true);
 		column.addSelectionListener(new CheckboxColumnSelectionHandler());
@@ -389,7 +419,7 @@
 		column = new TableColumn(table, SWT.CENTER);
 		column.setText(COLUMN_HEAD_START_ADDR);
 		column.setWidth(COLUMN_WIDTH_START_ADDRESS);
-		column.setData(new Integer(COLUMN_ID_START_ADDR));
+		column.setData(Integer.valueOf(COLUMN_ID_START_ADDR));
 		column.setMoveable(true);
 		column.setResizable(true);
 		column.addSelectionListener(new CheckboxColumnSelectionHandler());
@@ -398,7 +428,7 @@
 		column = new TableColumn(table, SWT.LEFT);
 		column.setText(COLUMN_HEAD_IN_BINARY);
 		column.setWidth(COLUMN_WIDTH_IN_BINARY);
-		column.setData(new Integer(COLUMN_ID_IN_BINARY));
+		column.setData(Integer.valueOf(COLUMN_ID_IN_BINARY));
 		column.setMoveable(true);
 		column.setResizable(true);
 		column.addSelectionListener(new CheckboxColumnSelectionHandler());
@@ -407,7 +437,7 @@
 		column = new TableColumn(table, SWT.LEFT);
 		column.setText(COLUMN_HEAD_IN_BINARY_PATH);
 		column.setWidth(COLUMN_WIDTH_IN_BINARY_PATH);
-		column.setData(new Integer(COLUMN_ID_IN_BINARY_PATH));
+		column.setData(Integer.valueOf(COLUMN_ID_IN_BINARY_PATH));
 		column.setMoveable(true);
 		column.setResizable(true);
 		column.addSelectionListener(new CheckboxColumnSelectionHandler());
@@ -416,7 +446,7 @@
 		column = new TableColumn(table, SWT.CENTER);
 		column.setText(COLUMN_HEAD_IS_CALLED_COUNT);
 		column.setWidth(COLUMN_WIDTH_IS_CALLED_COUNT);
-		column.setData(new Integer(COLUMN_ID_IS_CALLED_COUNT));
+		column.setData(Integer.valueOf(COLUMN_ID_IS_CALLED_COUNT));
 		column.setMoveable(true);
 		column.setResizable(true);
 		column.addSelectionListener(new CheckboxColumnSelectionHandler());
@@ -428,7 +458,7 @@
 		column = new TableColumn(table, SWT.CENTER);
 		column.setText(COLUMN_HEAD_IS_CALLER_COUNT);
 		column.setWidth(COLUMN_WIDTH_IS_CALLER_COUNT);
-		column.setData(new Integer(COLUMN_ID_IS_CALLER_COUNT));
+		column.setData(Integer.valueOf(COLUMN_ID_IS_CALLER_COUNT));
 		column.setMoveable(true);
 		column.setResizable(true);
 		column.addSelectionListener(new CheckboxColumnSelectionHandler());
@@ -570,7 +600,7 @@
 		column = new TableColumn(table, SWT.RIGHT);
 		column.setText(COLUMN_HEAD_CALLER_PERCENT);
 		column.setWidth(COLUMN_WIDTH_CALLER_PERCENT);
-		column.setData(new Integer(COLUMN_ID_CALLER_PERCENT));
+		column.setData(Integer.valueOf(COLUMN_ID_CALLER_PERCENT));
 		column.setMoveable(true);
 		column.setResizable(true);
 		column.addSelectionListener(new CalledByColumnSelectionHandler());
@@ -579,7 +609,7 @@
 		column = new TableColumn(table, SWT.CENTER);
 		column.setText(COLUMN_HEAD_IS_CALLER_COUNT2);
 		column.setWidth(COLUMN_WIDTH_IS_CALLER_COUNT2);
-		column.setData(new Integer(COLUMN_ID_IS_CALLER_COUNT));
+		column.setData(Integer.valueOf(COLUMN_ID_IS_CALLER_COUNT));
 		column.setMoveable(true);
 		column.setResizable(true);
 		column.addSelectionListener(new CalledByColumnSelectionHandler());
@@ -588,7 +618,7 @@
 		column = new TableColumn(table, SWT.LEFT);
 		column.setText(COLUMN_HEAD_FUNCTION);
 		column.setWidth(COLUMN_WIDTH_FUNCTION_NAME);
-		column.setData(new Integer(COLUMN_ID_FUNCTION));
+		column.setData(Integer.valueOf(COLUMN_ID_FUNCTION));
 		column.setMoveable(true);
 		column.setResizable(true);
 		column.addSelectionListener(new CalledByColumnSelectionHandler());
@@ -597,7 +627,7 @@
 		column = new TableColumn(table, SWT.CENTER);
 		column.setText(COLUMN_HEAD_START_ADDR);
 		column.setWidth(COLUMN_WIDTH_START_ADDRESS);
-		column.setData(new Integer(COLUMN_ID_START_ADDR));
+		column.setData(Integer.valueOf(COLUMN_ID_START_ADDR));
 		column.setMoveable(true);
 		column.setResizable(true);
 		column.addSelectionListener(new CalledByColumnSelectionHandler());
@@ -606,7 +636,7 @@
 		column = new TableColumn(table, SWT.LEFT);
 		column.setText(COLUMN_HEAD_IN_BINARY);
 		column.setWidth(COLUMN_WIDTH_IN_BINARY);
-		column.setData(new Integer(COLUMN_ID_IN_BINARY));
+		column.setData(Integer.valueOf(COLUMN_ID_IN_BINARY));
 		column.setMoveable(true);
 		column.setResizable(true);
 		column.addSelectionListener(new CalledByColumnSelectionHandler());
@@ -615,7 +645,7 @@
 		column = new TableColumn(table, SWT.LEFT);
 		column.setText(COLUMN_HEAD_IN_BINARY_PATH);
 		column.setWidth(COLUMN_WIDTH_IN_BINARY_PATH);
-		column.setData(new Integer(COLUMN_ID_IN_BINARY_PATH));
+		column.setData(Integer.valueOf(COLUMN_ID_IN_BINARY_PATH));
 		column.setMoveable(true);
 		column.setResizable(true);
 		column.addSelectionListener(new CalledByColumnSelectionHandler());
@@ -624,7 +654,7 @@
 		column = new TableColumn(table, SWT.RIGHT);
 		column.setText(COLUMN_HEAD_IS_CALLER);
 		column.setWidth(COLUMN_WIDTH_IS_CALLER);
-		column.setData(new Integer(COLUMN_ID_IS_CALLER));
+		column.setData(Integer.valueOf(COLUMN_ID_IS_CALLER));
 		column.setMoveable(true);
 		column.setResizable(true);
 		column.addSelectionListener(new CalledByColumnSelectionHandler());
@@ -768,7 +798,7 @@
 		column = new TableColumn(table, SWT.RIGHT);
 		column.setText(COLUMN_HEAD_CALLEE_PERCENT);
 		column.setWidth(COLUMN_WIDTH_CALLEE_PERCENT);
-		column.setData(new Integer(COLUMN_ID_CALLEE_PERCENT));
+		column.setData(Integer.valueOf(COLUMN_ID_CALLEE_PERCENT));
 		column.setMoveable(true);
 		column.setResizable(true);
 		column.addSelectionListener(new CalledColumnSelectionHandler());
@@ -777,7 +807,7 @@
 		column = new TableColumn(table, SWT.CENTER);
 		column.setText(COLUMN_HEAD_IS_CALLED_COUNT2);
 		column.setWidth(COLUMN_WIDTH_IS_CALLED_COUNT2);
-		column.setData(new Integer(COLUMN_ID_IS_CALLED_COUNT));
+		column.setData(Integer.valueOf(COLUMN_ID_IS_CALLED_COUNT));
 		column.setMoveable(true);
 		column.setResizable(true);
 		column.addSelectionListener(new CalledColumnSelectionHandler());
@@ -786,7 +816,7 @@
 		column = new TableColumn(table, SWT.LEFT);
 		column.setText(COLUMN_HEAD_FUNCTION);
 		column.setWidth(COLUMN_WIDTH_FUNCTION_NAME);
-		column.setData(new Integer(COLUMN_ID_FUNCTION));
+		column.setData(Integer.valueOf(COLUMN_ID_FUNCTION));
 		column.setMoveable(true);
 		column.setResizable(true);
 		column.addSelectionListener(new CalledColumnSelectionHandler());
@@ -795,8 +825,8 @@
 		column = new TableColumn(table, SWT.CENTER);
 		column.setText(COLUMN_HEAD_START_ADDR);
 		column.setWidth(COLUMN_WIDTH_START_ADDRESS);
-//		column.setData(new Integer(COLUMN_ID_START_ADDR3));
-		column.setData(new Integer(COLUMN_ID_START_ADDR));
+//		column.setData(Integer.valueOf(COLUMN_ID_START_ADDR3));
+		column.setData(Integer.valueOf(COLUMN_ID_START_ADDR));
 		column.setMoveable(true);
 		column.setResizable(true);
 		column.addSelectionListener(new CalledColumnSelectionHandler());
@@ -805,8 +835,8 @@
 		column = new TableColumn(table, SWT.LEFT);
 		column.setText(COLUMN_HEAD_IN_BINARY);
 		column.setWidth(COLUMN_WIDTH_IN_BINARY);
-//		column.setData(new Integer(COLUMN_ID_IN_BINARY3));
-		column.setData(new Integer(COLUMN_ID_IN_BINARY));
+//		column.setData(Integer.valueOf(COLUMN_ID_IN_BINARY3));
+		column.setData(Integer.valueOf(COLUMN_ID_IN_BINARY));
 		column.setMoveable(true);
 		column.setResizable(true);
 		column.addSelectionListener(new CalledColumnSelectionHandler());
@@ -815,8 +845,8 @@
 		column = new TableColumn(table, SWT.LEFT);
 		column.setText(COLUMN_HEAD_IN_BINARY_PATH);
 		column.setWidth(COLUMN_WIDTH_IN_BINARY_PATH);
-//		column.setData(new Integer(COLUMN_ID_IN_BINARY_PATH3));
-		column.setData(new Integer(COLUMN_ID_IN_BINARY_PATH));
+//		column.setData(Integer.valueOf(COLUMN_ID_IN_BINARY_PATH3));
+		column.setData(Integer.valueOf(COLUMN_ID_IN_BINARY_PATH));
 		column.setMoveable(true);
 		column.setResizable(true);
 		column.addSelectionListener(new CalledColumnSelectionHandler());
@@ -825,8 +855,8 @@
 		column = new TableColumn(table, SWT.RIGHT);
 		column.setText(COLUMN_HEAD_IS_CALLED);
 		column.setWidth(COLUMN_WIDTH_IS_CALLED);
-//		column.setData(new Integer(COLUMN_ID_IS_CALLED3));
-		column.setData(new Integer(COLUMN_ID_IS_CALLED));
+//		column.setData(Integer.valueOf(COLUMN_ID_IS_CALLED3));
+		column.setData(Integer.valueOf(COLUMN_ID_IS_CALLED));
 		column.setMoveable(true);
 		column.setResizable(true);
 		column.addSelectionListener(new CalledColumnSelectionHandler());
@@ -1414,27 +1444,14 @@
 		if (this.myTrace == null)
 			return;
 		
-	    this.myTrace.parseEntries(start, end);
-	    this.functionArray = myTrace.getEntriesSorted(GfcTrace.SORT_BY_TOTAL_LOAD);
-	    this.currentFunctionTableViewer.setInput(this.functionArray);
-		
-	    updateCallerCalleeTables(null);
-	    
-	    Table table = this.currentFunctionTableViewer.getTable();
-	    
-	    if (table.getItemCount() == 0)
-	    	return;
-	    
-	    if (table.getSortColumn() == null) {
-	    	table.setSortColumn(currentFunctionDefaultColumn);
-	    	table.setSortDirection(SWT.UP);
-	    } else {
-	    	// use the user's preferred sort column, if any
-	    	boolean sortAscending = !((SharedSorter) currentFunctionTableViewer.getSorter()).getSortAscending();
-			((SharedSorter) currentFunctionTableViewer.getSorter()).setSortAscending(sortAscending);
-	    }
-	    
-	    sortAndRefresh(this.currentFunctionTableViewer, table.getSortColumn());
+		this.curStart = start;
+		this.curEnd = end;
+		needsRefresh = true;
+
+		if (isPageActive){
+			setTimeframeJob.cancel();
+			setTimeframeJob.schedule();
+		}
 	}
 
 	private static class CallerCalleeItem {
@@ -1997,6 +2014,137 @@
 		
 		return copyString;
 	}
+
+	private void createSetTimeframeJob() {
+		//this functionality used to be in the setStartEnd() method
+		//but now the long-running calculations are in a background job
+		//and the short-running refresh of table viewers is done in the UI thread
+		
+		setTimeframeJob = new Job("Updating function hierarchy..."){
+			@Override
+			protected IStatus run(IProgressMonitor monitor) {
+				//run the time consuming calculations in the background
+				if (myTrace == null){
+					return Status.CANCEL_STATUS;
+				}				
+				
+				needsRefresh = false;
+			    myTrace.parseEntries(curStart, curEnd);			    
+			    functionArray = myTrace.getEntriesSorted(GfcTrace.SORT_BY_TOTAL_LOAD);
+			    
+			    return Status.OK_STATUS;
+			}
+		};
+		
+		setTimeframeJob.addJobChangeListener(new JobChangeAdapter() {
+			public void done(IJobChangeEvent event) {
+				if (event.getResult().isOK()) {
+					Display.getDefault().syncExec( new Runnable() {
+						public void run () {
+							
+							if (!currentFunctionTableViewer.getControl().isDisposed()){
+								
+								//updating the table viewers has to be done in the UI thread (this operation doesn't take long)
+							    currentFunctionTableViewer.setInput(functionArray);
+								
+							    updateCallerCalleeTables(null);
+							    
+							    Table table = currentFunctionTableViewer.getTable();
+							    
+							    if (table.getItemCount() == 0)
+							    	return;
+							    
+							    if (table.getSortColumn() == null) {
+							    	table.setSortColumn(currentFunctionDefaultColumn);
+							    	table.setSortDirection(SWT.UP);
+							    } else {
+							    	// use the user's preferred sort column, if any
+							    	boolean sortAscending = !((SharedSorter) currentFunctionTableViewer.getSorter()).getSortAscending();
+									((SharedSorter) currentFunctionTableViewer.getSorter()).setSortAscending(sortAscending);
+							    }
+							    
+							    sortAndRefresh(currentFunctionTableViewer, table.getSortColumn());
+								
+							}
+						}
+					});
+
+				} else {
+					//unsuccessful operation: we still need to refresh
+					needsRefresh = true;
+				}
+			}
+		});
+		
+		setTimeframeJob.setUser(true); //show a progress dialog to the user
+		
+		currentFunctionTableViewer.getControl().addDisposeListener(new DisposeListener(){
+			public void widgetDisposed(DisposeEvent e) {
+				setTimeframeJob.cancel();
+			}
+		});
+	}
+    
+    private void createPageListeners() {
+    	final IPageChangedListener pageChangeListener = new IPageChangedListener(){
+
+			/* (non-Javadoc)
+			 * @see org.eclipse.jface.dialogs.IPageChangedListener#pageChanged(org.eclipse.jface.dialogs.PageChangedEvent)
+			 */
+			public void pageChanged(PageChangedEvent event) {
+				isPageActive = (event.getSelectedPage() == CallVisualiser.this.curPage);//compare on reference
+				if (isPageActive && needsRefresh){ 
+					// if this ProfileVisualiser is the page being activated, 
+					// check if the time frame selection needs updating
+					setTimeframeJob.cancel();
+					setTimeframeJob.schedule();
+				}
+				
+			}
+			
+		};
+    	final IPartListener partListener = new IPartListener(){
+
+			public void partActivated(IWorkbenchPart part) {
+				if (part instanceof PIPageEditor){
+					PIPageEditor editor = (PIPageEditor) part;
+					isPageActive = (editor.getActivePage() == pageIndex);
+					if (isPageActive && needsRefresh){ 
+						setTimeframeJob.cancel();
+						setTimeframeJob.schedule();
+					}
+				}
+			}
+
+			public void partBroughtToTop(IWorkbenchPart part) {
+				// nothing to do
+			}
+
+			public void partClosed(IWorkbenchPart part) {
+				if (part instanceof PIPageEditor){
+					//remove listeners
+					PIPageEditor editor = (PIPageEditor) part;
+					editor.removePageChangedListener(pageChangeListener);
+					editor.getSite().getPage().removePartListener(this);
+				}
+			}
+
+			public void partDeactivated(IWorkbenchPart part) {
+				// nothing to do
+			}
+
+			public void partOpened(IWorkbenchPart part) {
+				// nothing to do
+			}
+    		
+    	};
+    	
+    	
+    	
+		PIPageEditor.currentPageEditor().addPageChangedListener(pageChangeListener);
+		PIPageEditor.currentPageEditor().getSite().getPage().addPartListener(partListener);
+    	
+	}
 	
     // added to give JUnit tests access
 	public TableViewer getCallerViewer() {
@@ -2017,4 +2165,5 @@
 	public void setCurrentMenuTable(Table currentMenuTable) {
 		this.currentMenuTable = currentMenuTable;
 	}
+
 }
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.call/src/com/nokia/carbide/cpp/pi/call/GfcFunctionItem.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.call/src/com/nokia/carbide/cpp/pi/call/GfcFunctionItem.java	Wed Apr 21 15:14:16 2010 +0300
@@ -242,7 +242,7 @@
 	public void addUnknownCaller(Integer callTime)
 	{
 		// store unknown callers with an address -1
-		if (!this.callerData.containsKey(new Long(-1)) )
+		if (!this.callerData.containsKey(Long.valueOf(-1)) )
 		{
 			GfcFunctionItemData newData = new GfcFunctionItemData();
 			newData.function = null;
@@ -250,12 +250,12 @@
 			newData.callTimes.add(callTime);
 
 			// add a new caller
-			this.callerData.put(new Long(-1),newData);
+			this.callerData.put(Long.valueOf(-1),newData);
 		}
 		else
 		{
 			// just add the call count of an existing caller
-			GfcFunctionItemData oldData = (GfcFunctionItemData)this.callerData.get(new Long(-1));
+			GfcFunctionItemData oldData = (GfcFunctionItemData)this.callerData.get(Long.valueOf(-1));
 			this.totalCallerAmount++;
 			oldData.callTimes.add(callTime);
 		}
@@ -266,7 +266,7 @@
 	// this function has been called
 	public void addCaller(GfcFunctionItem caller, Integer callTime)
 	{
-		Long address = new Long(caller.address);
+		Long address = Long.valueOf(caller.address);
 		if (!this.callerData.containsKey(address))
 		{
 			GfcFunctionItemData newData = new GfcFunctionItemData();
@@ -293,7 +293,7 @@
 	// this function has called another function
 	public void addCallee(GfcFunctionItem callee, Integer callTime)
 	{
-		Long address = new Long(callee.address);
+		Long address = Long.valueOf(callee.address);
 		if (!this.calleeData.containsKey(address))
 		{
 			GfcFunctionItemData newData = new GfcFunctionItemData();
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.call/src/com/nokia/carbide/cpp/pi/call/GfcSample.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.call/src/com/nokia/carbide/cpp/pi/call/GfcSample.java	Wed Apr 21 15:14:16 2010 +0300
@@ -20,11 +20,12 @@
 import java.util.Vector;
 
 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.FunctionResolver;
 import com.nokia.carbide.cpp.internal.pi.model.GenericSampleWithFunctions;
+import com.nokia.carbide.cpp.internal.pi.model.IFunction;
 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.model.UnresolvedFunction;
 import com.nokia.carbide.cpp.pi.address.GppSample;
 import com.nokia.carbide.cpp.pi.address.GppTrace;
 
@@ -39,11 +40,11 @@
   public long linkRegister;
   public long sampleNumber;
 
-  public Function callerFunctionSym;
-  public Function currentFunctionSym;
+  private IFunction callerFunctionSym;
+  private IFunction currentFunctionSym;
   
-  public Function callerFunctionItt;
-  public Function currentFunctionItt;
+  private IFunction callerFunctionItt;
+  private IFunction currentFunctionItt;
   
   public GfcSample(long programCounter, long linkRegister, long sampleNumber, long sampleSynchTime)
   {
@@ -53,6 +54,7 @@
     this.sampleSynchTime = sampleSynchTime;
   }
 
+  @Override
   public void resolveFunction(FunctionResolver res)
   {
 	  if (res.getResolverName().equals("Symbol")) //$NON-NLS-1$
@@ -62,7 +64,7 @@
 		  if (gppSamples != null && index < gppSamples.size()) {
 			  GppSample gppSample = (GppSample)gppSamples.get(index);
 			  if (gppSample.programCounter == programCounter)
-				  this.currentFunctionSym = gppSample.currentFunctionSym;
+				  this.currentFunctionSym = gppSample.getCurrentFunctionSym();
 			  else
 				  this.currentFunctionSym = res.findFunctionForAddress(programCounter);
 		  } else
@@ -74,22 +76,101 @@
 			  this.callerFunctionItt  = res.findFunctionForAddress(linkRegister);
 		  if (this.currentFunctionSym == null) {
 			  GppSample gppSample = (GppSample)gppSamples.get((int)this.sampleNumber);
-			  if (gppSample.programCounter == programCounter)
-				  this.currentFunctionItt = gppSample.currentFunctionItt;
+			  if (gppSample.programCounter == programCounter){
+				  IFunction function = gppSample.getCurrentFunctionItt();
+				  
+				  //if it's an unresolved function don't store it, we can generate it later
+				  if (!(function instanceof UnresolvedFunction)){
+					  this.currentFunctionItt = function;					  
+				  }
+			  }
 			  else
-				  this.currentFunctionItt = res.findFunctionForAddress(programCounter);		  
+				  this.currentFunctionItt = res.findFunctionForAddress(programCounter, sampleSynchTime);		  
 		  }
 	  }
   }
   
-  public String toString()
+	 /**
+	  * Getter for the caller function (resolved from Symbol file)
+	 * @return the callerFunctionSym
+	 */
+	public IFunction getCallerFunctionSym() {
+		return callerFunctionSym;
+	}
+	
+	/**
+	  * Setter for the caller function (resolved from Symbol file)
+	 * @param callerFunctionSym the callerFunctionSym to set
+	 */
+	public void setCallerFunctionSym(IFunction callerFunctionSym) {
+		this.callerFunctionSym = callerFunctionSym;
+	}
+	
+	/**
+	  * Getter for the current function (resolved from Symbol file)
+	 * @return the currentFunctionSym
+	 */
+	public IFunction getCurrentFunctionSym() {
+		return currentFunctionSym;
+	}
+	
+	/**
+	  * Setter for the current function (resolved from Symbol file)
+	 * @param currentFunctionSym the currentFunctionSym to set
+	 */
+	public void setCurrentFunctionSym(IFunction currentFunctionSym) {
+		this.currentFunctionSym = currentFunctionSym;
+	}
+
+	/**
+	  * Getter for the caller function (resolved from dynamic binary trace)
+	 * @return the callerFunctionItt
+	 */
+	public IFunction getCallerFunctionItt() {
+		if (callerFunctionItt == null && callerFunctionSym == null){
+			return new UnresolvedFunction(linkRegister);
+		}
+		
+		return callerFunctionItt;
+	}
+	
+	/**
+	  * Setter for the caller function (resolved from dynamic binary trace)
+	 * @param callerFunctionItt the callerFunctionItt to set
+	 */
+	public void setCallerFunctionItt(IFunction callerFunctionItt) {
+		this.callerFunctionItt = callerFunctionItt;
+	}
+	
+	/**
+	  * Getter for the current function (resolved from dynamic binary trace)
+	 * @return the currentFunctionItt
+	 */
+	public IFunction getCurrentFunctionItt() {
+		if (currentFunctionItt == null && currentFunctionSym == null){
+			return new UnresolvedFunction(programCounter);
+		}
+		
+		return currentFunctionItt;
+	}
+	
+	/**
+	  * Getter for the current function (resolved from dynamic binary trace)
+	 * @param currentFunctionItt the currentFunctionItt to set
+	 */
+	public void setCurrentFunctionItt(IFunction currentFunctionItt) {
+		this.currentFunctionItt = currentFunctionItt;
+	}
+
+	@Override
+public String toString()
   {
   	return "Gfc:#" + this.sampleSynchTime //$NON-NLS-1$
   			+ " @0x" + Long.toHexString(this.programCounter) //$NON-NLS-1$
   			+ " fS:" //$NON-NLS-1$
-  			+ ((this.currentFunctionSym == null || (this.currentFunctionSym.functionName == null)) ? "" : this.currentFunctionSym.functionName) //$NON-NLS-1$
+  			+ ((this.currentFunctionSym == null || (this.currentFunctionSym.getFunctionName() == null)) ? "" : this.currentFunctionSym.getFunctionName()) //$NON-NLS-1$
   			+ " cS:" //$NON-NLS-1$
-  			+ ((this.callerFunctionSym  == null || (this.callerFunctionSym.functionName  == null)) ? "" : this.callerFunctionSym.functionName); //$NON-NLS-1$
+  			+ ((this.callerFunctionSym  == null || (this.callerFunctionSym.getFunctionName()  == null)) ? "" : this.callerFunctionSym.getFunctionName()); //$NON-NLS-1$
   }
   
   public static void setAddressTraceSamples() {
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.call/src/com/nokia/carbide/cpp/pi/call/GfcTrace.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.call/src/com/nokia/carbide/cpp/pi/call/GfcTrace.java	Wed Apr 21 15:14:16 2010 +0300
@@ -29,7 +29,7 @@
 import com.nokia.carbide.cpp.internal.pi.model.GenericSampledTraceWithFunctions;
 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.GenericTraceGraph;
+import com.nokia.carbide.cpp.pi.visual.IGenericTraceGraph;
 
 
 public class GfcTrace extends GenericSampledTraceWithFunctions
@@ -206,35 +206,35 @@
   	    CallerCallee caller = new CallerCallee();
   	    CallerCallee callee = new CallerCallee();
 
-		if (  (gSam.callerFunctionSym == null || gSam.callerFunctionSym.functionName.endsWith(Messages.getString("GfcTrace.functionNotFound"))) //$NON-NLS-1$
-			&& gSam.callerFunctionItt != null) //$NON-NLS-1$
+		if (  (gSam.getCallerFunctionSym() == null || gSam.getCallerFunctionSym().getFunctionName().endsWith(Messages.getString("GfcTrace.functionNotFound"))) //$NON-NLS-1$
+			&& gSam.getCallerFunctionItt() != null) //$NON-NLS-1$
 		{
-			caller.functionName = gSam.callerFunctionItt.functionName;
-    		caller.startAdress  = gSam.callerFunctionItt.startAddress;
-			caller.binaryName   = gSam.callerFunctionItt.functionBinary.binaryName;
+			caller.functionName = gSam.getCallerFunctionItt().getFunctionName();
+    		caller.startAdress  = gSam.getCallerFunctionItt().getStartAddress();
+			caller.binaryName   = gSam.getCallerFunctionItt().getFunctionBinary().getBinaryName();
 			caller.symbolParsed = false;
 		}
 		else
 		{
-			caller.functionName = gSam.callerFunctionSym.functionName;
-			caller.startAdress  = gSam.callerFunctionSym.startAddress;
-			caller.binaryName   = gSam.callerFunctionSym.functionBinary.binaryName;
+			caller.functionName = gSam.getCallerFunctionSym().getFunctionName();
+			caller.startAdress  = gSam.getCallerFunctionSym().getStartAddress();
+			caller.binaryName   = gSam.getCallerFunctionSym().getFunctionBinary().getBinaryName();
 			caller.symbolParsed = Boolean.valueOf(true);
 		}
 		
-		if (   (gSam.currentFunctionSym == null || gSam.currentFunctionSym.functionName.endsWith(Messages.getString("GfcTrace.functionNotFound"))) //$NON-NLS-1$
-			&& gSam.currentFunctionItt != null) //$NON-NLS-1$
+		if (   (gSam.getCurrentFunctionSym() == null || gSam.getCurrentFunctionSym().getFunctionName().endsWith(Messages.getString("GfcTrace.functionNotFound"))) //$NON-NLS-1$
+			&& gSam.getCurrentFunctionItt() != null) //$NON-NLS-1$
 		{
-			callee.functionName = gSam.currentFunctionItt.functionName;
-    		callee.startAdress  = gSam.currentFunctionItt.startAddress;
-			callee.binaryName   = gSam.currentFunctionItt.functionBinary.binaryName;
+			callee.functionName = gSam.getCurrentFunctionItt().getFunctionName();
+    		callee.startAdress  = gSam.getCurrentFunctionItt().getStartAddress();
+			callee.binaryName   = gSam.getCurrentFunctionItt().getFunctionBinary().getBinaryName();
 			callee.symbolParsed = Boolean.valueOf(false);
 		}
 		else
 		{
-			callee.functionName = gSam.currentFunctionSym.functionName;
-    		callee.startAdress  = gSam.currentFunctionSym.startAddress;
-			callee.binaryName   = gSam.currentFunctionSym.functionBinary.binaryName;
+			callee.functionName = gSam.getCurrentFunctionSym().getFunctionName();
+    		callee.startAdress  = gSam.getCurrentFunctionSym().getStartAddress();
+			callee.binaryName   = gSam.getCurrentFunctionSym().getFunctionBinary().getBinaryName();
 			callee.symbolParsed = Boolean.valueOf(true);
 		}
 
@@ -284,8 +284,8 @@
 
 	    if (!caller.equals(callee))
 	    {
-	    	callee.addCaller(caller, new Integer((int)sample));
-	    	caller.addCallee(callee, new Integer((int)sample));
+	    	callee.addCaller(caller, Integer.valueOf((int)sample));
+	    	caller.addCallee(callee, Integer.valueOf((int)sample));
 	    }
 	}
   
@@ -459,7 +459,7 @@
 	  	{
 	  		ItemSorter is = (ItemSorter)elements.nextElement();
 	  		f[i++] = is.item;
-	  		this.parsedGfcTrace.put(new Long(is.item.address), is.item);
+	  		this.parsedGfcTrace.put(Long.valueOf(is.item.address), is.item);
 	  	}
   	
 	  	return f;
@@ -518,19 +518,7 @@
   			}
   		}
   	}
-  	
-  	// this method is not used
-  	public GenericTraceGraph getTraceGraph()
-  	{
-  		return null;
-  	}
-
-  	// this method is not used
-  	public GenericTraceGraph getTraceGraph(int graphNumber)
-  	{
-		return null;
-	}
-	
+  		
 	public CallVisualiser getCallVisualiser()
 	{
 		return this.callVisualiser;
@@ -556,23 +544,4 @@
 		return this.completeGfcTrace;
 	}
 
-	@Override
-	public void finalizeTrace()
-	{
-		for (int i = 0; i < samples.size(); i++) {
-			GfcSample sample = (GfcSample) samples.get(i);
-			
-			if (sample.currentFunctionItt == null && sample.currentFunctionSym == null) {
-				sample.currentFunctionItt = new Function(Messages.getString("GfcTrace.functionNotFound1") + Long.toHexString(sample.programCounter) + Messages.getString("GfcTrace.functionNotFound2"), //$NON-NLS-1$ //$NON-NLS-2$
-						new Long(sample.programCounter),
-						Messages.getString("GfcTrace.binaryNotFound1") +  Long.toHexString(sample.programCounter) + Messages.getString("GfcTrace.binaryNotFound2")); //$NON-NLS-1$ //$NON-NLS-2$
-			}
-			
-			if (sample.callerFunctionItt == null && sample.callerFunctionSym == null) {
-				sample.callerFunctionItt = new Function(Messages.getString("GfcTrace.functionNotFound1") + Long.toHexString(sample.linkRegister) + Messages.getString("GfcTrace.functionNotFound2"), //$NON-NLS-1$ //$NON-NLS-2$
-						new Long(sample.linkRegister),
-						Messages.getString("GfcTrace.binaryNotFound1") +  Long.toHexString(sample.linkRegister) + Messages.getString("GfcTrace.binaryNotFound2")); //$NON-NLS-1$ //$NON-NLS-2$
-			}
-		}
-	}
 }
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.call/src/com/nokia/carbide/cpp/pi/call/GfcTraceParser.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.call/src/com/nokia/carbide/cpp/pi/call/GfcTraceParser.java	Wed Apr 21 15:14:16 2010 +0300
@@ -196,12 +196,12 @@
 	  	  					//System.out.println("REP: pc:"+Long.toHexString(pc)+" lr:"+Long.toHexString(lr)+" sa:"+sa);
 	  	  					// sometimes the first address/thread sample had to be discarded,
 	  	  					// so 2nd call sample matches first address/thread sample
-	  	  					if (   sampleTime == gppSample.sampleSynchTime && gppSample.sampleSynchTime == samplingInterval * 2
+	  	  					if ( gppSample != null &&  sampleTime == gppSample.sampleSynchTime && gppSample.sampleSynchTime == samplingInterval * 2
 	  	  						&& this.completeGfcTrace.size() == 1) {
 	  	  						// replace the first sample with this one
 	  	  						this.completeGfcTrace.remove(0);
 	  	  					}
-	  	  					this.completeGfcTrace.add(new Long[]{new Long(sampleTime),new Long(pc), new Long(lr)});
+	  	  					this.completeGfcTrace.add(new Long[]{Long.valueOf(sampleTime),Long.valueOf(pc), Long.valueOf(lr)});
 	  					}
 	  				}
 	  				else
@@ -236,12 +236,12 @@
 	  					//System.out.println("pc:"+Long.toHexString(pc)+" lr:"+Long.toHexString(lr)+" sa:"+sa);
   	  					// sometimes the first address/thread sample had to be discarded,
   	  					// so 2nd call sample matches first address/thread sample
-  	  					if (   sampleTime == gppSample.sampleSynchTime && gppSample.sampleSynchTime == samplingInterval * 2
+  	  					if ( gppSample != null &&   sampleTime == gppSample.sampleSynchTime && gppSample.sampleSynchTime == samplingInterval * 2
   	  						&& this.completeGfcTrace.size() == 1) {
   	  						// replace the first sample with this one
   	  						this.completeGfcTrace.remove(0);
   	  					}
-	  					this.completeGfcTrace.add(new Long[]{new Long(sampleTime),new Long(pc), new Long(lr)});
+	  					this.completeGfcTrace.add(new Long[]{Long.valueOf(sampleTime),Long.valueOf(pc), Long.valueOf(lr)});
 	  					
 	  					data[0] = pc;
 	  					data[1] = lr;
@@ -336,7 +336,7 @@
 		    }
 		    previousSample = sample;
 	
-		    this.completeGfcTrace.add(new Long[]{new Long(sample),new Long(programCounter), new Long(linkRegister)});
+		    this.completeGfcTrace.add(new Long[]{Long.valueOf(sample),Long.valueOf(programCounter), Long.valueOf(linkRegister)});
 		    byteCount += 12;
 	    }
 //		setProgressBarString("Done");
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.call/src/com/nokia/carbide/cpp/pi/call/messages.properties	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.call/src/com/nokia/carbide/cpp/pi/call/messages.properties	Wed Apr 21 15:14:16 2010 +0300
@@ -49,6 +49,7 @@
 CallVisualiser.calleeFunctions=Called by Selected Function
 CallVisualiser.calls=Calls
 CallPlugin.0=Call trace failed to create UI
+CallPlugin.1=Function call
 CallVisualiser.selectFunction=Select One Function
 CallVisualiser.selectedFunction=Select One Function
 CallVisualiser.callingSelectedFunction=Functions calling the selected function
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.core/META-INF/MANIFEST.MF	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.core/META-INF/MANIFEST.MF	Wed Apr 21 15:14:16 2010 +0300
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: Carbide.c++ Performance Investigator Core
 Bundle-SymbolicName: com.nokia.carbide.cpp.pi.core;singleton:=true
-Bundle-Version: 1.5.0.qualifier
+Bundle-Version: 2.3.0.qualifier
 Bundle-Activator: com.nokia.carbide.cpp.pi.core.PICorePlugin
 Bundle-Vendor: Nokia
 Bundle-Localization: plugin
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/META-INF/MANIFEST.MF	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/META-INF/MANIFEST.MF	Wed Apr 21 15:14:16 2010 +0300
@@ -1,9 +1,6 @@
 Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
-Bundle-Name: Carbide.c++ Performance Investigator Help
+Bundle-Name: Carbide.c++ Extensions - Performance Investigator Help Plug-in
 Bundle-SymbolicName: com.nokia.carbide.cpp.pi.doc.user;singleton:=true
-Bundle-Version: 1.5.0.qualifier
+Bundle-Version: 2.3.0.qualifier
 Bundle-Vendor: Nokia
-Bundle-Localization: plugin
-Require-Bundle: org.eclipse.help,
- org.eclipse.ui.cheatsheets
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/about.html	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,22 @@
+<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.0//EN”>
+<html>
+<head>
+  <title>About</title>
+  <meta http-equiv="content-type"
+  content="application/xhtml+xml; charset=iso-8859-1" charset="ISO-8859-1”">
+</head>
+
+<body lang="”EN-US”">
+<h2>About This Content</h2>
+
+<p>April 21, 2010</p>
+
+<h3>Copyright</h3>
+
+<p>Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights
+reserved. <br>
+License: <a
+href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>
+</p>
+</body>
+</html>
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/Getting_Started/GS_index.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/Getting_Started/GS_index.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -19,6 +19,6 @@
 <p class="note"><b>NOTE</b> The recommended amount of memory is at least 1Gbytes. If you open or import several large profiler data files, the Java Virtual Machine executing Carbide.c++ may run out of memory.
 <br /> <br />
 To allocate more memory, edit the <span class="code">Carbide.c++.ini</span> file (typically in the Carbide.c++ folder that contains <span class="code">Carbide.c++.exe</span>). For example, for 1GBytes, edit <span class="code">Carbide.c++.ini</span> to contain <span class="code">-Xmx1024m</span> and then restart Carbide.c++.</p>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
    </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/Getting_Started/example_project.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/Getting_Started/example_project.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -1,49 +1,122 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html><head>
-<title>Examining a Profiling Project</title>
-<link href="../../book.css" rel="stylesheet" type="text/css" />
-</head><body>
-<h2><a name="example" id="example"></a>Examining a Profiling Project</h2>
-<p>The purpose of creating a profiling use case is to analyze the performance of Symbian OS applications. In general, the objective is to define the behavior of an application and its environment when they are interacting. When designing a profiling use case, it helps to document the process and save log files.</p>
-<p>Existing test cases created by application developers or test personnel can be used as a template. However, consider the following when designing and preparing a test of a profiling use case.</p>
-<p>High Profiler sampling rates can cause trace files to grow excessively large, especially if the test lasts for a long time. Therefore, it is recommended that the duration of the test be as short as possible. The maximum duration of a profiling test is typically two to three minutes. There should also be reasonable gaps between input events so that specific events can be easily detected and distinguished from the trace log.</p>
-<p>The following example describes in a high-level how to search for performance bottlenecks. Refer to Figure 1 to illustrate an example of determining time spent in a particular application and the related functions consuming most of the CPU time.</p>
-<p align="center"><img src="../images/GS_example_figure1.png" width="679" height="574" /></p>
-<p align="center" class="figure">Figure 1. Examining a Specific Application</p>
-<p align="left">As shown in Figure 1, examine the thread load graph and select the time interval of interest. In this example, the selected time interval is 21.010 to 21.970 seconds.</p>
-<p align="left">Figure 1 indicates the three most CPU time consuming threads in the time frame 21-22 seconds:</p>
-<ul>
-  <li>23.02% Null</li>
-  <li>16.56% Wserv_36 </li>
-  <li>15.31% Main_295</li>
-</ul>
-<p>Notice that only <span class="code">Null (ekern.exe[1]::Null_0)</span> and<span class="code"> Wserv_36</span> are checked and thus are shown in the graph. To add or remove threads from the graph, use the shift and control keys to check or uncheck multiple lines. Right-click to display a context menu for more options.</p>
-<p>You can determine which binaries are executed by the threads during the 21-22 second interval by right-clicking inside the table and selecting <strong>Thread &gt; Binary</strong>. This will change the graph displayed to the binary load graph in Figure 2.</p>
-<p align="center"><img src="../images/GS_example_figure2.png" width="679" height="574" /></p>
-<p align="center" class="figure">Figure 2. Binary Load Graph </p>
-<p>As shown in Figure 2, this application spends 21.25% of the time in the <span class="code">_reka2_ekern.exe</span> binary. At the lowest level, you can find out which functions are executed by the binaries that execute during the 21-22 second interval by right-clicking inside either table and selecting <strong>Thread &gt; Binary &gt; Function</strong>. This will change the graph displayed to the function load graph in Figure 3.</p>
-<p class="note"><strong>NOTE:</strong> For each selected binary in Figure 2, the Analyser graphs all of
-that binary's samples, just as if you had selected that binary in the Binaries tab. The graph does not only
-show binary samples that are also associated with threads
-<span class="code">ekern.exe[1]::Null_0</span> and<span class="code"> Wserv_36</span>.
-We expect to deliver that functionality in a future release. 
-Keep this in mind as you drill down into a specific thread, binary, or function.</p>
-<p align="center"><img src="../images/GS_example_figure3.png" width="679" height="574" /></p>
-<p align="center" class="figure">Figure 3. Function Load Graph</p>
-<p>Figure 3 shows that 9.90% of the execution time was spent in a single function called NKern::RestoreInterrupts(int), within the _reka2_ekern.exe binary. In the Function table scroll to see the <strong>In Binary</strong> column to determine the binary containing the function.</p>
-<p>Select the Function Calls tab to view the Function Call Analysis tables, as shown in Figure 4.</p>
-<p align="center"><img src="../images/GS_example_figure4.png" width="682" height="574" /></p>
-<p align="center" class="figure">Figure 4. Function Call Analysis</p>
-<p align="left">Individual functions can be selected to determine, within the time frame 21-22 seconds, which functions called the selected function and which functions were called by the selected function. You can sort functions by clicking the headings provided for each column.</p>
-<p align="left"><strong>Related references</strong></p>
-<ul>
-  <li><a href="../reference/analyzer/GUI_tour.htm">Analyzer GUI Controls </a></li>
-  <li><a href="../reference/analyzer/analyzing_table_data.htm">Analyzing Table Data</a> </li>
-  <li><a href="../reference/analyzer/thread_load.htm">Thread Load</a></li>
-  <li><a href="../reference/analyzer/binary_load.htm">Binary Load</a></li>
-  <li><a href="../reference/analyzer/function_load.htm">Function Load</a></li>
-  <li><a href="../reference/analyzer/function_calls.htm">Function Calls</a></li>
-</ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br />License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
-
-</body>
-</html>
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html>
+<head>
+  <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
+  <title>Examining a Profiling Project</title>
+  <link href="../../book.css" rel="stylesheet" type="text/css" />
+</head>
+
+<body>
+<h2><a name="example" id="example"></a>Examining a Profiling Project</h2>
+
+<p>The purpose of creating a profiling use case is to analyze the performance
+of Symbian OS applications. In general, the objective is to define the behavior
+of an application and its environment when they are interacting. When designing
+a profiling use case, it helps to document the process and save log files.</p>
+
+<p>Existing test cases created by application developers or test personnel can
+be used as a template. However, consider the following when designing and
+preparing a test of a profiling use case.</p>
+
+<p>High Profiler sampling rates can cause trace files to grow excessively
+large, especially if the test lasts for a long time. Therefore, it is
+recommended that the duration of the test be as short as possible. The maximum
+duration of a profiling test is typically two to three minutes. There should
+also be reasonable gaps between input events so that specific events can be
+easily detected and distinguished from the trace log.</p>
+
+<p>The following example describes in a high-level how to search for
+performance bottlenecks. Refer to Figure 1 to illustrate an example of
+determining time spent in a particular application and the related functions
+consuming most of the CPU time.</p>
+
+<p align="center"><img src="../images/GS_example_figure1.png" /></p>
+
+<p align="center" class="figure">Figure 1. Examining a Specific Application</p>
+
+<p align="left">As shown in Figure 1, examine the thread load graph and select
+the time interval of interest. In this example, the selected time interval is
+21.010 to 21.970 seconds.</p>
+
+<p align="left">Figure 1 indicates the three most CPU time consuming threads in
+the time frame 21-22 seconds:</p>
+<ul>
+  <li>23.02% Null</li>
+  <li>16.56% Wserv_36 </li>
+  <li>15.31% Main_295</li>
+</ul>
+
+<p>Notice that only <span class="code">Null (ekern.exe[1]::Null_0)</span>
+and<span class="code">Wserv_36</span> are checked and thus are shown in the
+graph. To add or remove threads from the graph, use the shift and control keys
+to check or uncheck multiple lines. Right-click to display a context menu for
+more options.</p>
+
+<p>You can determine which binaries are executed by the threads during the
+21-22 second interval by right-clicking inside the table and selecting
+<strong>Thread &gt; Binary</strong>. This will change the graph displayed to
+the binary load graph in Figure 2.</p>
+
+<p align="center"><img src="../images/GS_example_figure2.png" /></p>
+
+<p align="center" class="figure">Figure 2. Binary Load Graph </p>
+
+<p>As shown in Figure 2, this application spends 21.25% of the time in the
+<span class="code">_reka2_ekern.exe</span> binary. At the lowest level, you can
+find out which functions are executed by the binaries that execute during the
+21-22 second interval by right-clicking inside either table and selecting
+<strong>Thread &gt; Binary &gt; Function</strong>. This will change the graph
+displayed to the function load graph in Figure 3.</p>
+
+<p class="note"><strong>NOTE:</strong> For each selected binary in Figure 2,
+the Analyser graphs all of that binary's samples, just as if you had selected
+that binary in the Binaries tab. The graph does not only show binary samples
+that are also associated with threads <span
+class="code">ekern.exe[1]::Null_0</span> and<span class="code">Wserv_36</span>.
+We expect to deliver that functionality in a future release. Keep this in mind
+as you drill down into a specific thread, binary, or function.</p>
+
+<p align="center"><img src="../images/GS_example_figure3.png" width="679"
+height="574" /></p>
+
+<p align="center" class="figure">Figure 3. Function Load Graph</p>
+
+<p>Figure 3 shows that 9.90% of the execution time was spent in a single
+function called NKern::RestoreInterrupts(int), within the _reka2_ekern.exe
+binary. In the Function table scroll to see the <strong>In Binary</strong>
+column to determine the binary containing the function.</p>
+
+<p>Select the Function Calls tab to view the Function Call Analysis tables, as
+shown in Figure 4.</p>
+
+<p align="center"><img src="../images/GS_example_figure4.png" width="682"
+height="574" /></p>
+
+<p align="center" class="figure">Figure 4. Function Call Analysis</p>
+
+<p align="left">Individual functions can be selected to determine, within the
+time frame 21-22 seconds, which functions called the selected function and
+which functions were called by the selected function. You can sort functions by
+clicking the headings provided for each column.</p>
+
+<p align="left"><strong>Related references</strong></p>
+<ul>
+  <li><a href="../reference/analyzer/GUI_tour.htm">Analyzer GUI Controls
+  </a></li>
+  <li><a href="../reference/analyzer/analyzing_table_data.htm">Analyzing Table
+    Data</a> </li>
+  <li><a href="../reference/analyzer/thread_load.htm">Thread Load</a></li>
+  <li><a href="../reference/analyzer/binary_load.htm">Binary Load</a></li>
+  <li><a href="../reference/analyzer/function_load.htm">Function Load</a></li>
+  <li><a href="../reference/analyzer/function_calls.htm">Function Calls</a></li>
+</ul>
+
+<div id="footer">
+Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights
+reserved. <br />
+License: <a
+href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+</body>
+</html>
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/Getting_Started/tour.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/Getting_Started/tour.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -10,6 +10,6 @@
   <p>The user interfaces for the target sotware (sampling application running on handheld device) and host software (profiler application running on PC) are described below.</p>
   <h4>Handheld Device</h4>
   <p>Handheld devices running the Symbian S60 Operating System can capture a data profile sequence from  a running application.</p>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/bugs_fixed.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/bugs_fixed.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -58,7 +58,7 @@
 </ul>
 <p><br />
 </p>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/abbrev.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/abbrev.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -109,6 +109,6 @@
     <td>Universal Asynchronous Receiver/Transmitter</td>
   </tr>
 </table>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/analyser.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/analyser.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -19,7 +19,7 @@
   <li><a href="../reference/analyzer/an_use_case_features.htm">Analyzing Sampled Data</a></li>
   <li><a href="../Getting_Started/example_project.htm">Examining a Profiler Project</a></li>
 </ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/basic_operation.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/basic_operation.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -18,6 +18,6 @@
   <li><a href="func_level_load.htm">Function Level Load Analysis</a></li>
 <li><a href="dll_support.htm">DLL Support Trace and Analysis</a></li>
 </ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/button_press_capture.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/button_press_capture.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -20,6 +20,6 @@
   <li><a href="../tasks/profiler/btn_press_enable.htm">Setting the Button Press Capture Option</a></li>
   <li><a href="../tasks/analyser/btn_press_show.htm">Showing/Hiding Button Events</a></li>
 </ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/dll_support.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/dll_support.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -11,6 +11,6 @@
 <h2>Dynamic Binary Support Trace and Analysis</h2>
 <p>Dynamic binary support  trace analysis is dedicated to performing function level performance analysis on binaries that have been uploaded to the device at run-time, at least in the operating system&rsquo;s point of view. In those cases, the address of the binary is not known at compile-time. If sampled with any of the previously mentioned methods, it is impossible to tell the binary from an address that is not found from the symbol file, which is produced at run-time. One solution to resolve the problem is to store small pieces of the executed binary code at run-time and store them along with the trace taken.</p>
 <p>Performance Investigator suppports  EKA2 dynamic support trace and analysis. Dynamic binary support trace in EKA2 works on a different principle than in EKA1. This is facilitated by certain changes in the kernel. In the EKA2 version, the collected information provides a semantically similar result as the EKA1 version, thus information about dynamically loaded binaries and their locations in memory is provided as the result of the analysis. However, the information collected from the system is much more straightforward in the EKA2 version.</p>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/func_level_load.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/func_level_load.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -26,6 +26,6 @@
 <p align="center"><img src="../images/figure5.png" width="849" height="482"></p>
 <p class="figure">Figure 3. Resolving correct values in linked function level load analysis</p>
 <p>Thus, through periodic sampling it is possible to always retrieve the address of the interrupted execution from the PC, and in a certain proportion of cases it is also possible to retrieve the caller of the function in which the execution takes place from the LR. The proportion of those two cases is in practice dictated by the proportion of instructions executed on average before and after the first subsequent BL command within the function. When analyzing the results, this proportion can be calculated for each function as a proportion between the sampled LR values that point outside the function and the values that point inside the function. In the analysis within the Performance Investigator, this proportion is used in extrapolating the amount of callers to a certain function. It is assumed that the distribution of callers of a certain function is the same in the samples from which the caller function could not be resolved as it is within the samples in which the value could be retrieved. This is shown in Figure 3. In specific circumstances, this assumption can result in an error, mainly by multiplying &ldquo;noise&rdquo; to statistically important dimensions. This has to be taken into consideration when reading the results.</p>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
Binary file sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/images/con_memory_usage.png has changed
Binary file sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/images/pi_thread_load_01.png has changed
Binary file sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/images/view_button_markers.png has changed
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/learn_prof.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/learn_prof.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -18,6 +18,6 @@
 <li> <a href="../reference/analyzer/analyser.htm">Performance Investigator Analyzer</a></li>
 <li><a href="../reference/profiler/Trace_Items.htm">Trace Items</a></li>
 </ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/memory_usage_capture.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/memory_usage_capture.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -10,7 +10,7 @@
 <body>
 <h2>Memory Usage Capture</h2>
 <p> Use the Profiler application's <b>Memory usage capture</b> <a href="../reference/profiler/tracing_options.htm">option</a> to capture memory usage data on the target device. The data is stored in the profiler data file during a trace operation and can later be viewed in the Analyzer (Figure 1).</p>
-<p align="center"><img src="images/con_memory_usage.png" width="708" height="653"></p>
+<p align="center"><img src="images/con_memory_usage.png" width="626" height="582"></p>
 <p class="figure">Figure 1. Memory Usage Capture information displayed in an analyser view. </p>
 <p>The Symbian OS API allocates memory in chunks. A chunk is a region of RAM mapped into contiguous linear addresses. At creation, a process has one to three chunks: </p>
 <ul>
@@ -28,6 +28,6 @@
 <ul>
   <li><a href="../reference/profiler/tracing_options.htm">Setting Tracing Options</a></li>
 </ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/methods.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/methods.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -26,6 +26,6 @@
   <li><a href="../reference/methods/rofs.htm">ROFS</a></li>
 </ul>
 <p class="note"> <strong>NOTE:</strong> Many of these methods and building blocks are specific to the OMAP/ARM architecture and Symbian OS actually used.</p>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/overview/overview.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/overview/overview.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -33,6 +33,6 @@
 <li><a href="../../reference/analyzer/analyser.htm">Analyzer</a></li>
 <li><a href="../../reference/abbrev.htm">Acronyms</a></li>
 </ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/overview/sw_performance.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/overview/sw_performance.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -29,6 +29,6 @@
 <ul>
   <li><a href="../perfanalysis/perfanalysis.htm">Software Performance Analysis</a></li>
 </ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/perfanalysis/perf_basic_procedures.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/perfanalysis/perf_basic_procedures.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -37,6 +37,6 @@
   <p>When you analyze the binaries and functions in which the application spends most of its execution time, it is recommended that you analyze based on a single thread at a time.</p>
   <p>For a high-load function, examine the code for an explanation (e.g., computation-intensive loop) as to why significant time was spent in the function. If you have captured function call data, examine the functions calling the high-load function to determine whether so many calls were necessary.</p>
 </blockquote>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/perfanalysis/perf_other_dynamic_mem.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/perfanalysis/perf_other_dynamic_mem.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -18,6 +18,6 @@
 </ol>
 <p>If the sequential functional trace shows the above pattern and it occurs frequently in the application, try to determine why it happens. Determine whether allocation and free operations for objects of the same type and size could be replaced with a simple cache.</p>
 <p>If an application uses dynamic memory extensively, it is beneficial to know statistics of utilized block sizes. Very small block sizes used frequently are potential performance bottlenecks.</p>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/perfanalysis/perf_other_server_threads.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/perfanalysis/perf_other_server_threads.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -18,6 +18,6 @@
 </ul>
 <p>In general, the goal should be to minimize unnecessary calls to servers. Multiple application requests should be grouped in a single server request whenever possible.<br>
 </p>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/perfanalysis/perf_other_subjects.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/perfanalysis/perf_other_subjects.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -14,6 +14,6 @@
   <li><a href="perf_other_server_threads.htm">Server Threads Analysis</a></li>
   <li><a href="perf_other_dynamic_mem.htm">Dynamic Memory Characteristics</a></li>
 </ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/perfanalysis/perfanalysis.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/perfanalysis/perfanalysis.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -15,6 +15,11 @@
   <li><a href="perf_other_dynamic_mem.htm">Dynamic Memory Characteristics</a></li>
   <li><a href="perf_other_server_threads.htm">Server Threads Analysis</a></li>
 </ul>
-<p><img src="../../images/nokia_copyright.png" alt="copyright" width="280" height="21"></img></p>
+
+<div id="footer">
+Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights
+reserved. <br>
+License: <a
+href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/power_usage_capture.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/concepts/power_usage_capture.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -20,6 +20,6 @@
 <h5>Related tasks</h5>
 <ul><li><a href="../reference/profiler/tracing_options.htm">Setting Tracing Options</a></li>
 </ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/context_help/com_nokia_carbide_pi_ipc.xml	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?NLS TYPE="org.eclipse.help.toc"?>
+
+<!-- Define help for Debug Perspective default views -->
+<!-- plugin="com.nokia.carbide.cpp.pi.address" -->
+
+<contexts>
+
+	<!-- THREAD TAB -->
+	<context id="ipcPageContext"  >
+		<description>Use the Interconnect Performance Counters view to visualise profiling data from interconnect performance counters.</description>
+		<topic label="Interconnect Performance Counters View"    					href="html/reference/analyzer/view_IPC.htm" />
+  <topic href="html/reference/analyzer/main_view.htm" label="Analyzer View"/>
+		<topic label="Using the Analyzer"  				href="html/reference/analyzer/an_use_case_features.htm" />
+		<topic label="Setting Time Interval"  			href="html/tasks/analyser/time_interval.htm" />
+	</context>
+
+	<!-- BINARIES TAB -->
+
+	<!-- FUNCTIONS TAB -->
+
+</contexts>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/context_help/com_nokia_carbide_pi_irq.xml	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?NLS TYPE="org.eclipse.help.toc"?>
+
+<!-- Define help for Debug Perspective default views -->
+<!-- plugin="com.nokia.carbide.cpp.pi.address" -->
+
+<contexts>
+
+	<!-- THREAD TAB -->
+	<context id="irqPageContext"  >
+		<description>Use the Interrupts view to visualise profiling data from hardware and software interrupts.</description>
+		<topic label="Interrupts View"    					href="html/reference/analyzer/interrupts_view.htm" />
+  <topic href="html/reference/analyzer/main_view.htm" label="Analyzer View"/>
+		<topic label="Using the Analyzer"  				href="html/reference/analyzer/an_use_case_features.htm" />
+		<topic label="Setting Time Interval"  			href="html/tasks/analyser/time_interval.htm" />
+	</context>
+
+	<!-- BINARIES TAB -->
+
+	<!-- FUNCTIONS TAB -->
+
+</contexts>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/context_help/com_nokia_carbide_pi_memory.xml	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?NLS TYPE="org.eclipse.help.toc"?>
+
+<!-- Define help for Debug Perspective default views -->
+<!-- plugin="com.nokia.carbide.cpp.pi.address" -->
+
+<contexts>
+
+	<!-- THREAD TAB -->
+	<context id="memoryPageContext"  >
+		<description>Use the Memory view to display the memory usage.</description>
+  <topic href="html/reference/analyzer/view_memory_usage.htm" label="Memory Usage View"/>
+		<topic label="Memory Graph Menu"    					href="html/reference/analyzer/menu_memory_graph.htm" />
+  <topic href="html/reference/analyzer/wnd_memory_usage_statistics.htm" label="Memory Usage Statistics"/>
+		<topic label="Analyzer view" 					href="html/reference/analyzer/main_view.htm" />
+		<topic label="Using the Analyzer"  				href="html/reference/analyzer/an_use_case_features.htm" />
+		<topic label="Setting Time Interval"  			href="html/tasks/analyser/time_interval.htm" />
+	</context>
+
+	<!-- BINARIES TAB -->
+
+	<!-- FUNCTIONS TAB -->
+
+</contexts>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/context_help/com_nokia_carbide_pi_pec.xml	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?NLS TYPE="org.eclipse.help.toc"?>
+
+<!-- Define help for Debug Perspective default views -->
+<!-- plugin="com.nokia.carbide.cpp.pi.address" -->
+
+<contexts>
+
+	<!-- THREAD TAB -->
+	<context id="pecPageContext"  >
+		<description>Use the Performance Counters view to visualise profiling data from performance counters.</description>
+		<topic label="Performance Counters View"    					href="html/reference/analyzer/view_performance_counters.htm" />
+  <topic href="html/reference/analyzer/traceable_events.htm" label="Traceable Event Types"/>
+  <topic href="html/reference/analyzer/main_view.htm" label="Analyzer View"/>
+  <topic href="html/reference/analyzer/view_IPC.htm" label="Interconnect Performance Counters View"/>
+		<topic label="Using the Analyzer"  				href="html/reference/analyzer/an_use_case_features.htm" />
+		<topic label="Setting Time Interval"  			href="html/tasks/analyser/time_interval.htm" />
+  <topic href="html/reference/profiler/Prof_counter_settings.htm" label="PIProfiler Performance Counter Settings"/>
+	</context>
+
+	<!-- BINARIES TAB -->
+
+	<!-- FUNCTIONS TAB -->
+
+</contexts>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/context_help/com_nokia_carbide_pi_power.xml	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?NLS TYPE="org.eclipse.help.toc"?>
+
+<!-- Define help for Debug Perspective default views -->
+<!-- plugin="com.nokia.carbide.cpp.pi.address" -->
+
+<contexts>
+
+	<!-- THREAD TAB -->
+	<context id="powerPageContext"  >
+		<description>Use the Power Usage view to display the power usage.</description>
+		<topic label="Power Usage View"    					href="html/reference/analyzer/view_power_usage.htm" />
+  <topic href="html/reference/analyzer/menu_power_graph.htm" label="Power Graph Menu"/>
+  <topic href="html/reference/analyzer/wnd_power_usage_statistics.htm" label="Power Usage Statistics"/>
+		<topic label="Analyzer view" 					href="html/reference/analyzer/main_view.htm" />
+		<topic label="Using the Analyzer"  				href="html/reference/analyzer/an_use_case_features.htm" />
+		<topic label="Setting Time Interval"  			href="html/tasks/analyser/time_interval.htm" />
+	</context>
+
+	<!-- BINARIES TAB -->
+
+	<!-- FUNCTIONS TAB -->
+
+</contexts>
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/legal.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/legal.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -11,7 +11,7 @@
 <h2>License Information</h2>
 <h5>COPYRIGHTS</h5>
 
-<p>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 <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.</p>
+<p>Copyright (c) 2010 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 <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.</p>
  
 <h5>Initial Contributors:</h5>
 <p> Nokia Corporation - initial contribution</p>
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/profiler.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/profiler.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -1,32 +1,46 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-
-<html>
-<head>
-	<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-	<title>Carbide.c++ User Guide</title>
-    <link href="../book.css" rel="stylesheet" type="text/css">
-	<style>
-		table, td, th { border: 0px none #FFF; }
-    </style>
-</head>
-
-<body background="images/background_carbide.jpg" >
-<p>&nbsp;</p>
-<table width="530" border="0" align="center" cellpadding="0" cellspacing="5" bgcolor="#FFFFFF" >
-  <tr>
-    <td width="215"><img src="images/about_cpp.png" width="225" height="200"></td>
-    <td width="294" valign="bottom"><p align="right"><b><img src="images/brandmark_cpp.gif" width="106" height="52"></b></p>
-        <p>&nbsp;</p>
-        <p>&nbsp;</p>
-        <p>&nbsp;</p>
-        <p class="titleSmall">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>
-        License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></p>
-    </td>
-  </tr>
-  <tr>
-    <td colspan="2"><h1 align="center">Performance Investigator User Guide </h1>
-      <p align="center" class="titleSmall">Version 2.1.0; June, 2009</p></td>
-  </tr>
-</table>
-</body>
-</html>
\ No newline at end of file
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+  <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+  <title>Carbide.c++ User Guide</title>
+  <link href="../book.css" rel="stylesheet" type="text/css">
+  <style>
+                table, td, th { border: 0px none #FFF; }
+  </style>
+</head>
+
+<body background="images/background_carbide.jpg">
+<p> </p>
+
+<table width="530" border="0" align="center" cellpadding="0" cellspacing="5"
+bgcolor="#FFFFFF">
+  <tbody>
+    <tr>
+      <td width="215"><img src="images/about_cpp.png" width="225"
+      height="200"></td>
+      <td width="294" valign="bottom"><p align="right"><b><img
+        src="images/brandmark_cpp.gif" width="106" height="52"></b></p>
+
+        <p> </p>
+
+        <p> </p>
+
+        <p> </p>
+
+        <p class="titleSmall">Copyright © 2010 Nokia Corporation and/or its
+        subsidiary(-ies). All rights reserved. <br>
+        License: <a
+        href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></p>
+      </td>
+    </tr>
+    <tr>
+      <td colspan="2"><h1 align="center">Performance Investigator User Guide
+        </h1>
+
+        <p align="center" class="titleSmall">Version 2.3.0; April, 2010</p>
+      </td>
+    </tr>
+  </tbody>
+</table>
+</body>
+</html>
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/abbrev.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/abbrev.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -74,6 +74,6 @@
     <td><p>Read Only Memory</p></td>
   </tr>
 </table>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/GUI_tour.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/GUI_tour.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -1,61 +1,206 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
-"http://www.w3.org/TR/html4/loose.dtd">
-<html>
-<head>
-	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-	<title>Analyzer GUI Controls</title>
-    <link href="../../../book.css" rel="stylesheet" type="text/css">
-</head>
-
-<body>
-<h2>Analyzer GUI Controls </h2>
-<p>The Analyzer provides several user interface items to control the analyzing process as shown in Figure 1.</p>
-<p align="center"><img src="images/analz_startend.png" width="138" height="30"></p>
-<p align="center" class="figure">Figure 1. Analyzer toolbar icons</p>
-<h5>Table 1. Toolbar icons</h5>
-<table width="90%" border="0" cellpadding="2" cellspacing="0" >
-  <tr>
-    <th width="244" scope="col">Option </th>
-    <th width="72" scope="col">Icon</th>
-    <th width="473" scope="col">Description</th>
-  </tr>
-  <tr>
-    <td><b>Select Time Interval </b></td>
-    <td><div align="center"><img src="images/icon_select_time_interval.png" width="17" height="18"></div></td>
-    <td>Select the Start-End icon to <a href="../../tasks/analyser/time_interval.htm">select</a> the time interval (in seconds) to be displayed in the current load graph being viewed.</td>
-  </tr>
-  <tr>
-    <td><b>Zoom In </b></td>
-    <td><div align="center"><img src="images/icon_zoom_in.png" width="19" height="19"></div></td>
-    <td>Zooms in on the graph view to display more detail. </td>
-  </tr>
-  <tr>
-    <td><b>Zoom Out </b></td>
-    <td><div align="center"><img src="images/icon_zoom_out.png" width="18" height="18"></div></td>
-    <td>In the graph view, zooms out to display less detail of the selected time interval. </td>
-  </tr>
-  <tr>
-    <td><b>Zoom to Selected Time Interval </b></td>
-    <td><div align="center"><img src="images/icon_zoom_to_selected_int.png" width="18" height="16"></div></td>
-    <td>Locates the graph's selected time interval and displays it in center of graph. </td>
-  </tr>
-  <tr>
-    <td><b>Show Entire Graph </b></td>
-    <td><div align="center"><img src="images/icon_show_entire_graph.png" width="18" height="16"></div></td>
-    <td>Displays all profiled data in graph.</td>
-  </tr>
-</table>
-<p>You can also hover the pointer over the graph to view information as shown in Figure 2. </p>
-<p align="center"><img src="images/analz_graphitem.png" width="295" height="200"></p>
-<p align="center" class="figure">Figure 2. Specific items in graph</p>
-<p><strong>Related references</strong></p>
-<ul>
-  <li><a href="main_view.htm">Analyzer View</a></li>
-  <li><a href="thread_load.htm">Thread Load</a></li>
-  <li><a href="binary_load.htm">Binary Load</a></li>
-  <li><a href="function_load.htm">Function Load</a></li>
-<li><a href="function_calls.htm">Function Calls</a></li>
-</ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
-</body>
-</html>
\ No newline at end of file
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+"http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
+  <title>Analyzer GUI Controls</title>
+  <link href="../../../book.css" rel="stylesheet" type="text/css">
+</head>
+
+<body>
+<h2>Analyzer GUI Controls </h2>
+
+<p>The Analyzer provides several user interface items to control the analyzing
+process.</p>
+
+<p>The icons available on the toolbar are shown in Figure 1.</p>
+
+<p align="center"><img src="images/analz_startend.png" width="138"
+height="30"></p>
+
+<p align="center" class="figure">Figure 1. Analyzer toolbar icons</p>
+
+<h5>Table 1. Toolbar icons</h5>
+
+<table width="90%" border="0" cellpadding="2" cellspacing="0">
+  <tbody>
+    <tr>
+      <th width="244" scope="col">Option </th>
+      <th width="72" scope="col">Icon</th>
+      <th width="473" scope="col">Description</th>
+    </tr>
+    <tr>
+      <td><b>Select Time Interval </b></td>
+      <td>
+        <div align="center">
+        <img src="images/icon_select_time_interval.png" width="17"
+        height="18"></div>
+      </td>
+      <td>Select the Start-End icon to <a
+        href="../../tasks/analyser/time_interval.htm">select</a> the time
+        interval (in seconds) to be displayed in the current load graph being
+        viewed.</td>
+    </tr>
+    <tr>
+      <td><b>Zoom In </b></td>
+      <td>
+        <div align="center">
+        <img src="images/icon_zoom_in.png" width="19" height="19"></div>
+      </td>
+      <td>Zooms in on the graph view to display more detail. </td>
+    </tr>
+    <tr>
+      <td><b>Zoom Out </b></td>
+      <td>
+        <div align="center">
+        <img src="images/icon_zoom_out.png" width="18" height="18"></div>
+      </td>
+      <td>In the graph view, zooms out to display less detail of the selected
+        time interval. </td>
+    </tr>
+    <tr>
+      <td><b>Zoom to Selected Time Interval </b></td>
+      <td>
+        <div align="center">
+        <img src="images/icon_zoom_to_selected_int.png" width="18"
+        height="16"></div>
+      </td>
+      <td>Locates the graph's selected time interval and displays it in center
+        of graph. </td>
+    </tr>
+    <tr>
+      <td><b>Show Entire Graph </b></td>
+      <td>
+        <div align="center">
+        <img src="images/icon_show_entire_graph.png" width="18"
+        height="16"></div>
+      </td>
+      <td>Displays all profiled data in graph.</td>
+    </tr>
+  </tbody>
+</table>
+
+<p></p>
+
+<p>There are also several icons available on Title bar which you can use to
+modify what is shown in the different views. See the Table 2 below for
+descriptions.</p>
+
+<h5>Table 2. Title bar icons</h5>
+
+<table width="90%" border="0" cellpadding="2" cellspacing="0">
+  <tbody>
+    <tr>
+      <th width="244" scope="col">Option </th>
+      <th width="72" scope="col">Icon</th>
+      <th width="473" scope="col">Description</th>
+    </tr>
+    <tr>
+      <td><b>Help</b></td>
+      <td>
+        <div align="center">
+        <img src="images/linkto_help.png" width="16" height="16"></div>
+      </td>
+      <td>Opens the help displaying a short description of the selected view,
+        and a list of links to related information. If you want more
+        information than what is shown in the description, click a link to one
+        of the related topics, or use one of the options available at the
+        bottom of the help view. </td>
+    </tr>
+    <tr>
+      <td><b>Minimize graph</b></td>
+      <td>
+        <div align="center">
+        <img src="images/minimize_graph.png" width="16" height="16"></div>
+      </td>
+      <td>Minimizes the graph so that only the title bar for the graph is
+        displayed. The corresponding table is hidden as well.</td>
+    </tr>
+    <tr>
+      <td><b>Restore graph</b></td>
+      <td>
+        <div align="center">
+        <img src="images/minimize_restore_graph.png" width="16"
+        height="16"></div>
+      </td>
+      <td>Restores a minimized graph and the corresponding table so that they
+        are displayed as normal.</td>
+    </tr>
+    <tr>
+      <td><b>Move graph down</b></td>
+      <td>
+        <div align="center">
+        <img src="images/move_graph_down.png" width="16" height="16"></div>
+      </td>
+      <td>Moves the graph down in the main view, so that the order of the
+        displayed graphs is changed. 
+
+        <p>If the graph cannot be moved up, this button is disabled.</p>
+      </td>
+    </tr>
+    <tr>
+      <td><b>Move graph up</b></td>
+      <td>
+        <div align="center">
+        <img src="images/move_graph_up.png" width="16" height="16"></div>
+      </td>
+      <td>Moves the graph up in the main view, so that the order of the
+        displayed graphs is changed. 
+
+        <p>If the graph cannot be moved up, this button is disabled.</p>
+      </td>
+    </tr>
+    <tr>
+      <td><b>Maximize graph</b></td>
+      <td>
+        <div align="center">
+
+        <div align="center">
+        <img src="images/maximize_graph.png" width="16" height="16"></div>
+        </div>
+      </td>
+      <td>Maximizes the graph so that all the other graphs are hidden and only
+        the selected graph is displayed in the main view. 
+
+        <p>This also affects the corresponding tables: The tables for the other
+        graphs are hidden and only the table for the selected graph is
+        displayed.</p>
+      </td>
+    </tr>
+    <tr>
+      <td><b>Restore graph</b></td>
+      <td>
+        <div align="center">
+        <img src="images/maximize_restore_graph.png" width="16"
+        height="16"></div>
+      </td>
+      <td>Restores a maximized graph and displays all the graphs and tables
+        simultaneously as normal.</td>
+    </tr>
+  </tbody>
+</table>
+
+<p>You can also hover the pointer over the graph to view information as shown
+in Figure 3. </p>
+
+<p align="center"><img src="images/analz_graphitem.png" width="295"
+height="200"></p>
+
+<p align="center" class="figure">Figure 3. Specific items in graph</p>
+
+<p><strong>Related references</strong></p>
+<ul>
+  <li><a href="main_view.htm">Analyzer View</a></li>
+  <li><a href="thread_load.htm">Thread Load</a></li>
+  <li><a href="binary_load.htm">Binary Load</a></li>
+  <li><a href="function_load.htm">Function Load</a></li>
+  <li><a href="function_calls.htm">Function Calls</a></li>
+</ul>
+
+<div id="footer">
+Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights
+reserved. <br>
+License: <a
+href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+</body>
+</html>
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/an_installation.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/an_installation.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -11,6 +11,6 @@
 <h2>Installing the Analyzer</h2>
 <p> The Performance Investigator Analyzer comes installed with Carbide.c++.</p>
 <p>Recommended amount of memory is at least 1Gbytes. If you open or import several large profiler data files, the Java Virtual Machine executing Carbide.c++ may run out of memory.</p>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/an_use_case_features.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/an_use_case_features.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -15,6 +15,6 @@
   <li><a href="GUI_tour.htm">Analyzer GUI Controls </a></li>
   <li><a href="../../Getting_Started/example_project.htm">Examining a Profiling Project</a></li>
 </ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/analyser.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/analyser.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -23,6 +23,6 @@
   <li><a href="an_use_case_features.htm">Analyzing Profiler Data</a></li>
   <li><a href="../profiler/Trace_Items.htm">Trace Items</a></li>
 </ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/analyzing_table_data.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/analyzing_table_data.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -58,6 +58,6 @@
   <li><a href="context_menu.htm">Context Menu</a></li>
   <li><a href="../../Getting_Started/example_project.htm">Examining a Profiling Project</a> </li>
 </ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/binary_load.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/binary_load.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -1,36 +1,61 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
-"http://www.w3.org/TR/html4/loose.dtd">
-<html>
-<head>
-	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-	<title>Binary Load</title>
-    <link href="../../../book.css" rel="stylesheet" type="text/css">
-</head>
-
-<body>
-<h2>Binary Load</h2>
-<p>Select the Binaries tab to display the Binary Load. The Binary Load graph and related table show information about binaries that were active during the selected time period. The load is visually separated according to the executed binary, independent of the thread or function that was executing. Figure 1 shows an example graph with the Binaries tab selected.</p>
-<p align="center"><img src="images/binary_mode_graph.png" width="705" height="659"></p>
-<p class="figure">Figure 1. Example Binary Load Graph</p>
-<p>You can check or uncheck items to be displayed in the graph or right-click to display a context menu of various options. The color next to a checkbox corresponds to that item’s color in the graph.</p>
-<p>Description of table columns:</p>
-<ul>
-  <li>The % Load column indicates what percentage of the CPU load was spent in each binary during the selected time interval.</li>
-<li>The Binary column identifies the binary files by name. </li>
-  <li>The Path column shows the PC folder containing the binary.</li>
-<li>The Samples column indicates how many samples were taken during the selected time interval (in this case between XXX and YYY seconds).</li>
-</ul>
-<p>Columns may be reordered, resized, and sorted by clicking or dragging column headers.</p>
-<p>The final row of the information section contains summary information about all binaries below a threshold, if a threshold limit has been specified. The threshold row is not affected by sorting, it is always the last row.</p>
-<p><strong>Related references</strong></p>
-<ul>
-  <li><a href="main_view.htm">Analyzer View</a></li>
-  <li><a href="../profiler/GPP_trace.htm">Address/Thread Trace</a></li>
-  <li><a href="thread_load.htm">Thread Load</a></li>
-  <li><a href="function_load.htm">Function Load</a></li>
-  <li><a href="function_calls.htm">Function Calls</a></li>
-<li><a href="threshold.htm">Threshold Limits for Traced Data</a></li>
-</ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
-</body>
-</html>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+"http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
+  <title>Binary Load</title>
+  <link href="../../../book.css" rel="stylesheet" type="text/css">
+</head>
+
+<body>
+<h2>Binary Load</h2>
+
+<p>Select the Binaries tab to display the Binary Load. The Binary Load graph
+and related table show information about binaries that were active during the
+selected time period. The load is visually separated according to the executed
+binary, independent of the thread or function that was executing. Figure 1
+shows an example graph with the Binaries tab selected.</p>
+
+<p align="center"><img src="images/binary_mode_graph.png" width="654"
+height="588"></p>
+
+<p class="figure">Figure 1. Example Binary Load Graph</p>
+
+<p>You can check or uncheck items to be displayed in the graph or right-click
+to display a context menu of various options. The color next to a checkbox
+corresponds to that item’s color in the graph.</p>
+
+<p>Description of table columns:</p>
+<ul>
+  <li>The % Load column indicates what percentage of the CPU load was spent in
+    each binary during the selected time interval.</li>
+  <li>The Binary column identifies the binary files by name. </li>
+  <li>The Path column shows the PC folder containing the binary.</li>
+  <li>The Samples column indicates how many samples were taken during the
+    selected time interval (in this case between XXX and YYY seconds).</li>
+</ul>
+
+<p>Columns may be reordered, resized, and sorted by clicking or dragging column
+headers.</p>
+
+<p>The final row of the information section contains summary information about
+all binaries below a threshold, if a threshold limit has been specified. The
+threshold row is not affected by sorting, it is always the last row.</p>
+
+<p><strong>Related references</strong></p>
+<ul>
+  <li><a href="main_view.htm">Analyzer View</a></li>
+  <li><a href="../profiler/GPP_trace.htm">Address/Thread Trace</a></li>
+  <li><a href="thread_load.htm">Thread Load</a></li>
+  <li><a href="function_load.htm">Function Load</a></li>
+  <li><a href="function_calls.htm">Function Calls</a></li>
+  <li><a href="threshold.htm">Threshold Limits for Traced Data</a></li>
+</ul>
+
+<div id="footer">
+Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights
+reserved. <br>
+License: <a
+href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+</body>
+</html>
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/context_menu.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/context_menu.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -1,227 +1,357 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
-"http://www.w3.org/TR/html4/loose.dtd">
-<html>
-<head>
-	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-	<title></title>
-    <link href="../../../book.css" rel="stylesheet" type="text/css">
-    <style type="text/css">
-<!--
-.style1 {
-	font-family: Georgia, "Times New Roman", Times, serif;
-	font-weight: bold;
-}
--->
-    </style>
-</head>
-
-<body>
-<h2>Context Menu Options </h2>
-<p>Right-clicking within the Analyzer graph and tables will display context popup menus that will vary slightly depending on where you initiated the popup menu. The following table lists and defines Analyzer context menu options.</p>
-<p class="note"><strong>Note </strong>Several menu options allow you to save information to a .csv file that can be opened in a text editor or system editor (such as Excel). Beware that the default filename to save information is <span class="style1">new_file.csv</span>. Specify a unique filename if you do not want the default file to be overwritten each time you save information. </p>
-<h5>Table 1. Analyzer context menu options</h5>
-<table width="90%" border="0" cellpadding="2" cellspacing="0" >
-  <tr>
-    <th width="25%" scope="col">Menu Option </th>
-    <th width="581" scope="col">Description</th>
-  </tr>
-  <tr>
-    <td><b>Binary -&gt; Function -&gt; Thread </b></td>
-    <td>Displays the Binary, Function, and Thread tables. The graph will display the Threads from which the selected binaries were executed. The functions within the binaries that were called are listed in the functions table. </td>
-  </tr>
-  <tr>
-    <td><b>Binary -&gt; Thread </b></td>
-    <td>Displays the Binary and Thread tables. The graph will display the threads where the selected binaries were executed.</td>
-  </tr>
-  <tr>
-    <td><b>Binary -&gt; Thread -&gt; Function </b></td>
-    <td>Displays the Binary, Thread, and Function tables. The graph will display the functions that were called in the selected binaries. The threads table lists the threads where the selected binaries were executed.</td>
-  </tr>
-  <tr>
-    <td><b>Binary -&gt;Function </b></td>
-    <td>Displays the Binary and Function tables. The graph will display the functions that were called from within the selected binaries. </td>
-  </tr>
-  <tr>
-    <td><b>Binary Only </b></td>
-    <td>Displays the Binary table and all selected binaries in the graph view. </td>
-  </tr>
-  <tr>
-    <td><span class="style1">Change Event Information...</span> </td>
-    <td>Right-click on a button event marker in the Thread Load, Binary Load, or Function Load graph and select this menu option to display a dialog to <a href="../../tasks/analyser/btn_press_change.htm">change related event information</a>.</td>
-  </tr>
-  <tr>
-    <td><b>Change Threshold Limits... </b></td>
-    <td>Displays the <a href="threshold.htm">Set Thread, Binary, or Function Thresholds</a> dialog box.</td>
-  </tr>
-  <tr>
-    <td><b>Check All Rows </b></td>
-    <td>All rows will be checked and represented on the graph.</td>
-  </tr>
-  <tr>
-    <td><b>Check Highlighted Rows </b></td>
-    <td>This option will place a check mark in all highlighted rows. You can use the shift key and mouse button to select and highlight a continuous sequence  of rows. Use the control key to select and highlight random rows. Checked rows will be visible on the graph.</td>
-  </tr>
-  <tr>
-    <td><b>Copy</b></td>
-    <td>Copies the contents of the selected data from the table to the clipboard.  </td>
-  </tr>
-  <tr>
-    <td><b>Copy Drilldown Tables</b></td>
-    <td>Copies the contents of the entire drilldown table to the clipboard including column titles for easy identification when pasted into a spreadsheet for analysis. </td>
-  </tr>
-  <tr>
-    <td><b>Copy Table</b></td>
-    <td>Copies the contents of the entire table in the current pane to the clipboard including column titles for easy identification when pasted into a spreadsheet for analysis. The table contents do not have to be selected for the table copy to occur.</td>
-  </tr>
-  <tr>
-    <td><span class="style1">Dynamically Rescale Based on Selected Threads </span></td>
-    <td>Right-click in Memory Usage graph and select this option to rescale the graph based on selected threads. </td>
-  </tr>
-  <tr>
-    <td><span class="style1">Function Only </span></td>
-    <td>Displays Functions only. </td>
-  </tr>
-  <tr>
-    <td class="style1">Function -&gt; Thread </td>
-    <td>Displays Functions and related Threads. The graph will display threads containing the function calls. </td>
-  </tr>
-  <tr>
-    <td class="style1">Function -&gt; Thread -&gt; Binary </td>
-    <td>Displays Functions and related Threads and Binaries containing the functions called.</td>
-  </tr>
-  <tr>
-    <td><span class="style1">Memory Usage Statistics </span></td>
-    <td>Right-click in Memory Usage graph and select this menu option to open a Memory Usage Statistics dialog box that reports memory use for the selected time interval.</td>
-  </tr>
-  <tr>
-    <td class="style1">Open Source for Function </td>
-    <td>Opens the source code file containing the selected function in the editor window.</td>
-  </tr>
-  <tr>
-    <td><span class="style1">Power Usage Settings...</span></td>
-    <td>Right-click in the Power Usage graph and select this menu option to display a dialog box that reports the voltage and battery capacity. The values can be modifed as mentioned in <a href="wnd_power_graph_settings.htm">Power Usage Settings</a>.</td>
-  </tr>
-  <tr>
-    <td><span class="style1">Power Usage Statistics </span></td>
-    <td>Right-click in the Power Usage graph and select this option to display a dialog that reports detailed power information for the selected time interval.</td>
-  </tr>
-  <tr>
-    <td><b>Recolor Highlighted Binaries...</b></td>
-    <td>Displays a color swatch for you to choose a different color for a highlighted row. If multiple rows are selected, then multiple color swatch windows will appear. Change or accept current color for each row selected. Selected rows appear grey.</td>
-  </tr>
-  <tr>
-    <td><b>Recolor Highlighted Functions...</b></td>
-    <td>Displays a color swatch for you to choose a different color for a highlighted row. If multiple rows are selected, then multiple color swatch windows will appear. Change or accept current color for each row selected. Selected rows appear grey.</td>
-  </tr>
-  <tr>
-    <td><b>Recolor Highlighted Threads...</b></td>
-    <td>Displays a color swatch for you to choose a different color for a highlighted row. If multiple rows are selected, then multiple color swatch windows will appear. Change or accept current color for each row selected. Selected rows appear grey.</td>
-  </tr>
-  <tr>
-    <td class="style1">Save All Call Samples for Interval... </td>
-    <td>Right-click in one of the Function Call Analysis tables (when Function Calls tab is selected) and choose this option to save all function calls to a .csv file for the selected time interval. Information provided includes the time, caller address, caller function, caller binary, callee address, callee function, and callee binary.</td>
-  </tr>
-  <tr>
-    <td class="style1">Save All Event Samples for Interval... </td>
-    <td>Right-click on a button event marker in the Thread Load, Binary Load, or Function Load graph and choose this option to save all button events for the selected time interval. </td>
-  </tr>
-  <tr>
-    <td><span class="style1">Save All Power Samples for Interval... </span></td>
-    <td>Right-click in the Power Usage graph and select this option to save all collected power samples for the selected time interval.</td>
-  </tr>
-  <tr>
-    <td class="style1">Save Data for Selected Function... </td>
-    <td>Select a function in the Select One Function table (when Function Calls tab is selected) and right-click to choose this option. Detailed information is saved to a .csv file for the selected function. </td>
-  </tr>
-  <tr>
-    <td><b>Save Drilldown Tables...</b></td>
-    <td>Saves the contents of the entire drilldown table (e.g. Thread -&gt; Binary -&gt; Function) to a specified file including column titles for easy identification when opened in a spreadsheet for analysis.</td>
-  </tr>
-  <tr>
-    <td><span class="style1">Save Priority Samples for Checked Threads...</span></td>
-    <td>Saves the priority setting for Threads that are checked in the Thread table. The first entry in the file shows the last value recorded before entering the selected time interval. Subsequent entries show a change in the priority during the interval. Priority settings are detected when a change is made; thus they are not sampled every millisecond.</td>
-  </tr>
-  <tr>
-    <td><span class="style1">Save Samples for Checked Binaries... </span></td>
-    <td>Right-click in the Binary table (when Binaries tab is selected) and choose this option to save samples for binaries that are checked.</td>
-  </tr>
-  <tr>
-    <td><span class="style1">Save Samples for Checked Threads... </span></td>
-    <td>When Threads tab is selected, save samples for Threads that are checked in the Thread table to a .csv file.</td>
-  </tr>
-  <tr>
-    <td><span class="style1">Save Memory Samples for Checked Table Entries...</span> </td>
-    <td>This option is enabled when a time interval is selected. Save memory samples that are checked in the Memory Usage table to a .csv file. The first entry in the file shows the last value recorded before entering the selected time interval. Subsequent entries show changes made during the interval. Memory samples are detected when a change is made; thus they are not sampled every millisecond.</td>
-  </tr>
-  <tr>
-    <td><b>Save Table...</b></td>
-    <td>Saves the contents of the entire table in the current pane to a specified file including column titles for easy identification when opened in a spreadsheet for analysis. The table contents do not have to be selected for the table to be saved.</td>
-  </tr>
-  <tr>
-    <td><b>Select All</b></td>
-    <td>Selects the entire table in the current pane.</td>
-  </tr>
-  <tr>
-    <td><b>Show Entire Graph </b></td>
-    <td>Displays all profiled data in graph.</td>
-  </tr>
-  <tr>
-    <td><b>Show highlighted function's call info </b></td>
-    <td>This context menu option appears in the top and bottom tables of the Function Calls table - <strong>Functions calling the selected function</strong> and <strong>Functions called by the selected function</strong>. Select a function in one of these two tables, right-click and select this option to move the selected function into middle table labeled <strong>Select One Function</strong>. Functions calling and called by the selected function will be displayed in top and bottom tables.</td>
-  </tr>
-  <tr>
-    <td class="style1">Show Selected Interval Average Power Line </td>
-    <td>This option appears when you right-click in the Power Usage graph. Check this option to display the average power for the selected time interval.</td>
-  </tr>
-  <tr>
-    <td><b>Sort by Binary Path, then Binary Name </b></td>
-    <td>In the Binaries and Functions table views, this option will alphabetically sort the path of binaries, then alphabetically sort the binary files by name. Binary path and binary file names are listed in the Binary and Path columns (Binaries table), and In Binary and Path of Binary columns (Functions table). </td>
-  </tr>
-  <tr>
-    <td><strong>Switch Key Press Profile</strong> </td>
-    <td>Opens a dialog that allows you to change the<a href="../../tasks/analyser/key_profile_switch.htm"> key map profile</a> associated with the current NPI file.</td>
-  </tr>
-  <tr>
-    <td><b>Thread -&gt; Binary</b></td>
-    <td>Displays the Thread and Binary tables. The graph will display the binaries that have executed in the selected Thread(s); in relation to the selected time interval. </td>
-  </tr>
-  <tr>
-    <td><b>Thread -&gt; Binary -&gt; Function </b></td>
-    <td>Displays the Thread, Binary, and Function tables. The graph will display the functions that have been called in the selected binaries that exist in the selected threads. </td>
-  </tr>
-  <tr>
-    <td><b>Thread -&gt; Function</b></td>
-    <td>Displays the Thread and Function tables. The graph will display the functions that have been called in the selected threads; in relation to the selected time interval. </td>
-  </tr>
-  <tr>
-    <td><b>Thread -&gt; Function -&gt; Binary </b></td>
-    <td>Displays the Thread, Function, and Binary tables. The graph will display the binaries executed in the selected threads. The functions within the binaries that were called are listed in the functions table.</td>
-  </tr>
-  <tr>
-    <td><b>Thread Only </b></td>
-    <td>Displays the Thread table and all selected threads in the graph view.</td>
-  </tr>
-  <tr>
-    <td><b>Uncheck All Rows </b></td>
-    <td>All rows will be unchecked and all related items will be removed from the graph. </td>
-  </tr>
-  <tr>
-    <td><b>Uncheck Highlighted Rows </b></td>
-    <td>Unchecks highlighted rows and removes the  represented item(s) from the graph. </td>
-  </tr>
-  <tr>
-    <td><b>Zoom In </b></td>
-    <td>Zooms in on the graph view to display more detail. </td>
-  </tr>
-  <tr>
-    <td><b>Zoom Out </b></td>
-    <td>In the graph view, zooms out to display less detail of the selected time interval. </td>
-  </tr>
-  <tr>
-    <td><b>Zoom to Selected Time Interval </b></td>
-    <td>Locates the graph's selected time interval and displays it in center of graph. </td>
-  </tr>
-</table>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
-</body>
-</html>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+"http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
+  <title></title>
+  <link href="../../../book.css" rel="stylesheet" type="text/css">
+  <style type="text/css">
+<!--
+ .style1 {
+font-family: Georgia, "Times New Roman", Times, serif;
+font-weight: bold;
+}
+-->
+
+  </style>
+</head>
+
+<body>
+<h2>Context Menu Options </h2>
+
+<p>Right-clicking within the Analyzer graphs and tables displays context pop-up
+menus, which vary slightly depending on where you initiated the menu. The
+following table lists and defines Analyzer context menu options.</p>
+
+<p class="note"><strong>Note </strong>Several menu options allow you to save
+information to a .csv file that can be opened in a text editor or system editor
+(such as Excel). Beware that the default filename to save information is <span
+class="style1">new_file.csv</span>. Specify a unique filename if you do not
+want the default file to be overwritten each time you save information. </p>
+
+<h5>Table 1. Analyzer context menu options</h5>
+
+<table width="90%" border="0" cellpadding="2" cellspacing="0">
+  <tbody>
+    <tr>
+      <th width="25%" scope="col">Menu Option </th>
+      <th width="581" scope="col">Description</th>
+    </tr>
+    <tr>
+      <td><b>Binary -&gt; Function -&gt; Thread </b></td>
+      <td>Displays the Binary, Function, and Thread tables. The graph will
+        display the Threads from which the selected binaries were executed. The
+        functions within the binaries that were called are listed in the
+        functions table. </td>
+    </tr>
+    <tr>
+      <td><b>Binary -&gt; Thread </b></td>
+      <td>Displays the Binary and Thread tables. The graph will display the
+        threads where the selected binaries were executed.</td>
+    </tr>
+    <tr>
+      <td><b>Binary -&gt; Thread -&gt; Function </b></td>
+      <td>Displays the Binary, Thread, and Function tables. The graph will
+        display the functions that were called in the selected binaries. The
+        threads table lists the threads where the selected binaries were
+        executed.</td>
+    </tr>
+    <tr>
+      <td><b>Binary -&gt;Function </b></td>
+      <td>Displays the Binary and Function tables. The graph will display the
+        functions that were called from within the selected binaries. </td>
+    </tr>
+    <tr>
+      <td><b>Binary Only </b></td>
+      <td>Displays the Binary table and all selected binaries in the graph
+        view. </td>
+    </tr>
+    <tr>
+      <td><b>Change Event Information...</b> </td>
+      <td>Right-click on a button event marker in the Thread Load, Binary Load,
+        or Function Load graph and select this menu option to display a dialog
+        to <a href="../../tasks/analyser/btn_press_change.htm">change related
+        event information</a>.</td>
+    </tr>
+    <tr>
+      <td><b>Change Threshold Limits... </b></td>
+      <td>Displays the <a href="threshold.htm">Set Thread, Binary, or Function
+        Thresholds</a> dialog box.</td>
+    </tr>
+    <tr>
+      <td><b>Check All Rows </b></td>
+      <td>All rows will be checked and represented on the graph.</td>
+    </tr>
+    <tr>
+      <td><b>Check Highlighted Rows </b></td>
+      <td>This option will place a check mark in all highlighted rows. You can
+        use the shift key and mouse button to select and highlight a continuous
+        sequence of rows. Use the control key to select and highlight random
+        rows. Checked rows will be visible on the graph.</td>
+    </tr>
+    <tr>
+      <td><b>Copy</b></td>
+      <td>Copies the contents of the selected data from the table to the
+        clipboard. </td>
+    </tr>
+    <tr>
+      <td><b>Copy Drilldown Tables</b></td>
+      <td>Copies the contents of the entire drilldown table to the clipboard
+        including column titles for easy identification when pasted into a
+        spreadsheet for analysis. </td>
+    </tr>
+    <tr>
+      <td><b>Copy Table</b></td>
+      <td>Copies the contents of the entire table in the current pane to the
+        clipboard including column titles for easy identification when pasted
+        into a spreadsheet for analysis. The table contents do not have to be
+        selected for the table copy to occur.</td>
+    </tr>
+    <tr>
+      <td><b>Dynamically Rescale Based on Selected Threads </b></td>
+      <td>Right-click in Memory Usage graph and select this option to rescale
+        the graph based on selected threads. </td>
+    </tr>
+    <tr>
+      <td><b>Function Only </b></td>
+      <td>Displays Functions only. </td>
+    </tr>
+    <tr>
+      <td><b>Function -&gt; Thread </b></td>
+      <td>Displays Functions and related Threads. The graph will display
+        threads containing the function calls. </td>
+    </tr>
+    <tr>
+      <td><b>Function -&gt; Thread -&gt; Binary </b></td>
+      <td>Displays Functions and related Threads and Binaries containing the
+        functions called.</td>
+    </tr>
+    <tr>
+      <td><b>Memory Usage Statistics </b></td>
+      <td>Right-click in Memory Usage graph and select this menu option to open
+        a Memory Usage Statistics dialog box that reports memory use for the
+        selected time interval.</td>
+    </tr>
+    <tr>
+      <td><b>Open Source for Function </b></td>
+      <td>Opens the source code file containing the selected function in the
+        editor window.</td>
+    </tr>
+    <tr>
+      <td><b>Power Usage Settings...</b></td>
+      <td>Right-click in the Power Usage graph and select this menu option to
+        display a dialog box that reports the voltage and battery capacity. The
+        values can be modifed as mentioned in <a
+        href="wnd_power_graph_settings.htm">Power Usage Settings</a>.</td>
+    </tr>
+    <tr>
+      <td><b>Power Usage Statistics </b></td>
+      <td>Right-click in the Power Usage graph and select this option to
+        display a dialog that reports detailed power information for the
+        selected time interval.</td>
+    </tr>
+    <tr>
+      <td><b>Recolor Highlighted Binaries...</b></td>
+      <td>Displays a color swatch for you to choose a different color for a
+        highlighted row. If multiple rows are selected, then multiple color
+        swatch windows will appear. Change or accept current color for each row
+        selected. Selected rows appear grey.</td>
+    </tr>
+    <tr>
+      <td><b>Recolor Highlighted Functions...</b></td>
+      <td>Displays a color swatch for you to choose a different color for a
+        highlighted row. If multiple rows are selected, then multiple color
+        swatch windows will appear. Change or accept current color for each row
+        selected. Selected rows appear grey.</td>
+    </tr>
+    <tr>
+      <td><b>Recolor Highlighted Threads...</b></td>
+      <td>Displays a color swatch for you to choose a different color for a
+        highlighted row. If multiple rows are selected, then multiple color
+        swatch windows will appear. Change or accept current color for each row
+        selected. Selected rows appear grey.</td>
+    </tr>
+    <tr>
+      <td><b>Save All Call Samples for Interval... </b></td>
+      <td>Right-click in one of the Function Call Analysis tables (when
+        Function Calls tab is selected) and choose this option to save all
+        function calls to a .csv file for the selected time interval.
+        Information provided includes the time, caller address, caller
+        function, caller binary, callee address, callee function, and callee
+        binary.</td>
+    </tr>
+    <tr>
+      <td><b>Save All Event Samples for Interval... </b></td>
+      <td>Right-click on a button event marker in the Thread Load, Binary Load,
+        or Function Load graph and choose this option to save all button events
+        for the selected time interval. </td>
+    </tr>
+    <tr>
+      <td><b>Save All Power Samples for Interval... </b></td>
+      <td>Right-click in the Power Usage graph and select this option to save
+        all collected power samples for the selected time interval.</td>
+    </tr>
+    <tr>
+      <td><b>Save Data for Selected Function... </b></td>
+      <td>Select a function in the Select One Function table (when Function
+        Calls tab is selected) and right-click to choose this option. Detailed
+        information is saved to a .csv file for the selected function. </td>
+    </tr>
+    <tr>
+      <td><b>Save Drilldown Tables...</b></td>
+      <td>Saves the contents of the entire drilldown table (e.g. Thread -&gt;
+        Binary -&gt; Function) to a specified file including column titles for
+        easy identification when opened in a spreadsheet for analysis.</td>
+    </tr>
+    <tr>
+      <td><b>Save Priority Samples for Checked Threads...</b></td>
+      <td>Saves the priority setting for Threads that are checked in the Thread
+        table. The first entry in the file shows the last value recorded before
+        entering the selected time interval. Subsequent entries show a change
+        in the priority during the interval. Priority settings are detected
+        when a change is made; thus they are not sampled every millisecond.</td>
+    </tr>
+    <tr>
+      <td><b>Save Samples for Checked Binaries... </b></td>
+      <td>Right-click in the Binary table (when Binaries tab is selected) and
+        choose this option to save samples for binaries that are checked.</td>
+    </tr>
+    <tr>
+      <td><b>Save Samples for Checked Threads... </b></td>
+      <td>When Threads tab is selected, save samples for Threads that are
+        checked in the Thread table to a .csv file.</td>
+    </tr>
+    <tr>
+      <td><b>Save Memory Samples for Checked Table Entries...</b> </td>
+      <td>This option is enabled when a time interval is selected. Save memory
+        samples that are checked in the Memory Usage table to a .csv file. The
+        first entry in the file shows the last value recorded before entering
+        the selected time interval. Subsequent entries show changes made during
+        the interval. Memory samples are detected when a change is made; thus
+        they are not sampled every millisecond.</td>
+    </tr>
+    <tr>
+      <td><b>Save Table...</b></td>
+      <td>Saves the contents of the entire table in the current pane to a
+        specified file including column titles for easy identification when
+        opened in a spreadsheet for analysis. The table contents do not have to
+        be selected for the table to be saved.</td>
+    </tr>
+    <tr>
+      <td><b>Select All</b></td>
+      <td>Selects the entire table in the current pane.</td>
+    </tr>
+    <tr>
+      <td><b>Show Combined CPU Graph</b></td>
+      <td>This option is enabled for SMP systems with more than one CPU. Select
+        this option to view all CPUs merged into one graph.</td>
+    </tr>
+    <tr>
+      <td><b>Show Entire Graph </b></td>
+      <td>Displays all profiled data in graph.</td>
+    </tr>
+    <tr>
+      <td><b>Show highlighted function's call info </b></td>
+      <td>This context menu option appears in the top and bottom tables of the
+        Function Calls table - <strong>Functions calling the selected
+        function</strong> and <strong>Functions called by the selected
+        function</strong>. Select a function in one of these two tables,
+        right-click and select this option to move the selected function into
+        middle table labeled <strong>Select One Function</strong>. Functions
+        calling and called by the selected function will be displayed in top
+        and bottom tables.</td>
+    </tr>
+    <tr>
+      <td><b>Show Selected Interval Average Power Line </b></td>
+      <td>This option appears when you right-click in the Power Usage graph.
+        Check this option to display the average power for the selected time
+        interval.</td>
+    </tr>
+    <tr>
+      <td><b>Show Separate CPU Graphs</b> </td>
+      <td>This option is enabled for SMP systems with more than one CPU. Select
+        this option to display a separate graph line for each CPU.</td>
+    </tr>
+    <tr>
+      <td><b>Show Total Memory Usage</b></td>
+      <td>Displays or disables the Total Memory Usage line on the Memory Usage
+        graph.</td>
+    </tr>
+    <tr>
+      <td><b>Sort by Binary Path, then Binary Name </b></td>
+      <td>In the Binaries and Functions table views, this option will
+        alphabetically sort the path of binaries, then alphabetically sort the
+        binary files by name. Binary path and binary file names are listed in
+        the Binary and Path columns (Binaries table), and In Binary and Path of
+        Binary columns (Functions table). </td>
+    </tr>
+    <tr>
+      <td><strong>Switch Key Press Profile</strong> </td>
+      <td>Opens a dialog that allows you to change the<a
+        href="../../tasks/analyser/key_profile_switch.htm">key map profile</a>
+        associated with the current NPI file.</td>
+    </tr>
+    <tr>
+      <td><b>Thread -&gt; Binary</b></td>
+      <td>Displays the Thread and Binary tables. The graph will display the
+        binaries that have executed in the selected Thread(s); in relation to
+        the selected time interval. </td>
+    </tr>
+    <tr>
+      <td><b>Thread -&gt; Binary -&gt; Function </b></td>
+      <td>Displays the Thread, Binary, and Function tables. The graph will
+        display the functions that have been called in the selected binaries
+        that exist in the selected threads. </td>
+    </tr>
+    <tr>
+      <td><b>Thread -&gt; Function</b></td>
+      <td>Displays the Thread and Function tables. The graph will display the
+        functions that have been called in the selected threads; in relation to
+        the selected time interval. </td>
+    </tr>
+    <tr>
+      <td><b>Thread -&gt; Function -&gt; Binary </b></td>
+      <td>Displays the Thread, Function, and Binary tables. The graph will
+        display the binaries executed in the selected threads. The functions
+        within the binaries that were called are listed in the functions
+      table.</td>
+    </tr>
+    <tr>
+      <td><b>Thread Only </b></td>
+      <td>Displays the Thread table and all selected threads in the graph
+      view.</td>
+    </tr>
+    <tr>
+      <td><b>Uncheck All Rows </b></td>
+      <td>All rows will be unchecked and all related items will be removed from
+        the graph. </td>
+    </tr>
+    <tr>
+      <td><b>Uncheck Highlighted Rows </b></td>
+      <td>Unchecks highlighted rows and removes the represented item(s) from
+        the graph. </td>
+    </tr>
+    <tr>
+      <td><b>Zoom In </b></td>
+      <td>Zooms in on the graph view to display more detail. </td>
+    </tr>
+    <tr>
+      <td><b>Zoom Out </b></td>
+      <td>In the graph view, zooms out to display less detail of the selected
+        time interval. </td>
+    </tr>
+    <tr>
+      <td><b>Zoom to Selected Time Interval </b></td>
+      <td>Locates the graph's selected time interval and displays it in center
+        of graph. </td>
+    </tr>
+  </tbody>
+</table>
+
+<div id="footer">
+Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights
+reserved. <br>
+License: <a
+href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+</body>
+</html>
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/function_calls.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/function_calls.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -42,6 +42,6 @@
   <li><a href="function_load.htm">Function Load</a></li>
   <li><a href="thread_load.htm">Thread Load</a></li>
 </ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/function_load.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/function_load.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -10,7 +10,7 @@
 <body>
 <h2>Function Load</h2>
 <p>Select the Functions tab to display the Function Load. The function load graph and related table show information about functions that were active during the selected time period. In Function mode, the graph and information views show the CPU load separated at a function level, independent of the thread that has been executing it. Figure 1 shows an example of the Function tab selected and Function load displayed.</p>
-<p align="center"><img src="images/function_mode_graph.png" width="708" height="605"> </p>
+<p align="center"><img src="images/function_mode_graph.png" width="697" height="588"> </p>
 <p class="figure">Figure 1. Function Load Graph</p>
 You can check or uncheck items to be displayed in the graph or right-click to display a context menu of various options. The color next to a checkbox corresponds to that item’s color in the graph.
 <p>Description of table columns:</p>
@@ -32,6 +32,6 @@
   <li><a href="function_calls.htm">Function Calls</a></li>
 <li><a href="threshold.htm">Threshold Limits for Traced Data</a></li>
 </ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
Binary file sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/IPC_view.png has changed
Binary file sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/MIPS_speed_dialog.png has changed
Binary file sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/Performance_counters_drop-down.png has changed
Binary file sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/analyzer_mainview.png has changed
Binary file sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/binary_mode_graph.png has changed
Binary file sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/event_loaded.png has changed
Binary file sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/event_unloaded.png has changed
Binary file sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/function_mode_graph.png has changed
Binary file sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/help_button.png has changed
Binary file sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/interrupts_view_HW.png has changed
Binary file sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/interrupts_view_SW.png has changed
Binary file sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/interrupts_view_drop-down.png has changed
Binary file sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/investigator_menu.png has changed
Binary file sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/investigator_menu_SMP.png has changed
Binary file sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/linkto_help.png has changed
Binary file sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/maximize_graph.png has changed
Binary file sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/maximize_restore_graph.png has changed
Binary file sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/memory_graph_drop_down.png has changed
Binary file sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/menu_memory_usage.png has changed
Binary file sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/minimize_graph.png has changed
Binary file sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/minimize_restore_graph.png has changed
Binary file sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/move_graph_down.png has changed
Binary file sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/move_graph_up.png has changed
Binary file sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/performance_counters_view_all_graphs.png has changed
Binary file sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/thread_mode_graph.png has changed
Binary file sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/thread_mode_separate_graphs.png has changed
Binary file sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/view_memory_library_events.png has changed
Binary file sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/view_memory_usage.png has changed
Binary file sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/images/view_power_usage.png has changed
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/import_rom_build_files.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/import_rom_build_files.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -40,6 +40,6 @@
   <li><a href="main_view.htm" align="left">Analyzer
 View</a></li>
 </ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/interrupts_view.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,128 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+"http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
+  <title>Thread Load</title>
+  <link href="../../../book.css" rel="stylesheet" type="text/css">
+</head>
+
+<body>
+<h2>Interrupts View</h2>
+
+<p>Use the Interrupts View to display information about data collected from SWI
+and IRQ interrupts. The graph portion of the Interrupts view shows the amount
+of interrupts per millisecond.</p>
+
+<p>The Interrupts View has two different view options: Software interrupts (see
+Figure 2.) or Hardware interrupts (see Figure 3.). The display is different
+depending upon the view option selected in the Title bar drop-down menu, shown
+in Figure 1.</p>
+
+<p align="center"><img src="images/interrupts_view_drop-down.png" width="113"
+height="46"></p>
+
+<p align="center" class="figure">Figure 1. Interrupts view Title bar drop-down
+menu</p>
+
+<p><strong>Software interrupts</strong></p>
+
+<p>The Software interrupts graph displays the interrupts according to the
+threads and SWI functions selected in the legend tables. A separate line of
+graph is displayed for each selected thread, with the thread name in the top
+left-hand corner. In the graph, the height of the column shows the amount of
+interrupts, and each color represents an SWI function. The scaling of the
+graphs is shown at the left side of the graph.</p>
+
+<p align="center"><img src="images/interrupts_view_SW.png" width="705"
+height="591"></p>
+
+<p align="center" class="figure">Figure 2. Software interrupts view</p>
+
+<p>There are two legend tables displayed below the software interrupts graph:
+One for the threads from a device and another for SWI functions.</p>
+
+<p>Description of columns in the Threads table:</p>
+<ul>
+  <li>The <b>Thread</b> column identifies the thread by name and executable
+    which is composed of: 
+    <ul>
+      <li>Executable or process name — name of the binary as identified by
+        the OS</li>
+      <li>Process ID (PID) — the process ID that uniquely identifies the
+        process to the OS </li>
+      <li>Thread name —the name of the thread</li>
+    </ul>
+  </li>
+  <li>The <b>Address</b> column indicates the address of the thread object that
+    was under execution during the time of the SWI.</li>
+</ul>
+
+<p>You can select the threads you want to display in the graph by checking the
+box next to the thread name in the table. A separate line of graph is displayed
+for each selected thread, with the thread name in the top left-hand corner.</p>
+
+<p></p>
+
+<p>Description of columns in the SWI Function table:</p>
+<ul>
+  <li>The <b>SWI Function</b> column indicates the name of the function</li>
+  <li>The <b>Return Address</b> column indicates the return address for the SWI
+    call, i.e. the address for the “caller function†of each software
+    interrupt</li>
+  <li>The <b>Count</b> column indicates the number of interrupts for the
+    selected area of the graph.</li>
+</ul>
+
+<p>You can select the functions you want to be displayed in the graph by
+checking the box next to the function. Each function is represented by a unique
+colour, shown next to the function name in the Function table.</p>
+
+<p>The columns in the tables may be reordered, resized, and sorted by clicking
+or dragging column headers.</p>
+
+<p></p>
+
+<p><strong>Hardware interrupts</strong></p>
+
+<p>The Hardware interrupts graph displays the interrupts for the selected IRQ
+lines. A separate line of graph is displayed for each selected IRQ line, with
+the line ID in the top left-hand corner. In the graph, the height of the column
+shows the amount of interrupts. The scaling of the graphs is shown at the left
+side of the graph.</p>
+
+<p> A legend table is displayed below the graph. </p>
+
+<p align="center"><img src="images/interrupts_view_HW.png" width="679"
+height="493"></p>
+
+<p align="center" class="figure">Figure 3. Hardware interrupts view</p>
+
+<p>Description of the columns in the IRQ lines table:</p>
+<ul>
+  <li>The <b>IRQ line</b> column indicates the ID of the actual IRQ line.</li>
+  <li>The <b>Count</b> column indicates the number of interrupts for the
+    selected area of the graph.</li>
+</ul>
+
+<p>You can select the IRQ line you want to be displayed in the graph by
+checking the box next to the line ID in the table. The color next to a check
+box corresponds to that item’s color in the graph.</p>
+
+<p>The columns in the tables may be reordered, resized, and sorted by clicking
+or dragging column header.</p>
+
+<p></p>
+
+<p><strong>Related references</strong></p>
+<ul>
+  <li><a href="main_view.htm">Analyzer View</a></li>
+</ul>
+
+<div id="footer">
+Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights
+reserved. <br>
+License: <a
+href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+</body>
+</html>
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/investigator_menu.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/investigator_menu.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -1,41 +1,92 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
-"http://www.w3.org/TR/html4/loose.dtd">
-<html>
-<head>
-	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-	<title>Investigator Menu</title>
-    <link href="../../../book.css" rel="stylesheet" type="text/css">
-</head>
-
-<body>
-<h2>Investigator Menu </h2>
-<p>In the main menu, select <b>Investigator</b> to display menu options available for the Analyzer; as shown in Figure 1.</p>
-<p align="center"><img src="images/investigator_menu.png" width="297" height="86"></p>
-<p class="figure">Figure 1 - Investigator menu options</p>
-<h5 align="left">Table 1. Investigator menu items </h5>
-<table width="90%" border="0" cellpadding="2" cellspacing="0" >
-  <tr>
-    <th width="224" scope="col">Menu Options</th>
-    <th width="584" scope="col">Description</th>
-  </tr>
-  <tr>
-    <td><b>Show Individual Samples </b></td>
-    <td>Displays selected items as a vertical line on the graph. Items are displayed at the time interval at which they occurred. </td>
-  </tr>
-  <tr>
-    <td><b>Fill in Graph Loads </b></td>
-    <td>Items in graph will be filled in with solid color representing each item. If Show Individual Samples is selected, this option has no effect. </td>
-  </tr>
-  <tr>
-    <td><b>Change Threshold Limits...</b></td>
-    <td>Opens the <a href="threshold.htm">Set Thread, Binary, or Function Thresholds</a> dialog box. </td>
-  </tr>
-</table>
-<h5>Related references</h5>
-<ul>
-  <li><a href="menu_memory_graph.htm">Memory Graph menu </a></li>
-<li><a href="menu_power_graph.htm">Power Graph menu</a></li>
-</ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
-</body>
-</html>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+"http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
+  <title>Investigator Menu</title>
+  <link href="../../../book.css" rel="stylesheet" type="text/css">
+</head>
+
+<body>
+<h2>Investigator Menu </h2>
+
+<p>In the main menu, select <b>Investigator</b> to display menu options
+available for the Analyzer; as shown in Figure 1.</p>
+
+<p align="center"><img src="images/investigator_menu.png" width="297"
+height="86"></p>
+
+<p class="figure">Figure 1 - Investigator menu options</p>
+
+<h5 align="left">Table 1. Investigator menu items </h5>
+
+<table width="90%" border="0" cellpadding="2" cellspacing="0">
+  <tbody>
+    <tr>
+      <th width="224" scope="col">Menu Options</th>
+      <th width="584" scope="col">Description</th>
+    </tr>
+    <tr>
+      <td><b>Show Individual Samples </b></td>
+      <td>Displays selected items as a vertical line on the graph. Items are
+        displayed at the time interval at which they occurred. </td>
+    </tr>
+    <tr>
+      <td><b>Fill in Graph Loads </b></td>
+      <td>Items in graph will be filled in with solid color representing each
+        item. If Show Individual Samples is selected, this option has no
+        effect. </td>
+    </tr>
+    <tr>
+      <td><b>Change Threshold Limits...</b></td>
+      <td>Opens the <a href="threshold.htm">Set Thread, Binary, or Function
+        Thresholds</a> dialog box. </td>
+    </tr>
+  </tbody>
+</table>
+
+<p></p>
+
+<p>In SMP systems with more than one CPU, two additional options are included
+in the investigator menu for viewing combined or separate CPU graphs. See
+Figure 2 below.</p>
+
+<p align="center"><img src="images/investigator_menu_SMP.png" width="349"
+height="109"></p>
+
+<p class="figure">Figure 2 - Investigator menu options in an SMP system</p>
+
+<h5 align="left">Table 1. Additional Investigator menu items for SMP systems
+</h5>
+
+<table width="90%" border="0" cellpadding="2" cellspacing="0">
+  <tbody>
+    <tr>
+      <th width="224" scope="col">Menu Options</th>
+      <th width="584" scope="col">Description</th>
+    </tr>
+    <tr>
+      <td><b>Show Combined CPU Graph</b></td>
+      <td>Displays thread loads from all CPUs in one graph and one legend
+      table.</td>
+    </tr>
+    <tr>
+      <td><b>Show Separate CPU Graphs</b></td>
+      <td>Displays a separate graph and legend table for each CPU.</td>
+    </tr>
+  </tbody>
+</table>
+
+<h5>Related references</h5>
+<ul>
+  <li><a href="menu_memory_graph.htm">Memory Graph menu </a></li>
+  <li><a href="menu_power_graph.htm">Power Graph menu</a></li>
+</ul>
+
+<div id="footer">
+Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights
+reserved. <br>
+License: <a
+href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+</body>
+</html>
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/main_view.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/main_view.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -1,31 +1,66 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
-"http://www.w3.org/TR/html4/loose.dtd">
-<html>
-<head>
-	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-	<title>Analyzer View</title>
-    <link href="../../../book.css" rel="stylesheet" type="text/css">
-</head>
-
-<body>
-<h2>Analyzer View</h2>
-<p>The main analysis view is visible after trace data taken by the profiler has been imported into Carbide.c++ and opened with the Analyzer. The thread load data in the main analysis view is built from the address/thread trace. Other trace data is also shown in the main analysis view, such as dynamic binary support trace and function call trace. Figure 1 is an example view of imported profiler data that has been opened with the analyzer, including memory and power usage information, with a time interval of 9.1 to 13 seconds selected.</p>
-<p align="center"><img src="images/analyzer_mainview.png" width="705" height="659"> </p>
-<p align="center" class="figure">Figure 1. Analyzer main view showing Thread, Memory, and Power graphs</p>
-<p>The address/thread trace graph is the most generic and perhaps most informative visual of the sampled data.
-  The different colors represent different items. You can select Thread load, Binary load, or Function load as shown in Figure 2. Time is represented on the horizontal axis of the graph and share of CPU use is represented on the vertical axis.</p>
-<p align="center"><img src="images/analz_loads_tabs.png" width="423" height="84"></p>
-<p align="center" class="figure">Figure 2. Selecting Threads, Binaries, Functions, or Function Calls</p>
-<p>Each of the lines in the thread list represents a single thread. The color codes in the thread list correspond to the colors in the thread load graphs. Therefore, each color in the thread load graph represents the load of its corresponding thread.</p>
-<p>You can select a portion of the graph by clicking on the trace graph. The Information view beneath the graph displays information about the currently selected part of the graph. For example, thread load statistics are shown in the information view if the thread load graph is selected.</p>
-<p><strong>Related references</strong></p>
-<ul>
-  <li><a href="GUI_tour.htm">Analyzer GUI Controls </a></li>
-<li><a href="thread_load.htm">Thread Load</a></li>
-<li><a href="binary_load.htm">Binary Load</a></li>
-<li><a href="function_load.htm">Function Load</a></li>
-<li><a href="function_calls.htm">Function Calls</a></li>
-</ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
-</body>
-</html>
\ No newline at end of file
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+"http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
+  <title>Analyzer View</title>
+  <link href="../../../book.css" rel="stylesheet" type="text/css">
+</head>
+
+<body>
+<h2>Analyzer View</h2>
+
+<p>The main analysis view is visible after trace data taken by Profiler has
+been imported into Carbide.c++ and opened with Analyzer. The thread load data
+in the main analysis view is built from the address/thread trace. Other trace
+data is also shown in the main analysis view, such as dynamic binary support
+trace and function call trace. Figure 1 is an example view of imported profiler
+data that has been opened with the analyzer, including memory and power usage
+information, with a time interval of 4 to 8 seconds selected.The Interrups
+graph and Performance Counters graph have been minized.</p>
+
+<p align="center"><img src="images/analyzer_mainview.png" width="679"
+height="770"> </p>
+
+<p align="center" class="figure">Figure 1. Analyzer main view showing Thread,
+Memory, and Power graphs</p>
+
+<p>The address/thread trace graph is the most generic and perhaps most
+informative visual of the sampled data. The different colors represent
+different items. Time is represented on the horizontal axis of the graph and
+share of CPU use is represented on the vertical axis. You can select Thread
+load, Binary load, or Function load by selecting the respective tabs at the
+bottom of the main view, as shown in Figure 2.</p>
+
+<p align="center"><img src="images/analz_loads_tabs.png" width="423"
+height="84"></p>
+
+<p align="center" class="figure">Figure 2. Selecting Threads, Binaries,
+Functions, or Function Calls</p>
+
+<p>Each of the lines in the thread table represents a single thread. The color
+codes in the thread list correspond to the colors in the thread load graphs.
+Therefore, each color in the thread load graph represents the load of its
+corresponding thread.</p>
+
+<p>You can select a portion of the graph by clicking on the trace graph. The
+legend table beneath the graph displays information about the currently
+selected part of the graph. For example, thread load statistics are shown in
+the table if the thread load graph is selected.</p>
+
+<p><strong>Related references</strong></p>
+<ul>
+  <li><a href="GUI_tour.htm">Analyzer GUI Controls </a></li>
+  <li><a href="thread_load.htm">Thread Load</a></li>
+  <li><a href="binary_load.htm">Binary Load</a></li>
+  <li><a href="function_load.htm">Function Load</a></li>
+  <li><a href="function_calls.htm">Function Calls</a></li>
+</ul>
+
+<div id="footer">
+Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights
+reserved. <br>
+License: <a
+href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+</body>
+</html>
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/menu_memory_graph.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/menu_memory_graph.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -1,55 +1,86 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
-"http://www.w3.org/TR/html4/loose.dtd">
-<html>
-<head>
-	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-	<title>Memory Graph Menu</title>
-    <link href="../../../book.css" rel="stylesheet" type="text/css">
-</head>
-
-<body>
-<h2>Memory Graph Menu </h2>
-<p>The <strong>Memory Graph</strong> menu is available whenever a <span class="code">.npi</span> or <span class="code">.bap</span> data file is opened that contains memory usage trace data. Use it to modify how the graph is calculated, view memory statistics, and control how the memory information is displayed. </p>
-<p align="center"><img src="images/menu_memory_usage.png" width="412" height="151"></p>
-<p class="figure">Figure 1. Memory Graph menu items </p>
-<h5>Table 1. Memory Graph &mdash;menu items
-</h5>
-<table width="778"
-border="0" cellpadding="2" cellspacing="0">
-  <tr valign="top">
-    <th width="236" class="Cell">Menu Item </th>
-    <th width="532" class="Cell">Description</th>
-  </tr>
-  <tr valign="top">
-    <td class="Cell"><b>Memory Usage Statistics </b></td>
-    <td class="Cell">Open the <a href="wnd_memory_usage_statistics.htm">Memory Usage Statistics</a> dialog. </td>
-  </tr>
-  <tr valign="top">
-    <td class="Cell"><p><b>Show Chunk Usage </b></p></td>
-    <td class="Cell"><p>Select<b> Show Chunk Usage</b> to show  chunks allocated to threads. Heap threads are not included. The graph refreshes and scales the vertical axis to cover the maximum non-heap chunk usage of the entire graph or the current selected threads. </p></td>
-  </tr>
-  <tr valign="top">
-    <td class="Cell"><b>Show Stack/Heap Usage </b></td>
-    <td class="Cell">Select<b> Show Stack/Heap Usage</b> to show thread heap chunks.</td>
-  </tr>
-  <tr valign="top">
-    <td class="Cell"><b>Show Current and Stack/Heap Usage </b></td>
-    <td class="Cell">This is the default setting showing both the current and stack/heap usage portions of the graph.</td>
-  </tr>
-  <tr valign="top">
-    <td class="Cell"><b>Dynamically Rescale to Selected Threads </b></td>
-    <td class="Cell">Enable to rescale the vertical axis of the graph to
-
-
-the maximum memory usage in the entire graph by the threads currently checked in the CPU load table. When disabled, rescale the vertical axis to the maximum memory usage of all threads in the entire graph. The default settings is disabled. </td>
-  </tr>
-</table>
-<p><strong>Related references </strong></p>
-<ul>
-  <li><a href="main_view.htm">Analyzer View</a></li>
-<li><a href="view_memory_usage.htm">Memory Usage View</a></li>
-<li><a href="wnd_memory_usage_statistics.htm">Memory Usage Statistics</a> </li>
-</ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
-</body>
-</html>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+"http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
+  <title>Memory Graph Menu</title>
+  <link href="../../../book.css" rel="stylesheet" type="text/css">
+</head>
+
+<body>
+<h2>Memory Graph Menu </h2>
+
+<p>The <strong>Memory Graph</strong> menu is available whenever a <span
+class="code">.npi</span> or <span class="code">.bap</span> data file is opened
+that contains memory usage trace data. Use it to modify how the graph is
+calculated, view memory statistics, and control how the memory information is
+displayed. </p>
+
+<p align="center"><img src="images/menu_memory_usage.png"></p>
+
+<p class="figure">Figure 1. Memory Graph menu items </p>
+
+<h5>Table 1. Memory Graph —menu items </h5>
+
+<table width="778" border="0" cellpadding="2" cellspacing="0">
+  <tbody>
+    <tr valign="top">
+      <th width="236" class="Cell">Menu Item </th>
+      <th width="532" class="Cell">Description</th>
+    </tr>
+    <tr valign="top">
+      <td class="Cell"><b>Memory Usage Statistics </b></td>
+      <td class="Cell">Open the <a
+        href="wnd_memory_usage_statistics.htm">Memory Usage Statistics</a>
+        dialog. </td>
+    </tr>
+    <tr valign="top">
+      <td class="Cell"><p><b>Show Chunk Usage </b></p>
+      </td>
+      <td class="Cell"><p>Select<b>Show Chunk Usage</b> to show chunks
+        allocated to threads. Heap threads are not included. The graph
+        refreshes and scales the vertical axis to cover the maximum non-heap
+        chunk usage of the entire graph or the current selected threads. </p>
+      </td>
+    </tr>
+    <tr valign="top">
+      <td class="Cell"><b>Show Stack/Heap Usage </b></td>
+      <td class="Cell">Select<b>Show Stack/Heap Usage</b> to show thread heap
+        chunks.</td>
+    </tr>
+    <tr valign="top">
+      <td class="Cell"><b>Show Current and Stack/Heap Usage </b></td>
+      <td class="Cell">This is the default setting showing both the current and
+        stack/heap usage portions of the graph.</td>
+    </tr>
+    <tr valign="top">
+      <td class="Cell"><b>Dynamically Rescale to Selected Threads </b></td>
+      <td class="Cell">Enable to rescale the vertical axis of the graph to the
+        maximum memory usage in the entire graph by the threads currently
+        checked in the CPU load table. When disabled, rescale the vertical axis
+        to the maximum memory usage of all threads in the entire graph. The
+        default settings is disabled. </td>
+    </tr>
+    <tr>
+      <td><b>Show Total Memory Usage</b></td>
+      <td>Displays or disables the Total Memory Usage line on the Memory Usage
+        graph.</td>
+    </tr>
+  </tbody>
+</table>
+
+<p><strong>Related references </strong></p>
+<ul>
+  <li><a href="main_view.htm">Analyzer View</a></li>
+  <li><a href="view_memory_usage.htm">Memory Usage View</a></li>
+  <li><a href="wnd_memory_usage_statistics.htm">Memory Usage Statistics</a>
+  </li>
+</ul>
+
+<div id="footer">
+Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights
+reserved. <br>
+License: <a
+href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+</body>
+</html>
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/menu_power_graph.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/menu_power_graph.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -40,6 +40,6 @@
 <li><a href="wnd_power_graph_settings.htm">Power Usage Graph Settings</a></li>
 <li><span class="Cell"><a href="wnd_power_usage_statistics.htm">Power Usage Statistics</a></span></li>
 </ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/save_table.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/save_table.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -31,6 +31,6 @@
 <h5>Save All Call Samples for Interval</h5>
 <p>When the Function Calls tab is selected, this command saves all function calls for the selected time interval. A dialog similar to the Save Table dialog will appear for you to save all function calls made during the selected time interval to a comma separated .csv file. This file can be opened in a spreadsheet application.</p>
 <p></p>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/thread_load.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/thread_load.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -1,43 +1,100 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
-"http://www.w3.org/TR/html4/loose.dtd">
-<html>
-<head>
-	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-	<title>Thread Load</title>
-    <link href="../../../book.css" rel="stylesheet" type="text/css">
-</head>
-
-<body>
-<h2>Thread Load</h2>
-<p>Select the Threads tab to display the Thread Load. The Thread Load graph and related table show information about threads that were active during the selected time period. The graph and table show the CPU load separated according to the executed thread, independent of the binary or function in which execution took place. Figure 1 shows an example graph with the Threads tab selected.</p>
-<p align="center"><img src="images/thread_mode_graph.png" width="705" height="659"> </p>
-<p align="center" class="figure">Figure 1. Thread Load Graph</p>
-<p>You can check or uncheck items to be displayed in the graph or right-click to display a context menu of various options. The color next to a checkbox corresponds to that item’s color in the graph.</p>
-<p>Description of table columns:</p>
-<ul>
-  <li>The <b>% Load</b> column indicates what percentage of the CPU load was spent in each thread during the selected time interval.</li>
-<li>The <b>Thread</b> column identifies the thread by name and executable which is composed of:
-    <ul>
-      <li>Executable or process  name &#8212; name of the binary as identified by the OS</li>
-      <li>Process ID (PID) &#8212;  the process ID that uniquely identifies the process to the OS </li>
-      <li>Thread name  &#8212;the name of the thread</li>
-      <li>Thread ID (TID) &#8212;  the thread ID that uniquely identifies the thread </li>
-    </ul>
-</li>
-  <li>The <b>Samples</b> column indicates how many samples were taken during the selected time interval (in this case between 8.16 and 8.5 seconds).</li>
-<li>If the profiler data file contained thread priority information, then a <b>Priority List</b> column will be shown.  The column lists the time at which a thread was assigned that priority. Sometimes you will see more than one priority listed for each thread.</li>
-</ul>
-<p>Columns may be reordered, resized, and sorted by clicking or dragging column headers.</p>
-<p> The final row of the information section contains summary information about all threads below a threshold, if a threshold limit has been specified. The threshold row is not affected by sorting, it is always the last row.</p>
-<p><strong>Related references</strong></p>
-<ul>
-  <li><a href="main_view.htm">Analyzer View</a></li>
-<li><a href="../profiler/GPP_trace.htm">Address/Thread Trace</a></li>
-  <li><a href="binary_load.htm">Binary Load</a></li>
-  <li><a href="function_load.htm">Function Load</a></li>
-<li><a href="function_calls.htm">Function Calls</a></li>
-<li><a href="threshold.htm">Threshold Limits for Traced Data</a></li>
-</ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
-</body>
-</html>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+"http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
+  <title>Thread Load</title>
+  <link href="../../../book.css" rel="stylesheet" type="text/css">
+</head>
+
+<body>
+<h2>Thread Load</h2>
+
+<p>Select the Threads tab to display the Thread Load. The Thread Load graph and
+related table show information about threads that were active during the
+selected time period. The graph and table show the CPU load separated according
+to the executed thread, independent of the binary or function in which
+execution took place. Figure 1 shows an example graph with the Threads tab
+selected.</p>
+
+<p align="center"><img src="images/thread_mode_graph.png" width="710"
+height="728"> </p>
+
+<p align="center" class="figure">Figure 1. Thread Load Graph displaying
+combined CPU graph</p>
+
+<p>Description of table columns:</p>
+<ul>
+  <li>The <b>% Load</b> column indicates what percentage of the CPU load was
+    spent in each thread during the selected time interval.</li>
+  <li>The <b>Thread</b> column identifies the thread by name and executable
+    which is composed of: 
+    <ul>
+      <li>Executable or process name — name of the binary as identified by
+        the OS</li>
+      <li>Process ID (PID) — the process ID that uniquely identifies the
+        process to the OS </li>
+      <li>Thread name —the name of the thread</li>
+      <li>Thread ID (TID) — the thread ID that uniquely identifies the thread
+      </li>
+    </ul>
+  </li>
+  <li>The <b>Samples</b> column indicates how many samples were taken during
+    the selected time interval (in this case between 8.16 and 8.5 seconds).</li>
+  <li>If the profiler data file contained thread priority information, then a
+    <b>Priority List</b> column will be shown. The column lists the time at
+    which a thread was assigned that priority. Sometimes you will see more than
+    one priority listed for each thread.</li>
+</ul>
+
+<p>Columns may be reordered, resized, and sorted by clicking or dragging column
+headers.</p>
+
+<p>The final row of the information section contains summary information about
+all threads below a threshold, if a threshold limit has been specified. The
+threshold row is not affected by sorting, it is always the last row.</p>
+
+<p>You can check or uncheck items to be displayed in the graph or right-click
+to display a context menu of various options. The color next to a checkbox
+corresponds to that item’s color in the graph.</p>
+
+<p>For SMP systems with more than one CPU it is also possible to select to</p>
+<ul>
+  <li><b>Show Combined CPU Graph</b>, that is, to view all CPUs merged into one
+    graph, as in Figure 1, or</li>
+  <li><b>Show Separate CPU Graphs</b>, that is, to view a separate graph and
+    table for each CPU, as in Figure 2.</li>
+</ul>
+
+<p>This is done by using either the context menu, which you can open by
+right-clicking on the CPU graph; or in the <a
+href="investigator_menu.htm">Investigator menu</a>'s CPU Load Graphs part.</p>
+
+<p align="center"><img src="images/thread_mode_separate_graphs.png" width="712"
+height="689"> </p>
+
+<p align="center" class="figure">Figure 2. Thread Load Graph displaying
+separate CPU graphs</p>
+
+<p>In the separate graphs view, there is also a separate legend table created
+for each graph. You can choose the table you want to view by using the tabs
+above the table. </p>
+
+<p><strong>Related references</strong></p>
+<ul>
+  <li><a href="main_view.htm">Analyzer View</a></li>
+  <li><a href="investigator_menu.htm">Investigator menu</a></li>
+  <li><a href="../profiler/GPP_trace.htm">Address/Thread Trace</a></li>
+  <li><a href="binary_load.htm">Binary Load</a></li>
+  <li><a href="function_load.htm">Function Load</a></li>
+  <li><a href="function_calls.htm">Function Calls</a></li>
+  <li><a href="threshold.htm">Threshold Limits for Traced Data</a></li>
+</ul>
+
+<div id="footer">
+Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights
+reserved. <br>
+License: <a
+href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+</body>
+</html>
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/threshold.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/threshold.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -28,6 +28,6 @@
 <p align="center" class="figure">Figure 2. Set Thresholds Dialog Box</p>
 <p><strong>Related Task</strong></p>
 <p><a href="../../tasks/analyser/set_thresholds.htm">Setting Thresholds For Threads, Binaries, and Functions</a></p>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/traceable_events.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,313 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+"http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
+  <title>Traceable Event Types</title>
+  <link href="../../../book.css" rel="stylesheet" type="text/css">
+  <style type="text/css">
+<!--
+ .style1 {
+font-family: Georgia, "Times New Roman", Times, serif;
+font-weight: bold;
+}
+-->
+
+  </style>
+</head>
+
+<body>
+<h2>Traceable Event Types </h2>
+
+<p>The table below lists the event types that can be traced. The performance
+counters for these traces can then be viewed with the PIAnalyzer Performance
+Counters view.</p>
+
+<h5>Table 1. Traceable event types</h5>
+
+<table width="80%" border="0" cellpadding="2" cellspacing="0">
+  <tbody>
+    <tr>
+      <th width="10%" scope="col">Value</th>
+      <th width="25%" scope="col">Trace name</th>
+      <th width="65%" scope="col">Description</th>
+    </tr>
+    <tr>
+      <td>0 
+
+        <p>(0x00)</p>
+      </td>
+      <td>Instruction cache miss to cachable location</td>
+      <td>Instruction cache miss to a cachable location requires fetch from
+        external memory.</td>
+    </tr>
+    <tr>
+      <td>1 
+
+        <p>(0x01) </p>
+      </td>
+      <td>Stall because instruction buffer cannot deliver</td>
+      <td>Stall because the instruction buffer cannot deliver an instruction.
+        This could indicate an Instruction Cache miss or an Instruction
+        MicroTLB miss. 
+
+        <p>This event occurs in every cycle in which the condition is
+        present.</p>
+      </td>
+    </tr>
+    <tr>
+      <td>2 
+
+        <p>(0x02) </p>
+      </td>
+      <td>Stall due to data dependency</td>
+      <td>Stall because of a data dependency. 
+
+        <p>This event occurs in every cycle in which the condition is
+        present.</p>
+      </td>
+    </tr>
+    <tr>
+      <td>3 
+
+        <p>(0x03) </p>
+      </td>
+      <td>Instruction MicroTLB miss</td>
+      <td>Instruction MicroTLB miss.</td>
+    </tr>
+    <tr>
+      <td>4 
+
+        <p>(0x04) </p>
+      </td>
+      <td>Data MicroTLB miss</td>
+      <td>Data MicroTLB miss.</td>
+    </tr>
+    <tr>
+      <td>5 
+
+        <p>(0x05)</p>
+      </td>
+      <td>Branch instruction executed</td>
+      <td>Branch instruction executed, branch might or might not have changed
+        program flow.</td>
+    </tr>
+    <tr>
+      <td>6 
+
+        <p>(0x06) </p>
+      </td>
+      <td>Branch mispredicted</td>
+      <td>Branch mispredicted.</td>
+    </tr>
+    <tr>
+      <td>7 
+
+        <p>(0x07) </p>
+      </td>
+      <td>Instruction executed</td>
+      <td>Instruction executed. If EVENTBUS bit [9] is HIGH, two instructions
+        were executed in this clock cycle and the count is increments by two.
+
+        <p>When performance counters for this trace are selected for the
+        PIAnalyzer Performance Counters view, the MIPS graph can also be
+        viewed.</p>
+      </td>
+    </tr>
+    <tr>
+      <td>9 
+
+        <p>(0x09) </p>
+      </td>
+      <td>Data cache access (cachable only)</td>
+      <td>Data cache access, not including Cache operations. 
+
+        <p>This event occurs for each nonsequential access to a cache line, for
+        cachable locations.</p>
+      </td>
+    </tr>
+    <tr>
+      <td>A 
+
+        <p>(0x0A) </p>
+      </td>
+      <td>Data cache access</td>
+      <td>Data cache access, not including Cache Operations. 
+
+        <p>This event occurs for each nonsequential access to a cache line,
+        regardless of whether or not the location is cachable.</p>
+      </td>
+    </tr>
+    <tr>
+      <td>B 
+
+        <p>(0x0B) </p>
+      </td>
+      <td>Data cache miss</td>
+      <td>Data cache miss, not including Cache Operations.</td>
+    </tr>
+    <tr>
+      <td>C 
+
+        <p>(0x0C) </p>
+      </td>
+      <td>Data cache write-back</td>
+      <td>Data cache write-back. 
+
+        <p>This event occurs once for each half line of four words that are
+        written back from the cache.</p>
+      </td>
+    </tr>
+    <tr>
+      <td>D 
+
+        <p>(0x0D) </p>
+      </td>
+      <td><p>Software changed the PC</p>
+      </td>
+      <td>Software changed the PC. 
+
+        <p>This event occurs any time the PC is changed by software and there
+        is not a mode change. For example, a MOV instruction with PC as the
+        destination triggers this event.</p>
+
+        <p>Executing a SWI from User mode does not trigger this event, because
+        it incurs a mode change. If EVENTBUS bit [15] is HIGH, two software PC
+        changes occurred in this clock cycle and the count is increments by
+        two.</p>
+      </td>
+    </tr>
+    <tr>
+      <td>F 
+
+        <p>(0x0F) </p>
+      </td>
+      <td>Main TLB miss</td>
+      <td>Main TLB miss.</td>
+    </tr>
+    <tr>
+      <td>10 
+
+        <p>(0x10) </p>
+      </td>
+      <td><p>External memory request</p>
+      </td>
+      <td>Explicit external data accesses (Data Cache linefills, Noncachable,
+        Write-Through).</td>
+    </tr>
+    <tr>
+      <td>11 
+
+        <p>(0x11) </p>
+      </td>
+      <td>Stall due to Load store Unit queue being full</td>
+      <td>Stall because the Load Store Unit request queue is full. 
+
+        <p>This event occurs in each clock cycle in which the condition is
+        met.</p>
+
+        <p>A high incidence of this event often indicates that the BCU is
+        waiting for transactions to complete on the external bus.</p>
+      </td>
+    </tr>
+    <tr>
+      <td>12 
+
+        <p>(0x12) </p>
+      </td>
+      <td>Forced write buffer drain</td>
+      <td>The number of times the Write Buffer was drained because of a Data
+        Synchronization Barrier command or Strongly Ordered operation.</td>
+    </tr>
+    <tr>
+      <td>20 
+
+        <p>(0x20) </p>
+      </td>
+      <td>ETMEXTOUT[0] asserted</td>
+      <td>ETMEXTOUT[0] signal was asserted for a cycle.</td>
+    </tr>
+    <tr>
+      <td>21 
+
+        <p>(0x21)</p>
+      </td>
+      <td>ETMEXTOUT[1] asserted</td>
+      <td>ETMEXTOUT[1] signal was asserted for a cycle.</td>
+    </tr>
+    <tr>
+      <td>22 
+
+        <p>(0x22)</p>
+      </td>
+      <td>ETMEXTOUT asserted</td>
+      <td>If both ETMEXTOUT[0] and ETMEXTOUT[1] signals are asserted then the
+        count is incremented by two.</td>
+    </tr>
+    <tr>
+      <td>23 
+
+        <p>(0x23)</p>
+      </td>
+      <td>Procedure call instruction executed</td>
+      <td>Procedure call instruction executed. The procedure return address was
+        pushed on to the return stack.</td>
+    </tr>
+    <tr>
+      <td>24 
+
+        <p>(0x24)</p>
+      </td>
+      <td>Procedure return instruction executed</td>
+      <td>Procedure return instruction executed. The procedure return address
+        was popped off the return stack.</td>
+    </tr>
+    <tr>
+      <td>25 
+
+        <p>(0x25)</p>
+      </td>
+      <td>Procedure return instruction executed and return address
+      predicted</td>
+      <td>Procedure return instruction executed and return address predicted.
+        The procedure return address was popped off the return stack and the
+        core branched to this address.</td>
+    </tr>
+    <tr>
+      <td>26 
+
+        <p>(0x26)</p>
+      </td>
+      <td>Procedure return instruction executed and return address predicted
+        incorrectly</td>
+      <td>Procedure return instruction executed and return address predicted
+        incorrectly. The procedure return address was restored to the return
+        stack following the prediction being identified as incorrect.</td>
+    </tr>
+    <tr>
+      <td>FF 
+
+        <p>(0xFF) </p>
+      </td>
+      <td>Cycles</td>
+      <td>An increment each cycle.</td>
+    </tr>
+  </tbody>
+</table>
+
+<h5>Related references</h5>
+<ul>
+  <li><a
+    href="../../reference/analyzer/view_performance_counters.htm">Performance
+    Counters View</a></li>
+  <li><a href="../../reference/profiler/Prof_counter_settings.htm">PIProfiler
+    Performance Counter Settings</a></li>
+</ul>
+
+<div id="footer">
+Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights
+reserved. <br>
+License: <a
+href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/view_IPC.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,85 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+"http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
+  <title>Interconnect Performance Counters View</title>
+  <link href="../../../book.css" rel="stylesheet" type="text/css">
+</head>
+
+<body>
+<h2>Interconnect Performance Counters View</h2>
+
+<p>Use the <strong>Interconnect Performance Counters</strong> view to monitor
+Processor Sub-System (PSS) bus (VIA) accesses. By default, the Interconnect
+Performance Counters view opens up as minimised on the PIAnalyzer main view. To
+view the graphs, click the restore button <img
+src="images/minimize_restore_graph.png" width="16" height="16"> or the maximize
+button <img src="images/maximize_graph.png" width="16" height="16"> on the
+Title bar.</p>
+
+<p>The graph portion of the Performance Counters view displays graphs of the
+selected traces. From all the IPC counters five different values are collected:
+cycle, read, write, wait and idle counts. Those are shown on separate lines in
+the graphs view, and the legend table. To select a trace for the graphs view,
+click the check box next to the trace name in the legend table.</p>
+
+<p>In the top left-hand corner of each graph line, the following information
+displayed:</p>
+<ul>
+  <li>Type of the trace</li>
+  <li>Sampling interval</li>
+</ul>
+
+<p>Note that the scaling of the graphs changes according to the maximum values
+for each graph. You can see the vertical axis values for each graph on the left
+side of the graph.</p>
+
+<p>You can move the mouse pointer on top of the graph lines to see the values
+as a tooltip, as shown below in Figure 1.</p>
+
+<p align="center"><img src="images/IPC_view.png" width="645" height="608"></p>
+
+<p class="figure">Figure 1. Interconnect Performance Counters view</p>
+
+<p></p>
+
+<p>A legend table is displayed below the graphs. </p>
+
+<p>Description of the table columns: </p>
+<ul>
+  <li>The <b>Char</b> column contains an identifier for each trace.</li>
+  <li>The <b>Name</b> column contains the type of performance counter that was
+    traced.</li>
+  <li>The <b>Average (1/ms)</b> column contains the average occurrence of the
+    event that was traced, within the selected timeframe.</li>
+  <li>The <b>Sum</b> column contains the total number of event occurrences
+    within the selected timeframe.</li>
+  <li>The <b>Min (1/ms)</b> column contains the minimum occurrence of the event
+    that was traced, within the selected timeframe.</li>
+  <li>The <b>Max (1/ms)</b> column contains the maximum occurrence of the event
+    that was traced, within the selected timeframe.</li>
+</ul>
+
+<p>Check the boxes at the left side of the table to select the traces for the
+graphs view.</p>
+
+<p>Columns may be reordered, resized, and sorted by clicking or dragging column
+headers.</p>
+
+<p>You can right-click on the table to open a context menu, where you can
+select to copy either selected lines or the entire table to clipboard; or to
+save the table to CSV format. </p>
+
+<p><strong>Related references </strong></p>
+<ul>
+  <li><a href="main_view.htm">Analyzer View</a></li>
+</ul>
+
+<div id="footer">
+Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights
+reserved. <br>
+License: <a
+href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+</body>
+</html>
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/view_memory_usage.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/view_memory_usage.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -1,44 +1,142 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
-"http://www.w3.org/TR/html4/loose.dtd">
-<html>
-<head>
-	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-	<title>Memory Usage View</title>
-    <link href="../../../book.css" rel="stylesheet" type="text/css">
-</head>
-
-<body>
-<h2>Memory Usage View</h2>
-<p>Use  the <strong>Memory  Usage</strong> view to display thread&#8217;s chunk usage, stack/heap usage, or both, of the profiled software running on a device. The graph portion of the Memory Usage view shows the amount of memory used along the same time interval as the thread load. A list of each thread or process appears at the bottom of the view showing the chunks, stack/heap, and total memory for each thread.</p>
-<p>Data in the Memory Usage view is layered with the stack/heap data overlaying the chunk data. Stack/heap data is represented by the color blue, while chunk data is represented by gold. The display is different depending upon the view option selected in the context menu (section A in Figure 1):</p>
-<ul>
-  <li>Show Chunk Usage &#8212; gold box only</li>
-  <li>Show Stack/Heap Usage &#8212; blue box only </li>
-  <li>Show Chunk and Stack/Heap Usage (Figure 1) &#8212; show gold box (chunk data) and a blue line (stack/heap data) </li>
-</ul>
-<p>When both are selected for display and the amounts are also equal, only a blue box will appear in the view. If the amounts are not equal, the chunk data is shown as a gold box and the stack/heap data is shown as a blue line. </p>
-<p class="note"><b>NOTE</b> The Memory Usage view is synchronized with the Thread Load view along the horizontal axis. </p>
-<p align="center"><img src="images/view_memory_usage.png" width="705" height="652"></p>
-<p class="figure">Figure 1. Memory Usage graph and thread list </p>
-<p>Description of table columns (section B in Figure 1):</p>
-<ul>
-  <li>The <b>Thread/Process</b> column name contains a wealth of data and is composed of:<ul>
-    <li>Chunks appear as: <span class="code">&lt;process&gt;::&lt;chunk name&gt; [&lt;hex start address&gt;]</span> </li>
-      <li>Threads appear as: <span class="code">&lt;process&gt;::&lt;thread name&gt;_&lt;thread ID&gt; </span></li>
-      <li> If no name is returned by the OS, the entry may appear as undetermined, e.g. &quot;<span class="code">::_</span>&quot;. </li>
-      </ul>
-  </li>
-  <li>The <b>Chunks</b> column displays the  amount of memory used by each chunk.</li>
-  <li>The <b>Stack/Heap</b> column displays the  amount  of memory used by the thread in its stack/heap.</li>
-  <li>The <b>Memory Total</b> column displays the  sum of the Chunks and Stack/Heap columns. </li>
-</ul>
-<p>Columns may be reordered, resized, and sorted by clicking or dragging column headers.</p>
-<p><strong>Related references </strong></p>
-<ul>
-  <li><a href="main_view.htm">Analyzer View</a></li>
-<li><a href="menu_memory_graph.htm">Memory Usage Menu </a></li>
-<li><a href="wnd_memory_usage_statistics.htm">Memory Usage Statistics</a> </li>
-</ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
-</body>
-</html>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+"http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
+  <title>Memory Usage View</title>
+  <link href="../../../book.css" rel="stylesheet" type="text/css">
+</head>
+
+<body>
+<h2>Memory Usage View</h2>
+
+<p>Use the <strong>Memory Usage</strong> view to display thread’s chunk
+usage, stack/heap usage, or both, of the profiled software running on a device.
+The graph portion of the Memory Usage view shows the amount of memory used
+along the same time interval as the thread load. A list of each thread or
+process appears at the bottom of the view showing the chunks, stack/heap, and
+total memory for each thread. In addition, if library events have been
+constructed into the imported PIProfiler data file, additional information is
+displayed for those, see <a href="#Library">Library events information</a>
+below.</p>
+
+<p>Data in the Memory Usage view is layered with the stack/heap data overlaying
+the chunk data. Stack/heap data is represented by the color blue, while chunk
+data is represented by gold. The display is different depending upon the view
+option selected in the Title bar drop-down menu, show in Figure 1, or in the
+Investigator menu &gt; <a href="menu_memory_graph.htm">Memory Graph Menu
+</a>.</p>
+
+<p align="center"><img src="images/memory_graph_drop_down.png" width="156"
+height="58"></p>
+
+<p class="figure">Figure 1. Memory Usage Title bar drop-down menu</p>
+
+<p>According to the selection, the graph displays the following (Figure 2):</p>
+<ul>
+  <li>Show Chunk Usage — gold box only</li>
+  <li>Show Stack/Heap Usage — blue box only </li>
+  <li>Show Chunk and Stack/Heap Usage (Figure 2) — gold box (chunk data) and
+    a blue line (stack/heap data) </li>
+</ul>
+
+<p>When both are selected for display and the amounts are also equal, only a
+blue box will appear in the view. If the amounts are not equal, the chunk data
+is shown as a gold box and the stack/heap data is shown as a blue line. </p>
+
+<p>Additionally, a black line indicating the total memory usage is available.
+The line is always displayed by default, but you can choose to hide or show the
+line by either right-clicking on the graph and selecting <strong>Show Total
+Memory Usage</strong>, or by selecting <strong>Investigator</strong> -&gt;
+<strong>Memory Graph</strong> -&gt; <strong>Show Total Memory Usage</strong> .
+</p>
+
+<p class="note"><b>NOTE</b> The Memory Usage view is synchronized with the
+Thread Load view along the horizontal axis. </p>
+
+<p align="center"><img src="images/view_memory_usage.png"></p>
+
+<p class="figure">Figure 2. Memory Usage graph and thread list </p>
+
+<p>Description of table columns (Figure 2):</p>
+<ul>
+  <li>The <b>Thread/Chunk</b> column name contains a wealth of data and is
+    composed of: 
+    <ul>
+      <li>Chunks appear as: <span class="code">&lt;process&gt;::&lt;chunk
+        name&gt; [&lt;hex start address&gt;]</span> </li>
+      <li>Threads appear as: <span class="code">&lt;process&gt;::&lt;thread
+        name&gt;_&lt;thread ID&gt; </span></li>
+      <li>If no name is returned by the OS, the entry may appear as
+        undetermined, e.g. "<span class="code">::_</span>". </li>
+    </ul>
+  </li>
+  <li>The <b>Chunks</b> column displays the amount of memory used by each
+  chunk.</li>
+  <li>The <b>Stack/Heap</b> column displays the amount of memory used by the
+    thread in its stack/heap.</li>
+  <li>The <b>Memory Total</b> column displays the sum of the Chunks and
+    Stack/Heap columns. </li>
+</ul>
+
+<p>Columns may be reordered, resized, and sorted by clicking or dragging column
+headers.</p>
+
+<h4><a name="Library" id="Library">Library event information</a></h4>
+
+<p>If the imported .dat file from Profiler includes library event data,
+additional information is displayed in the Memory Usage graph, and a separate
+table is included for Library Events information below the graph, see Figure 3
+below.</p>
+
+<p align="center"><img src="images/view_memory_library_events.png"></p>
+
+<p class="figure">Figure 2. Memory Usage graph with library events information
+</p>
+
+<p>In the Memory Usage graph:</p>
+<ul>
+  <li>Below the vertical axis of the graph a <img
+    src="images/event_loaded.png"> symbol is displayed for an event where a
+    library is loaded, and <img src="images/event_unloaded.png"> symbol when a
+    library is unloaded. When the mouse pointer is placed on the symbol a
+    tooltip is displayed, including: 
+    <ul>
+      <li>library name,</li>
+      <li>name of the process that loaded/unloaded the library,</li>
+      <li>load size of the library, and</li>
+      <li>count of times the library has been loaded on system level.</li>
+    </ul>
+  </li>
+</ul>
+
+<p>The Library Events table lists all the libraries for which data is
+available. The following columns are included:</p>
+<ul>
+  <li>The <strong>Loaded Library</strong> column displays the name of the
+    library. The check boxes indicate the libraries selected for the graph. By
+    default the libraries are selected according to the selection in the Memory
+    Usage table, that is, only the libraries used by the selected threads or
+    chunks are selected for the graph, but you can also select to include other
+    libraries.</li>
+  <li>The <strong>Load Size</strong> column indicates the size of the library
+    within the selected time slot.</li>
+  <li>The <strong>Selection Event Count</strong> column indicates the number of
+    library events within the selected time slot.</li>
+</ul>
+
+<p><strong>Related references </strong></p>
+<ul>
+  <li><a href="main_view.htm">Analyzer View</a></li>
+  <li><a href="menu_memory_graph.htm">Memory Graph Menu </a></li>
+  <li><a href="wnd_memory_usage_statistics.htm">Memory Usage Statistics</a>
+  </li>
+</ul>
+
+<div id="footer">
+Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights
+reserved. <br>
+License: <a
+href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/view_performance_counters.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,133 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+"http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
+  <title>Performance Counters View</title>
+  <link href="../../../book.css" rel="stylesheet" type="text/css">
+</head>
+
+<body>
+<h2>Performance Counters View</h2>
+
+<p>Use the <strong>Performance Counters</strong> view to display information on
+performance counter traces. By default, the Performance Counters view opens up
+as minimised on the PIAnalyzer main view. To view the graphs, click the restore
+button <img src="images\minimize_restore_graph.png" width="16" height="16"> or
+the maximize button <img src="images\maximize_graph.png" width="16"
+height="16"> on the Title bar.</p>
+
+<p>The Performance Counters displayed in the view include two user selected
+traces (A and B in Figure 1) and CPU cycles (C in Figure 1). A MIPS (Million
+Instructions Per Second) counter is also available if <b>Instructions
+executed</b> has been selected as one of the traces.</p>
+
+<p>You can select which traces are displayed in the graphs view by clicking the
+check box next to the trace name in the legend table below the graphs. When
+several traces are selected, a separate graph line is displayed for each trace,
+as shown in Figure 1. </p>
+
+<p>In the top left-hand corner of each graph line, the following information
+displayed:</p>
+<ul>
+  <li>type of the trace,</li>
+  <li>the sampling interval (1 sample per millisecond in Figure 1),</li>
+  <li>the minimum and maximum values over the whole duration of the trace.
+    (Note that the legend table lists the minimum and maximum values only for
+    the selected timeframe.) </li>
+</ul>
+
+<p>Note that the scaling of the graphs changes according to the maximum values
+for each graph. You can see the vertical axis values for each graph on the left
+side of the graph.</p>
+
+<p>A legend table is displayed below the graphs.</p>
+
+<p align="center"><img
+src="images/performance_counters_view_all_graphs.png"></p>
+
+<p class="figure">Figure 1. Performance Counters view with all trace graphs
+displayed</p>
+
+<p></p>
+
+<p>Description of the table columns: </p>
+<ul>
+  <li>The <b>Char</b> column contains an identifier for each trace.</li>
+  <li>The <b>Name</b> column contains the type of performance counter that was
+    traced.</li>
+  <li>The <b>Average (1/ms)</b> column contains the average occurrence of the
+    event that was traced, within the selected timeframe (for example, the
+    average number of cache misses per millisecond, as shown in Figure 1).</li>
+  <li>The <b>Sum</b> column contains the total number of event occurrences
+    within the selected timeframe. (not included for MIPS)</li>
+  <li>The <b>Min (1/ms)</b> column contains the minimum occurrence of the event
+    that was traced, within the selected timeframe (for example, minimum number
+    of data stalls per millisecond, as show in Figure 1).</li>
+  <li>The <b>Max (1/ms)</b> column contains the maximum occurrence of the event
+    that was traced, within the selected timeframe (for example, maximum number
+    of data stalls per millisecond, as show in Figure 1).</li>
+  <li>The <b>Per A</b> / <b>Per B</b> / <b>Per C</b> columns show the ratio of
+    the values of the different traces (For example, Per A shows the number of
+    events in the sum column of each trace divided by the sum of trace A). (not
+    included for MIPS)</li>
+</ul>
+
+<p>Check the boxes at the right side of the table to select the traces for the
+graphs view.</p>
+
+<p>Columns may be reordered, resized, and sorted by clicking or dragging column
+headers.</p>
+
+<p>You can right-click on the table to open a context menu, where you can
+select to copy either selected lines or the entire table to clipboard; or to
+save the table to CSV format. </p>
+<br>
+
+
+<p><strong>MIPS counter and graph</strong></p>
+
+<p>The Million Instructions Per Second (MIPS) graph gives you a general idea of
+CPU speed in a measured use case. The basic use case for the MIPS analysis
+would be to check any low areas in the graph since they may reveal unoptimized
+features, for example, in terms of memory access (reads and writes). The higher
+the MIPS values, the better and the faster the CPU is in executing
+instructions.</p>
+
+<p>A MIPS (Million Instructions Per Millisecond) graph is displayed in the
+Performance Counters view, when <b>Instructions executed</b> has been selected
+as one of the counters. If <b>Instructions executed</b> has been selected, the
+dialog below is displayed during PIAnalyser file import:</p>
+
+<p align="center"><img src="images/MIPS_speed_dialog.png"></p>
+
+<p class="figure">Figure 1. MIPS Graph Generation</p>
+
+<p>The processor speed information is needed for calculating the data for the
+MIPS graph. The rest of the data for the calculation is included in the
+<b>Instructions executed</b> and <b>CPU cycles</b> counters.</p>
+
+<p>The MIPS counter information is displayed in the graphs view and the legend
+table together with the other performance counters. Note, however, that for
+MIPS only <b>Average (1/ms)</b>, <b>Min (1/ms)</b>, and <b>Max (1/ms)</b>
+information is displayed in the legend table.</p>
+
+<p><br>
+</p>
+
+<p><strong>Related references </strong></p>
+<ul>
+  <li><a href="../../reference/analyzer/traceable_events.htm">Traceable Event
+    Types</a></li>
+  <li><a href="../../reference/profiler/Prof_counter_settings.htm">PIProfiler
+    Performance Counter Settings</a></li>
+  <li><a href="main_view.htm">Analyzer View</a></li>
+</ul>
+
+<div id="footer">
+Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights
+reserved. <br>
+License: <a
+href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+</body>
+</html>
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/view_power_usage.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/view_power_usage.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -2,32 +2,49 @@
 "http://www.w3.org/TR/html4/loose.dtd">
 <html>
 <head>
-	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-	<title>Power Usage View</title>
-    <link href="../../../book.css" rel="stylesheet" type="text/css">
+  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
+  <title>Power Usage View</title>
+  <link href="../../../book.css" rel="stylesheet" type="text/css">
 </head>
 
 <body>
 <h2>Power Usage View</h2>
-<p>Use  the <strong>Power Usage</strong> view to display  the power consumption of the profiled software running on a device. </p>
-<p align="center"><img src="images/view_power_usage.png" width="705" height="652"></p>
+
+<p>Use the <strong>Power Usage</strong> view to display the power consumption
+of the profiled software running on a device. </p>
+
+<p align="center"><img src="images/view_power_usage.png" width="629"
+height="468"></p>
+
 <p class="figure">Figure 1. Power Usage graph</p>
+
 <p>The Power Usage view (Figure 1) provides:</p>
 <ul>
   <li>graph power usage over time.</li>
-<li>graph or hide a horizontal line of average power usage during the selected time interval</li>
-<li>display and change the voltage (v)</li>
-<li>display and change the battery capacity (mAh)</li>
-<li>display average power usage (mV) over the selected interval</li>
-<li>display average energy consumption (mWs) over the selected interval</li>
+  <li>graph or hide a horizontal line of average power usage during the
+    selected time interval</li>
+  <li>display and change the voltage (v)</li>
+  <li>display and change the battery capacity (mAh)</li>
+  <li>display average power usage (mV) over the selected interval</li>
+  <li>display average energy consumption (mWs) over the selected interval</li>
 </ul>
-<p>Left-click and drag the pointer across the graph to select a portion of the power consumption graph. As the pointer is dragged, the start and end lines appear on the graph. Once the mouse click is released, the time interval is updated to indicate the changes made. </p>
+
+<p>Left-click and drag the pointer across the graph to select a portion of the
+power consumption graph. As the pointer is dragged, the start and end lines
+appear on the graph. Once the mouse click is released, the time interval is
+updated to indicate the changes made. </p>
+
 <p><strong>Related references </strong></p>
 <ul>
   <li><a href="main_view.htm">Analyzer View</a></li>
-<li><a href="menu_power_graph.htm">Power Graph Menu </a></li>
-	<li><a href="wnd_power_usage_statistics.htm">Power Usage Statistics</a> </li>
+  <li><a href="menu_power_graph.htm">Power Graph Menu </a></li>
+  <li><a href="wnd_power_usage_statistics.htm">Power Usage Statistics</a> </li>
 </ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+
+<div id="footer">
+Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights
+reserved. <br>
+License: <a
+href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/wnd_memory_usage_statistics.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/wnd_memory_usage_statistics.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -22,6 +22,6 @@
   <li><a href="main_view.htm">Analyzer View</a></li>
 <li><a href="menu_memory_graph.htm">Memory Graph Menu </a></li>
 </ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/wnd_power_graph_settings.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/wnd_power_graph_settings.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -22,6 +22,6 @@
   <li><a href="main_view.htm">Analyzer View</a></li>
 <li><a href="menu_power_graph.htm">Power Graph Menu </a></li>
 </ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/wnd_power_usage_statistics.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/analyzer/wnd_power_usage_statistics.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -26,6 +26,6 @@
   <li><a href="main_view.htm">Analyzer View</a></li>
 <li><a href="menu_power_graph.htm">Power Graph Menu </a></li>
 </ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/banked_registers.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/banked_registers.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -11,6 +11,6 @@
 <h3>Banked Registers </h3>
 <P LANG="en-GB" ALIGN=JUSTIFY>Current ARM processor architecture has a total of 37 registers. The registers are arranged into overlapping banks. Each of the banks represents a set of 16 general-purpose registers, a current program status register and an optional stored program status register (which is present only in the exception mode banks). There is one bank of registers for each of the processor modes. Some of the registers between the register banks refer to the same physical register, and some of the registers are private for each of the banks respectively. </P>
 <P LANG="en-GB" ALIGN=JUSTIFY>Purpose of the banks is to reduce the amount of data to be stored to the stack when the processor mode is changed. User mode registers can be accessed from the privileged modes through a specific form of the STM (store multiple) and LDM (load multiple) instructions. Information within the user mode registers are valuable in performance measurements when analyzing the operation of the user mode software from a privileged mode, such as during a periodic interrupt</P>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/compile_time.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/compile_time.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -11,6 +11,6 @@
 <h3>Compile-Time Symbolic Information</h3>
 <p>The deployment of programmed and compiled functionality within a final software image can be resolved from symbolic information that is produced at compile-time. In practice, symbolic information contains an address map of each of the data and code segments that have been produced within the compilation and combined when building a complete image in so-called rombuild stage (in Symbian toolchain). The address map connects the final addresses within a software image with names of functions, methods, dynamic link libraries, executables, device drivers, or other names that have been assigned by the programmer.</p>
 <P LANG="en-GB" ALIGN=JUSTIFY>In performance evaluation, it is essential to be able to discriminate points of execution according to their presence in different functions. With the ability to perform such discrimination, it is possible to identify the functions and methods in which the execution has been recorded to take place. Accordingly, it is possible to calculate statistical utilization percentages for individual functions or methods. On the other hand, symbolic information has other applications. In general, without sources of symbolic information, performance measurement information cannot be grounded to the actual software design known by the developer, making it difficult to interpret the results. Through understanding of the memory layout of the analyzed software image, it becomes possible to perform more complicated analysis such as resolution of function call chains.</P>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/cpu_timer.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/cpu_timer.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -19,6 +19,6 @@
 			is that in most cases the timers have already been employed
 			by other activities. Through investigation of those activities it
 is still possible to use the CPU timers in harmony with them, but with certain limitations.</p>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/curr_pgm_status_reg.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/curr_pgm_status_reg.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -23,6 +23,6 @@
 			to distinguish the modes and to select appropriate actions
 			according to the mode. Without such precautions, exceptions or
 fault situations might take place.</p>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/delayed_fn_call.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/delayed_fn_call.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -11,6 +11,6 @@
 <h3>Delayed Function Call</h3>
 <P LANG="en-GB" ALIGN=JUSTIFY>A delayed function call (DFC) is a feature within the Symbian interrupt architecture. DFCs are used to perform interrupt-related activities that are too time-consuming to be processed in the interrupt service routine (ISR). Symbian kernel keeps a list of all DFCs queued to be processed. An ISR can add a DFC to the queue at any time, but the actual processing of the DFCs takes place only after all the ISRs have been processed first, but before the control is taken back to the scheduled threads. In addition to the exit from the interrupt handling, the DFC queue is also processed in the context of exit from a kernel executive call or a kernel server call.</P>
 <P LANG="en-GB" ALIGN=JUSTIFY>Performance measurements can utilize DFCs in activities that require processing that cannot be performed within the interrupts. Such processing could be, for example, exporting buffered data from privileged buffers to user-mode software. In addition, performance measurements should take into account the time spent within the DFCs, since the activities that take place in them do not belong to the normal processing of the scheduled threads.</P>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/dynamic_bin_res.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/dynamic_bin_res.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -16,6 +16,6 @@
   <LI>
     <P LANG="en-GB" ALIGN=JUSTIFY>The actual binary code is sampled during execution so that small pieces of executable binaries can be known to have resided at a certain address at a certain time. After sampling the execution, it is then possible to solve the puzzle of many small pieces of code/address/time elements during the analysis phase. This approach requires quite complicated processing.</P>
 </OL>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/file_sys_storing.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/file_sys_storing.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -10,6 +10,6 @@
 <body>
 <h3>File System Storing</h3>
 <p>Storing performance related data has to suit the performance measurement activity. If there is not much data, it can be exported from the device right away by suitable means, such as through the serial port. When the amount of data is larger, it can also be exported to a file within the file system. In that case it is practical to store the data at first to a small memory buffer. Then the buffer can be written to the file in a separate activity that does not disturb the measured mechanisms. For example if the data is being collected within an interrupt or in a kernel hook, the file system related activities should take place within the user code.</p>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/int_stack.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/int_stack.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -10,6 +10,6 @@
 <body>
 <h3>Interrupt Stack</h3>
 <p>When the ARM processor state is switched to the IRQ (or FIQ) mode, the processor registers that are in use are also changed to banked registers dedicated to that mode. Each of the processor modes has specific banked registers in the ARM architecture, facilitating rapid switching between the modes. The stack pointer register (usually register R13) has a banked register in each of the modes. The pointer within the R13 points to the Interrupt Stack, which becomes the active stack immediately after execution is resumed within the interrupt processing. The interrupt stack holds the return value to the point of execution immediately before the interrupt. Therefore it is possible to resolve the exact point of execution for statistical analysis within an interrupt, such as for example within a periodic interrupt.</p>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/kernel_containers.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/kernel_containers.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -11,6 +11,6 @@
 <h3>Kernel Containers </h3>
 <P LANG="en-GB" ALIGN=JUSTIFY>Kernel containers are internal parts of the Symbian OS kernel. The Kernel stores its most fundamental data structures in kernel containers. Those fundamental data structures include threads, processes, chunks, mutex objects, semaphores, and many other similar kinds of elements that belong to the internal operation of the OS. In an interrupt, it is possible to investigate the contents of the kernel container, thus resolving information that is available in a readily processed form and that may be very difficult to be extracted by any other means.</P>
 <P LANG="en-GB" ALIGN=JUSTIFY>One use of investigating kernel containers is in the implementation of memory tracing. Information about the memory allocated by each thread (stack and heap size) can be easily acquired during an interrupt. Experiences show that resolving the same information from the user side requires much more processing.</P>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/kernel_hook.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/kernel_hook.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -11,6 +11,6 @@
 <h3>Kernel Hook</h3>
 <P LANG="en-GB" ALIGN=JUSTIFY>The information and execution flow within the Symbian kernel contains lots of useful information that can be used to trace sources of performance problems. The only problem with that information is that it is difficult to be stored at real time with any external user-mode software, since it has no access to the data that is private to the kernel executable. One way to gain access to the private data of the kernel is to add small modifications to selected locations of the kernel. Those modifications are referred to as the kernel hooks.</P>
 <P LANG="en-GB" ALIGN=JUSTIFY>When execution reaches a kernel hook, a small part of kernel hook code is executed. The kernel hook code stores selected important information that may be available only at a small fraction of time in the processing that takes place at the immediate vicinity of the hook. The collected few bytes of data are then stored sequentially into a large memory array. The process takes place quickly and should not disturb the kernel activities very much.</P>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/link_register.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/link_register.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -11,6 +11,6 @@
 <h3>Link Register Value</h3>
 <p>Link register as presented here is specific to the instruction set of the ARM architecture, even though similar solutions can be found from other processor families. Purpose of the link register is to store the value of the address following an executed Branch and Link instruction. Purpose of storing the value is to be able to continue the execution from the next instruction following the branch and link instruction, after returning from a subroutine. In practice this takes place by storing the value from the link register back to the program counter. Link register is a banked register, thus each of the processor modes refer to a dedicated physical register. In performance measurements, link register values can be inspected in order to resolve addresses from which the execution has branched to the currently executing function. A problem in this resolution is that the link register value is usually stored to the stack after entering a custom subroutine, and therefore the values in it do not have to be preserved. The correct link register value is always retrieved from the stack just before returning from the subroutine. This permits the subroutine to trash the value present in the link register during its execution. The trashing usually takes place when a sequential branch and link command is executed within a subroutine. It leaves the link register with a value of the address next to the most recent branch and link command instead of the original value (stored to the stack) that would point to the return address outside the subroutine.</p>
 <P LANG="en-GB" ALIGN=JUSTIFY>In performance measurements, link register values can be used to resolve the caller / callee relations between the functions or methods at run-time. In a practical arrangement, this can be done for example during a periodic interrupt. The explained limitations within the correctness of the link register value have to be taken into account in the analysis, but by following a certain logic the correct values can be distinguished from the values in which the link register has already trashed. In simple terms, the values that point outside the function that are currently under execution can be considered as correct return values for the function, thus revealing the caller of that function. The values that point inside the same function result from subsequent branches that have taken place within the function before the investigation, and cannot be considered correct return values.</P>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/os_thread.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/os_thread.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -10,6 +10,6 @@
 <body>
 <h3>OS Thread Name and ID </h3>
 <p>In interrupt processing or kernel executable in a privileged mode and within the kernel process, it is possible to efficiently resolve the name and the thread ID of the currently executing thread. Accordingly, it is possible to resolve the average execution time distribution between different threads in a periodic interrupt. This takes place simply by sequentially storing the identification of the thread that was under execution when the interrupt occurred.</p>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/periodic_int.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/periodic_int.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -10,6 +10,6 @@
 <body>
 <h3>Periodic Interrupt</h3>
 <p>Symbian OS provides periodic interrupts that occur each millisecond or its multiples. The benefit of employing a periodic interrupt in performance measurements is that when the interrupt occurs, the processor is switched to a privileged mode before the measurement software interrupt gets executed. In a privileged mode it is possible to gather information from the operating system in ways that would not be possible while in user mode. Disadvantage of periodic interrupts is that activities within them cannot last for too long in order not to disturb other processing. Therefore the recorded information has to be gathered in a memory buffer and written to an external output or file system at a later time, for example in a DFC.</p>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/pgm_counter.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/pgm_counter.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -11,6 +11,6 @@
 <h3>Program Counter Value</h3>
 <p>Program counter is a special register in sequential processors following the principles of Von Neumann architecture. Its purpose is to store the address of the currently executing instruction. In performance measurements, the value of the program counter can be inspected in order to resolve the location of the current execution. On the other hand, program counter-relative values stored to the stack can be used to retrieve return values of branch instructions and interrupts. In ARM architecture, program counter is the register R15 but it is usually referred to as the PC. It is an unbanked register thus its value refers to the same physical register in each of the processor modes.<br>
 </p>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/proc_mode.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/proc_mode.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -12,6 +12,6 @@
 <P LANG="en-GB" ALIGN=JUSTIFY>ARM processor architecture supports seven processor modes. Names of the modes are User, FIQ, IRQ, Supervisor, Abort, Undefined, and System. Purpose of the modes is to enable a suitably written operating system to control the use of certain system resources. On the other hand, the modes enable fast switching of context, for example, from user code to interrupt handling (see Banked Registers). All modes except the User mode are known as privileged modes. Of the privileged modes, all five modes except the System mode are known as exception modes. Exception modes are entered when an exception or an interrupt occurs. System mode can be used to control system resources from within the same register context as the user mode.</P>
 <P LANG="en-GB" ALIGN=JUSTIFY>User mode can be changed to another mode only through an exception or an interrupt, making it possible to efficiently control the change between modes. In performance measurements, processor modes have a large importance since the processor mode indicates the status of processing within the system. When storing performance Related references in a part of the system that may be accessed with any of the processor modes active, it may be necessary to deduce from the processor mode whether certain operations are legal or not, and to proceed accordingly.</P>
 <p>&nbsp;</p>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/read_write_load.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/read_write_load.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -18,6 +18,6 @@
 <P LANG="en-GB" ALIGN=JUSTIFY>Secondly, operation of the file system is similarly complicated by disturbing factors such as the activity of other processing within the system, and interrupt load caused by other peripherals or other similar activity. For example, the load within the bus through which the data is transferred to the peripheral storing the information and disturbance caused by concurrent write or read requests.</P>
 <P LANG="en-GB" ALIGN=JUSTIFY>Therefore the performance measurements related to either memory or file system should be made under as undisturbed conditions as possible. Sometimes the measurements should be made repeatable so that the performance changes caused by possible modifications in certain properties of the system could be easily resolved.</P>
 <P LANG="en-GB" ALIGN=JUSTIFY>On the other hand, it may be handy to have measurement results of practical performance of memory/file system as it is seen by the applications. For that purpose it can be possible to use a technique similar to the sampling, as described earlier. In that approach very short tests are performed periodically and changes in their respective results are investigated with the other activities performed within the system. Through such kind of investigation it can be possible to identify which activities within the system are those that cause actual performance loss in say, the file system.</P>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/rofs.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/rofs.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -10,6 +10,6 @@
 <body>
 <h3>Read Only File System (ROFS) </h3>
 <p>Read Only File System, which is actually the greatest source of need for dynamic binary resolution. ROFS is a file system that dynamically loads system binaries at run-time in an on-demand basis, thus reducing the amount of binary code required in the system start-up phase.</p>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/saved_pgm_status_reg.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/saved_pgm_status_reg.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -19,6 +19,6 @@
 			instrumentation within an interrupt, it can be useful to
 			investigate the value within the SPSR in order to find out the
 mode of the processor before the interrupt.</p>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/serial_output.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/serial_output.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -10,6 +10,6 @@
 <body>
 <h2>Serial Output</h2>
 <p>Serial Output through an UART can be used to generate an immediate trace of certain performance-critical activities. If formatted debug printing is supported by the software system (as it is in Symbian OS), it is possible to output information in human readable form. This includes numeric values or strings that are in connection to the immediate situation within the system at the point the printing occurs. Serial Output is a slow way to output information, and its excessive use affects the system performance significantly. Therefore it cannot be used in order to gather large amounts of data.</p>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/sw_interrupt.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/sw_interrupt.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -11,6 +11,6 @@
 <h3>SWI, Software Interrupt</h3>
 <p>In the ARM instruction set, software interrupts are software-generated exceptions that cause the processor mode to change to the supervisor mode, normal interrupts to disable, and the execution to branch into the location corresponding to the software interrupt exception (0xFFFF0008 or 0x00000008, depending on the configuration). The type of the interrupt can be defined with a 24-bit value.</p>
 <P LANG="en-GB" ALIGN=JUSTIFY>A software interrupt is issued with the SWI instruction. Software interrupts are used generally to implement operating system calls, since they enable a quick and controlled context switch to a privileged mode. When performing software performance measurements, the use of software interrupts can become very useful, as they provide a way to record run-time information about the current state of the software by using the resources available within the kernel while being in a privileged mode.</P>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/swi_interrupt.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/swi_interrupt.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -13,6 +13,6 @@
 <P LANG="en-GB" ALIGN=JUSTIFY>When processing a SWI, the operating mode of the ARM is switched rapidly to the supervisor mode, thus allowing a controlled means for accessing system and kernel resources with privileged rights. This makes SWIs a valuable tool for performance measurements. Custom SWIs can be used to collect important system-level information during the execution of normal user-level software.</P>
 <P LANG="en-GB" ALIGN=JUSTIFY>A drawback is that the instruction that causes the SWI to take place has to be added to the specific part of interest within the software. Recompilation of that part of source code is consequently needed. In practice this restricts the use of SWIs in performance measurements to those specific parts of software that have already been identified as interesting through other means of performance analysis.</P>
 <P LANG="en-GB" ALIGN=JUSTIFY>It may also be necessary to follow certain precautions before inserting a SWI into a custom part of software code &ndash; some generic functions can be entered in both user and privileged modes. Since SWIs are allowed in general only in user mode software, it may be necessary to take a look at the CPSR (current program status register) in order to resolve the current processor mode before invoking the SWI.</P>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/tcpip.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/methods/tcpip.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -15,6 +15,6 @@
   <li>by measuring the network traffic itself (TIP trace) that is passed through the stack when the connection opened.</li>
 </ul>
 <P LANG="en-GB" ALIGN=JUSTIFY>TCP/IP trace (or TIP trace) gathers information about packet sizes, source and destination addresses/ports and visualize the data in a cumulative graph. The main intention is to gather information about the causes of network traffic blocks whether they are caused by false implementation of an application or protocol stack or a result of highly loaded network.</P>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/BUP_trace.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/BUP_trace.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -15,6 +15,6 @@
 <ul>
   <li><a href="../../tasks/analyser/key_profile_pref.htm">Key Press Profile</a></li>
 </ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/DSP_trace.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/DSP_trace.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -10,6 +10,6 @@
 <body>
 <h2>DSP Trace</h2>
 <p>This provides an exact trace for DSP load visualization.</p>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/GFC_trace.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/GFC_trace.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -17,6 +17,6 @@
 <ul>
   <li><a href="GPP_trace.htm">Address/Thread Trace</a></li>
 </ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/GPP_trace.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/GPP_trace.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -39,6 +39,6 @@
   <li><a href="GFC_trace.htm">Function Call Trace</a>  </li>
 </ul>
 <p></p>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/IRQ_trace.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/IRQ_trace.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -10,6 +10,6 @@
 <body>
 <h2>Interrupt Request Trace</h2>
 <p>This trace records IRQ interrupts and their respective identification.</p>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/ITT_trace.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/ITT_trace.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -14,6 +14,6 @@
 <p>When you import a Profiler data file (*.dat) that contains dynamic binary support trace information, the importer needs to locate the compiled dynamic binary files. The importer relies on .pkg, .oby, and .iby files for mapping the fullpath binary names on the target device to the compiled dynamic binaries.</p>
 <p>If you specified a Carbide.c++ project for importing, the associated .pkg file will be automatically added. On the other hand, you may have a .oby or .iby file, such as the ROFS .oby file, that contains a list of binaries to be included. If an oby/iby file is added to the list, the importer automatically leaves out files that are known not to be binary executable data.   If you specified a Carbide.c++ project or EPOCROOT, the importer will try to help you find oby/iby files to add.</p>
 <p>If you have custom files in your oby/iby file that are not binary executables and should not take part in the analysis, you might consider removing them from the oby/iby before continuing with the analysis. If those files are very large, processing might take longer.</p>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/MEM_trace.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/MEM_trace.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -26,6 +26,6 @@
   <li><a href="../analyzer/view_memory_usage.htm"> Memory Usage View</a></li>
 <li><a href="../analyzer/wnd_memory_usage_statistics.htm">Memory Usage Statistics </a></li>
 </ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/PRI_trace.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/PRI_trace.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -10,6 +10,6 @@
 <body>
 <h2>Thread Priority Trace</h2>
 <p>This trace takes samples of thread priorities. When the operating system is called, the time and priority ranking for the currently executing thread is recorded. Because a thread's priority may change over time, sometimes more than one priority ranking will be recorded for a thread.</p>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/PWR_trace.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/PWR_trace.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -17,6 +17,6 @@
 <li><a href="../analyzer/wnd_power_graph_settings.htm">Power Usage Settings</a> </li>
 <li><a href="../analyzer/wnd_power_usage_statistics.htm">Power Usage Statistics </a></li>
 </ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/Prof_counter_settings.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,83 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+  <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+  <title>PIProfiler Performance Counter Settings</title>
+  <link href="../../../book.css" rel="stylesheet" type="text/css">
+  <style type="text/css">
+<!--
+ .style1 {font-family: "Courier New", Courier, mono}
+-->
+
+  </style>
+</head>
+
+<body>
+<h2>PIProfiler Performance Counter Settings</h2>
+
+<p>The figures and instructions below demonstrate the Performance Counter
+sampler settings for PIProfiler.</p>
+
+<p align="center"><img src="images/profiler_PEC_settings5.png" width="180"
+height="320"></p>
+
+<p class="figure">Figure 1. Performance counter sampler in PI Profiler UI list
+(S60)</p>
+<ol>
+  <li>In the Profiler sampler list (Figure 1), select <b>Performance
+    counter sampler</b> -&gt; <b>Sampler settings</b> to open
+    the Performance counter settings dialog (Figure 2). 
+    <p align="center"><img src="images/profiler_PEC_settings1.png" width="180"
+    height="320"></p>
+    <p class="figure">Figure 2. Performance counter settings dialog ( two
+    counters setup)</p>
+  </li>
+  <li>In the Performance counter settings dialog, select Performance counter 1.
+    The below dialog opens (Figure 3). 
+    <p align="center"><img src="images/profiler_PEC_settings2.png" width="180"
+    height="320"></p>
+    <p class="figure">Figure 3. Setting the trace point for performance counter
+    #1.</p>
+    <p>Type in the trace point and select <b>OK</b>.</p>
+  </li>
+  <li>Select performance counter 2: the below dialog opens. 
+    <p align="center"><img src="images/profiler_PEC_settings3.png" width="180"
+    height="320" alt=""> </p>
+    <p class="figure">Figure 4. Setting the trace point for performance counter
+    #2</p>
+    <p>Type in the trace point and select <b>OK</b>. </p>
+  </li>
+  <li>Select Back to return to the sampler list.</li>
+  <li>Enable the sampler by selecting from the list: <b>Performance
+    counter sampler</b>s -&gt; <b>Enable</b>.
+    <p align="center"><img src="images/profiler_PEC_settings4.png" width="180"
+    height="320"></p>
+    <p class="figure">Figure 5. Enabling the sampler</p>
+  </li>
+
+  <p>You can view the information on the sampler by selecting
+  <b>Performance counter sampler</b> -&gt; <b>Sampler
+  info</b>. See figure 6.</p>
+
+  <p align="center"><img src="images/profiler_PEC_settings6.png" width="180"
+  height="320"></p>
+
+  <p class="figure">Figure 6. Performance counter sampler info dialog</p>
+
+<h5>Related references</h5>
+</ol>
+<ul>
+  <li><a
+    href="../../reference/analyzer/view_performance_counters.htm">Performance
+    Counters View</a></li>
+  <li><a href="../../reference/analyzer/traceable_events.htm">Traceable Event
+    Types</a></li>
+</ul>
+
+<div id="footer">
+Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights
+reserved. <br>
+License: <a
+href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+</body>
+</html>
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/SWI_trace.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/SWI_trace.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -10,6 +10,6 @@
 <body>
 <h2>Software Interrupt Trace</h2>
 <p>This trace records information on software interrupts and the threads that caused them.</p>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/TIP_trace.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/TIP_trace.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -10,6 +10,6 @@
 <body>
 <h2>TCP/IP Trace</h2>
 <p>This is an exact trace that records TCP/IP activity such as packet and data amounts.</p>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/Trace_Items.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/Trace_Items.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -19,6 +19,6 @@
   <li><a href="PWR_trace.htm">Power Usage Trace </a></li>
   <li><a href="PRI_trace.htm">Thread Priority Trace</a></li>
 </ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/advanced_options.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/advanced_options.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -83,6 +83,6 @@
   <li><a href="tracing_options.htm">Setting Tracing Options</a></li>
 <li><a href="output_settings.htm">Setting Output Settings </a>    </li>
 </ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/cmd_line_overview.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/cmd_line_overview.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -41,6 +41,6 @@
 <ul>
   <li><a href="../settings.htm">Profiler Settings File </a></li>
 </ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
Binary file sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/images/profiler_PEC_settings1.png has changed
Binary file sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/images/profiler_PEC_settings2.png has changed
Binary file sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/images/profiler_PEC_settings3.png has changed
Binary file sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/images/profiler_PEC_settings4.png has changed
Binary file sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/images/profiler_PEC_settings5.png has changed
Binary file sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/images/profiler_PEC_settings6.png has changed
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/output_settings.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/output_settings.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -71,6 +71,6 @@
   <li><a href="advanced_options.htm">Setting Advanced Options</a></li>
   <li><a href="tracing_options.htm">Setting Tracing Options</a></li>
 </ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/prof_using.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/prof_using.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -120,6 +120,6 @@
   <li><a href="../../tasks/profiler/prof_installation.htm">Installing the Profiler on the Target Device</a></li>
   <li><a href="../../tasks/analyser/an_load_trace_files.htm">Importing Profiler Data File for Analysis </a></li>
 </ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/profiler.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/profiler.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -20,6 +20,6 @@
   <li><a href="../../tasks/profiler/prof_installation.htm">Installing the Profiler on the Target Device</a></li>
   <li><a href="prof_using.htm">Using the Profiler</a></li>
 </ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/tracing_options.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/profiler/tracing_options.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -79,6 +79,6 @@
   <li><a href="advanced_options.htm">Setting Advanced Options</a></li>
   <li><a href="output_settings.htm">Setting Output Settings </a> </li>
 </ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/settings.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/reference/settings.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -183,6 +183,6 @@
 <ul>
   <li>   <a href="profiler/cmd_line_overview.htm"> Using the Command-line</a></li>
 </ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/release_notes.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/release_notes.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -1,103 +1,223 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
-<head>
-<meta http-equiv="content-type"
- content="text/html; charset=ISO-8859-1">
-<title>Release Notes</title>
-<link href="../book.css" rel="stylesheet" type="text/css">
-<style type="text/css">
-<!--
-.style2 {font-size: 13px}
--->
-</style>
-</head>
-<body bgcolor="#FFFFFF">
-<h2>Performance Investigator Release Notes</h2>
-<ul>
-  <li><a href="#whatsNew">What's new </a></li>
-  <li><a href="#agent" >Target Performance Investigator Agent</a></li>
-  <li><a href="#pi_bugs">Fixed bugs and workarounds</a></li>
-  <li><a href="#support">Technical support</a></li>
-</ul>
-<h3><a name="whatsNew" id="whatsNew"></a>What's New </h3>
-<p>The Performance Investigator (PI) provides the means to measure program performance on a device running the Symbian OS. The new PI features provided with this release include:</p>
-<ul>
-  <li><b>Key Press profiles support</b> &#8212; PI now supports changing the key press map profile associated with a NPI file. Once changed using any of the pre-built profiles for TechView, S60, MOAP, UIQ, and PI pre-2.0, you can customize the key presses as desired to match new device functionality requirements.</li>
-  <li><b>Performance  improvements</b> &#8212; Several graphic routines have been rewritten to decrease the time it takes to draw and manipulate large data sets, making the process of changing graph sizes and scrolling them much more responsive. Also, the time to import a DAT file has been decreased. </li>
-  <li><b>Memory usage improvements</b> &#8212; Memory usage has has been significantly lowered. </li>
-</ul>
-<p><b>1.3.1</b></p>
-<ul>
-  <li><b>Copy tables and paste into spreadsheets</b> &#8212; copy displayed information in Threads, Binaries, Functions, and Function Calls tables to the clipboard and paste into a spreadsheet application, such as Microsoft Excel</li>
-  <li><b>Save tables</b> &#8212; save information displayed in tables into a comma delimited .csv file format that can be opened in a spreadsheet application</li>
-  <li><strong>Save more precise data in tables</strong> &#8212; save specific information about selected data within a table. For example, save samples for Threads that are checked in the Thread table or save the priority setting for Threads that are checked. You can also save data for one or more selected binaries, checked functions in Functions table, a single selected function in Function Calls table, checked memory samples, all button events for specified time interval, and all Power samples for time interval.</li>
-</ul>
-<p><b>1.5.0</b></p>
-<ul>
-  <li><b>PI Profiler 2.02 support added.</b> &#8212; Support for more detailed event based memory model added.</li>
-  <li><b>Touch Event support</b> &#8212; Button plug-in is now able to recognize touch events.</li>
-  <li><b>Some minor usability improvements and bug fixes</b></li>
-</ul>
-<h3><a name="agent"></a>Target Performance Investigator Profiler </h3>
-<ul>
-  <li>To produce a Profiler data file, you need to install one of these profiler agents: 
-    <ul>
-      <li><span class="code">Carbide Profiler 2.0 Installer</span> - for S60 3.0 (3rd Edition, initial release) devices</li>
-      <li><span class="code">Carbide Profiler 2.0 (Dual CPU) Installer </span>- for S60 3.1 (3rd Edition, Feature Pack 1) devices with dual CPUs, such as the N95 and N96</li>
-      <li><span class="code">Carbide Profiler 2.0 (Single CPU)Installer</span> - for S60 3.1 (3rd Edition, Feature Pack 1) devices with a single CPU, such as the E71, N76,  6290, N78 and 5320
-    </ul>
-    <p>Those files and others can be can be downloaded and installed using the <b>On-Device Connections &gt; New Connection Wizard &gt;</b><a href="PLUGINS_ROOT/com.nokia.carbide.cpp.doc.user/html/reference/trk/wnd_new_connection_wizard.htm"> Install remote agents</a> pane.</p>
-  </li>
-</ul>
-<h3><a name="pi_bugs"></a>Fixed bugs and workarounds</h3>
-<ul>
-  <li>Complete list of Carbide.c++ <a href="bugs_fixed.htm">bugs fixed</a></li>
-  <li>Workarounds for known issues:</li>
-</ul>
-<table width="100%"  border="0" cellpadding="2" cellspacing="0" >
-  <tr>
-    <th width="27%" scope="col">Item</th>
-    <th width="62%" scope="col">Explanation</th>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;"><span class="style2">The Investigator menu item does not appear on the menu toolbar after an invalid format error occurs while opening an NPI file.</span></td>
-    <td style="vertical-align: top;"><p>Workaround:  To show the Investigator menu item, give focus to any non-NPI file or to any view other than the editor view (e.g., to the Symbian Project Navigator view).</p>
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;"><p>[3005] Profiling an application with all traces enabled and using the maximum sample rates (50ms and 250ms) may cause Profiler to exhibit strange behaviors</p></td>
-    <td style="vertical-align: top;"><p>Symptoms:</p>
-        <ul>
-          <li>S60 - You may get unusual errors such loss of icons in lists.</li>
-          <li>UIQ 3.0 - The generated .dat file is corrupted and when imported into the Analyzer can cause a crash.</li>
-        </ul>
-      <p>Workaround: Do not use maximum sampling rates, if all traces must be enabled, to avoid a high CPU overload condition. You can do this by either upping the time interval to 100ms/500ms or by disabling some traces.</p></td>
-  </tr>
-  <tr >
-    <td valign="top">[3049] Profiler sampling application closes when power usage sampling is requested on a device without power management</td>
-    <td valign="top"><p >On devices, such the N93, that do not have power management hardware, attempting to sample power usage will fail, and the application that samples, CProfApp, will close. </p>
-        <p >There is no workaround.</p></td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">Carbide.c++ may run out of memory If you open or import several large profiler data files, the Java Virtual Machine may run out of memory.</td>
-    <td style="vertical-align: top;"><p>The workaround is to allocate more memory in the Carbide.c++.ini file (typically in the Carbide.c++ folder that contains Carbide.c++.exe). For example, to allocate 1GB, edit the Carbide.c++.ini to contain &ldquo;-Xmx1024m&rdquo; and then restart Carbide.c++.</p>
-        <p class="note"><b>NOTE</b> The eclipse.ini file was renamed Carbide.c++.ini for purposes of this product.</p></td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">Host cannot import debug output from the target device You can send sampling data to the debug port of your device. However, this release cannot import the .base64 file that contains this data.</td>
-    <td style="vertical-align: top;">No workaround. </td>
-  </tr>
-</table>
-<h3><a name="support" id="support"></a>Technical support </h3>
-<p>The following support services are available:</p>
-<ul>
-  <li>Licensed technical support - submit service requests at <a href="https://pro.forum.nokia.com/loadServiceRequest.do">Forum Nokia Developer Programs</a> (<i>not available for Express users</i>) </li>
-  <li>License issues - send questions to <a href="mailto:license.carbide@nokia.com">license.carbide@nokia.com</a> to resolve any licensing issues </li>
-  <li>Visit the <a href="http://discussion.forum.nokia.com/forum/forumdisplay.php?s=&amp;forumid=95">Forum Nokia Developer Discussion Board</a> for lively Carbide.c++ discussions </li>
-  <li>Forum Nokia Wiki - visit <a href="http://wiki.forum.nokia.com/index.php/Carbide.c++">wiki.forum.nokia.com/index.php/Carbide.c++</a> for updated information, downloads and tips </li>
-  <li>Customer feedback - send your comments and suggestions to <a href="mailto:feedback.carbide@nokia.com">feedback.carbide@nokia.com</a></li>
-</ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
-
-</body>
-</html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+  <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+  <title>Release Notes</title>
+  <link href="../book.css" rel="stylesheet" type="text/css">
+  <style type="text/css">
+<!--
+ .style2 {font-size: 13px}
+-->
+
+  </style>
+</head>
+
+<body bgcolor="#FFFFFF">
+<h2>Release Notes</h2>
+
+<h4>Performance Investigator Analyser Carbide.c++ Extension &ndash; Version
+2.3.0</h4>
+
+<p>Released 21st April 2010</p>
+<ul>
+  <li><a href="#whatsNew">What's new </a></li>
+  <li><a href="#agent">Target Performance Investigator Agent</a></li>
+  <li><a href="#pi_bugs">Fixed bugs and workarounds</a></li>
+  <li><a href="#support">Technical support</a></li>
+</ul>
+
+<h3><a name="whatsNew" id="whatsNew"></a>What's New </h3>
+
+<p><strong>2.3.0</strong></p>
+<ul>
+  <li><b>Performance improvements</b> &mdash; Improved overall memory
+    consumption. </li>
+  <li><b>Version numbers harmonized</b> &mdash; Version numbers of Performance
+    Investigator plug-ins and feature increased to 2.3.0.</li>
+  <li><b>Instruction trace (ITT) support</b> &mdash; Support for the RVCT 4.0
+    map file format.</li>
+  <li><b>Library event support</b> &mdash; Memory plug-in supports
+    investigating memory usage by a library from the application developer's
+    point of view. </li>
+  <li><b>Performance Investigator Import Wizard</b> &mdash; Support for
+    importing multiple profiler data files with the same configuration from a
+    file system, and a new possibility to select the desired views from the
+    available trace types for each imported file. </li>
+</ul>
+
+<h3><a name="agent"></a>Target Performance Investigator Profiler </h3>
+<ul>
+  <li>To produce a Profiler data file, you need to install one of these
+    profiler agents: 
+    <ul>
+      <li><span class="code">Carbide Profiler 2.0 Installer</span> - for S60
+        3.0 (3rd Edition, initial release) devices</li>
+      <li><span class="code">Carbide Profiler 2.0 (Dual CPU) Installer </span>-
+        for S60 3.1 (3rd Edition, Feature Pack 1) devices with dual CPUs, such
+        as the N95 and N96</li>
+      <li><span class="code">Carbide Profiler 2.0 (Single CPU)Installer</span>
+        - for S60 3.1 (3rd Edition, Feature Pack 1) devices with a single CPU,
+        such as the E71, N76, 6290, N78 and 5320 </li>
+    </ul>
+    <p>Those files and others can be can be downloaded and installed using the
+    <b>On-Device Connections &gt; New Connection Wizard &gt;</b><a
+    href="PLUGINS_ROOT/com.nokia.carbide.cpp.doc.user/html/reference/trk/wnd_new_connection_wizard.htm">Install
+    remote agents</a> pane.</p>
+  </li>
+</ul>
+
+<h3><a name="pi_bugs"></a>Fixed bugs and workarounds</h3>
+<ul>
+  <li>Complete list of Carbide.c++ <a href="bugs_fixed.htm">bugs fixed</a></li>
+  <li>Workarounds for known issues:</li>
+</ul>
+
+<table width="100%" border="0" cellpadding="2" cellspacing="0">
+  <tbody>
+    <tr>
+      <th width="27%" scope="col">Item</th>
+      <th width="62%" scope="col">Explanation</th>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;"><span class="style2">The Investigator
+        menu item does not appear on the menu toolbar after an invalid format
+        error occurs while opening an NPI file.</span></td>
+      <td style="vertical-align: top;"><p>Workaround: To show the Investigator
+        menu item, give focus to any non-NPI file or to any view other than the
+        editor view (e.g., to the Symbian Project Navigator view).</p>
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;"><p>[3005] Profiling an application with
+        all traces enabled and using the maximum sample rates (50ms and 250ms)
+        may cause Profiler to exhibit strange behaviors</p>
+      </td>
+      <td style="vertical-align: top;"><p>Symptoms:</p>
+        <ul>
+          <li>S60 - You may get unusual errors such loss of icons in lists.</li>
+          <li>UIQ 3.0 - The generated .dat file is corrupted and when imported
+            into the Analyzer can cause a crash.</li>
+        </ul>
+
+        <p>Workaround: Do not use maximum sampling rates, if all traces must be
+        enabled, to avoid a high CPU overload condition. You can do this by
+        either upping the time interval to 100ms/500ms or by disabling some
+        traces.</p>
+      </td>
+    </tr>
+    <tr>
+      <td valign="top">[3049] Profiler sampling application closes when power
+        usage sampling is requested on a device without power management</td>
+      <td valign="top"><p>On devices, such the N93, that do not have power
+        management hardware, attempting to sample power usage will fail, and
+        the application that samples, CProfApp, will close. </p>
+
+        <p>There is no workaround.</p>
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">Carbide.c++ may run out of memory If you
+        open or import several large profiler data files, the Java Virtual
+        Machine may run out of memory.</td>
+      <td style="vertical-align: top;"><p>The workaround is to allocate more
+        memory in the Carbide.c++.ini file (typically in the Carbide.c++ folder
+        that contains Carbide.c++.exe). For example, to allocate 1GB, edit the
+        Carbide.c++.ini to contain &ldquo;-Xmx1024m&rdquo; and then restart
+        Carbide.c++.</p>
+
+        <p class="note"><b>NOTE</b> The eclipse.ini file was renamed
+        Carbide.c++.ini for purposes of this product.</p>
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">Host cannot import debug output from the
+        target device You can send sampling data to the debug port of your
+        device. However, this release cannot import the .base64 file that
+        contains this data.</td>
+      <td style="vertical-align: top;">No workaround. </td>
+    </tr>
+  </tbody>
+</table>
+
+<h3><a name="support" id="support"></a>Technical support </h3>
+
+<p>The following support services are available:</p>
+<ul>
+  <li>Licensed technical support - submit service requests at <a
+    href="https://pro.forum.nokia.com/loadServiceRequest.do">Forum Nokia
+    Developer Programs</a> (<i>not available for Express users</i>) </li>
+  <li>License issues - send questions to <a
+    href="mailto:license.carbide@nokia.com">license.carbide@nokia.com</a> to
+    resolve any licensing issues </li>
+  <li>Visit the <a
+    href="http://discussion.forum.nokia.com/forum/forumdisplay.php?s=&amp;forumid=95">Forum
+    Nokia Developer Discussion Board</a> for lively Carbide.c++ discussions
+  </li>
+  <li>Forum Nokia Wiki - visit <a
+    href="http://wiki.forum.nokia.com/index.php/Carbide.c++">wiki.forum.nokia.com/index.php/Carbide.c++</a>
+    for updated information, downloads and tips </li>
+  <li>Customer feedback - send your comments and suggestions to <a
+    href="mailto:feedback.carbide@nokia.com">feedback.carbide@nokia.com</a></li>
+</ul>
+
+<h3>Version history</h3>
+
+<p><strong>2.2.0</strong></p>
+<ul>
+  <li><b>Interrupt support</b> &mdash; Support for viewing software and
+    hardware interrupts. Interrupts view can be used for tracking down low
+    level performance issues.</li>
+  <li><b>Performance counter support</b> &mdash; Support for viewing
+    performance counter traces. This feature has been ported from Bappea to
+    Performance Investigator. If the <strong>Instructions executed</strong>
+    counter (performance counter number 7) has been activated during the
+    profiling, the MIPS graph can be included in the Performance counter
+  view.</li>
+  <li><b>Interconnect performance counter support</b> &mdash; Support for
+    viewing interconnect performance counter traces. This feature has been
+    ported from Bappea to Performance Investigator.</li>
+  <li><b>SMP support for CPU Profiler</b> &mdash; The Threads view can now be
+    broken down into separate graphs, one per available CPU on SMP systems.</li>
+  <li><b>Usability enhancements for graphs</b> &mdash; Title bar added for each
+    graph for manipulating the location and size of a single graph.</li>
+  <li><b>Version numbers harmonized</b> &mdash; Version numbers of Performance
+    Investigator plug-ins and feature increased to 2.2.0.</li>
+  <li><b>Instruction trace (ITT) support</b> &mdash; Support for event based
+    ITT traces (ITT_V2.00).</li>
+</ul>
+
+<p><strong>1.5.0</strong></p>
+<ul>
+  <li><b>PI Profiler 2.02 support added.</b> &mdash; Support for more detailed
+    event based memory model added.</li>
+  <li><b>Touch Event support</b> &mdash; Button plug-in is now able to
+    recognize touch events.</li>
+  <li>Some minor usability improvements and bug fixes</li>
+</ul>
+
+<p><b>1.3.1</b></p>
+<ul>
+  <li><b>Copy tables and paste into spreadsheets</b> &mdash; copy displayed
+    information in Threads, Binaries, Functions, and Function Calls tables to
+    the clipboard and paste into a spreadsheet application, such as Microsoft
+    Excel</li>
+  <li><b>Save tables</b> &mdash; save information displayed in tables into a
+    comma delimited .csv file format that can be opened in a spreadsheet
+    application</li>
+  <li><strong>Save more precise data in tables</strong> &mdash; save specific
+    information about selected data within a table. For example, save samples
+    for Threads that are checked in the Thread table or save the priority
+    setting for Threads that are checked. You can also save data for one or
+    more selected binaries, checked functions in Functions table, a single
+    selected function in Function Calls table, checked memory samples, all
+    button events for specified time interval, and all Power samples for time
+    interval.</li>
+</ul>
+
+<div id="footer">
+Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights
+reserved. <br>
+License: <a
+href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+</body>
+</html>
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/analyser/an_load_trace_files.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/analyser/an_load_trace_files.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -1,114 +1,186 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
 <html>
 <head>
-  <meta http-equiv="Content-Type"
- content="text/html; charset=iso-8859-1">
+  <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
   <title>Loading Sample Trace File for Analysis</title>
   <link href="../../../book.css" rel="stylesheet" type="text/css">
 </head>
+
 <body>
 <h2>Importing Profiler Data Files</h2>
-<p>After capturing run-time information from your application on the
-target device, saving the profiler data file, and transfering the file
-to your PC, you must then import the profiler data (.dat) file.
-Importing the data file converts the file into a format that can be
-displayed by the analyzer (a .NPI file).</p>
-<p class="note"><strong>NOTE</strong> If a large .dat file is imported, the graph and table response time will slow down   until the  large NPI file is saved. Saving the NPI file will be performed in the background and  cannot be canceled.</p>
-<p>Importing a profiler data file will vary depending on if your
-application was built by Carbide.c++ or is a standalone application. To
-find the binaries in your application, the importer will need the *.pkg
-file created when your application was built, or you will need to list
-all application binaries. If you wish to analyze applications that
-execute at a static address, you will need the ROM image .symbol file
-that represents your phone. For dynamically loaded binaries stored in a
-phone&#8217;s ROFS or ROM, a .oby file can be used to describe and list
-binaries.</p>
-<p>Unless your application executes from a fixed address in phone
-memory (e.g., is part of the flashed phone image), enable dynamic
-binary support in the Profiler application when capturing your
-application data in a profiler data file.</p>
+
+<p>After capturing run-time information from your application on the target
+device, saving the profiler data file, and transferring the file to your PC,
+you must then import the profiler data (.dat) file. Importing the data file
+converts the file into a format that can be displayed by the analyzer (a .NPI
+file).</p>
+
+<p class="note"><strong>NOTE</strong> If a large .dat file is imported, the
+graph and table response time will slow down until the large NPI file is saved.
+Saving the NPI file will be performed in the background and cannot be
+canceled.</p>
+
+<p>Importing a profiler data file will vary depending on if your application
+was built by Carbide.c++ or is a standalone application. To find the binaries
+in your application, the importer will need the *.pkg file created when your
+application was built, or you will need to list all application binaries. If
+you wish to analyze applications that execute at a static address, you will
+need the ROM image .symbol file that represents your phone. For dynamically
+loaded binaries stored in a phone&rsquo;s ROFS or ROM, a .oby file can be used
+to describe and list binaries.</p>
+
+<p>Unless your application executes from a fixed address in phone memory (e.g.,
+is part of the flashed phone image), enable dynamic binary support in the
+Profiler application when capturing your application data in a profiler data
+file.</p>
+
 <p>To import your profiler data file, perform the following steps.</p>
+
 <div class="step">
 <h4>Importing a Profiler Data File</h4>
 <ol>
-  <li><a name="Select_Performance_Investigator_Data"></a>Select
-Performance Investigator Data</li>
-  <p>Select <strong>File &gt; Import...</strong> from Carbide.c++ to
-display Import dialog box (Figure 1), and select Performance
-Investigator Data and click <strong>Next</strong>.</p>
-  <p align="center"><img src="images/importdatfile_step1.png"
- width="470" height="550"></p>
+  <li><a name="Select_Performance_Investigator_Data"></a>Select Performance
+    Investigator Data</li>
+
+  <p>Select <strong>File &gt; Import...</strong> from Carbide.c++ to display
+  Import dialog box (Figure 1), and select Performance Investigator Data and
+  click <strong>Next</strong>.</p>
+
+  <p align="center"><img src="images/importdatfile_step1.png"></p>
+
   <p align="center" class="figure">Figure 1. Carbide.c++ Import window </p>
-  <li><a name="Select_Profiler_Data_File"></a>Select Profiler Data File</li>
-  <p>Click <strong>Profiler Sample File...</strong>   and select the .dat file you transferred to your PC. The
-.dat file will be converted to a format displayable by the Carbide.c++
-analyzer and assigned the .npi extension (Figure 2). Click <strong>Next</strong>
-to continue.</p>
-  <p align="center"><img src="images/CB_import_step2.PNG" width="541"
- height="385"></p>
-  <p align="center" class="figure">Figure 2. Select Profiler Data File</p>
-  <li><a name="Select_Known_Available_Information"></a>Select Known Available information </li>
-  <p align="left">Use the <strong>Available Information</strong> page to choose how the
-    profiler session is imported. The options include:</p>
-  <ul>
-    <li>Project importer &#8212; select this option if you have a Carbide project that has a PKG file or if you have a standalone PKG file (a PKG file that has absolute paths)</li>
-    <li>Project and ROM importer &#8212; select this option if you have both a Carbide project / package file for the profiled application as well as the ROM image symbol file and OBY file for the profiled device </li>
-    <li>ROM importer &#8212; select this option if you have  the ROM image symbol file and the OBY file for the profiled device</li>
-    <li>Unknown importer &#8212; select this option when you have neither a project or a ROM image </li>
-  </ul>
-  <p align="left">Click <strong>Next</strong> to continue.</p>
-  <p align="left" class="note"><strong>NOTE</strong> You can also click the Finish button (if enabled) to fill in the remaining wizard pages  with persisted values from the last .dat file import. In a new workspace or first time a workspace is used, you will need to define related information in remaining pages, since there is no previous import related to the new workspace. For a new imported .dat file, a new output file name will be generated base on this input file name (+ _digit + .npi).</p>
-  <p align="center"><img src="images/import_dat_file_step3.png"
- width="629" height="705"></p>
-  <p align="center" class="figure">Figure 3. Enter known Available
+  <li><a name="Select_Profiler_Data_File"
+    id="Select_Profiler_Data_File"></a>Select Profiler Data File(s) 
+    <p>Select .dat file(s) to the <strong>From File System</strong> list by
+    selecting either</p>
+    <ul>
+      <li><strong>Add File</strong> and browsing to the file, or</li>
+      <li><strong>Add Directory</strong> and browsing to the directory you want
+        to import files from.</li>
+      <li>The .dat file(s) will be converted to a format displayable by the
+        Carbide.c++ analyzer and assigned the .npi extension. </li>
+    </ul>
+    <p>After selecting the file, the <strong>PI views included in the
+    analysis</strong><strong>for <em>filename</em>.dat</strong> table will
+    display a list of available views, according to the trace types available
+    in the selected .dat file. </p>
+    <ul>
+      <li>By default, all available trace types in the table are selected, so
+        you can de-select the types you do not wish to include in the analysis.
+        The CPU load view is a mandatory analysis and cannot be
+      de-selected.</li>
+    </ul>
+    <p>Click Next to continue. </p>
+    <p align="center"><img src="images/CB_import_step2.PNG" alt=""></p>
+    <p align="center" class="figure">Figure 2. Select Profiler Data File</p>
+  </li>
+  <li><a name="Select_Known_Available_Information"></a>Select Known Available
+    information 
+    <p align="left">Use the <strong>Available Information</strong> page to
+    choose how the profiler session is imported. The options include:</p>
+    <ul>
+      <li>Project importer &mdash; select this option if you have a Carbide
+        project that has a PKG file or if you have a standalone PKG file (a PKG
+        file that has absolute paths)</li>
+      <li>Project and ROM importer &mdash; select this option if you have both
+        a Carbide project / package file for the profiled application as well
+        as the ROM image symbol file and OBY file for the profiled device </li>
+      <li>ROM importer &mdash; select this option if you have the ROM image
+        symbol file and the OBY file for the profiled device</li>
+      <li>Unknown importer &mdash; select this option when you have neither a
+        project or a ROM image </li>
+    </ul>
+    <p align="left">Click <strong>Next</strong> to continue.</p>
+    <p align="left" class="note"><strong>NOTE</strong> You can also click the
+    Finish button (if enabled) to fill in the remaining wizard pages with
+    persisted values from the last .dat file import. In a new workspace or
+    first time a workspace is used, you will need to define related information
+    in remaining pages, since there is no previous import related to the new
+    workspace. For a new imported .dat file, a new output file name will be
+    generated based on this input file name (+ (digit) + .npi).</p>
+    <p align="center"><img src="images/import_dat_file_step3.png"></p>
+    <p align="center" class="figure">Figure 3. Enter known Available
     Information</p>
-  <li><a name="ROM_files"></a>If  <strong>Both</strong> or <strong>the ROM image symbol file</strong> option is selected, the <strong>Select build files from ROM</strong> dialog appears. (optional) </li>
-  <p>Use the <strong><a href="../../reference/analyzer/import_rom_build_files.htm">Select build files from ROM</a></strong> dialog to select the build files that correspond to the ROM on the device. Start by selecting the SDK, then the ROM OBY file as well as the ROM symbol file. When done, clickc Next. </p>
-  <p align="center"><img src="../../images/wnd_import_rom_build_files.png" width="629" height="705"></p>
+  </li>
+  <li><a name="ROM_files"></a>If <strong>Both</strong> or <strong>the ROM image
+    symbol file</strong> option is selected, the <strong>Select build files
+    from ROM</strong> dialog appears. (optional) </li>
+
+  <p>Use the <strong><a
+  href="../../reference/analyzer/import_rom_build_files.htm">Select build files
+  from ROM</a></strong> dialog to select the build files that correspond to the
+  ROM on the device. Start by selecting the SDK, then the ROM OBY file as well
+  as the ROM symbol file. When done, click Next. </p>
+
+  <p align="center"><img src="../../images/wnd_import_rom_build_files.png"></p>
+
   <p class="figure">Figure 4. Select build files from ROM dialog</p>
-  <li><a name="Select_Associated_Project_and_Package"></a>Select
-    Associated Project and Package (.pkg) File</li>
-  <p align="left">Use the Associated Project and Package (.pkg) File
-    page to select one or more projects to associate with the imported .dat
-    file as well as choosing its project configuration. Use the Add PKG
-    File control to add a .pkg file during the import operation or the
-    Remove PKG Files control to remove a PKG file from the imported
-    profiler session. Click <strong>Next</strong> to continue.</p>
-  <p align="center"><img src="images/import_dat_file_step4.png"
- width="517" height="496"></p>
-  <p align="center" class="figure">Figure 5. Enter Associated Project
-    and Pakage (.pkg) File Information</p>
+  <li><a name="Select_Associated_Project_and_Package"></a>Select Associated
+    Project and Package (.pkg) File 
+    <p align="left">Use the Associated Project and Package (.pkg) File page to
+    select one or more projects to associate with the imported .dat file as
+    well as choosing its project configuration. Use the Add PKG File control to
+    add a .pkg file during the import operation or the Remove PKG Files control
+    to remove a PKG file from the imported profiler session. Click
+    <strong>Next</strong> to continue.</p>
+    <p align="center"><img src="images/import_dat_file_step4.png"></p>
+    <p align="center" class="figure">Figure 5. Enter Associated Project and
+    Package (.pkg) File Information</p>
+  </li>
   <li>Select Key Press Mapping Profile (requires button trace information)</li>
-  <p>If the DAT file has button trace enable, the <b>Select Key Press Mapping Profile</b> page appears. Select either a Carbide builtin Key Map Profile or user defined profile (if available) for the target device  key map. The  key map profile selected in the  <strong>Window &gt; Preferences &gt; Carbide.c++ &gt; Performance Investigator</strong> preference panel is highlighted as the suggested default. </p>
-  <p>A suggested key profile will also be selected if only one ROM kit/SDK is selected previously in this import wizard or the profile XML file in the ROM kit/SDK contains only   one key map profile.</p>
-  <p align="center"><img src="images/importdatfile_keyprofile.png" alt="keymap profile" width="541" height="516"></p>
-  <p align="center" class="figure">Figure 6. Select Key Press Mapping Profile </p>
-  <li><a name="Select_Output_File_and_Project"></a>Select Output File
-    and Project </li>
+
+  <p>If the DAT file has button trace enable, the <b>Select Key Press Mapping
+  Profile</b> page appears. Select either a Carbide builtin Key Map Profile or
+  user defined profile (if available) for the target device key map. The key
+  map profile selected in the <strong>Window &gt; Preferences &gt; Carbide.c++
+  &gt; Performance Investigator</strong> preference panel is highlighted as the
+  suggested default. </p>
+
+  <p>A suggested key profile will also be selected if only one ROM kit/SDK is
+  selected previously in this import wizard or the profile XML file in the ROM
+  kit/SDK contains only one key map profile.</p>
+
+  <p align="center"><img src="images/importdatfile_keyprofile.png"
+  alt="keymap profile"></p>
+
+  <p align="center" class="figure">Figure 6. Select Key Press Mapping Profile
+  </p>
+  <li><a name="Select_Output_File_and_Project"></a>Select Output File and
+    Project </li>
 
-  <p>Use the Output File and Project page to import the .dat file into
-an existing project or create a new empty project. In addition, use the
-Output file name field to specify the name output file name for the
-imported .dat file.</p>
+  <p>Use the Output File and Project page to import the .dat file into an
+  existing project or create a new empty project. </p>
+
+  <p align="center"><img src="images/import_dat_file_step5.png"></p>
 
-  <p align="center"><img src="images/import_dat_file_step5.png"
- width="517" height="496"></p>
-  <p align="center" class="figure">Figure 7. Enter Output File and
-Project Information</p>
-  <li>Click Finish to create the *.npi file and open it with the
-Analyzer (Figure 8).</li>
-  <p align="center"><img src="images/importdatfile_step7.png"
- width="708" height="653"></p>
-  <p align="center" class="figure">Figure 8. Performance Investigator
-Analyzer</p>
+  <p align="center" class="figure">Figure 7. Enter Output File and Project
+  Information</p>
+  <li>Click Finish to create the *.npi file.</li>
+  <li>If <b>Instructions executed</b> has been selected as one of the trace, a
+    the dialog below is displayed during PIAnalyser file import (once for each
+    file f several are imported): 
+    <p align="center"><img
+    src="../../reference/analyzer/images/MIPS_speed_dialog.png"></p>
+  </li>
+  <li>If you imported only one file, PIAnalyser will open showing the views
+    selected for that file. 
+    <p>If you imported several files, a project will be opened to the
+    <strong>Carbide Project Explorer</strong> where you can choose the file to
+    be viewed with PIAnalyser.</p>
+  </li>
 </ol>
 </div>
+
 <p align="left"><strong>Related references</strong></p>
 <ul>
-  <li><a href="../../reference/analyzer/main_view.htm" align="left">Analyzer
-View</a></li>
+  <li><a href="../../reference/analyzer/main_view.htm">Analyzer View</a></li>
   <li><a href="key_profile_pref.htm">Key Press Profile</a> </li>
 </ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+
+<div id="footer">
+Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights
+reserved. <br>
+License: <a
+href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/analyser/btn_press_change.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/analyser/btn_press_change.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -10,10 +10,10 @@
 <body>
 <h2>Changing  Button Event Information</h2>
 <p>The default button event information includes the time when the event was recorded and a name for the button. The default display is shown in Figure 1. </p>
-<p align="center"><img src="images/pi_thread_load_01.png" width="550" height="125"></p>
+<p align="center"><img src="images/pi_thread_load_01.png" width="550" height="130"></p>
 <p class="figure"><span class="figure">Figure 1.  Button event information shown in an Analyzer view</span></p>
 <p>To view additional information about the event, click a button event to see a tooltip with additional information about the event. </p>
-<p align="center"><img src="images/pi_thread_load_02.png" width="615" height="126"></p>
+<p align="center"><img src="images/pi_thread_load_02.png" width="615" height="130"></p>
 <p class="figure"><span class="figure">Figure 2.  Click to show additional button event information in the tooltip</span></p>
 <p>To edit the button event information, double-click the button event marker to open the Button dialog to modifiy the information as shown in Figure 3. Edit the information in the dialog and press <b>OK</b> to save the changes to the NPI file. For example you can change the key label &quot;Down&quot; to a custom name for the button.</p>
 <p>Check &quot;Propagate to all labels of the same button&quot; to change all labels related to  the same key in the active NPI file.</p>
@@ -29,6 +29,6 @@
   <li><a href="../profiler/btn_press_enable.htm">Setting the Button Press Capture Option</a></li>
   <li><a href="btn_press_show.htm">Showing/Hiding Button Events</a></li>
 </ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/analyser/btn_press_show.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/analyser/btn_press_show.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -10,7 +10,7 @@
 <body>
 <h2>Showing/Hiding  Button Events</h2>
 <p>Use the <b>Show Button Events</b> menu item to show or hide button event information in the Analyzer view. Button event information is displayed when a checkmark is present, or hidden if no checkmark appears on the menu item. </p>
-<p align="center"><img src="../../concepts/images/view_button_markers.png" width="816" height="154"></p>
+<p align="center"><img src="../../concepts/images/view_button_markers.png" width="817" height="155"></p>
 <p class="figure">Figure 1.  Button event information shown in an Analyzer view</p>
 <div class="step">
   <h4>Changing the Button Event Visibility</h4>
@@ -27,6 +27,6 @@
 <ul>
   <li><a href="../../reference/profiler/prof_using.htm">Using the Profiler</a> </li>
 </ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/analyser/chng_graphcolor.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/analyser/chng_graphcolor.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -17,6 +17,6 @@
 <p align="left">You can use the shift and control keys and the left mouse button to select multiple items. If multiple items are selected, then the swatch is displayed for each item selected. To select the same color for multiple selections, you will need to select the color and click OK for each swatch.</p>
 <p align="left" class="note"><strong>Note:</strong> Currently, any recoloring changes you make to binary and thread items will dirty the file, and will be saved to the .npi file when you save the file. Any recoloring changes you make to function items will not be saved. For function items, default colors are restored when the .npi file is reopened.<br>
 </p>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
Binary file sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/analyser/images/CB_import_step2.PNG has changed
Binary file sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/analyser/images/import_dat_file_step5.png has changed
Binary file sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/analyser/images/pi_thread_load_01.png has changed
Binary file sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/analyser/images/pi_thread_load_02.png has changed
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/analyser/key_profile_exp.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/analyser/key_profile_exp.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -30,6 +30,6 @@
   <li><a href="key_profile_switch.htm">Switch Key Map Profile</a></li>
   <li><a href="btn_press_change.htm">Changing Button Event Information</a> </li>
 </ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/analyser/key_profile_imp.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/analyser/key_profile_imp.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -32,6 +32,6 @@
   <li><a href="key_profile_switch.htm">Switch Key Map Profile</a></li>
   <li><a href="btn_press_change.htm">Changing Button Event Information</a> </li>
 </ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/analyser/key_profile_pref.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/analyser/key_profile_pref.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -80,6 +80,6 @@
   <li><a href="key_profile_switch.htm">Switch Key Map Profile</a></li>
   <li><a href="btn_press_change.htm">Changing Button Event Information</a> </li>
 </ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/analyser/key_profile_select.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/analyser/key_profile_select.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -24,6 +24,6 @@
 <ul>
   <li><a href="key_profile_pref.htm">Key Press Profile</a></li>
 </ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/analyser/key_profile_switch.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/analyser/key_profile_switch.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -39,6 +39,6 @@
 <ul>
   <li><a href="btn_press_change.htm">Changing Button Event Information</a> </li>
 </ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/analyser/set_thresholds.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/analyser/set_thresholds.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -34,6 +34,6 @@
 </table>
 <p><strong>Related references</strong></p>
 <p><a href="../../reference/analyzer/threshold.htm"> Threshold Limits for Traced Data</a></p>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/analyser/source_lookup.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/analyser/source_lookup.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -20,6 +20,6 @@
 	<p>A source lookup is performed on the project. If a single source is found it is displayed in an editor view. If more than one source is found, a list of sources is presented to choose from. </p>
   </ul>
 </div>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/analyser/time_interval.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/analyser/time_interval.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -34,6 +34,6 @@
   <li><a href="../../reference/analyzer/GUI_tour.htm">Analyzer GUI Controls</a></li>
 <li><a href="../../reference/analyzer/context_menu.htm">Context Menu Options</a></li>
 </ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/profiler/bluetooth_connection.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/profiler/bluetooth_connection.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -84,6 +84,6 @@
   <li><a href="serial_connection.htm">Connecting by Serial Interface </a></li>
   <li><a href="usb_connection.htm">Connecting by USB</a></li>
 </ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/profiler/btn_press_enable.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/profiler/btn_press_enable.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -27,6 +27,6 @@
 <ul>
   <li><a href="../../reference/profiler/prof_using.htm">Using the Profiler</a> </li>
 </ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/profiler/key_profile_exp.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/profiler/key_profile_exp.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -32,6 +32,6 @@
   <li><a href="key_profile_imp.htm" align="left">Importing a Key Map Profile </a></li>
   <li><a href="../analyser/key_profile_pref.htm">Key Press Profile</a> </li>
 </ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/profiler/key_profile_imp.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/profiler/key_profile_imp.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -37,6 +37,6 @@
   <li><a href="key_profile_exp.htm" align="left">Exporting Key Map Profile</a></li>
   <li><a href="../analyser/key_profile_pref.htm">Key Press Profile</a> </li>
 </ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/profiler/prof_installation.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/profiler/prof_installation.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -1,41 +1,67 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-
-<html>
-<head>
-	<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-	<title>Performance Investigator Profiler Installation</title>
-    <link href="../../../book.css" rel="stylesheet" type="text/css">
-</head>
-
-<body>
-<h2>Installing the Profiler on the Target Device</h2>
-<p> The Performance Investigator Profiler consists of  self installing Symbian executable files (.sisx) to be installed on the handheld device.The Profiler agent  can be downloaded and installed using the <b><a href="PLUGINS_ROOT/com.nokia.carbide.cpp.doc.user/html/reference/trk/wnd_new_conn_wiz_edit.htm">Install remote agents</a></b> pane in the <b>On-device Connections</b> wizard.</p>
-<p class="note"><b>NOTE</b> Nokia PC Suite is used by the Install remote agents pane to transfer the selected agent to the  device. Nokia <a href="http://www.nokia.com/pcsuite" title="PC Suite" target="_blank">PC Suite</a> is a free download from the Nokia website and can also be used to transfer, store, synchronize, and edit Nokia phone files with a compatible PC.</p>
-<p align="center"><img src="../images/wizard_new_connection.png" width="456" height="554"></p>
-<p class="figure">Figure 1 - New Connection window</p>
-<div class="step">  
-  <h4>Installing the Carbide Profiler
-  </h4>
-  <ol>
-    <li>Click <b>Help &gt; On-Device Connections...</b> to open the <b>New Connection</b> wizard</li>
-    <li>Enter a <b>Connection name</b>, and choose a<b> Connection type</b> from the connection types listed</li>
-    <li>Click <b>Next</b></li>
-    <li>Click the <b>Install remote agent</b> tab (Figure 1)</li>
-    <li>Select the type and version of <b>Carbide Profiler</b> to install</li>
-    <li>Click <b>Install</b></li>
-    <li>Click <b>Finish</b> once installation is complete</li>
-    </ol>
-</div>
-<p>Alternately, save the Profiler agent  to your PC by selecting a version of the Carbide Profiler and clicking <b>Save</b>. Once stored on your PC, you can connect and transfer the agent to the target device using one of the following transfer methods:</p>
-<ul>
-  <li><a href="bluetooth_connection.htm">Connecting by Bluetooth</a></li>
-  <li><a href="usb_connection.htm">Connecting by USB </a></li>
-  <li><a href="serial_connection.htm">Connecting by Serial Interface</a></li>
-</ul>
-<h5>Related Task</h5>
-<ul>
-  <li><a href="../../reference/profiler/prof_using.htm">Using the Profiler</a>  </li>
-</ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
-</body>
-</html>
\ No newline at end of file
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+  <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+  <title>Performance Investigator Profiler Installation</title>
+  <link href="../../../book.css" rel="stylesheet" type="text/css">
+</head>
+
+<body>
+<h2>Installing the Profiler on the Target Device</h2>
+
+<p>The Performance Investigator Profiler consists of self installing Symbian
+executable files (.sisx) to be installed on the handheld device.The Profiler
+agent can be downloaded and installed using the <b><a
+href="PLUGINS_ROOT/com.nokia.carbide.cpp.doc.user/html/reference/trk/wnd_new_conn_install_tab.htm">Install
+remote agents</a></b> tab in the <b>On-device Connections</b> wizard.</p>
+
+<p class="note"><b>NOTE</b> Nokia PC Suite is used by the Install remote agents
+pane to transfer the selected agent to the device. Nokia <a
+href="http://www.nokia.com/pcsuite" title="PC Suite" target="_blank">PC
+Suite</a> is a free download from the Nokia website and can also be used to
+transfer, store, synchronize, and edit Nokia phone files with a compatible
+PC.</p>
+
+<p align="center"><img src="../images/wizard_new_connection.png" width="456"
+height="554"></p>
+
+<p class="figure">Figure 1 - New Connection window</p>
+
+<div class="step">
+<h4>Installing the Carbide Profiler </h4>
+<ol>
+  <li>Click <b>Help &gt; On-Device Connections...</b> to open the <b>New
+    Connection</b> wizard</li>
+  <li>Enter a <b>Connection name</b>, and choose a<b>Connection type</b> from
+    the connection types listed</li>
+  <li>Click <b>Next</b></li>
+  <li>Click the <b>Install remote agent</b> tab (Figure 1)</li>
+  <li>Select the type and version of <b>Carbide Profiler</b> to install</li>
+  <li>Click <b>Install</b></li>
+  <li>Click <b>Finish</b> once installation is complete</li>
+</ol>
+</div>
+
+<p>Alternately, save the Profiler agent to your PC by selecting a version of
+the Carbide Profiler and clicking <b>Save</b>. Once stored on your PC, you can
+connect and transfer the agent to the target device using one of the following
+transfer methods:</p>
+<ul>
+  <li><a href="bluetooth_connection.htm">Connecting by Bluetooth</a></li>
+  <li><a href="usb_connection.htm">Connecting by USB </a></li>
+  <li><a href="serial_connection.htm">Connecting by Serial Interface</a></li>
+</ul>
+
+<h5>Related Task</h5>
+<ul>
+  <li><a href="../../reference/profiler/prof_using.htm">Using the Profiler</a>
+  </li>
+</ul>
+
+<div id="footer">
+Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights
+reserved. <br>
+License: <a
+href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+</body>
+</html>
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/profiler/serial_connection.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/profiler/serial_connection.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -17,6 +17,6 @@
   <li><a href="bluetooth_connection.htm">Connecting by Bluetooth</a></li>
   <li><a href="usb_connection.htm">Connecting by USB</a></li>
 </ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/profiler/usb_connection.htm	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/html/tasks/profiler/usb_connection.htm	Wed Apr 21 15:14:16 2010 +0300
@@ -50,6 +50,6 @@
   <li><a href="bluetooth_connection.htm">Connecting by Bluetooth</a></li>
   <li><a href="serial_connection.htm">Connecting by Serial Interface</a></li>
 </ul>
-<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
+<div id="footer">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
 </body>
 </html>
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/plugin.xml	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/plugin.xml	Wed Apr 21 15:14:16 2010 +0300
@@ -92,6 +92,26 @@
        <!-- ECLIPSE NEW/IMPORT/EXPORT WIZARDS and PREF PANELS HELP  -->
        <contexts file="html/context_help/org_eclipse_ui.xml"
        		plugin="org.eclipse.ui" />
+       <contexts
+             file="html/context_help/com_nokia_carbide_pi_memory.xml"
+             plugin="com.nokia.carbide.cpp.pi.memory">
+       </contexts>
+       <contexts
+             file="html/context_help/com_nokia_carbide_pi_pec.xml"
+             plugin="com.nokia.carbide.cpp.pi.perfcounters">
+       </contexts>
+       <contexts
+             file="html/context_help/com_nokia_carbide_pi_ipc.xml"
+             plugin="com.nokia.carbide.cpp.pi.ipc">
+       </contexts>
+       <contexts
+             file="html/context_help/com_nokia_carbide_pi_irq.xml"
+             plugin="com.nokia.carbide.cpp.pi.irq">
+       </contexts>
+       <contexts
+             file="html/context_help/com_nokia_carbide_pi_power.xml"
+             plugin="com.nokia.carbide.cpp.pi.power">
+       </contexts>
 
 	</extension>
 
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/tocAnalyzer.xml	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/tocAnalyzer.xml	Wed Apr 21 15:14:16 2010 +0300
@@ -21,12 +21,6 @@
 	</topic>
 	<topic label="Examining a Profiling Project"  		href="html/Getting_Started/example_project.htm" />
 
-	<topic label="Memory Usage" href="html/concepts/memory_usage_capture.htm" >
-		<topic label="Memory Usage view" 	href="html/reference/analyzer/view_memory_usage.htm" />
-		<topic label="Memory Usage Statistics" 	href="html/reference/analyzer/wnd_memory_usage_statistics.htm" />
-		<topic label="Memory Usage menu" 	href="html/reference/analyzer/menu_memory_graph.htm" />
-	</topic>
-
 	<topic label="Menus">
 		<topic label="Context Menu Options" 	href="html/reference/analyzer/context_menu.htm" />
 		<topic label="Save Table" 				href="html/reference/analyzer/save_table.htm" />
@@ -36,6 +30,28 @@
 		<topic label="Show Button Events" 		href="html/tasks/analyser/btn_press_show.htm" />
 	</topic>
 
+	<topic label="Memory Usage" href="html/concepts/memory_usage_capture.htm" >
+		<topic label="Memory Usage view" 	href="html/reference/analyzer/view_memory_usage.htm" />
+		<topic label="Memory Usage Statistics" 	href="html/reference/analyzer/wnd_memory_usage_statistics.htm" />
+		<topic label="Memory Usage menu" 	href="html/reference/analyzer/menu_memory_graph.htm" />
+	</topic>
+
+	<topic label="Power Usage" 					href="html/reference/analyzer/view_power_usage.htm" >
+		<topic label="Power Usage Settings" 	href="html/reference/analyzer/wnd_power_graph_settings.htm" />
+		<topic label="Power Usage Statistics" 	href="html/reference/analyzer/wnd_power_usage_statistics.htm" />
+		<topic label="Power Graph menu" 		href="html/reference/analyzer/menu_power_graph.htm" />
+	</topic>
+ <topic href="html/reference/analyzer/interrupts_view.htm" label="Interrupts View">
+ </topic>
+ <topic href="html/reference/analyzer/view_performance_counters.htm" label="Performance Counters View">
+    <topic href="html/reference/analyzer/traceable_events.htm" label="Traceable Event Types">
+    </topic>
+    <topic href="html/reference/profiler/Prof_counter_settings.htm" label="PIProfiler Performance Counter Settings">
+    </topic>
+ </topic>
+ <topic href="html/reference/analyzer/view_IPC.htm" label="Interconnect Performance Counters">
+ </topic>
+
 	<topic label="Options"  >
 		<topic label="Changing Button Event Information" 	href="html/tasks/analyser/btn_press_change.htm" />
 		<topic label="Changing Graph Colors" 				href="html/tasks/analyser/chng_graphcolor.htm" />
@@ -45,12 +61,6 @@
 
 	</topic>
 
-	<topic label="Power Usage" 					href="html/reference/analyzer/view_power_usage.htm" >
-		<topic label="Power Usage Settings" 	href="html/reference/analyzer/wnd_power_graph_settings.htm" />
-		<topic label="Power Usage Statistics" 	href="html/reference/analyzer/wnd_power_usage_statistics.htm" />
-		<topic label="Power Graph menu" 		href="html/reference/analyzer/menu_power_graph.htm" />
-	</topic>
-
 	<topic label="Using Source Lookup" 					href="html/tasks/analyser/source_lookup.htm" />
 	<topic label="Analyzing Table Data" 				href="html/reference/analyzer/analyzing_table_data.htm" />
 
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/tocPI.xml	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.doc.user/tocPI.xml	Wed Apr 21 15:14:16 2010 +0300
@@ -1,15 +1,16 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <?NLS TYPE="org.eclipse.help.toc"?>
 
-<toc label="Performance Investigator User Guide" href="html/profiler.htm" >
+<toc label="Performance Investigator" link_to="../com.nokia.carbide.help.common/carbideHelpTOC.xml#anchorCarbideMisc">
+
+<topic label="Performance Investigator" href="html/profiler.htm">
 				
 	<topic label="Release notes" href="html/release_notes.htm" />
-	<topic label="Getting Started with Performance Investigator"      href="html/Getting_Started/GS_index.htm" />
+	<topic label="Getting Started with Performance Investigator" href="html/Getting_Started/GS_index.htm" />
 	
 	<topic label="Software Performance" >
 		<link toc="tocConcepts.xml" />
-	</topic>
-	
+	</topic>	
 	
 	<topic label="Profiler" >
 		<link toc="tocProfiler.xml" />
@@ -23,5 +24,5 @@
 	
 	<topic label="Bugs fixed" href="html/bugs_fixed.htm" />
 	<topic label="Legal" href="html/legal.htm" />
-		      
+		</topic>	      
 </toc>
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.function/META-INF/MANIFEST.MF	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.function/META-INF/MANIFEST.MF	Wed Apr 21 15:14:16 2010 +0300
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: Carbide.c++ Performance Investigator Functions
 Bundle-SymbolicName: com.nokia.carbide.cpp.pi.function;singleton:=true
-Bundle-Version: 1.5.0.qualifier
+Bundle-Version: 2.3.0.qualifier
 Bundle-Activator: com.nokia.carbide.cpp.pi.function.FunctionPlugin
 Bundle-Vendor: Nokia
 Bundle-Localization: plugin
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.function/src/com/nokia/carbide/cpp/pi/function/NewFunctionAnalyse.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.function/src/com/nokia/carbide/cpp/pi/function/NewFunctionAnalyse.java	Wed Apr 21 15:14:16 2010 +0300
@@ -65,6 +65,7 @@
 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.IFunction;
 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;
@@ -503,13 +504,13 @@
 			{
 				threads.put(s,sample.thread);
 				//listData.add(sample.thread.process.name+"::"+sample.thread.threadName);
-				threadSampleAmount.put(s,new Integer(1));
+				threadSampleAmount.put(s,Integer.valueOf(1));
 			}
 			else
 			{
 				int value = ((Integer)threadSampleAmount.get(s)).intValue();
 				threadSampleAmount.remove(s);
-				threadSampleAmount.put(s,new Integer(value+1));
+				threadSampleAmount.put(s,Integer.valueOf(value+1));
 			}
 		}
 		
@@ -561,7 +562,7 @@
 							if (this.originallySelectedThreads[i].equals(test))
 							{
 								//System.out.println("Match:"+this.originallySelectedThreads[i]+" index "+k);
-								selectedIndx.add(new Integer(k));
+								selectedIndx.add(Integer.valueOf(k));
 							}
 						}
 					}
@@ -607,7 +608,7 @@
 			if (!containsKey)
 		    {
 		        binaries.put(bi, sample);
-		        binarySampleAmount.put(bi, new Integer(1));
+		        binarySampleAmount.put(bi, Integer.valueOf(1));
 		    }
 		    else
 		    {
@@ -618,7 +619,7 @@
 		            {
 		                int value = ((Integer)binarySampleAmount.get(biTemp)).intValue();
 		                binarySampleAmount.remove(biTemp);
-						binarySampleAmount.put(biTemp, new Integer(value+1));
+						binarySampleAmount.put(biTemp, Integer.valueOf(value+1));
 		            }
 		        }
 		    }
@@ -683,7 +684,7 @@
 							if (this.originallySelectedBinaries[i].equalsIgnoreCase(test))
 							{
 								//System.out.println("Match:"+this.originallySelectedThreads[i]+" index "+k);
-								selectedIndx.add(new Integer(k));
+								selectedIndx.add(Integer.valueOf(k));
 							}
 						}
 					}
@@ -734,7 +735,7 @@
 				if (!threadVector.contains(threadName))
 				{
 					threadVector.add(threadName);
-					threadSampleAmount.add(new Integer(1));
+					threadSampleAmount.add(Integer.valueOf(1));
 				}
 				else
 				{	
@@ -743,7 +744,7 @@
 					int value = ((Integer)threadSampleAmount.get(index)).intValue();
 					
 					threadSampleAmount.remove(index);
-					threadSampleAmount.add(index,new Integer(value+1));
+					threadSampleAmount.add(index,Integer.valueOf(value+1));
 				}
 			}
 		}
@@ -807,7 +808,7 @@
 			    int index = (found) ? counter : -1;
 				if (index != -1)
 				{
-					indexStore.add(new Integer(index));
+					indexStore.add(Integer.valueOf(index));
 				}
 				else
 				{
@@ -836,7 +837,7 @@
 //				int index = listData.indexOf(value);
 				if (index != -1)
 				{
-					indexStore.add(new Integer(index));
+					indexStore.add(Integer.valueOf(index));
 				}
 				else
 				{
@@ -891,7 +892,7 @@
 				if (!binaryVector.contains(binaryName))
 				{
 					binaryVector.add(binaryName);
-					binarySampleAmount.add(new Integer(1));
+					binarySampleAmount.add(Integer.valueOf(1));
 				}
 				else
 				{	
@@ -900,7 +901,7 @@
 					int value = ((Integer)binarySampleAmount.get(index)).intValue();
 					
 					binarySampleAmount.remove(index);
-					binarySampleAmount.add(index,new Integer(value+1));
+					binarySampleAmount.add(index,Integer.valueOf(value+1));
 				}
 			}
 		}
@@ -956,7 +957,7 @@
 				int index = listData.indexOf(valueStore[i]);
 				if (index != -1)
 				{
-					indexStore.add(new Integer(index));
+					indexStore.add(Integer.valueOf(index));
 				}
 				else
 				{
@@ -970,7 +971,7 @@
 				int index = listData.indexOf(value);
 				if (index != -1)
 				{
-					indexStore.add(new Integer(index));
+					indexStore.add(Integer.valueOf(index));
 				}
 				else
 				{
@@ -1093,7 +1094,7 @@
 					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));
+					percentValueList.add(Integer.valueOf(1));
 					// add a vector for the function offset values
 					
 					if (this.functionPercents.isSelected() == true)
@@ -1119,7 +1120,7 @@
 					
 					Integer value = (Integer)percentValueList.elementAt(index);
 					percentValueList.remove(index);
-					percentValueList.add(index,new Integer(value.intValue()+1));
+					percentValueList.add(index,Integer.valueOf(value.intValue()+1));
 					
 					if (this.functionPercents.isSelected() == true)
 					{					
@@ -1230,30 +1231,30 @@
 		String binaryName;
 		if (this.symbolPrimary || this.ittTrace == null)
 		{
-			binaryName = s.currentFunctionSym.functionBinary.binaryName;
+			binaryName = s.getCurrentFunctionSym().getFunctionBinary().getBinaryName();
 			if (!binaryName.endsWith(Messages.getString("NewFunctionAnalyse.notFound"))) //$NON-NLS-1$
 				return new BinaryNameItem(binaryName,false);
 		}
 
-		if (s.currentFunctionItt != null)
+		if (s.getCurrentFunctionItt() != null)
 		{
-			binaryName = s.currentFunctionItt.functionBinary.binaryName;
+			binaryName = s.getCurrentFunctionItt().getFunctionBinary().getBinaryName();
 			if (!binaryName.endsWith(Messages.getString("NewFunctionAnalyse.notFound"))) //$NON-NLS-1$
 			{
 				return new BinaryNameItem(binaryName,true);
 			}
 			else
 			{
-				binaryName = s.currentFunctionSym.functionBinary.binaryName;
+				binaryName = s.getCurrentFunctionSym().getFunctionBinary().getBinaryName();
 				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$
+		else if (!s.getCurrentFunctionSym().getFunctionBinary().getBinaryName().endsWith(Messages.getString("NewFunctionAnalyse.notFound"))) //$NON-NLS-1$
 		{
-			binaryName = s.currentFunctionSym.functionBinary.binaryName;
+			binaryName = s.getCurrentFunctionSym().getFunctionBinary().getBinaryName();
 			return new BinaryNameItem(binaryName,false);
 		}
 		else
@@ -1336,18 +1337,18 @@
 	{
 		//String functionName;
 		if ((this.symbolPrimary || this.ittTrace == null) && 
-				!s.currentFunctionSym.functionBinary.binaryName.endsWith(Messages.getString("NewFunctionAnalyse.notFound")) ) //$NON-NLS-1$
+				!s.getCurrentFunctionSym().getFunctionBinary().getBinaryName().endsWith(Messages.getString("NewFunctionAnalyse.notFound")) ) //$NON-NLS-1$
 		{
-			return new Long(s.programCounter-s.currentFunctionSym.startAddress.longValue());
+			return new Long(s.programCounter-s.getCurrentFunctionSym().getStartAddress().longValue());
 		}
-		if (s.currentFunctionItt != null && !s.currentFunctionItt.functionName.endsWith(Messages.getString("NewFunctionAnalyse.notFound"))) //$NON-NLS-1$
+		if (s.getCurrentFunctionItt() != null && !s.getCurrentFunctionItt().getFunctionName().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());
+			return new Long(s.programCounter-s.getCurrentFunctionItt().getStartAddress().longValue());
 		}
-		else if (s.currentFunctionSym != null)
+		else if (s.getCurrentFunctionSym() != null)
 		{
-			return new Long(s.programCounter-s.currentFunctionSym.startAddress.longValue());
+			return new Long(s.programCounter-s.getCurrentFunctionSym().getStartAddress().longValue());
 		}
 		else
 		{
@@ -1370,26 +1371,26 @@
 			}
 			else
 			{
-				functionName = s.currentFunctionSym.functionName;
+				functionName = s.getCurrentFunctionSym().getFunctionName();
 				if (!functionName.endsWith(Messages.getString("NewFunctionAnalyse.notFound"))) //$NON-NLS-1$
 				{					
-					item = new FunctionNameItem(functionName,s.currentFunctionSym,false);
+					item = new FunctionNameItem(functionName,s.getCurrentFunctionSym(),false);
 					this.functionNameCacheSym.put(s,item);
 					return item;
 				}
 			}
 		}
 		
-		if (s.currentFunctionItt != null)
+		if (s.getCurrentFunctionItt() != null)
 		{
 			FunctionNameItem item = (FunctionNameItem)this.functionNameCacheItt.get(s);
 			if (item != null) return item;
 			
-			functionName = s.currentFunctionItt.functionName;
+			functionName = s.getCurrentFunctionItt().getFunctionName();
 
 			if (!functionName.endsWith(Messages.getString("NewFunctionAnalyse.notFound"))) //$NON-NLS-1$
 			{
-				item = new FunctionNameItem(functionName,s.currentFunctionItt,true);
+				item = new FunctionNameItem(functionName,s.getCurrentFunctionItt(),true);
 				this.functionNameCacheItt.put(s,item);
 				return item;
 //				return new FunctionNameItem(functionName,s.currentFunctionItt,true);
@@ -1399,20 +1400,20 @@
 				item = (FunctionNameItem)this.functionNameCacheSym.get(s);
 				if (item != null) return item;
 				
-				functionName = s.currentFunctionSym.functionName;
-				item = new FunctionNameItem(functionName,s.currentFunctionSym,false);
+				functionName = s.getCurrentFunctionSym().getFunctionName();
+				item = new FunctionNameItem(functionName,s.getCurrentFunctionSym(),false);
 				this.functionNameCacheSym.put(s,item);
 				return item;
 //				return new FunctionNameItem(functionName,s.currentFunctionSym,false);
 			}
 		}
-		else if (s.currentFunctionSym != null)
+		else if (s.getCurrentFunctionSym() != null)
 		{
 			FunctionNameItem item = (FunctionNameItem)this.functionNameCacheSym.get(s);
 			if (item != null) return item;
 			
-			functionName = s.currentFunctionSym.functionName;
-			item = new FunctionNameItem(functionName,s.currentFunctionSym,false);
+			functionName = s.getCurrentFunctionSym().getFunctionName();
+			item = new FunctionNameItem(functionName,s.getCurrentFunctionSym(),false);
 			this.functionNameCacheSym.put(s,item);
 			return item;
 //			return new FunctionNameItem(functionName,s.currentFunctionSym,false);
@@ -1777,11 +1778,11 @@
 		public boolean itt;
 		public int sampleAmount;
 		public int totalSamples;
-		public Function function;
+		public IFunction function;
 		public Vector offsetVector;
 		public double currentPercent;
 		
-		public FunctionNameItem(String name, Function function, boolean itt)
+		public FunctionNameItem(String name, IFunction function, boolean itt)
 		{
 			this.offsetVector = new Vector();
 			this.sampleAmount = 0;
@@ -1857,7 +1858,7 @@
 			if (this.functionNameItem != null && this.functionNameItem.offsetVector != null)
 			{
 				
-				long length = this.functionNameItem.function.length;
+				long length = this.functionNameItem.function.getLength();
 				g.setColor(
 						// AWT
 					    AWTColorPalette.getColor(new RGB(255, 255, 255))
@@ -2082,16 +2083,16 @@
 				
 				if (item.function != null)
 				{
-					if (item.function.functionBinary != null && item.function.functionBinary.binaryName != null)
+					if (item.function.getFunctionBinary() != null && item.function.getFunctionBinary().getBinaryName() != 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$
+						this.setToolTipText(Messages.getString("NewFunctionAnalyse.function1")+item.function.getFunctionName()+Messages.getString("NewFunctionAnalyse.function2")+ //$NON-NLS-1$ //$NON-NLS-2$
+								Long.toHexString(item.function.getStartAddress().longValue())+
+								Messages.getString("NewFunctionAnalyse.function3")+item.function.getFunctionBinary().getBinaryName()); //$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())+
+						this.setToolTipText(Messages.getString("NewFunctionAnalyse.function1")+item.function.getFunctionName()+Messages.getString("NewFunctionAnalyse.function2")+ //$NON-NLS-1$ //$NON-NLS-2$
+								Long.toHexString(item.function.getStartAddress().longValue())+
 								Messages.getString("NewFunctionAnalyse.function3") + Messages.getString("NewFunctionAnalyse.binaryNotFound")); //$NON-NLS-1$ //$NON-NLS-2$
 					}
 				}
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/META-INF/MANIFEST.MF	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/META-INF/MANIFEST.MF	Wed Apr 21 15:14:16 2010 +0300
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: Carbide.c++ Performance Investigator Dynamic Binaries
 Bundle-SymbolicName: com.nokia.carbide.cpp.pi.instr;singleton:=true
-Bundle-Version: 1.5.0.qualifier
+Bundle-Version: 2.3.0.qualifier
 Bundle-Activator: com.nokia.carbide.cpp.pi.instr.InstrPlugin
 Bundle-Vendor: Nokia
 Bundle-Localization: plugin
@@ -11,6 +11,7 @@
  org.eclipse.core.resources,
  com.nokia.carbide.cpp.pi,
  com.nokia.carbide.cpp.pi.core,
- com.nokia.carbide.cpp.pi.util
+ com.nokia.carbide.cpp.pi.util,
+ com.nokia.carbide.cpp.pi.address
 Bundle-ActivationPolicy: lazy
 Export-Package: com.nokia.carbide.cpp.pi.instr;x-friends:="com.nokia.carbide.cpp.pi.instr.tests"
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/src/com/nokia/carbide/cpp/pi/instr/AdvancedMemoryMap.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/src/com/nokia/carbide/cpp/pi/instr/AdvancedMemoryMap.java	Wed Apr 21 15:14:16 2010 +0300
@@ -23,6 +23,7 @@
 import com.nokia.carbide.cpp.internal.pi.model.Binary;
 import com.nokia.carbide.cpp.internal.pi.model.Function;
 import com.nokia.carbide.cpp.internal.pi.model.FunctionResolver;
+import com.nokia.carbide.cpp.internal.pi.model.IBinary;
 
 
 public class AdvancedMemoryMap implements FunctionResolver
@@ -154,10 +155,10 @@
 			else
 			{
 				b = new Binary(Messages.getString("AdvancedMemoryMap.binaryForAddressNotFound1")+Long.toHexString(sample.programCounter)+Messages.getString("AdvancedMemoryMap.binaryForAddressNotFound2")); //$NON-NLS-1$ //$NON-NLS-2$
-				b.length = 0;
-				b.offsetToCodeStart = 0;
-				b.startAddress = sample.programCounter+4;
-				b.type = null;
+				b.setLength(0);
+				b.setOffsetToCodeStart(0);
+				b.setStartAddress( sample.programCounter+4);
+				b.setType(null);
 				return b;
 			}
 		}
@@ -177,14 +178,14 @@
 			Binary b = this.decided.findBinaryForSample(sample);
 			if (b != null)
 			{
-				int offset = (int)(sample.programCounter+4-(b.startAddress+b.offsetToCodeStart));
-				pb = this.binReader.getProcessedBinaryForName(b.binaryName);
+				int offset = (int)(sample.programCounter+4-(b.getStartAddress()+b.getOffsetToCodeStart()));
+				pb = this.binReader.getProcessedBinaryForName(b.getBinaryName());
 				if (pb != null)
 				{
 					f = pb.getFunctionForOffset(offset);
 					if (f != null) 
 					{
-						f.startAddress = new Long(b.startAddress+f.offsetFromBinaryStart+pb.offsetToCodeStart);
+						f.setStartAddress(Long.valueOf(b.getStartAddress()+f.getOffsetFromBinaryStart()+pb.getOffsetToCodeStart()));
 						// function found ok
 						// System.out.println(f.toString());
 						return f;
@@ -192,15 +193,15 @@
 					
 					// function not found in processed binary
 					f = new Function(Messages.getString("AdvancedMemoryMap.functionForAddressNotFound1")+Long.toHexString(sample.programCounter)+Messages.getString("AdvancedMemoryMap.functionForAddressNotFound2"), //$NON-NLS-1$ //$NON-NLS-2$
-							new Long(pb.startAddress),
-							pb.binaryName);
+							Long.valueOf(pb.getStartAddress()),
+							pb.getBinaryName());
 					return f;
 				}
 			}
 			
 			// in all other cases
 			f = new Function(Messages.getString("AdvancedMemoryMap.functionForAddressNotFound1")+Long.toHexString(sample.programCounter)+Messages.getString("AdvancedMemoryMap.functionForAddressNotFound2"), //$NON-NLS-1$ //$NON-NLS-2$
-					new Long(sample.programCounter),
+					Long.valueOf(sample.programCounter),
 					Messages.getString("AdvancedMemoryMap.binaryForAddressNotFound1")+Long.toHexString(sample.programCounter)+Messages.getString("AdvancedMemoryMap.binaryForAddressNotFound2")); //$NON-NLS-1$ //$NON-NLS-2$
 			return f;
 		}
@@ -210,7 +211,7 @@
 		}
 	}
 	
-	public Function findFunctionForAddress(long address)
+	public Function findFunctionForAddress(long address, long sampleSynchTime)
 	{
 		if (this.ittTrace122 == null)
 		{
@@ -218,16 +219,20 @@
 		}
 		else
 		{
-			return this.ittTrace122.getFunctionForAddress(address,this.binaryReader122);
+			return this.ittTrace122.getFunctionForAddress(address, sampleSynchTime, this.binaryReader122);
 		}
 	}
 	
+	public Function findFunctionForAddress(long address){
+		return findFunctionForAddress(address, -1);
+	}
+	
 	public String findFunctionNameForAddress(long address)
 	{
 		Function f = this.findFunctionForAddress(address);
 		if (f != null)
 		{
-			return f.functionName;
+			return f.getFunctionName();
 		}
 		else
 		{
@@ -240,7 +245,7 @@
 		Function f = this.findFunctionForAddress(address);
 		if (f != null)
 		{
-			return f.functionBinary.binaryName;
+			return f.getFunctionBinary().getBinaryName();
 		}
 		else
 		{
@@ -258,23 +263,28 @@
 		return Messages.getString("AdvancedMemoryMap.resolverITT"); //$NON-NLS-1$
 	}
 	
-	public Binary findBinaryForAddress(long address)
+	public IBinary findBinaryForAddress(long address)
+	{
+		return findBinaryForAddress(address, -1);
+	}
+	
+	public IBinary findBinaryForAddress(long address, long sampleSynchTime)
 	{
 		if (this.ittTrace122 == null)
 		{
 			Function f = this.findFunctionForAddress(address);
 			
 			if (f != null)
-				return f.functionBinary;
+				return f.getFunctionBinary();
 			else 
 				return null;
 		}
 		else
 		{
-			Function f = this.ittTrace122.getFunctionForAddress(address,this.binaryReader122);
+			Function f = this.ittTrace122.getFunctionForAddress(address, sampleSynchTime, this.binaryReader122);
 			
 			if (f != null)
-				return f.functionBinary;
+				return f.getFunctionBinary();
 			else 
 				return null;
 		}
@@ -287,8 +297,8 @@
 			Binary b = this.decided.findBinaryForSample(sample);
 			if (b != null)
 			{
-				int offset = (int)(sample.programCounter+4-(b.startAddress+b.offsetToCodeStart));
-				return this.binReader.getFunctionName(b.binaryName,offset);
+				int offset = (int)(sample.programCounter+4-(b.getStartAddress()+b.getOffsetToCodeStart()));
+				return this.binReader.getFunctionName(b.getBinaryName(),offset);
 			}
 			else 
 			{
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/src/com/nokia/carbide/cpp/pi/instr/BinaryReader.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/src/com/nokia/carbide/cpp/pi/instr/BinaryReader.java	Wed Apr 21 15:14:16 2010 +0300
@@ -82,9 +82,9 @@
 
   public BinaryReaderResult findSequence(IttSample sample, Binary b)
   {
-    if (this.processedFiles.containsKey(b.binaryName))
+    if (this.processedFiles.containsKey(b.getBinaryName()))
     {
-      ProcessedBinary pf = (ProcessedBinary)this.processedFiles.get(b.binaryName);
+      ProcessedBinary pf = (ProcessedBinary)this.processedFiles.get(b.getBinaryName());
       return this.findSequence(sample,pf);
     }
     return null;
@@ -103,15 +103,15 @@
   
   public boolean checkSampleInBinary(IttSample sample,Binary binary,int differencesAllowed)
   {
-  	ProcessedBinary pb = this.getProcessedBinaryForName(binary.binaryName);
+  	ProcessedBinary pb = this.getProcessedBinaryForName(binary.getBinaryName());
   	if (pb == null)
   	{
-  		System.out.println(Messages.getString("BinaryReader.cannotFindBinary")+binary.binaryName); //$NON-NLS-1$
+  		System.out.println(Messages.getString("BinaryReader.cannotFindBinary")+binary.getBinaryName()); //$NON-NLS-1$
 		return false;
   	}
   	
-  	if (binary.startAddress <= sample.programCounter &&
-  	   binary.startAddress+binary.length >= sample.programCounter)
+  	if (binary.getStartAddress() <= sample.programCounter &&
+  	   binary.getStartAddress()+binary.getLength() >= sample.programCounter)
   	{
   		// the program counter value indicates that the sample
   		// is within the binary
@@ -121,9 +121,9 @@
   		{
   			
   			long instruction = reversedInstructions[i];
-  			long offset = (long)(sample.programCounter-binary.startAddress);
+  			long offset = (long)(sample.programCounter-binary.getStartAddress());
 
-  			if (offset < binary.length)
+  			if (offset < binary.getLength())
   			{
   				// add the amount of bytes that match in the next 4 bytes
   				matches += this.testNextFourBytes((int)offset+(i*4),instruction,pb);
@@ -185,7 +185,7 @@
 
             int match = 0;
             
-            if (i < pf.length - 5)
+            if (i < pf.getLength() - 5)
             {
               if (pf.data[i] == (byte) first) match++;
               
@@ -219,13 +219,13 @@
                         {
 
                           // add this location to possible binaries
-                          Binary b = new Binary(pf.binaryName);
-                          b.length = pf.length;
-                          b.offsetToCodeStart = pf.offsetToCodeStart;
-                          b.type = pf.type;
+                          Binary b = new Binary(pf.getBinaryName());
+                          b.setLength(pf.getLength());
+                          b.setOffsetToCodeStart(pf.getOffsetToCodeStart());
+                          b.setType(pf.getType());
 
                           // binary start address is the this address - this offset
-                          b.startAddress = sample.programCounter-i;
+                          b.setStartAddress(sample.programCounter-i);
                           possibleBinaries.add(b);
 
                           //System.out.println (	"CHECKSUM MATCH at "+pf.binaryName+"@0x"+Long.toHexString(b.startAddress-b.offsetToCodeStart)+
@@ -240,13 +240,13 @@
 
                           // add this location to possible binaries
 
-                          Binary b = new Binary(pf.binaryName);
-                          b.length = pf.length;
-                          b.offsetToCodeStart = pf.offsetToCodeStart;
-                          b.type = pf.type;
+                          Binary b = new Binary(pf.getBinaryName());
+                          b.setLength(pf.getLength());
+                          b.setOffsetToCodeStart(pf.getOffsetToCodeStart());
+                          b.setType(pf.getType());
 
                           // binary start address is this address - this offset
-                          b.startAddress = sample.programCounter-i;
+                          b.setStartAddress(sample.programCounter-i);
                           possibleBinaries.add(b);
 
                           //System.out.println(	"MATCH at "+pf.binaryName+"@0x"+Long.toHexString(b.startAddress-b.offsetToCodeStart)+
@@ -274,7 +274,7 @@
 
   public void printBinaryFromOffset(ProcessedBinary pf, int offset, int length)
   {
-    if (pf.length < offset+length) return;
+    if (pf.getLength() < offset+length) return;
     int c = 0;
 
     for (int i=offset;i<offset+length;i++)
@@ -301,7 +301,7 @@
 
       int matches = 0;
       
-      if (pf.length > offset+4)
+      if (pf.getLength() > offset+4)
       {
         if (pf.data[offset] == (byte)first) matches++; 
         
@@ -336,7 +336,7 @@
       if (length == -1)
         {
           startOffset = 0;
-          length = pf.length;
+          length = pf.getLength();
         }
 
       for (int i=startOffset;i<startOffset+length;i++)
@@ -412,14 +412,14 @@
         name = name.substring(name.indexOf(File.separator),name.length());
 
         if (!(this.processedFiles.containsKey(name) &&
-              (((ProcessedBinary)this.processedFiles.get(name)).length == f.length())))
+              (((ProcessedBinary)this.processedFiles.get(name)).getLength() == f.length())))
         {
           try
           {
             ProcessedBinary pf = processFile(f);
             //System.out.println(f.getName());
-            this.processedFiles.put(pf.binaryName, pf);
-            length += pf.length;
+            this.processedFiles.put(pf.getBinaryName(), pf);
+            length += pf.getLength();
             addedFiles++;
           }
           catch (Exception e)
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/src/com/nokia/carbide/cpp/pi/instr/BinaryReader122.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/src/com/nokia/carbide/cpp/pi/instr/BinaryReader122.java	Wed Apr 21 15:14:16 2010 +0300
@@ -25,9 +25,13 @@
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map.Entry;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+import org.eclipse.core.runtime.Path;
+
 import com.nokia.carbide.cpp.internal.pi.model.Binary;
 import com.nokia.carbide.cpp.pi.importer.SampleImporter;
 import com.nokia.carbide.cpp.pi.importer.SampleImporter.PkgObyFile;
@@ -83,8 +87,32 @@
 	}
 	
 	public MapFile getMapFileForBinary(Binary b)
-	{
-		return this.binaryToMapFile.get(b);
+	{	
+		MapFile mf = binaryToMapFile.get(b);
+		if(mf == null){
+			String binaryName = b.getBinaryName();
+			try{
+				binaryName = new Path(b.getBinaryName()).lastSegment();
+			}catch (Exception e) {
+				// use defaults
+			}		
+			Iterator<Entry<Binary, MapFile>> iterator = binaryToMapFile.entrySet().iterator();
+			while(iterator.hasNext()){
+				Entry<Binary, MapFile> entry = iterator.next();			
+				String name = entry.getKey().getBinaryName();
+				try{
+					name = new Path(name).lastSegment();
+				}catch (Exception e) {
+					// use defaults
+				}
+				if(name.equals(binaryName)){
+					b.setBinaryName(entry.getKey().getBinaryName());
+					mf = entry.getValue();
+					break;
+				}
+			}
+		}
+		return mf;
 	}
 	
 	public Binary getBinaryForHostName(String s)
@@ -169,9 +197,9 @@
 				        	  
 					          if (binary != null)
 					          {
-					        	  if (debug)System.out.println(Messages.getString("BinaryReader122.foundPkgBinary1")+binary.binaryName+Messages.getString("BinaryReader122.foundPkgBinary2")+localFile); //$NON-NLS-1$ //$NON-NLS-2$
-				        		  binary.binaryName = localFile;
-				        		  getHostNameToBinary().put(binary.binaryName, binary);
+					        	  if (debug)System.out.println(Messages.getString("BinaryReader122.foundPkgBinary1")+binary.getBinaryName()+Messages.getString("BinaryReader122.foundPkgBinary2")+localFile); //$NON-NLS-1$ //$NON-NLS-2$
+				        		  binary.setBinaryName(localFile);
+				        		  getHostNameToBinary().put(binary.getBinaryName(), binary);
 					          }
 							  
 					          mapName = localFile+".map"; //$NON-NLS-1$
@@ -183,7 +211,7 @@
 			        			  {
 			        				  if (binary != null)
 			        				  {
-							        	  if (debug)System.out.println(Messages.getString("BinaryReader122.canGetBinaryFrom1")+binary.binaryName+Messages.getString("BinaryReader122.canGetBinaryFrom2")+localFile); //$NON-NLS-1$ //$NON-NLS-2$
+							        	  if (debug)System.out.println(Messages.getString("BinaryReader122.canGetBinaryFrom1")+binary.getBinaryName()+Messages.getString("BinaryReader122.canGetBinaryFrom2")+localFile); //$NON-NLS-1$ //$NON-NLS-2$
 			        					  binaryToMapFile.put(binary,mf);
 			        				  }
 			        				  else
@@ -227,8 +255,8 @@
 					if (fileSpecMatcher.matches()) {
 						Binary binary = ittTrace122.getBinaryForFileName(fileSpecMatcher.group(2).trim());
 						if (binary != null) {
-							binary.binaryName = fileSpecMatcher.group(1).trim();
-							getHostNameToBinary().put(binary.binaryName, binary);
+							binary.setBinaryName(fileSpecMatcher.group(1).trim());
+							getHostNameToBinary().put(binary.getBinaryName(), binary);
 							
 							String pcFileName = fileSpecMatcher.group(1).trim();
 							// .OBY is referring everything as root relative,
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/src/com/nokia/carbide/cpp/pi/instr/BinaryReaderResult.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/src/com/nokia/carbide/cpp/pi/instr/BinaryReaderResult.java	Wed Apr 21 15:14:16 2010 +0300
@@ -30,7 +30,7 @@
     String s = ""; //$NON-NLS-1$
     for (int i=0;i<possibleBinaries.length;i++)
     {
-      s = s+"\n"+possibleBinaries[i].binaryName+" @ "+possibleBinaries[i].startAddress+" "+checksumValues[i].booleanValue(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+      s = s+"\n"+possibleBinaries[i].getBinaryName()+" @ "+possibleBinaries[i].getStartAddress()+" "+checksumValues[i].booleanValue(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
     }
     return s;
   }
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/src/com/nokia/carbide/cpp/pi/instr/DecidedPool.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/src/com/nokia/carbide/cpp/pi/instr/DecidedPool.java	Wed Apr 21 15:14:16 2010 +0300
@@ -133,18 +133,18 @@
 		if (winner != null)
 		{
 			ProcessedBinary pb = this.amm.getBinaryReader().
-									getProcessedBinaryForName(winner.binaryName);
+									getProcessedBinaryForName(winner.getBinaryName());
 			
 			
 			String fName = pb.getFunctionNameForOffset(
-							address-(winner.startAddress+winner.offsetToCodeStart));
+							address-(winner.getStartAddress()+winner.getOffsetToCodeStart()));
 			
-			String bName = winner.binaryName;
+			String bName = winner.getBinaryName();
 			long fOffset = pb.getOffsetFromBinaryStartForFunction(fName);
-			Long fStart = new Long(winner.startAddress+winner.offsetToCodeStart+fOffset);
+			Long fStart = Long.valueOf(winner.getStartAddress()+winner.getOffsetToCodeStart()+fOffset);
 			
 			Function f = new Function(fName,fStart,bName);
-			f.length = pb.getFunctionLengthForOffset(fOffset);
+			f.setLength(pb.getFunctionLengthForOffset(fOffset));
 			
 			return f;
 
@@ -187,12 +187,12 @@
 	
 	public void insertDecidedBinary(Binary binary,Vector samples)
 	{		
-		Vector currentBins = this.memLayout.isOccupiedBy(binary.startAddress,binary.length);
+		Vector currentBins = this.memLayout.isOccupiedBy(binary.getStartAddress(),binary.getLength());
 		
 		if (currentBins.size() == 0)
 		{
-			if (debug) System.out.println(Messages.getString("DecidedPool.analysisResolved1")+binary.binaryName+Messages.getString("DecidedPool.analysisResolved2")+Long.toHexString(binary.startAddress+binary.offsetToCodeStart)+ //$NON-NLS-1$ //$NON-NLS-2$
-					Messages.getString("DecidedPool.analysisResolved3")+Long.toHexString(binary.startAddress+binary.offsetToCodeStart+binary.length)); //$NON-NLS-1$
+			if (debug) System.out.println(Messages.getString("DecidedPool.analysisResolved1")+binary.getBinaryName()+Messages.getString("DecidedPool.analysisResolved2")+Long.toHexString(binary.getStartAddress()+binary.getOffsetToCodeStart())+ //$NON-NLS-1$ //$NON-NLS-2$
+					Messages.getString("DecidedPool.analysisResolved3")+Long.toHexString(binary.getStartAddress()+binary.getOffsetToCodeStart()+binary.getLength())); //$NON-NLS-1$
 			
 			DecidedLocation dl = new DecidedLocation(binary);
 			dl.insertSupportingSamples(samples);
@@ -214,7 +214,7 @@
 				{
 					IttSample is = (IttSample)sampEnum.nextElement();
 
-					if (is.programCounter >= b.startAddress && is.programCounter <= b.startAddress+b.length)
+					if (is.programCounter >= b.getStartAddress() && is.programCounter <= b.getStartAddress()+b.getLength())
 					{
 						if (this.trySampleWithBinary(is,b,4) == false) 
 							okForThis=false;
@@ -455,8 +455,8 @@
 			while (enumer.hasMoreElements())
 			{
 				Binary b = (Binary)enumer.nextElement();
-				long bStart = b.startAddress;
-				long bEnd = b.startAddress+b.length;
+				long bStart = b.getStartAddress();
+				long bEnd = b.getStartAddress()+b.getLength();
 				long end = start+length;
 				
 				// starts within the area
@@ -501,8 +501,8 @@
 			while (enumer.hasMoreElements())
 			{
 				Binary b = (Binary)enumer.nextElement();
-				long bStart = b.startAddress;
-				long bEnd = b.startAddress+b.length;
+				long bStart = b.getStartAddress();
+				long bEnd = b.getStartAddress()+b.getLength();
 				
 				if (address >= bStart && address <= bEnd)
 				{
@@ -519,7 +519,7 @@
 			while (dls.hasMoreElements())
 			{
 				Binary b = (Binary)dls.nextElement();
-				if (b.binaryName.toLowerCase().equals(binaryName.toLowerCase())) return b;
+				if (b.getBinaryName().toLowerCase().equals(binaryName.toLowerCase())) return b;
 			}
 			return null;
 		}
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/src/com/nokia/carbide/cpp/pi/instr/InstrPlugin.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/src/com/nokia/carbide/cpp/pi/instr/InstrPlugin.java	Wed Apr 21 15:14:16 2010 +0300
@@ -97,10 +97,24 @@
 		return "Dynamic Binary Support"; //$NON-NLS-1$
 	}
 
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace#getTraceTitle()
+	 */
+	public String getTraceTitle() {
+		return Messages.getString("InstrPlugin.0"); //$NON-NLS-1$
+	}
+
 	public int getTraceId() {
 		return 3;
 	}
 
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace#parseTraceFiles(java.io.File[])
+	 */
+	public ParsedTraceData parseTraceFiles(File[] files) throws Exception {
+		throw new UnsupportedOperationException();
+	}
+
 	public ParsedTraceData parseTraceFile(File file /*, ProgressBar progressBar*/) throws Exception 
 	{
 		try
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/src/com/nokia/carbide/cpp/pi/instr/IttEvent122.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/src/com/nokia/carbide/cpp/pi/instr/IttEvent122.java	Wed Apr 21 15:14:16 2010 +0300
@@ -27,7 +27,8 @@
 	public String binaryName;
 	public long binaryLength;
 	public long binaryLocation;
-	public Binary binary;
+	private Binary binary;
+	public double eventEndTime;
 
 	public IttEvent122()
 	{
@@ -37,9 +38,19 @@
 	public void createBinary()
 	{
 		binary = new Binary(this.binaryName);
-		binary.length = (int)this.binaryLength;
-		binary.offsetToCodeStart = 0;
-		binary.startAddress = this.binaryLocation;
-		binary.type = Messages.getString("IttEvent122.unknownBinaryType"); //$NON-NLS-1$
+		binary.setLength((int)this.binaryLength);
+		binary.setOffsetToCodeStart(0);
+		binary.setStartAddress(this.binaryLocation);
+		binary.setType(Messages.getString("IttEvent122.unknownBinaryType")); //$NON-NLS-1$
 	}
+
+	/**
+	 * Getter for the binary
+	 * @return the binary
+	 */
+	public Binary getBinary() {
+		return binary;
+	}
+	
+	
   }
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/src/com/nokia/carbide/cpp/pi/instr/IttSample.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/src/com/nokia/carbide/cpp/pi/instr/IttSample.java	Wed Apr 21 15:14:16 2010 +0300
@@ -17,24 +17,23 @@
 
 package com.nokia.carbide.cpp.pi.instr;
 
-import com.nokia.carbide.cpp.internal.pi.model.Binary;
 import com.nokia.carbide.cpp.internal.pi.model.Function;
 import com.nokia.carbide.cpp.internal.pi.model.FunctionResolver;
 import com.nokia.carbide.cpp.internal.pi.model.GenericSampleWithFunctions;
+import com.nokia.carbide.cpp.internal.pi.model.IBinary;
+import com.nokia.carbide.cpp.internal.pi.model.IFunction;
 
 
 public class IttSample extends GenericSampleWithFunctions
 {
-  private static final long serialVersionUID = 31446918621985951L;
+	private static final long serialVersionUID = -6451379240317856526L;
 	
   public long[] instructions;
   public long checksum;
   public long programCounter;
 
-  public Function currentFunctionItt;
-  public Binary currentBinaryItt;
-  public Function currentFunctionSym;
-  public Binary currentBinarySym;
+  private IFunction currentFunctionItt;
+  private IFunction currentFunctionSym;
   
   public IttSample(int size)
   {
@@ -68,17 +67,11 @@
   	if (res.getResolverName().equals("Symbol"))  //$NON-NLS-1$
   	{
   		this.currentFunctionSym = res.findFunctionForAddress(programCounter);
-  		
-  		if (this.currentFunctionSym != null)
-  			this.currentBinarySym = this.currentFunctionSym.functionBinary;
   	}
   	else if (res.getResolverName().equals("ITT"))  //$NON-NLS-1$
   	{
   		if (currentFunctionSym == null) {
-	  		this.currentFunctionItt = res.findFunctionForAddress(programCounter);
-	  		
-	  		if (this.currentFunctionItt != null)
-	  			this.currentBinaryItt = this.currentFunctionItt.functionBinary;
+	  		this.currentFunctionItt = res.findFunctionForAddress(programCounter, sampleSynchTime);
   		}
   	}
   }
@@ -98,14 +91,72 @@
     }
     return s;
   }
-  
-  public String toString()
+	  
+	 /**
+	  * Getter for current function resolved from dynamic binary trace
+	 * @return the currentFunctionItt
+	 */
+	public IFunction getCurrentFunctionItt() {
+		return currentFunctionItt;
+	}
+	
+	/**
+	  * Setter for current function resolved from dynamic binary trace
+	 * @param currentFunctionItt the currentFunctionItt to set
+	 */
+	public void setCurrentFunctionItt(Function currentFunctionItt) {
+		this.currentFunctionItt = currentFunctionItt;
+	}
+	
+	/**
+	  * Getter for current function resolved from symbols
+	 * @return the currentFunctionSym
+	 */
+	public IFunction getCurrentFunctionSym() {
+		return currentFunctionSym;
+	}
+	
+	/**
+	  * Setter for current function resolved from symbols
+	 * @param currentFunctionSym the currentFunctionSym to set
+	 */
+	public void setCurrentFunctionSym(Function currentFunctionSym) {
+		this.currentFunctionSym = currentFunctionSym;
+	}
+
+	/**
+	 * Getter for the current binary resolved from dynamic binary trace
+	 * @return the currentBinaryItt
+	 */
+	public IBinary getCurrentBinaryItt() {
+		IBinary ret = null;
+  		if (this.currentFunctionItt != null){
+  			ret = this.currentFunctionItt.getFunctionBinary();
+  		}
+  		return ret;
+	}
+
+	/**
+	 * Getter for the current binary resolved from symbols
+	 * @return the currentBinarySym
+	 */
+	public IBinary getCurrentBinarySym() {
+		IBinary ret = null;
+  		if (this.currentFunctionSym != null){
+  			ret = this.currentFunctionSym.getFunctionBinary();
+  		}
+		return ret;
+	}
+
+
+	@Override
+	public String toString()
   {
   	long diff = 0;
   	
-  	if (this.currentBinaryItt != null && this.currentBinarySym != null)
-  		diff = this.currentBinaryItt.startAddress+this.currentBinaryItt.offsetToCodeStart-
-			   this.currentBinarySym.startAddress;
+  	if (this.getCurrentBinaryItt() != null && this.getCurrentBinarySym() != null)
+  		diff = this.getCurrentBinaryItt().getStartAddress()+this.getCurrentBinaryItt().getOffsetToCodeStart()-
+			   this.getCurrentBinarySym().getStartAddress();
   	else
   	{
   		System.out.println("NULL"); //$NON-NLS-1$
@@ -113,10 +164,10 @@
   	
   	String result = "Itt:#"+this.sampleSynchTime+ //$NON-NLS-1$
 			" @0x"+Long.toHexString(this.programCounter)+ //$NON-NLS-1$
-			" fS:"+this.currentFunctionSym.functionName+ //$NON-NLS-1$
-			" oS:"+Long.toHexString(this.currentFunctionSym.startAddress.longValue())+" +"+(this.programCounter-this.currentFunctionSym.startAddress.longValue())+ //$NON-NLS-1$ //$NON-NLS-2$
-			" fI:"+this.currentFunctionItt.functionName+ //$NON-NLS-1$
-			" oI:"+Long.toHexString(this.currentFunctionItt.startAddress.longValue())+" +"+(this.programCounter-this.currentFunctionItt.startAddress.longValue()); //$NON-NLS-1$ //$NON-NLS-2$
+			" fS:"+this.currentFunctionSym.getFunctionName()+ //$NON-NLS-1$
+			" oS:"+Long.toHexString(this.currentFunctionSym.getStartAddress().longValue())+" +"+(this.programCounter-this.currentFunctionSym.getStartAddress().longValue())+ //$NON-NLS-1$ //$NON-NLS-2$
+			" fI:"+this.currentFunctionItt.getFunctionName()+ //$NON-NLS-1$
+			" oI:"+Long.toHexString(this.currentFunctionItt.getStartAddress().longValue())+" +"+(this.programCounter-this.currentFunctionItt.getStartAddress().longValue()); //$NON-NLS-1$ //$NON-NLS-2$
   	
   	if (diff != 0) result=" DIFF: "+diff+" "+result; //$NON-NLS-1$ //$NON-NLS-2$
   	
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/src/com/nokia/carbide/cpp/pi/instr/IttTrace.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/src/com/nokia/carbide/cpp/pi/instr/IttTrace.java	Wed Apr 21 15:14:16 2010 +0300
@@ -18,7 +18,6 @@
 package com.nokia.carbide.cpp.pi.instr;
 
 import com.nokia.carbide.cpp.internal.pi.model.GenericSampledTraceWithFunctions;
-import com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph;
 
 
 public class IttTrace extends GenericSampledTraceWithFunctions
@@ -34,15 +33,4 @@
 	{
 		return (IttSample)this.samples.elementAt(number);
 	}
-
-	public GenericTraceGraph getTraceGraph() {
-		return null;
-	}
-
-	/* (non-Javadoc)
-	 * @see com.nokia.carbide.cpp.internal.pi.model.GenericSampledTrace#getTraceGraph(int, com.nokia.carbide.cpp.internal.pi.analyser.AnalyseTab)
-	 */
-	public GenericTraceGraph getTraceGraph(int graphNumber) {
-		return null;
-	}
 }
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/src/com/nokia/carbide/cpp/pi/instr/IttTrace122.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/src/com/nokia/carbide/cpp/pi/instr/IttTrace122.java	Wed Apr 21 15:14:16 2010 +0300
@@ -17,15 +17,22 @@
 
 package com.nokia.carbide.cpp.pi.instr;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Comparator;
 import java.util.Enumeration;
 import java.util.Hashtable;
+import java.util.List;
+import java.util.Vector;
 
+import com.nokia.carbide.cpp.internal.pi.analyser.NpiInstanceRepository;
 import com.nokia.carbide.cpp.internal.pi.model.Binary;
 import com.nokia.carbide.cpp.internal.pi.model.Function;
 import com.nokia.carbide.cpp.internal.pi.model.GenericEvent;
 import com.nokia.carbide.cpp.internal.pi.model.GenericEventTrace;
+import com.nokia.carbide.cpp.internal.pi.model.ParsedTraceData;
+import com.nokia.carbide.cpp.internal.pi.model.TraceDataRepository;
+import com.nokia.carbide.cpp.pi.address.GppTrace;
 
 
 public class IttTrace122 extends GenericEventTrace
@@ -50,16 +57,17 @@
 			if (   (address >= ev.binaryLocation)
 				&& (address < (ev.binaryLocation + ev.binaryLength)) )
 			{
-				//System.out.println("Found "+Long.toHexString(address));
-				return ev.binary;			
+				return ev.getBinary();			
 			}
 		}
 		
 		return null;
 	}
 
-	public Binary getBinaryForAddressNew(long address)
+	
+	public Binary getBinaryForAddressNew(long address, float sampleTime)
 	{
+		List<IttEvent122> foundedEvents  = new ArrayList<IttEvent122>();
 		if (!sortedEvents) {
 			sorted = this.getEvents().toArray();
 			Arrays.sort(sorted, new Comparator<Object>() {
@@ -74,7 +82,7 @@
 			});
 			sortedEvents = true;
 		}
-
+		
 		int high = sorted.length;
 		int low = -1;
 		int next;
@@ -83,10 +91,19 @@
 		while (high - low > 1) {
 			next = (low + high) >>> 1;
 			IttEvent122 event = (IttEvent122)sorted[next];
-
 			if (   (address >= event.binaryLocation)
 				&& (address < (event.binaryLocation + event.binaryLength)) ) {
-				return event.binary;
+				// first suitable event of the list is found and let's find also next ones
+				for( int i=next ; i < sorted.length ; i++ ){
+					IttEvent122 ie = (IttEvent122)sorted[i];
+					if (   (address >= ie.binaryLocation)
+							&& (address < (ie.binaryLocation + ie.binaryLength)) ) {
+						foundedEvents.add(ie);
+					}else{
+						break;
+					}
+				}
+				break;
 			}
 
 			if (event.binaryLocation >= address) {
@@ -95,13 +112,35 @@
 				low = next;
 			}
 		}
-
+		
+		if(!foundedEvents.isEmpty()){
+			if(foundedEvents.size() == 1){
+				return foundedEvents.get(0).getBinary();
+			}else{
+				if(sampleTime <= 0){
+					// if sample time is not known just pick up first event of the list
+					return foundedEvents.get(0).getBinary();
+				}
+				for (IttEvent122 event : foundedEvents) {
+					if (sampleTime >= event.eventTime
+							&& (sampleTime < event.eventEndTime)) {
+						// event is in the time frame
+						return event.getBinary();
+					} else if (sampleTime >= event.eventTime
+							&& event.eventEndTime <= 0.0) {
+						// event is started in the time frame
+						return event.getBinary();
+					}
+				}
+			}
+		}
 		return null;
 	}
-
-	public Function getFunctionForAddress(long address,BinaryReader122 br)
-	{
-		Binary b = this.getBinaryForAddressNew(address);
+	
+	public Function getFunctionForAddress(long address, long sampleSynchTime, BinaryReader122 br)
+	{		
+		float sampleTime = calculateSampleTime(sampleSynchTime);
+		Binary b = this.getBinaryForAddressNew(address, sampleTime);
 		if (b != null)
 		{	
 			MapFile mf = br.getMapFileForBinary(b);
@@ -109,15 +148,15 @@
 			
 			if (mf != null)
 			{
-				f = mf.getFunctionForOffset(address-b.startAddress);
+				f = mf.getFunctionForOffset(address-b.getStartAddress());
 				if (f != null)
 				{
-					f.startAddress = new Long(b.startAddress+mf.getOffsetFromBinaryStartForFunction(f.functionName));
-					if (f.startAddress != null)
+					f.setStartAddress(Long.valueOf(b.getStartAddress()+mf.getOffsetFromBinaryStartForFunction(f.getFunctionName())));
+					if (f.getStartAddress() != null)
 					{
-						if (f.functionBinary != null) 
+						if (f.getFunctionBinary() != null) 
 						{
-							f.functionBinary = b;
+							f.setFunctionBinary(b);
 						}
 						//System.out.println("Resolved function to "+f.functionName+" "+Long.toHexString(f.startAddress.longValue()));
 						return f;
@@ -128,7 +167,7 @@
 			}
 			else
 			{
-				if (debug)System.out.println(Messages.getString("IttTrace122.mapfileNotFound1")+b.binaryName+Messages.getString("IttTrace122.mapfileNotFound2")); //$NON-NLS-1$ //$NON-NLS-2$
+				if (debug)System.out.println(Messages.getString("IttTrace122.mapfileNotFound1")+b.getBinaryName()+Messages.getString("IttTrace122.mapfileNotFound2")); //$NON-NLS-1$ //$NON-NLS-2$
 			}
 			
 			if (f != null)
@@ -142,10 +181,10 @@
 				f = this.knownFunctions.get(fName);
 				
 				if (f == null) {
-					f = new Function(fName, new Long(address), b.binaryName);
-					f.functionBinary = b;
-					f.length = 1;
-					f.offsetFromBinaryStart = 0;
+					f = new Function(fName, Long.valueOf(address), b.getBinaryName());
+					f.setFunctionBinary(b);
+					f.setLength(1);
+					f.setOffsetFromBinaryStart(0);
 					
 					this.knownFunctions.put(fName, f);
 				}
@@ -155,30 +194,40 @@
 		}
 		else
 			return null;
-//		{
-//			String bName = Messages.getString("IttTrace122.binaryForAddressNotFound1")+Long.toHexString(address)+Messages.getString("IttTrace122.binaryForAddressNotFound2"); //$NON-NLS-1$ //$NON-NLS-2$
-//
-//			b = this.knownBinaries.get(bName);
-//			
-//			if (b == null) {
-//				b = new Binary(bName);
-//				b.length = 1;
-//				b.offsetToCodeStart = 0;
-//				b.startAddress = address;
-//				b.type = Messages.getString("IttTrace122.unknownBinaryType"); //$NON-NLS-1$
-//				this.knownBinaries.put(bName, b);
-//			}
-//			
-//			Function f = new Function(	Messages.getString("IttTrace122.functionForAddressNotFound1")+Long.toHexString(address)+Messages.getString("IttTrace122.functionForAddressNotFound2"), //$NON-NLS-1$ //$NON-NLS-2$
-//										new Long(address),
-//										bName);
-//			
-//			f.functionBinary = b;
-//			f.length = 1;
-//			f.offsetFromBinaryStart = 0;
-//			
-//			return f;			
-//		}
+	}
+
+	/**
+	 * Calculate an event time from given sample synch time
+	 * 
+	 * @param sampleSynchTime
+	 * @return the sample time
+	 */
+	@SuppressWarnings("restriction")
+	protected float calculateSampleTime(long sampleSynchTime) {
+		if (sampleSynchTime <= 0) {
+			// sampleSynchTime is not used
+			return sampleSynchTime;
+		}
+		int cpuCount = 1;
+		int samplingInterval = 1;
+		try {
+			ParsedTraceData ptd = TraceDataRepository.getInstance().getTrace(
+					NpiInstanceRepository.getInstance().activeUid(),
+					GppTrace.class);
+
+			final GppTrace gppTraceTmp = (GppTrace) ptd.traceData;
+			cpuCount = gppTraceTmp.getCPUCount();
+			samplingInterval = (Integer) NpiInstanceRepository
+					.getInstance()
+					.activeUidGetPersistState(
+							"com.nokia.carbide.cpp.pi.address.samplingInterval"); //$NON-NLS-1$
+
+		} catch (Exception e) {
+			// use default values for the calculation
+		}
+		
+		return (((sampleSynchTime * samplingInterval) / cpuCount) + 1)
+				* (1 / 1000.0f) - 0.0005f;
 	}
 	
 	  public Binary getBinaryForFileName(String fileName)
@@ -188,8 +237,43 @@
 		  {
 			  IttEvent122 e = (IttEvent122)en.nextElement();
 			  if (e.binaryName.toLowerCase().indexOf(fileName.toLowerCase()) != -1)
-				  return e.binary;
+				  return e.getBinary();
 		  }
 		  return null;
 	  }
-  }
+	 
+	/**
+	 * Add given event into the event table. If version 2.x is used updates
+	 * event's end time for the same event which is founded earlier otherwise
+	 * event is added into the table
+	 * 
+	 * @param ge
+	 * @param isVersion2x
+	 *            is used 2.x version or earlier 1.22 version
+	 */
+	public void addEvent(GenericEvent ge, boolean isVersion2x) {
+		if (!isVersion2x) {
+			super.addEvent(ge);
+			return;
+		}
+
+		IttEvent122 e = (IttEvent122) ge;
+		Vector<GenericEvent> eventVector = getEvents();
+		for (int i = (eventVector.size() - 1) ; i >= 0 ; i--) {
+			IttEvent122 ie = (IttEvent122) eventVector.get(i);
+			if (ie.getBinary().getLength() == e.getBinary().getLength()
+					&& ie.binaryLocation == e.binaryLocation
+					&& ie.binaryName.equals(e.binaryName)) {
+				if (ie.eventTime > 0.0 && ie.eventEndTime <= 0.0) {	
+					// set event's end time
+					ie.eventEndTime = e.eventTime;
+					return;
+				} else {
+					break;
+				}
+			}
+		}
+		// Given event is a new one or it is created again
+		super.addEvent(ge);
+	}
+}
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/src/com/nokia/carbide/cpp/pi/instr/IttTraceParser.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/src/com/nokia/carbide/cpp/pi/instr/IttTraceParser.java	Wed Apr 21 15:14:16 2010 +0300
@@ -25,6 +25,7 @@
 
 import com.nokia.carbide.cpp.internal.pi.analyser.NpiInstanceRepository;
 import com.nokia.carbide.cpp.internal.pi.model.FunctionResolver;
+import com.nokia.carbide.cpp.internal.pi.model.GenericEvent;
 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.Parser;
@@ -215,10 +216,13 @@
 	   		// end of trace
 	   	}
     }
-    else if (traceVersion.indexOf("ITT_V1.22") != -1 || traceVersion.indexOf("ITT_V2.01") != -1) //$NON-NLS-1$ //$NON-NLS-2$
+    else if (traceVersion.indexOf("ITT_V1.22") != -1 ) //$NON-NLS-1$ 
     {
-    	boolean isVersion201 = traceVersion.indexOf("ITT_V2.01") != -1; //$NON-NLS-1$
-    	this.trace122 = parse122IttTrace(traceArray, isVersion201);
+    	this.trace122 = parse122IttTrace(traceArray, false);
+    }
+    else if (traceVersion.indexOf("ITT_V2.00") != -1 || traceVersion.indexOf("ITT_V2.01") != -1) //$NON-NLS-1$ //$NON-NLS-2$
+    {
+    	this.trace122 = parse122IttTrace(traceArray, true);
     }
     else
     {
@@ -226,7 +230,7 @@
     }
   }
    
-  private IttTrace122 parse122IttTrace(byte[] traceArray, boolean isVersion201)
+  private IttTrace122 parse122IttTrace(byte[] traceArray, boolean isVersion2x)
   {
 	  IttTrace122 trace = new IttTrace122();
 	  
@@ -235,24 +239,26 @@
 	  // read the first header
 	  byte length = traceArray[ptr++];
 	  String txt = new String(traceArray,ptr,length);ptr+=length;
-	  
-	  Vector sortables = new Vector();
-	  
+	
 	  class SortableString implements Sortable
 	  {
 		  String string;
 		  long value;
 		  long startAddress;
 		  long endAddress;
-		  double samplingTime;
+		  double sampleStartTime;
+		  double sampleRemoveTime;
 		  
 		  public long valueOf()
 		  {
 			  return this.value;
 		  }
 	  }
+	  Vector<SortableString> sortables = new Vector<SortableString>();
 	  
-	  int adjust = isVersion201 ? 12 : 8;
+
+	  
+	  int adjust = isVersion2x ? 12 : 8;
 	  
 	  while(ptr < traceArray.length)
 	  {
@@ -284,7 +290,7 @@
 		  len = (len<<32)>>>32;
 		  event.binaryLength = len;
 		  
-		  if (isVersion201) {
+		  if (isVersion2x) {
 			  long time = getUnsignedByte(traceArray[ptr++]);
 			  time |= (getUnsignedByte(traceArray[ptr++])<<8);
 			  time |= (getUnsignedByte(traceArray[ptr++])<<16);
@@ -297,35 +303,56 @@
 
 		  event.createBinary();
 		  
-		  trace.addEvent(event);
-		  if (debug)
-		  {
-			  SortableString s = new SortableString();
-			  s.string = Long.toHexString(adr)+" - "+Long.toHexString(adr+len)+" \t "+event.binary.binaryName+" length:"+len; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-			  s.value = adr;
-			  s.startAddress = adr;
-			  s.endAddress = adr+len;
-			  s.samplingTime = event.eventTime;
-			  sortables.add(s);
-		  }
+		  trace.addEvent(event, isVersion2x);
 	  }
 	  
 	  if (debug)
 	  {
+		  for(GenericEvent ge : trace.getEvents())
+		  {
+			  IttEvent122 ie = (IttEvent122)ge;
+			  SortableString s = new SortableString();
+			  if(isVersion2x){
+				  s.string = Long.toHexString(ie.binaryLocation)+" - "+Long.toHexString(ie.binaryLocation+ie.binaryLength)+" \t "+ie.getBinary().getBinaryName()+" length:"+ie.binaryLength+"\tEvent Start Time: "+ie.eventTime+"\tEvent End Time: "+ie.eventEndTime; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$  //$NON-NLS-4$ //$NON-NLS-5$  
+			  }else{
+				  s.string = Long.toHexString(ie.binaryLocation)+" - "+Long.toHexString(ie.binaryLocation+ie.binaryLength)+" \t "+ie.getBinary().getBinaryName()+" length:"+ie.binaryLength; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ 
+			  }
+			  
+			  s.value = ie.binaryLocation;
+			  s.startAddress = ie.binaryLocation;
+			  s.endAddress = ie.binaryLocation+ie.binaryLength;
+			  s.sampleStartTime = ie.eventTime;
+			  s.sampleRemoveTime = ie.eventEndTime;
+			  sortables.add(s);
+		  }
 		  QuickSortImpl.sort(sortables);
-		  Enumeration e = sortables.elements();
+		  Enumeration<SortableString> e = sortables.elements();
 		  SortableString prev = null;
 		  while (e.hasMoreElements())
 		  {
 			  SortableString s = (SortableString)e.nextElement();
 			  if (prev != null)
 			  {
-				 // System.out.println("Empty:"+(s.startAddress - prev.endAddress)+" bytes");
-				  if (s.startAddress < prev.endAddress) {
-					  System.out.println(Messages.getString("IttTraceParser.debugOverlapping")); //$NON-NLS-1$
-					  System.out.println(Messages.getString("IttTraceParser.previous") + prev.string); //$NON-NLS-1$
-					  System.out.println(Messages.getString("IttTraceParser.this") + s.string); //$NON-NLS-1$
+				  if(isVersion2x){
+					  if(prev.sampleRemoveTime <= 0){
+						  prev.sampleRemoveTime = Double.MAX_VALUE;
+					  }
+					  if(s.sampleRemoveTime <= 0){
+						  s.sampleRemoveTime = Double.MAX_VALUE;
+					  }
+					  if (s.startAddress < prev.endAddress && s.sampleStartTime < prev.sampleRemoveTime && s.sampleRemoveTime > prev.startAddress) {
+						  System.out.println(Messages.getString("IttTraceParser.debugOverlapping")); //$NON-NLS-1$
+						  System.out.println(Messages.getString("IttTraceParser.previous") + prev.string); //$NON-NLS-1$
+						  System.out.println(Messages.getString("IttTraceParser.this") + s.string); //$NON-NLS-1$
+					  }
+				  }else{
+					  if (s.startAddress < prev.endAddress) {
+						  System.out.println(Messages.getString("IttTraceParser.debugOverlapping")); //$NON-NLS-1$
+						  System.out.println(Messages.getString("IttTraceParser.previous") + prev.string); //$NON-NLS-1$
+						  System.out.println(Messages.getString("IttTraceParser.this") + s.string); //$NON-NLS-1$
+					  } 
 				  }
+			
 			  }
 			  System.out.println(s.string);
 			  prev = s;
@@ -431,7 +458,7 @@
     return this.samples.elements();
   }
 
-  private GenericTrace getTrace()
+  public GenericTrace getTrace()
   {
 	  if (this.trace122 == null)
 	  {
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/src/com/nokia/carbide/cpp/pi/instr/MapFile.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/src/com/nokia/carbide/cpp/pi/instr/MapFile.java	Wed Apr 21 15:14:16 2010 +0300
@@ -46,7 +46,7 @@
 	private Function lastGccFunction = null;
 	
 	// RVCT/RVDS map file line
-	private static final Pattern rvctLinePattern = Pattern.compile("\\p{Blank}*((?!\\d)\\S.+)\\p{Blank}+(0[x|X]\\p{XDigit}+|\\d+)\\p{Blank}+(?:ARM Code|Thumb Code)\\p{Blank}+(0x\\p{XDigit}+|\\d+)\\p{Blank}*.*");	//$NON-NLS-1$
+	private static final Pattern rvctLinePattern = Pattern.compile("^\\p{Blank}*((?!\\d)\\S.+)\\p{Blank}+(0[x|X]\\p{XDigit}+|\\d+)\\p{Blank}+(?:ARM Code|Thumb Code)\\p{Blank}+(0x\\p{XDigit}+|\\d+)\\p{Blank}.*\\(\\.text\\)$");	//$NON-NLS-1$
 
 	// a GCC map file line looks like this:
 	// <%x|%d> <symbol name> for function symbols
@@ -57,6 +57,7 @@
 	// *fill* <%x|%d> <%x|%d> 00000000 for filler
 	private static final Pattern gccLibOrFillerLinePattern = Pattern.compile("\\p{Blank}*(?:\\S*)\\p{Blank}*(0[x|X]\\p{XDigit}+|\\d+)\\p{Blank}+(0[x|X]\\p{XDigit}+|\\d+)\\p{Blank}+(\\S.+)"); //$NON-NLS-1$
 
+	private static final String EXPORTED = " (EXPORTED)";
 
 	public MapFile(File file, String referencePath, long referenceLineNumber)
 	{
@@ -107,21 +108,21 @@
 			// is the asked offset within the area of this function
 			// test first is the offset equal or past the first
 			// instruction of the function
-			if (offset >= f.offsetFromBinaryStart)
+			if (offset >= f.getOffsetFromBinaryStart())
 			{
 				// if so, make sure that the offset is less
 				// or equal to the last instruction within 
 				// this function
-				if (offset < (f.offsetFromBinaryStart+f.length))
+				if (offset < (f.getOffsetFromBinaryStart()+f.getLength()))
 				{
-					return f.functionName;
+					return f.getFunctionName();
 				}
 			}
 		}
 		
 		return Messages.getString("MapFile.functionWithOffsetNotFound1")+offset+Messages.getString("MapFile.functionWithOffsetNotFound2")+this.name+ //$NON-NLS-1$ //$NON-NLS-2$
 				Messages.getString("MapFile.functionWithOffsetNotFound3")+ //$NON-NLS-1$
-				(this.sortedFunctionData.get(this.sortedFunctionData.size() - 1)).offsetFromBinaryStart; 		 //$NON-NLS-1$
+				(this.sortedFunctionData.get(this.sortedFunctionData.size() - 1)).getOffsetFromBinaryStart(); 		 //$NON-NLS-1$
 	}
 	
 	public Function getFunctionForOffset(long offset)
@@ -136,12 +137,12 @@
 			// is the asked offset within the area of this function
 			// test first is the offset equal or past the first
 			// instruction of the function
-			if (offset >= f.offsetFromBinaryStart)
+			if (offset >= f.getOffsetFromBinaryStart())
 			{
 				// if so, make sure that the offset is less
 				// or equal to the last instruction within 
 				// this function
-				if (offset < (f.offsetFromBinaryStart+f.length))
+				if (offset < (f.getOffsetFromBinaryStart()+f.getLength()))
 				{
 					return f;
 				}
@@ -163,14 +164,14 @@
 			// is the asked offset within the area of this function
 			// test first is the offset equal or past the first
 			// instruction of the function
-			if (offset >= f.offsetFromBinaryStart)
+			if (offset >= f.getOffsetFromBinaryStart())
 			{
 				// if so, make sure that the offset is less
 				// or equal to the last instruction within 
 				// this function
-				if (offset < (f.offsetFromBinaryStart+f.length))
+				if (offset < (f.getOffsetFromBinaryStart()+f.getLength()))
 				{
-					return f.length;
+					return f.getLength();
 				}
 			}
 		}
@@ -186,9 +187,9 @@
 
 		for (Function f : sortedFunctionData)
 		{
-			if (f.functionName.equals(functionName))
+			if (f.getFunctionName().equals(functionName))
 			{
-				return f.offsetFromBinaryStart;
+				return f.getOffsetFromBinaryStart();
 			}
 		}
 		return -1;
@@ -196,11 +197,11 @@
 	
 	private Function FunctionFromTokens(String funcNameToken, String funcOffsetToken, String funcLengthToken)
 	{	
-		Function f = new Function(funcNameToken,new Long(0),null);
+		Function f = new Function(funcNameToken,Long.valueOf(0),null);
 		// look for length, set it tentatively
 		// we may adjust it later
-		f.length = Long.decode(funcLengthToken);
-		f.offsetFromBinaryStart = Long.decode(funcOffsetToken);
+		f.setLength(Long.decode(funcLengthToken));
+		f.setOffsetFromBinaryStart( Long.decode(funcOffsetToken));
 
 		return f;
 	}
@@ -296,10 +297,13 @@
 			// internal symbol, not a function
 			if (funcNameToken.indexOf(Messages.getString("MapFile.dollarSign")) != -1) //$NON-NLS-1$
 				return;
+			if(funcNameToken.endsWith(EXPORTED)){
+				funcNameToken = funcNameToken.substring(0, funcNameToken.lastIndexOf(EXPORTED));
+			}
 			
 			String funcOffsetToken = rvctLineMatcher.group(2).trim();
 			
-			if (funcOffsetToken.equalsIgnoreCase("0x00000001") && line.contains("Thumb Code"))
+			if (funcOffsetToken.equalsIgnoreCase("0x00000001") && line.contains("Thumb Code")) //$NON-NLS-1$ //$NON-NLS-2$
 				return;
 			
 			String funcLengthToken = rvctLineMatcher.group(3).trim();
@@ -364,15 +368,15 @@
 			f = FunctionFromTokens(funcNameToken, funcOffsetToken, funcLengthToken);
 			
 			// Some GCC symbol may be bogus
-			if (qualifyGCCSymbol(f.offsetFromBinaryStart, funcNameToken)) {
+			if (qualifyGCCSymbol(f.getOffsetFromBinaryStart(), funcNameToken)) {
 				this.insertToFunctionData(f);
 			} 
 			
 			if (lastGccFunction != null){
 				// calculate size of last function with offset from current line
-				if (f.offsetFromBinaryStart > lastGccFunction.offsetFromBinaryStart &&
-						f.offsetFromBinaryStart < currentGccLibEndingOffset) {
-					currentLineOffset = f.offsetFromBinaryStart;
+				if (f.getOffsetFromBinaryStart() > lastGccFunction.getOffsetFromBinaryStart() &&
+						f.getOffsetFromBinaryStart() < currentGccLibEndingOffset) {
+					currentLineOffset = f.getOffsetFromBinaryStart();
 				}
 			}
 			
@@ -389,8 +393,8 @@
 		// update last function's size if needed
 		if (lastGccFunction != null)
 		{
-			if (currentLineOffset > lastGccFunction.offsetFromBinaryStart) {
-				lastGccFunction.length = currentLineOffset - lastGccFunction.offsetFromBinaryStart;
+			if (currentLineOffset > lastGccFunction.getOffsetFromBinaryStart()) {
+				lastGccFunction.setLength(currentLineOffset - lastGccFunction.getOffsetFromBinaryStart());
 			}
 		}
 		
@@ -405,13 +409,13 @@
 		{
 			functionData.addFirst(function);
 		}
-		else if ((functionData.getFirst()).offsetFromBinaryStart 
-					< function.offsetFromBinaryStart)
+		else if ((functionData.getFirst()).getOffsetFromBinaryStart() 
+					< function.getOffsetFromBinaryStart())
 		{
 			functionData.addFirst(function);
 		}
-		else if ((functionData.getLast()).offsetFromBinaryStart 
-					> function.offsetFromBinaryStart)
+		else if ((functionData.getLast()).getOffsetFromBinaryStart() 
+					> function.getOffsetFromBinaryStart())
 		{
 			functionData.addLast(function);
 		}
@@ -419,8 +423,8 @@
 		{
 			for (int i=0;i<functionData.size();i++)
 			{
-				if ((functionData.get(i)).offsetFromBinaryStart 
-						< function.offsetFromBinaryStart)
+				if ((functionData.get(i)).getOffsetFromBinaryStart() 
+						< function.getOffsetFromBinaryStart())
 				{
 					functionData.add(i,function);
 					break;
@@ -435,7 +439,7 @@
 			return;
 		}
 		this.sortedFunctionData.clear();
-		long start = (this.functionData.getLast()).offsetFromBinaryStart;
+		long start = (this.functionData.getLast()).getOffsetFromBinaryStart();
 		Function previous = null;
 		boolean reallyAdded = false;
 		
@@ -443,7 +447,7 @@
 		{
 			//System.out.println(i);
 			Function f = this.functionData.get(i);
-			f.offsetFromBinaryStart = f.offsetFromBinaryStart - start;
+			f.setOffsetFromBinaryStart(f.getOffsetFromBinaryStart() - start);
 			
 			if (this.sortedFunctionData.size() == 0)
 			{
@@ -451,13 +455,13 @@
 				this.sortedFunctionData.add(f);
 				reallyAdded = true;
 			}
-			else if ( (this.sortedFunctionData.get(this.sortedFunctionData.size()-1)).offsetFromBinaryStart != f.offsetFromBinaryStart)
+			else if ( (this.sortedFunctionData.get(this.sortedFunctionData.size()-1)).getOffsetFromBinaryStart() != f.getOffsetFromBinaryStart())
 			{
 				// add the function if the offset is not the same as with the previous line
 				this.sortedFunctionData.add(f);
 				reallyAdded = true;
 			}	
-			else if ( (this.sortedFunctionData.get(this.sortedFunctionData.size()-1)).functionName.startsWith("_")) //$NON-NLS-1$
+			else if ( (this.sortedFunctionData.get(this.sortedFunctionData.size()-1)).getFunctionName().startsWith("_")) //$NON-NLS-1$
 			{	
 				// if there is a key with this offset, discard the previous with prefix "_"
 				this.sortedFunctionData.remove(this.sortedFunctionData.get(this.sortedFunctionData.size()-1));
@@ -471,7 +475,7 @@
 			{
 				// store the length of the previous function
 				if (previous != null)
-					previous.length = f.offsetFromBinaryStart - previous.offsetFromBinaryStart;
+					previous.setLength(f.getOffsetFromBinaryStart() - previous.getOffsetFromBinaryStart());
 				previous = f;	
 				reallyAdded = false;
 			}
@@ -495,15 +499,16 @@
 	*/
 	
 	private void flagFileNotFound(File file, String referencePath, long referenceLineNumber) {
-		  String myMessage = Messages.getString("MapFile.map.file") +  file.getAbsoluteFile().getName() + Messages.getString("MapFile.not.found"); //$NON-NLS-1$ //$NON-NLS-2$
+		  String myMessage = Messages.getString("MapFile.map.file") +  file.getAbsoluteFile() + Messages.getString("MapFile.not.found"); //$NON-NLS-1$ //$NON-NLS-2$
+		  myMessage += Messages.getString("MapFile.map.check.project"); //$NON-NLS-1$
 		  if (referencePath != null && referencePath.length() > 0) {
 			  myMessage += Messages.getString("MapFile.referenced.by") + referencePath; //$NON-NLS-1$
 		  }
 		  if (referenceLineNumber > 0) {
 			  myMessage += Messages.getString("MapFile.line.number") + referenceLineNumber; //$NON-NLS-1$
 		  }
-
-    	  GeneralMessages.PiLog(myMessage, GeneralMessages.ERROR);
+		  
+    	  GeneralMessages.PiLog(myMessage, GeneralMessages.WARNING);
 	}
 
 	private void flagIOException(File file, String referencePath, long referenceLineNumber) {
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/src/com/nokia/carbide/cpp/pi/instr/PiInstrFunctionResolver.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/src/com/nokia/carbide/cpp/pi/instr/PiInstrFunctionResolver.java	Wed Apr 21 15:14:16 2010 +0300
@@ -19,9 +19,9 @@
 
 import java.io.File;
 
-import com.nokia.carbide.cpp.internal.pi.model.Binary;
-import com.nokia.carbide.cpp.internal.pi.model.Function;
 import com.nokia.carbide.cpp.internal.pi.model.FunctionResolver;
+import com.nokia.carbide.cpp.internal.pi.model.IBinary;
+import com.nokia.carbide.cpp.internal.pi.model.IFunction;
 import com.nokia.carbide.cpp.internal.pi.resolvers.RofsSymbolFileFunctionResolver;
 import com.nokia.carbide.cpp.pi.importer.SampleImporter;
 
@@ -56,20 +56,24 @@
 		rofsResolver.adjustRuntimeBinary(binaryReader122.getHostNameToBinary());		
 	}
 	
-	public Binary findBinaryForAddress(long address) {
-		Function f = this.findFunctionForAddress(address);
+	public IBinary findBinaryForAddress(long address, long sampleSynchTime) {
+		IFunction f = this.findFunctionForAddress(address, sampleSynchTime);
 		
 		if (f != null)
-			return f.functionBinary;
+			return f.getFunctionBinary();
 		else 
 			return null;
 	}
+	
+	public IBinary findBinaryForAddress(long address) {
+		return findBinaryForAddress(address, -1);
+	}
 
 	public String findBinaryNameForAddress(long address) {
-		Function f = this.findFunctionForAddress(address);
+		IFunction f = this.findFunctionForAddress(address);
 		if (f != null)
 		{
-			return f.functionBinary.binaryName;
+			return f.getFunctionBinary().getBinaryName();
 		}
 		else
 		{
@@ -77,20 +81,25 @@
 		}
 	}
 
-	public Function findFunctionForAddress(long address) {
-		Function f;
+	public IFunction findFunctionForAddress(long address, long sampleSynchTime) {
+		IFunction f;
 		f = this.rofsResolver.findFunctionForAddress(address);
 		if (f == null) {	//$NON-NLS-1$
-			f = this.ittTrace122.getFunctionForAddress(address,this.binaryReader122);
+			f = this.ittTrace122.getFunctionForAddress(address, sampleSynchTime, this.binaryReader122);
 		}
 		return f;
 	}
 
+	public IFunction findFunctionForAddress(long address) {
+		return findFunctionForAddress(address, -1);
+	}
+
+	
 	public String findFunctionNameForAddress(long address) {
-		Function f = this.findFunctionForAddress(address);
+		IFunction f = this.findFunctionForAddress(address);
 		if (f != null)
 		{
-			return f.functionName;
+			return f.getFunctionName();
 		}
 		else
 		{
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/src/com/nokia/carbide/cpp/pi/instr/ProcessedBinary.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/src/com/nokia/carbide/cpp/pi/instr/ProcessedBinary.java	Wed Apr 21 15:14:16 2010 +0300
@@ -142,15 +142,15 @@
   		
   		long offsetFromBinaryStart = this.mapFile.getOffsetFromBinaryStartForFunction(name); 
   		// this cannot be resolved here, since the address is not known
-  		Long addr = new Long(0);
+  		Long addr = Long.valueOf(0);
   		
   		String search = name + dllName;
   		Function f = this.knownFunctions.get(search);
   		
   		if (f == null) {
 	  		f = new Function(name,addr,dllName);
-	  		f.offsetFromBinaryStart = offsetFromBinaryStart;
-	  		f.length = this.mapFile.getFunctionLengthForOffset(offset);
+	  		f.setOffsetFromBinaryStart(offsetFromBinaryStart);
+	  		f.setLength(this.mapFile.getFunctionLengthForOffset(offset));
 	  		this.knownFunctions.put(search, f);
   		}
   		
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/src/com/nokia/carbide/cpp/pi/instr/UndecidedPool.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/src/com/nokia/carbide/cpp/pi/instr/UndecidedPool.java	Wed Apr 21 15:14:16 2010 +0300
@@ -67,17 +67,17 @@
 		{
 			Binary possibleBinary = brr.possibleBinaries[i];
 			UndecidedLocation ul = 
-				(UndecidedLocation)undecidedLocations.get(possibleBinary.binaryName);
+				(UndecidedLocation)undecidedLocations.get(possibleBinary.getBinaryName());
 			
 			if (ul != null)
 			{
-				ul.addSample(sample,possibleBinary.startAddress);
+				ul.addSample(sample,possibleBinary.getStartAddress());
 			}
 			else
 			{
 				ul = new UndecidedLocation(possibleBinary); 
-				ul.addSample(sample,possibleBinary.startAddress);
-				this.undecidedLocations.put(possibleBinary.binaryName,ul);
+				ul.addSample(sample,possibleBinary.getStartAddress());
+				this.undecidedLocations.put(possibleBinary.getBinaryName(),ul);
 			}
 			
 			// the value of decisionBoundary has to be reduced in the future
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/src/com/nokia/carbide/cpp/pi/instr/messages.properties	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/src/com/nokia/carbide/cpp/pi/instr/messages.properties	Wed Apr 21 15:14:16 2010 +0300
@@ -10,6 +10,7 @@
 ProcessedBinary.unknownType=unknown
 ProcessedBinary.mapFileForBinaryNotFound1=Mapfile for 
 ProcessedBinary.mapFileForBinaryNotFound2=\ not found - unable to resolve functions
+InstrPlugin.0=Dynamic binaries
 IttSample.space=\ 
 DecidedPool.debugDecidedPool=Something wrong in ITT trace / insertSample\!
 DecidedPool.analysisResolved1=Dynamic binary support Analysis - resolved: 
@@ -87,6 +88,7 @@
 MapFile.line.number=\ line 
 MapFile.ioexception=\ encountered IOException upon access.
 MapFile.zero=0
+MapFile.map.check.project=\ Please check that the project is properly built.
 MapFile.map.file=Map file 
 MapFile.not.found=\ not found.
 MapFile.parsingMapFile=Parsing map file 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.ipc/.classpath	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.ipc/.settings/org.eclipse.jdt.core.prefs	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,8 @@
+#Tue Jan 19 15:21:41 GMT 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.ipc/META-INF/MANIFEST.MF	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,17 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Carbide.c++ Interconnect Performance Counters PI Plugin
+Bundle-SymbolicName: com.nokia.carbide.cpp.pi.ipc;singleton:=true
+Bundle-Version: 2.3.0.qualifier
+Bundle-Activator: com.nokia.carbide.cpp.pi.ipc.IpcPlugin
+Bundle-Vendor: Nokia
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ com.nokia.carbide.cpp.pi;bundle-version="2.2.0",
+ org.eclipse.draw2d,
+ com.nokia.carbide.cpp.pi.util;bundle-version="2.2.0",
+ org.eclipse.ui.ide,
+ com.nokia.carbide.cpp.pi.peccommon;bundle-version="2.2.0"
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-ActivationPolicy: lazy
+Eclipse-ExtensibleAPI: true
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.ipc/build.properties	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,5 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               plugin.xml
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.ipc/plugin.xml	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+   <extension
+         point="com.nokia.carbide.cpp.pi.piPluginData">
+      <plugin
+            pluginClass="com.nokia.carbide.cpp.pi.ipc.IpcReturnPlugin">
+      </plugin>
+   </extension>
+
+</plugin>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.ipc/src/com/nokia/carbide/cpp/pi/internal/ipc/IpcSample.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2010 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: 
+ *
+ */
+
+package com.nokia.carbide.cpp.pi.internal.ipc;
+
+import java.util.Arrays;
+
+import com.nokia.carbide.cpp.pi.peccommon.PecCommonSample;
+
+
+/**
+ * Represents an Interconnect Performance Counter Sample
+ */
+public class IpcSample extends PecCommonSample 
+{
+	private static final long serialVersionUID = 84123271817196064L;
+
+	/**
+	 * Constructor
+	 * @param values trace event values for this sample
+	 * @param time The time for this sample
+	 */
+	public IpcSample(int[] values, long time) {
+		super(values, time);
+	}
+
+	@Override
+	public String toString() {
+		return String.format(Messages.IpcSample_0, sampleSynchTime, Arrays.toString(values));
+	}
+	
+	
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.ipc/src/com/nokia/carbide/cpp/pi/internal/ipc/IpcTrace.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2010 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: 
+ *
+ */
+
+package com.nokia.carbide.cpp.pi.internal.ipc;
+
+import com.nokia.carbide.cpp.pi.peccommon.PecCommonTrace;
+
+/**
+ * The model class for Performance Counter traces. This manages the data
+ * for the IPC trace graphs, and is responsible for creating the graphs. 
+ */
+public class IpcTrace extends PecCommonTrace {
+	private static final long serialVersionUID = 4425739452429422333L;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.ipc/src/com/nokia/carbide/cpp/pi/internal/ipc/IpcTraceParser.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,383 @@
+/*
+ * Copyright (c) 2010 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: 
+ *
+ */
+
+package com.nokia.carbide.cpp.pi.internal.ipc;
+
+import java.io.DataInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.nokia.carbide.cpp.internal.pi.model.ParsedTraceData;
+import com.nokia.carbide.cpp.internal.pi.model.Parser;
+
+
+/**
+ * Parser for performance counter event traces in binary format.
+ * Converts parsed content into IpcSamples.
+ */
+public class IpcTraceParser extends Parser {
+	private static final String IPC_EVENT_NOT_RECOGNISED = Messages.IpcTraceParser_0;
+	private static final int MAX_IPC_EVENTS_TRACED = 14; //2 IPC events * 5 possible values + 4 optional L2 counter values
+	private static final int MAX_IPC_NO_L2_EVENTS_TRACED = 10; //2 IPC events * 5 possible values
+	
+	
+	//private static int CPU_CLOCK_TICK_DIV64 = 0xFFFF;
+	private boolean debug = false; //CH: this could be replaced with Eclipse-style logging
+	private boolean l2Enabled = false;
+	
+	long time = 0;
+	
+	private static final Map<Integer, String> eventTypeTable = new HashMap<Integer, String>();
+	static {
+		eventTypeTable.put(0x0,Messages.IpcTraceParser_1);
+		eventTypeTable.put(0x1,Messages.IpcTraceParser_2);
+		eventTypeTable.put(0x2,Messages.IpcTraceParser_3);
+		eventTypeTable.put(0x3,Messages.IpcTraceParser_4);
+		eventTypeTable.put(0x4,Messages.IpcTraceParser_5);
+	}
+	private static final Map<Integer, String> counterTypeTable = new HashMap<Integer, String>();
+	static {
+		counterTypeTable.put(0x0,Messages.IpcTraceParser_6);
+		counterTypeTable.put(0x1,Messages.IpcTraceParser_7);
+		counterTypeTable.put(0x2,Messages.IpcTraceParser_8);
+		counterTypeTable.put(0x3,Messages.IpcTraceParser_9);
+		counterTypeTable.put(0x4,Messages.IpcTraceParser_10);
+		counterTypeTable.put(0x5,Messages.IpcTraceParser_11);
+	}	
+	private static final Map<Integer, String> l2EventTypeTable = new HashMap<Integer, String>();
+	static {
+		l2EventTypeTable.put(0x3,Messages.IpcTraceParser_12);
+		l2EventTypeTable.put(0x4,Messages.IpcTraceParser_13);
+		l2EventTypeTable.put(0x5,Messages.IpcTraceParser_14);
+		l2EventTypeTable.put(0x6,Messages.IpcTraceParser_15);
+		l2EventTypeTable.put(0x7,Messages.IpcTraceParser_16);
+		l2EventTypeTable.put(0xC,Messages.IpcTraceParser_17);
+		l2EventTypeTable.put(0xD,Messages.IpcTraceParser_18);
+	}			
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.model.Parser#parse(java.io.File)
+	 */
+	@Override
+	public ParsedTraceData parse(File file) throws Exception 
+	{
+		ParsedTraceData ptd = new ParsedTraceData();
+		ptd.functionResolvers = null;
+		ptd.staticData = null;
+		ptd.traceData = new IpcTrace();
+		doParsing(file,(IpcTrace)ptd.traceData);
+		time = 0;
+		
+		return ptd;
+	}
+	
+	private void doParsing(File f, IpcTrace trace) throws FileNotFoundException
+ {
+		DataInputStream dis = new DataInputStream(new FileInputStream(f));
+		try {
+			int len = dis.readByte();
+			byte[] versionString = new byte[len];
+			dis.read(versionString);
+			this.traceVersion = new String(versionString);
+			if (debug){
+				System.out.println("IPC trace version:" + this.traceVersion); //$NON-NLS-1$				
+			}
+
+			List<Integer> counterTypes = new ArrayList<Integer>();
+			List<Integer> counterL2Types = new ArrayList<Integer>();
+
+			// IPC counters
+			int firstCounter = dis.readUnsignedByte();
+			counterTypes.add(firstCounter);
+			int secondCounter = dis.readUnsignedByte();
+			counterTypes.add(secondCounter);
+
+			// this type is always the cpu clock tick div 64
+			// int thirdData = CPU_CLOCK_TICK_DIV64;
+			// valueTypeVector.add(new Integer(thirdData));
+
+			if (dis.readUnsignedByte() != 0) {
+				// L2 counters, add if available
+				int thirdCounter = dis.readUnsignedByte();
+				counterL2Types.add(thirdCounter);
+				int fourthCounter = dis.readUnsignedByte();
+				counterL2Types.add(fourthCounter);
+				int fifthCounter = dis.readUnsignedByte();
+				counterL2Types.add(fifthCounter);
+				int sixthCounter = dis.readUnsignedByte();
+				counterL2Types.add(sixthCounter);
+
+				trace.setValueTypes(this.parseValueTypes(counterTypes, counterL2Types));
+			} else {
+				trace.setValueTypes(this.parseValueTypes(counterTypes, null));
+			}
+
+			// System.out.println("IPC first "+firstCounter+" second "+secondCounter);
+
+			IpcSample s = null;
+			while (true) {
+				s = readSample(dis, s);
+				// System.out.println(this.time+" "+Long.toHexString(s.values[0])+" "+Long.toHexString(s.values[1])+" "+Long.toHexString(s.values[2]));
+				trace.addSample(s);
+			}
+		} catch (IOException ioe) {
+			// CH: is this just caught for end-of-file condition?
+		}
+	}
+
+	private IpcSample readSample(DataInputStream dis, IpcSample prevSample)
+			throws IOException {
+		// int headerByte = (dis.readInt()); // << 24) >>> 24;
+		int headerByte1 = (dis.readByte() << 24) >>> 24;
+		int headerByte2 = (dis.readByte() << 24) >>> 24;
+		int headerByte3 = (dis.readByte() << 24) >>> 24;
+		int headerByte4 = (dis.readByte() << 24) >>> 24;
+		int headerByte = ((((headerByte1) | (headerByte2) << 8) | (headerByte3) << 16) | headerByte4 << 24);
+
+		int headerByte11 = 0;
+		int headerByte12 = 0;
+		int headerByteL2 = 0;
+		// int j = ((headerByte >>> 30)&1);
+		if (((headerByte >>> 30) & 1) != 0 || l2Enabled) // flag bit in trace =>
+															// L2 trace included
+		{
+			l2Enabled = true;
+			headerByte11 = (dis.readByte() << 24) >>> 24;
+			headerByte12 = (dis.readByte() << 24) >>> 24; // overflow bits
+			headerByteL2 = ((headerByte11) | ((headerByte12) << 8));
+		}
+
+		int eventNumber = l2Enabled ? MAX_IPC_EVENTS_TRACED
+				: MAX_IPC_NO_L2_EVENTS_TRACED;
+
+		int[] neg = new int[eventNumber];
+		int[] prev = new int[eventNumber];
+
+		if (prevSample != null) {
+			prev[0] = prevSample.values[0];
+			prev[1] = prevSample.values[1];
+			prev[2] = prevSample.values[2];
+			prev[3] = prevSample.values[3];
+			prev[4] = prevSample.values[4];
+			prev[5] = prevSample.values[5];
+			prev[6] = prevSample.values[6];
+			prev[7] = prevSample.values[7];
+			prev[8] = prevSample.values[8];
+			prev[9] = prevSample.values[9];
+			if (l2Enabled) {
+				prev[10] = prevSample.values[10];
+				prev[11] = prevSample.values[11];
+				prev[12] = prevSample.values[12];
+				prev[13] = prevSample.values[13];
+			}
+		}
+		// /*if(debug) if(this.time > 7820 && this.time < 7830)*/
+		// System.out.println("header: "+Long.toHexString(headerByte)+" = "+Integer.toBinaryString(headerByte));
+
+		if (((headerByte >>> 29) & 1) != 0) {
+			neg[0] = 1;
+		}
+
+		if (((headerByte >>> 28) & 1) != 0) {
+			neg[1] = 1;
+		}
+
+		if (((headerByte >>> 27) & 1) != 0) {
+			neg[2] = 1;
+		}
+		if (((headerByte >>> 26) & 1) != 0) {
+			neg[3] = 1;
+		}
+
+		if (((headerByte >>> 25) & 1) != 0) {
+			neg[4] = 1;
+		}
+
+		if (((headerByte >>> 24) & 1) != 0) {
+			neg[5] = 1;
+		}
+		if (((headerByte >>> 23) & 1) != 0) {
+			neg[6] = 1;
+		}
+
+		if (((headerByte >>> 22) & 1) != 0) {
+			neg[7] = 1;
+		}
+
+		if (((headerByte >>> 21) & 1) != 0) {
+			neg[8] = 1;
+		}
+		if (((headerByte >>> 20) & 1) != 0) {
+			neg[9] = 1;
+		}
+
+		// check overflows of L2 counters
+		if (l2Enabled) {
+			if (((headerByteL2 >>> 11) & 1) != 0) {
+				neg[10] = 1;
+			}
+
+			if (((headerByteL2 >>> 10) & 1) != 0) {
+				neg[11] = 1;
+			}
+
+			if (((headerByteL2 >>> 9) & 1) != 0) {
+				neg[12] = 1;
+			}
+			if (((headerByteL2 >>> 8) & 1) != 0) {
+				neg[13] = 1;
+			}
+
+		}
+
+		int[] len = new int[eventNumber];
+		len[0] = (((headerByte >> 18) << 30) >>> 30) + 1;
+		len[1] = (((headerByte >> 16) << 30) >>> 30) + 1;
+		len[2] = (((headerByte >> 14) << 30) >>> 30) + 1;
+		len[3] = (((headerByte >> 12) << 30) >>> 30) + 1;
+		len[4] = (((headerByte >> 10) << 30) >>> 30) + 1;
+		len[5] = (((headerByte >> 8) << 30) >>> 30) + 1;
+		len[6] = (((headerByte >> 6) << 30) >>> 30) + 1;
+		len[7] = (((headerByte >> 4) << 30) >>> 30) + 1;
+		len[8] = (((headerByte >> 2) << 30) >>> 30) + 1;
+		len[9] = (((headerByte) << 30) >>> 30) + 1;
+
+		if (l2Enabled) {
+			len[10] = (((headerByteL2 >> 6) << 30) >>> 30) + 1;
+			len[11] = (((headerByteL2 >> 4) << 30) >>> 30) + 1;
+			len[12] = (((headerByteL2 >> 2) << 30) >>> 30) + 1;
+			len[13] = ((headerByteL2 << 30) >>> 30) + 1;
+		}
+		if (debug)
+			if (this.time > 7820 && this.time < 7830)
+				System.out.println("T:" + this.time + " len0:" + len[0] + " len1:" + len[1] + " len2:" + len[2]); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+		if (debug)
+			if (this.time > 7900 && this.time < 7900)
+				System.out.println("H: " + Integer.toBinaryString(headerByte) + " N0:" + neg[0] + " N1:" + neg[1] + " N2:" + neg[2]); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ //$NON-NLS-4$
+
+		int[] val = new int[eventNumber];
+		val[0] = readVal(neg[0], len[0], dis);
+		val[1] = readVal(neg[1], len[1], dis);
+		val[2] = readVal(neg[2], len[2], dis);
+		val[3] = readVal(neg[3], len[3], dis);
+		val[4] = readVal(neg[4], len[4], dis);
+		val[5] = readVal(neg[5], len[5], dis);
+		val[6] = readVal(neg[6], len[6], dis);
+		val[7] = readVal(neg[7], len[7], dis);
+		val[8] = readVal(neg[8], len[8], dis);
+		val[9] = readVal(neg[9], len[9], dis);
+
+		if (l2Enabled) {
+			val[10] = readVal(neg[10], len[10], dis);
+			val[11] = readVal(neg[11], len[11], dis);
+			val[12] = readVal(neg[12], len[12], dis);
+			val[13] = readVal(neg[13], len[13], dis);
+		}
+
+		if (debug)
+			if (this.time > 7820 && this.time < 7900)
+				System.out.println("READ T:" + this.time + "   V0:" + Integer.toHexString(val[0]) + " V1:" + Long.toHexString(val[1]) + " V2:" + Long.toHexString(val[2])); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+		for (int i = 0; i < eventNumber; i++) {
+			val[i] = prev[i] - val[i];
+		}
+
+		IpcSample ps = new IpcSample(val, this.time);
+
+		if (debug)
+			if (this.time > 7820 && this.time < 7900)
+				System.out.println("T:" + this.time + "   V0:" + Long.toHexString(val[0]) + " V1:" + Long.toHexString(val[1]) + " V2:" + Long.toHexString(val[2])); //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$ //$NON-NLS-4$
+		if (debug)
+			if (this.time > 7820 && this.time < 7900)
+				System.out.println("T:" + this.time + " " + val[0] + " " + val[1] + " " + val[2]); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ //$NON-NLS-4$
+		this.time++;
+		/*
+		 * dis.readByte(); dis.readByte(); dis.readByte(); dis.readByte();
+		 */
+		return ps;
+	}
+
+	private int readVal(int neg,int len,DataInputStream dis) throws IOException
+	{
+		byte[] array = new byte[len];
+		dis.read(array);
+		
+		//System.out.println("array: "+array);
+		
+		if(debug)
+			for(int k=0;k<array.length;k++)
+			{
+				if(this.time > 7820 && this.time < 7900) System.out.println(" "+Integer.toHexString(array[k])); //$NON-NLS-1$
+			}
+		
+		long total = 0;
+		for(int i=0;i<len;i++)
+		{
+			int value = ((array[i] << 24) >>> 24) << (i*8);			
+			total |= value;
+		}
+		
+		if(debug) if(this.time > 7820 && this.time < 7900) System.out.println("\n"+Long.toHexString(total)); //$NON-NLS-1$
+
+		if(debug) if(this.time > 7820 && this.time < 7900) System.out.println("T:"+this.time+" "+Long.toHexString(total));  //$NON-NLS-1$//$NON-NLS-2$
+		
+		if(neg != 0) total = ~total;
+		
+		return (int)total;
+	}
+		
+	private String[] parseValueTypes(List<Integer> counterTypes, List<Integer> counterL2Types){
+		String[] s = new String[counterTypes.size() * eventTypeTable.size() + (counterL2Types == null ? 0 : counterL2Types.size())];
+		int k = 0;
+		for (int i = 0; i < eventTypeTable.size(); i++) {
+			String eventType =  eventTypeTable.get(i);
+			for (Integer counterType : counterTypes) {
+				s[k] = String.format(Messages.IpcTraceParser_20, eventType, convertCounterType(counterType));
+				k++;
+			}
+		}
+		
+		if (counterL2Types != null){
+			for (Integer l2Type : counterL2Types) {
+				s[k] = convertL2EventType(l2Type);
+				k++;				
+			}
+		}
+		return s;
+	}
+	
+	private String convertL2EventType(Integer value) {
+		String s = IpcTraceParser.l2EventTypeTable.get(value);
+		if (s == null) {
+			s = String.format(IPC_EVENT_NOT_RECOGNISED, value);
+		}
+		return s;
+	}
+	
+	private String convertCounterType(Integer value) {
+		String s = IpcTraceParser.counterTypeTable.get(value);
+		if (s == null) {
+			s = String.format(IPC_EVENT_NOT_RECOGNISED, value);
+		}
+		return s;
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.ipc/src/com/nokia/carbide/cpp/pi/internal/ipc/Messages.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,35 @@
+package com.nokia.carbide.cpp.pi.internal.ipc;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS {
+	private static final String BUNDLE_NAME = "com.nokia.carbide.cpp.pi.internal.ipc.messages"; //$NON-NLS-1$
+	public static String IpcSample_0;
+	public static String IpcTraceParser_0;
+	public static String IpcTraceParser_1;
+	public static String IpcTraceParser_10;
+	public static String IpcTraceParser_11;
+	public static String IpcTraceParser_12;
+	public static String IpcTraceParser_13;
+	public static String IpcTraceParser_14;
+	public static String IpcTraceParser_15;
+	public static String IpcTraceParser_16;
+	public static String IpcTraceParser_17;
+	public static String IpcTraceParser_18;
+	public static String IpcTraceParser_2;
+	public static String IpcTraceParser_20;
+	public static String IpcTraceParser_3;
+	public static String IpcTraceParser_4;
+	public static String IpcTraceParser_5;
+	public static String IpcTraceParser_6;
+	public static String IpcTraceParser_7;
+	public static String IpcTraceParser_8;
+	public static String IpcTraceParser_9;
+	static {
+		// initialize resource bundle
+		NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+	}
+
+	private Messages() {
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.ipc/src/com/nokia/carbide/cpp/pi/internal/ipc/messages.properties	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,21 @@
+IpcSample_0=IPC [Time=%d ms, values=%s]
+IpcTraceParser_0=Value %d not identified as Interconnect Performance counter event\!
+IpcTraceParser_1=Cycle count
+IpcTraceParser_10=D2SDA
+IpcTraceParser_11=Global Direct Memory Access Sub-System
+IpcTraceParser_12=[CPU data read hit to ARM L210 cache]
+IpcTraceParser_13=[CPU data read request to ARM L210 cache]
+IpcTraceParser_14=[CPU data write hit in ARM L210 cache]
+IpcTraceParser_15=[CPU data write request to ARM L210 cache, not write-through]
+IpcTraceParser_16=[CPU data write request to ARM L210 cache, write-through]
+IpcTraceParser_17=[CPU instruction read hit in ARM L210 cache]
+IpcTraceParser_18=[CPU instruction read request to ARM L210 cache]
+IpcTraceParser_2=Read count
+IpcTraceParser_20=[%s of %s] / [1 sampled ms]
+IpcTraceParser_3=Write count
+IpcTraceParser_4=Wait count
+IpcTraceParser_5=Idle count
+IpcTraceParser_6=MCU data access
+IpcTraceParser_7=MCU I/O access
+IpcTraceParser_8=MCU PPF
+IpcTraceParser_9=MCU PPS
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.ipc/src/com/nokia/carbide/cpp/pi/ipc/IpcPlugin.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,320 @@
+package com.nokia.carbide.cpp.pi.ipc;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.swt.widgets.Event;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+
+import com.nokia.carbide.cpp.internal.pi.analyser.NpiInstanceRepository;
+import com.nokia.carbide.cpp.internal.pi.analyser.ProfileVisualiser;
+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.plugin.model.AbstractPiPlugin;
+import com.nokia.carbide.cpp.internal.pi.plugin.model.IClassReplacer;
+import com.nokia.carbide.cpp.internal.pi.plugin.model.IEventListener;
+import com.nokia.carbide.cpp.internal.pi.plugin.model.IFinalizeTrace;
+import com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace;
+import com.nokia.carbide.cpp.internal.pi.plugin.model.IVisualizable;
+import com.nokia.carbide.cpp.internal.pi.visual.GraphDrawRequest;
+import com.nokia.carbide.cpp.pi.editors.PIPageEditor;
+import com.nokia.carbide.cpp.pi.internal.ipc.IpcSample;
+import com.nokia.carbide.cpp.pi.internal.ipc.IpcTrace;
+import com.nokia.carbide.cpp.pi.internal.ipc.IpcTraceParser;
+import com.nokia.carbide.cpp.pi.peccommon.PecCommonGuiManager;
+import com.nokia.carbide.cpp.pi.visual.IGenericTraceGraph;
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class IpcPlugin extends AbstractPiPlugin implements ITrace, IEventListener, IVisualizable, IFinalizeTrace, IClassReplacer {
+
+	/** number of graphs created (one on each page)*/
+	public static final int GRAPH_COUNT = 3;
+
+	/** The plug-in ID */
+	public static final String PLUGIN_ID = "com.nokia.carbide.cpp.pi.ipc"; //$NON-NLS-1$
+	
+	private static final String HELP_CONTEXT_ID = PIPageEditor.PI_ID + ".ipc";  //$NON-NLS-1$
+	/** context help id of the main page */
+	public static final String HELP_CONTEXT_ID_MAIN_PAGE = HELP_CONTEXT_ID + ".ipcPageContext";  //$NON-NLS-1$
+
+	/** the trace id for PEC traces */
+	private static final int PEC_TRACE_ID = 12;
+	
+	/** Persistable preference for the performance counter trace draw mode (show single graph or all graphs)  */
+	public static final String PECTRACE_DRAWMODE = "com.nokia.carbide.cpp.pi.ipc.drawmode";//$NON-NLS-1$
+	/** draw mode for showing all graphs */
+	public static final String PECTRACE_DRAWMODE_SHOW_ALL = "ShowAll";//$NON-NLS-1$
+
+	// The shared instance
+	private static IpcPlugin plugin;
+	
+	private static final Map<Integer, PecCommonGuiManager> guiManagerMap = new HashMap<Integer, PecCommonGuiManager>();
+
+	/**
+	 * The constructor
+	 */
+	public IpcPlugin() {
+		super();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+	 */
+	@Override
+	public void start(BundleContext context) throws Exception {
+		super.start(context);
+		plugin = this;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+	 */
+	@Override
+	public void stop(BundleContext context) throws Exception {
+		plugin = null;
+		super.stop(context);
+	}
+
+	/**
+	 * Returns the shared instance
+	 *
+	 * @return the shared instance
+	 */
+	public static IpcPlugin getDefault() {
+		return plugin;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace#getTraceClass()
+	 */
+	public Class getTraceClass() {
+		return IpcTrace.class;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace#initialiseTrace(com.nokia.carbide.cpp.internal.pi.model.GenericTrace)
+	 */
+	public void initialiseTrace(GenericTrace trace) {
+		if (!(trace instanceof IpcTrace)){
+			throw new IllegalArgumentException();
+		}
+			
+		IpcTrace parsedTrace = (IpcTrace)trace;
+		
+		int samplingInterval = 1; //in milliseconds
+		if (parsedTrace.samples.size() > 2) {
+			samplingInterval = (int) ((parsedTrace.samples.get(1)).sampleSynchTime - (parsedTrace.samples.get(0)).sampleSynchTime); 
+		}
+		parsedTrace.setSamplingInterval(samplingInterval);
+		
+		
+		NpiInstanceRepository.getInstance().activeUidAddTrace(PLUGIN_ID, trace);
+		
+		//create the GUI class which manages the graphs
+		int uid = NpiInstanceRepository.getInstance().activeUid();
+		guiManagerMap.put(uid, new PecCommonGuiManager(uid, parsedTrace, IpcPlugin.GRAPH_COUNT, Messages.IpcPlugin_0));
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace#getTraceName()
+	 */
+	public String getTraceName() {
+		return "IPC"; //$NON-NLS-1$
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace#getTraceTitle()
+	 */
+	public String getTraceTitle() {
+		return Messages.IpcPlugin_1;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace#getTraceId()
+	 */
+	public int getTraceId() {
+		return PEC_TRACE_ID;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace#parseTraceFile(java.io.File)
+	 */
+	public ParsedTraceData parseTraceFile(File file) throws Exception {
+		IpcTraceParser p = new IpcTraceParser();
+		ParsedTraceData ptd = p.parse(file);
+		
+		return ptd;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace#parseTraceFiles(java.io.File[])
+	 */
+	public ParsedTraceData parseTraceFiles(File[] files) throws Exception {
+		throw new UnsupportedOperationException();
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.IEventListener#receiveEvent(java.lang.String, org.eclipse.swt.widgets.Event)
+	 */
+	public void receiveEvent(String action, Event event) {
+		//no-op
+		
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.IVisualizable#arePagesCreated()
+	 */
+	public boolean arePagesCreated() {
+		return false; //PEC traces add graphs to existing pages
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.IVisualizable#createPage(int)
+	 */
+	public ProfileVisualiser createPage(int index) {
+		return null; //PEC traces add graphs to existing pages
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.IVisualizable#getCreatePageCount()
+	 */
+	public int getCreatePageCount() {
+		return 0; //PEC traces don't create pages
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.IVisualizable#getCreatePageIndex(int)
+	 */
+	public int getCreatePageIndex(int index) {
+		throw new UnsupportedOperationException(); //PEC traces don't create pages
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.IVisualizable#getDrawRequest(int)
+	 */
+	public GraphDrawRequest getDrawRequest(int graphIndex) {
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.IVisualizable#getGraphCount()
+	 */
+	public int getGraphCount() {
+		return GRAPH_COUNT;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.IVisualizable#getLastSample(int)
+	 */
+	public Integer getLastSample(int graphIndex) {
+		IpcTrace trace = (IpcTrace) NpiInstanceRepository.getInstance().activeUidGetTrace(PLUGIN_ID);
+		if(trace == null){
+			return 0;
+		}
+		
+		return trace.getLastSampleNumber();
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.IVisualizable#getPageNumber(int)
+	 */
+	public int getPageNumber(int graphIndex) {
+		if (graphIndex == 0) {
+			return PIPageEditor.THREADS_PAGE;
+		} else if (graphIndex == 1) {
+			return PIPageEditor.BINARIES_PAGE;
+		} else if (graphIndex == 2) {
+			return PIPageEditor.FUNCTIONS_PAGE;
+		}
+
+		return PIPageEditor.NEXT_AVAILABLE_PAGE;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.IVisualizable#getTraceGraph(int)
+	 */
+	public IGenericTraceGraph getTraceGraph(int graphIndex) {
+		int uid = NpiInstanceRepository.getInstance().activeUid();
+		PecCommonGuiManager guiManager = guiManagerMap.get(uid);
+		
+		if (guiManager != null){
+			return guiManager.getTraceGraph(graphIndex, HELP_CONTEXT_ID_MAIN_PAGE);			
+		}
+		
+		throw new IllegalStateException();
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.IVisualizable#setPageIndex(int, int)
+	 */
+	public void setPageIndex(int index, int pageIndex) {
+		//no-op
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.IVisualizable#setPagesCreated(boolean)
+	 */
+	public void setPagesCreated(boolean pagesCreated) {
+		//no-op
+	}
+	
+	/**
+	 * Returns a File corresponding to the given bundle relative path.
+	 * @param path the bundle relative path to resource to locate
+	 * @return the File corresponding to the given bundle relative path, or null
+	 * @throws IOException
+	 */
+	public File locateFileInBundle(final String path) throws IOException {
+		Bundle myBundle= getDefault().getBundle();
+		IPath ppath= new Path(path);
+		ppath= ppath.makeRelative();
+		URL[] urls= FileLocator.findEntries(myBundle, ppath);
+		if(urls.length != 1) {
+			return null;
+		}
+		return new File(FileLocator.toFileURL(urls[0]).getFile());
+	}
+
+	
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.IFinalizeTrace#runOnDispose()
+	 */
+	public void runOnDispose() {
+		// called when editor closes
+		
+		// Do any cleanup work here when the editor closes
+		int uid = NpiInstanceRepository.getInstance().activeUid();
+		guiManagerMap.remove(uid);
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.IFinalizeTrace#runOnPartOpened()
+	 */
+	public void runOnPartOpened() {
+		// nothing to do
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.IClassReplacer#getReplacedClass(java.lang.String)
+	 */
+	public Class getReplacedClass(String className) {
+		if (className.startsWith("com.nokia.carbide.cpp.pi.internal.ipc.IpcTrace")){ //$NON-NLS-1$
+			return IpcTrace.class;
+		} else if (className.startsWith("com.nokia.carbide.cpp.pi.internal.ipc.IpcSample")){//$NON-NLS-1$
+			return IpcSample.class;
+		}
+		return null;
+	}
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.ipc/src/com/nokia/carbide/cpp/pi/ipc/IpcReturnPlugin.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2010 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: 
+ *
+ */
+
+package com.nokia.carbide.cpp.pi.ipc;
+
+import com.nokia.carbide.cpp.internal.pi.interfaces.IReturnPlugin;
+import com.nokia.carbide.cpp.internal.pi.plugin.model.AbstractPiPlugin;
+
+/**
+ * Implements the extension point piPluginData to register this plugin as a PI plugin
+ */
+public class IpcReturnPlugin implements IReturnPlugin {
+	public AbstractPiPlugin getPlugin() {
+		return IpcPlugin.getDefault();
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.ipc/src/com/nokia/carbide/cpp/pi/ipc/Messages.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,16 @@
+package com.nokia.carbide.cpp.pi.ipc;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS {
+	private static final String BUNDLE_NAME = "com.nokia.carbide.cpp.pi.ipc.messages"; //$NON-NLS-1$
+	public static String IpcPlugin_0;
+	public static String IpcPlugin_1;
+	static {
+		// initialize resource bundle
+		NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+	}
+
+	private Messages() {
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.ipc/src/com/nokia/carbide/cpp/pi/ipc/messages.properties	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,2 @@
+IpcPlugin_0=Interconnect Performance Counters
+IpcPlugin_1=Interconnect performance counter
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.irq/.classpath	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.irq/.settings/org.eclipse.jdt.core.prefs	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,8 @@
+#Wed Jan 13 14:21:09 EET 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.irq/META-INF/MANIFEST.MF	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,16 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Carbide.c++ Performance Investigator IRQ plug-in
+Bundle-SymbolicName: com.nokia.carbide.cpp.pi.irq;singleton:=true
+Bundle-Version: 2.3.0.qualifier
+Bundle-Activator: com.nokia.carbide.cpp.pi.irq.IrqPlugin
+Bundle-Vendor: Nokia
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ com.nokia.carbide.cpp.pi,
+ com.nokia.carbide.cpp.pi.address;bundle-version="1.4.0",
+ org.eclipse.draw2d,
+ org.eclipse.ui.ide;bundle-version="3.5.0",
+ com.nokia.carbide.cpp.pi.util;bundle-version="2.2.0"
+Bundle-ActivationPolicy: lazy
+Export-Package: com.nokia.carbide.cpp.pi.irq;x-friends:="com.nokia.carbide.cpp.pi.irq.tests"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.irq/build.properties	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,5 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               plugin.xml
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.irq/plugin.xml	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+   <extension
+         point="com.nokia.carbide.cpp.pi.piPluginData">
+      <plugin
+            pluginClass="com.nokia.carbide.cpp.pi.irq.IrqReturnPlugin">
+      </plugin>
+   </extension>
+
+</plugin>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.irq/src/com/nokia/carbide/cpp/pi/irq/IrqLineLabelProvider.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2010 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: 
+ *
+ */
+
+package com.nokia.carbide.cpp.pi.irq;
+
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Table;
+import com.nokia.carbide.cpp.internal.pi.visual.GenericTable;
+
+/**
+ * LabelProvider for irq line table
+ */
+public class IrqLineLabelProvider extends LabelProvider implements ITableLabelProvider {
+	
+	/* irq table */
+    Table table;
+
+    /**
+     * constructor
+     * @param table irq table
+     */
+	public IrqLineLabelProvider(Table table) {
+		super();
+		this.table = table;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java.lang.Object, int)
+	 */
+	public String getColumnText(Object element, int columnIndex) {
+        int columnId = ((Integer) table.getColumn(columnIndex).getData()).intValue();
+
+		
+		
+		switch (columnId)
+		{
+			case GenericTable.COLUMN_ID_IRQ_LINE:
+				
+				// name of the irq line
+				if (element instanceof IrqSampleTypeWrapper){
+					IrqSampleTypeWrapper item = (IrqSampleTypeWrapper) element;
+					return IrqSampleTypeWrapper.getLineText(item.getPrototypeSample().getIrqL1Value());
+				}
+				
+				/* Bappea implementation
+					if(element instanceof Long){
+					Long value = (Long) element;
+					return "IRQ interrupt L1 0x" + Long.toHexString(value);
+					/*if(value != 0)
+					{
+						this.setText("IRQ interrupt L1 0x"+Integer.toHexString(valueL1)+" ("+valueL1+")");
+					}
+					else
+					{
+						int valueL2 = stw.prototypeSample.getIrqL2Value();
+						this.setText("IRQ interrupt L2 0x"+Integer.toHexString(valueL2)+" ("+(32+valueL2)+")");				
+					}	*/
+				//}
+				break;
+				
+			case GenericTable.COLUMN_ID_IRQ_COUNT:
+				// count of interrupts in the selection area
+				if (element instanceof IrqSampleTypeWrapper){
+					IrqSampleTypeWrapper item = (IrqSampleTypeWrapper) element;
+					return Integer.toString(item.count);
+				}
+			default:
+			{
+				break;
+			}
+		}
+		// should never get here
+		return ""; //$NON-NLS-1$
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang.Object, int)
+	 */
+	public Image getColumnImage(Object element, int columnIndex) {
+		return null;
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.irq/src/com/nokia/carbide/cpp/pi/irq/IrqLineTable.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,623 @@
+/*
+ * Copyright (c) 2010 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: 
+ *
+ */
+
+package com.nokia.carbide.cpp.pi.irq;
+
+import java.awt.event.MouseEvent;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import org.eclipse.jface.viewers.CheckStateChangedEvent;
+import org.eclipse.jface.viewers.CheckboxTableViewer;
+import org.eclipse.jface.viewers.ICheckStateListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.ColorDialog;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
+import org.eclipse.swt.widgets.MessageBox;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.TableItem;
+import com.nokia.carbide.cpp.internal.pi.visual.GenericTable;
+
+/**
+ * Table for irq lines
+ */
+public class IrqLineTable extends GenericTable implements ICheckStateListener {
+
+	/* sort direction */
+	private boolean sortAscending = true;
+
+	/* Graph */
+	private IrqTraceGraph myGraph;
+
+	/* Parent component where ui components are placed */
+	private Composite parent;
+
+	/* item data for table */
+	protected Vector<IrqSampleTypeWrapper> tableItemData;
+
+	/**
+	 * Constructor
+	 * 
+	 * @param myGraph
+	 *            graph
+	 * @param parent
+	 *            Parent component where ui components are placed
+	 */
+	public IrqLineTable(IrqTraceGraph myGraph, Composite parent) {
+		this.myGraph = myGraph;
+		this.parent = parent;
+
+		this.tableViewer = CheckboxTableViewer.newCheckList(parent, SWT.BORDER
+				| SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION);
+		this.table = this.tableViewer.getTable();
+
+		// add the check state handler, label provider and content provider
+		this.tableViewer.addCheckStateListener(this);
+		this.tableViewer.setLabelProvider(new IrqLineLabelProvider(this.table));
+		this.tableViewer.setContentProvider(new TableContentProvider());
+		this.tableViewer.setSorter(new SharedSorter());
+
+		// create the columns
+		TableColumn column;
+
+		// data associated with the TableViewer will note which columns contain
+		// hex values
+		// Keep this in the order in which columns have been created
+		boolean[] isHex = { false, false, false, false };
+		this.table.setData("isHex", isHex); //$NON-NLS-1$
+
+		// Check and color column
+		column = new TableColumn(this.table, SWT.CENTER);
+		column.setText(Messages.IrqLineTable_0);
+		column.setWidth(COLUMN_WIDTH_CHECK_COLUMN);
+		column.setData(COLOR_COLUMN_INDEX);
+		column.setMoveable(true);
+		column.setResizable(true);
+		column.addSelectionListener(new ColumnSelectionHandler());
+
+		// Thread line column
+		column = new TableColumn(this.table, SWT.LEFT);
+		column.setText(Messages.IrqLineTable_1);
+		column.setWidth(COLUMN_WIDTH_THREAD_IRQ_LINE);
+		column.setData(COLUMN_ID_IRQ_LINE);
+		column.setMoveable(true);
+		column.setResizable(true);
+		column.addSelectionListener(new ColumnSelectionHandler());
+
+		// Return address
+		column = new TableColumn(tableViewer.getTable(), SWT.RIGHT);
+		column.setText(Messages.IrqLineTable_2);
+		column.setWidth(COLUMN_WIDTH_ADDRESS_COUNT);
+		column.setData(COLUMN_ID_IRQ_COUNT);
+		column.setMoveable(true);
+		column.setResizable(true);
+		column.addSelectionListener(new ColumnSelectionHandler());
+
+		// add mouse listener and set other table settings
+		this.table.addMouseListener(new TableMouseListener());
+		this.table.setHeaderVisible(true);
+		this.table.setLinesVisible(true);
+		this.table.setRedraw(true);
+
+		// format data into table
+		this.updateItemData(true);
+		((SharedSorter) tableViewer.getSorter()).doSort(COLUMN_ID_IRQ_COUNT);
+
+		// Select initially no lines
+		this.tableViewer.setAllChecked(false);
+
+		// listen for key sequences such as Ctrl-A and Ctrl-C
+		table.addKeyListener(new TableKeyListener());
+
+		tableViewer.refresh();
+		table.redraw();
+		this.addColor();
+	}
+
+	/**
+	 * content provider for table
+	 */
+	private static class TableContentProvider implements
+			IStructuredContentProvider {
+
+		/**
+		 * Constructor
+		 */
+		public TableContentProvider() {
+			super();
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see
+		 * org.eclipse.jface.viewers.IStructuredContentProvider#getElements(
+		 * java.lang.Object)
+		 */
+		@SuppressWarnings("unchecked")
+		public Object[] getElements(Object inputElement) {
+			return ((Vector<IrqSampleTypeWrapper>) inputElement).toArray();
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see org.eclipse.jface.viewers.IContentProvider#dispose()
+		 */
+		public void dispose() {
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see
+		 * org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse
+		 * .jface.viewers.Viewer, java.lang.Object, java.lang.Object)
+		 */
+		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.visual.GenericTable#action(java.lang
+	 * .String)
+	 */
+	public void action(String actionString) {
+		if (actionString.equals("add")) { //$NON-NLS-1$
+			checkOrUncheckSelectedItems(true);
+		} else if (actionString.equals("remove")) { //$NON-NLS-1$
+			checkOrUncheckSelectedItems(false);
+		} else if (actionString.equals("addall")) { //$NON-NLS-1$
+			checkOrUncheckAllItems(true);
+		} else if (actionString.equals("removeall")) { //$NON-NLS-1$
+			checkOrUncheckAllItems(false);
+		} else if (actionString.equals(Messages.IrqLineTable_3)) {
+			actionRecolor();
+		} else if (actionString.equals("copy")) //$NON-NLS-1$
+		{
+			actionCopyOrSave(true, this.table, CHECKBOX_TEXT, false, "\t", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
+			return; // no redraw needed
+		} else if (actionString.equals("copyTable")) //$NON-NLS-1$
+		{
+			actionCopyOrSave(true, this.table, CHECKBOX_TEXT, true, "\t", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
+			return; // no redraw needed
+		} else if (actionString.equals("selectAll")) //$NON-NLS-1$
+		{
+			actionSelectAll();
+			return;
+		}
+
+		else if (actionString.equals("saveTable")) //$NON-NLS-1$
+		{
+			actionCopyOrSave(false, this.table, CHECKBOX_TEXT, true, ",", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
+			return; // no redraw needed
+		}
+	}
+
+	/**
+	 * Checks or unchecks all selected irq lines from table
+	 * 
+	 * @param value
+	 *            true if items are checked
+	 */
+	private void checkOrUncheckSelectedItems(boolean value) {
+		// go thru selected items from thread table and notify graph that
+		// threads are checked or unchecked
+		TableItem[] selectedItems = this.table.getSelection();
+		for (int i = 0; i < selectedItems.length; i++) {
+
+			if (selectedItems[i].getData().getClass() == IrqSampleTypeWrapper.class) {
+				selectedItems[i].setChecked(value);
+				IrqSampleTypeWrapper wrapper = (IrqSampleTypeWrapper) selectedItems[i]
+						.getData();
+				if (value) {
+					myGraph.irqLineChecked(wrapper);
+				} else {
+					myGraph.irqLineUnchecked(wrapper);
+
+				}
+			}
+
+		}
+		myGraph.updateIrqCountsInLegendsAsynch(IrqTraceGraph.TYPE_IRQ);
+		myGraph.repaint();
+
+	}
+
+	/**
+	 * Checks or unchecks all table items
+	 * 
+	 * @param value
+	 *            true if all items are checked
+	 */
+	private void checkOrUncheckAllItems(boolean value) {
+		// go thru all items from thread table and notify graph that threads are
+		// checked or unchecked
+		TableItem[] allItems = this.table.getItems();
+		for (int i = 0; i < allItems.length; i++) {
+			if (allItems[i].getData().getClass() == IrqSampleTypeWrapper.class) {
+				allItems[i].setChecked(value);
+				IrqSampleTypeWrapper wrapper = (IrqSampleTypeWrapper) allItems[i]
+						.getData();
+				if (value) {
+					myGraph.irqLineChecked(wrapper);
+				} else {
+					myGraph.irqLineUnchecked(wrapper);
+
+				}
+			}
+
+		}
+		myGraph.updateIrqCountsInLegendsAsynch(IrqTraceGraph.TYPE_IRQ);
+		myGraph.repaint();
+
+	}
+
+	/**
+	 * Updates item data to table
+	 * 
+	 * @param setInput
+	 *            true if table needs to be refreshed
+	 */
+	public void updateItemData(boolean setInput) {
+
+		// get sample type wrappers from irq trace
+		tableItemData = new Vector<IrqSampleTypeWrapper>();
+		Hashtable<Long, IrqSampleTypeWrapper> irqLines = this.myGraph
+				.getIrqTrace().getIrqTable();
+
+		// create table item for each sample type wrapper
+		Enumeration<Long> k = irqLines.keys();
+		while (k.hasMoreElements()) {
+			IrqSampleTypeWrapper threadValue = (IrqSampleTypeWrapper) irqLines
+					.get(k.nextElement());
+			tableItemData.add(threadValue);
+		}
+
+		// refresh the table, if needed
+		if (setInput)
+			refreshTableViewer();
+	}
+
+	/**
+	 * Refreshes table viewer
+	 */
+	public void refreshTableViewer() {
+		this.tableViewer.setInput(tableItemData);
+		this.addColor();
+
+	}
+
+	/**
+	 * @return table viewer
+	 */
+	public CheckboxTableViewer getTableViewer() {
+		return this.tableViewer;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.jface.viewers.ICheckStateListener#checkStateChanged(org.eclipse
+	 * .jface.viewers.CheckStateChangedEvent)
+	 */
+	public void checkStateChanged(CheckStateChangedEvent event) {
+		if (event.getElement().getClass() == IrqSampleTypeWrapper.class) {
+			IrqSampleTypeWrapper irqLine = (IrqSampleTypeWrapper) event
+					.getElement();
+			if (event.getChecked()) {
+				myGraph.irqLineChecked(irqLine);
+			} else {
+				myGraph.irqLineUnchecked(irqLine);
+			}
+			myGraph.repaint();
+			myGraph.updateIrqCountsInLegendsAsynch(IrqTraceGraph.TYPE_IRQ);
+
+		}
+	}
+
+	/**
+	 * Adds colors into irq line table
+	 */
+	public void addColor() {
+		if (this.tableViewer == null)
+			return;
+
+		IrqSampleTypeWrapper pGeneric;
+		TableItem[] items = this.table.getItems();
+		for (int i = 0; i < items.length; i++) {
+			if (items[i].getData().getClass() == IrqSampleTypeWrapper.class) {
+				pGeneric = (IrqSampleTypeWrapper) items[i].getData();
+				items[i].setBackground(COLOR_COLUMN_INDEX, new Color(parent
+						.getDisplay(), pGeneric.rgb));
+			}
+		}
+
+		table.redraw();
+	}
+
+	/**
+	 * MouseListener for table
+	 */
+	private class TableMouseListener implements MouseListener {
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see
+		 * org.eclipse.swt.events.MouseListener#mouseDoubleClick(org.eclipse
+		 * .swt.events.MouseEvent)
+		 */
+		public void mouseDoubleClick(org.eclipse.swt.events.MouseEvent e) {
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see
+		 * org.eclipse.swt.events.MouseListener#mouseDown(org.eclipse.swt.events
+		 * .MouseEvent)
+		 */
+		public void mouseDown(org.eclipse.swt.events.MouseEvent e) {
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see
+		 * org.eclipse.swt.events.MouseListener#mouseUp(org.eclipse.swt.events
+		 * .MouseEvent)
+		 */
+		public void mouseUp(org.eclipse.swt.events.MouseEvent e) {
+
+			if (e.button == MouseEvent.BUTTON3) {
+				// get rid of last Menu created so we don't have double menu
+				// on click
+				if (contextMenu != null) {
+					contextMenu.dispose();
+				}
+
+				contextMenu = new Menu(table.getShell(), SWT.POP_UP);
+				getCheckRows(contextMenu, table.getSelectionCount() > 0);
+
+				// select all, copy, and copy all
+				new MenuItem(contextMenu, SWT.SEPARATOR);
+				getSelectAllItem(contextMenu, table.getItemCount() > 0);
+				getCopyItem(contextMenu, table.getSelectionCount() > 0);
+				getCopyTableItem(contextMenu, table.getItemCount() > 0);
+
+				// save all
+				new MenuItem(contextMenu, SWT.SEPARATOR);
+				getSaveTableItem(contextMenu, table.getItemCount() > 0);
+
+				// Recolor highlighted items
+				new MenuItem(contextMenu, SWT.SEPARATOR);
+				getRecolorItem(contextMenu, Messages.IrqLineTable_4, table
+						.getSelectionCount() > 0);
+
+				contextMenu.setLocation(parent.toDisplay(e.x
+						+ table.getLocation().x, e.y + table.getLocation().y));
+				contextMenu.setVisible(true);
+
+				table.setMenu(contextMenu);
+			}
+		}
+	}
+
+	/**
+	 * ColumnselectionHandler for irq columns
+	 */
+	private class ColumnSelectionHandler extends SelectionAdapter {
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see
+		 * org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse
+		 * .swt.events.SelectionEvent)
+		 */
+		public void widgetSelected(SelectionEvent e) {
+			if (!(e.widget instanceof TableColumn))
+				return;
+
+			sortOnColumnSelection((TableColumn) e.widget);
+		}
+	}
+
+	/**
+	 * @param tableColumn
+	 *            which column is sorted
+	 */
+	public void sortOnColumnSelection(TableColumn tableColumn) {
+		int columnID = ((Integer) tableColumn.getData()).intValue();
+		((SharedSorter) tableViewer.getSorter()).doSort(columnID);
+
+		this.refreshTableViewer();
+		this.table.redraw();
+	}
+
+	/**
+	 * Sorter for irq table
+	 */
+	private class SharedSorter extends ViewerSorter {
+		// last column sorted
+		private int column = -1;
+
+		/*
+		 * decide on which column to sort by, and the sort ordering
+		 */
+		public void doSort(int column) {
+			// ignore the column passed in and use the id set by the column
+			// selection handler
+			if (column == this.column) {
+				// sort in other order
+				sortAscending = !sortAscending;
+			} else {
+				// changed columns, so sort in the default order
+				switch (column) {
+				case COLOR_COLUMN_INDEX: {
+					// sort in ascending order
+					sortAscending = true;
+					break;
+				}
+				case COLUMN_ID_IRQ_LINE:
+				case COLUMN_ID_IRQ_COUNT: {
+					// sort in descending order
+					sortAscending = false;
+					break;
+				}
+				default: {
+					// ignore the column
+					return;
+				}
+				}
+				this.column = column;
+			}
+
+			// find the TableColumn corresponding to column, and give it a
+			// column direction
+			TableColumn sortByColumn = null;
+			for (int i = 0; i < table.getColumnCount(); i++) {
+				if (table.getColumn(i).getData() instanceof Integer) {
+					if (((Integer) table.getColumn(i).getData()) == column) {
+						sortByColumn = table.getColumn(i);
+						break;
+					}
+				}
+			}
+
+			if (sortByColumn != null) {
+				table.setSortColumn(sortByColumn);
+				table.setSortDirection(sortAscending ? SWT.UP : SWT.DOWN);
+			}
+		}
+
+		/*
+		 * compare two items from a table column
+		 */
+		public int compare(Viewer viewer, Object e1, Object e2) {
+			int returnCode = 0;
+
+			IrqSampleTypeWrapper elem1 = (IrqSampleTypeWrapper) e1;
+			IrqSampleTypeWrapper elem2 = (IrqSampleTypeWrapper) e2;
+
+			// find the information for the two irq lines
+
+			// compare based on the memory information
+			switch (column) {
+			case COLOR_COLUMN_INDEX:
+				if (tableViewer.getChecked(e1) == true
+						&& tableViewer.getChecked(e2) == false) {
+					returnCode = -1;
+				} else {
+					returnCode = 1;
+				}
+				break;
+			case COLUMN_ID_IRQ_LINE:
+				returnCode = elem1.getPrototypeSample().getIrqL1Value() > elem2
+						.getPrototypeSample().getIrqL1Value() ? 1 : -1;
+				break;
+			case COLUMN_ID_IRQ_COUNT:
+				returnCode = elem1.count > elem2.count ? 1 : -1;
+				break;
+			default:
+				break;
+			}
+
+			// for descending order, reverse the sense of the compare
+			if (!sortAscending)
+				returnCode = -returnCode;
+
+			return returnCode;
+		}
+	}
+
+	/**
+	 * Action for opening color dialog for all selected irq lines.
+	 */
+	private void actionRecolor() {
+
+		// go thru selected items and open color dialog for each.
+		TableItem[] selection = table.getSelection();
+		for (TableItem item : selection) {
+
+			if (item.getData().getClass() == IrqSampleTypeWrapper.class) {
+
+				IrqSampleTypeWrapper wrapper = (IrqSampleTypeWrapper) item
+						.getData();
+				ColorDialog colorDialog = new ColorDialog(
+						this.table.getShell(), SWT.PRIMARY_MODAL);
+
+				// set name of the irq line as topic of the dialog
+				colorDialog.setText(IrqSampleTypeWrapper.getLineText(wrapper
+						.getPrototypeSample().getIrqL1Value()));
+				RGB color = colorDialog.open();
+
+				// if OK pressed, save new color into trace and set editor as
+				// dirty
+				if (color != null && color != wrapper.rgb) {
+
+					// ensure that color is not yet assigned for another
+					// thread/irq line
+					if (!myGraph.getIrqTrace().getColorSet().contains(color)) {
+
+						myGraph.getIrqTrace().changeColorOfThreadOrIRQLine(
+								wrapper, color);
+
+					} else {
+						// if same color was alreadyassigned for another
+						// thread/irq line, show error message
+						MessageBox errorDialog = new MessageBox(this.table
+								.getShell(), SWT.ICON_ERROR | SWT.OK);
+						errorDialog.setText(Messages.IrqLineTable_5);
+						errorDialog
+								.setMessage(Messages.IrqLineTable_6);
+						errorDialog.open();
+					}
+				}
+
+			}
+
+		}
+		this.myGraph.repaint();
+		myGraph.getIrqTrace().updateAllTableViewers();
+	}
+
+	/**
+	 * sets sort direction
+	 * 
+	 * @param sortAscending
+	 *            new sort direction
+	 */
+	public void setSortAscending(boolean sortAscending) {
+		this.sortAscending = sortAscending;
+	}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.irq/src/com/nokia/carbide/cpp/pi/irq/IrqPlugin.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,336 @@
+/*
+ * Copyright (c) 2010 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: 
+ *
+ */
+
+package com.nokia.carbide.cpp.pi.irq;
+
+import java.io.File;
+import org.osgi.framework.BundleContext;
+import com.nokia.carbide.cpp.internal.pi.analyser.NpiInstanceRepository;
+import com.nokia.carbide.cpp.internal.pi.analyser.ProfileVisualiser;
+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.plugin.model.AbstractPiPlugin;
+import com.nokia.carbide.cpp.internal.pi.plugin.model.IClassReplacer;
+import com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace;
+import com.nokia.carbide.cpp.internal.pi.plugin.model.IVisualizable;
+import com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph;
+import com.nokia.carbide.cpp.internal.pi.visual.GraphDrawRequest;
+import com.nokia.carbide.cpp.pi.editors.PIPageEditor;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class IrqPlugin extends AbstractPiPlugin implements ITrace,
+		IClassReplacer, IVisualizable {
+
+	/** The plug-in ID */
+	public static final String PLUGIN_ID = "com.nokia.carbide.cpp.pi.irq"; //$NON-NLS-1$
+
+	private static final String HELP_CONTEXT_ID = PIPageEditor.PI_ID + ".irq";  //$NON-NLS-1$
+	/** context help id of the main page */
+	public static final String HELP_CONTEXT_ID_MAIN_PAGE = HELP_CONTEXT_ID + ".irqPageContext";  //$NON-NLS-1$
+
+	private IrqTrace trace = null;
+
+	// There will be 1 graph for editor page 0
+	// This code may assume that page 0 has the threads graph
+	private final static int GRAPH_COUNT = 3;
+
+	// The plug-in ID
+
+	// The shared instance
+	private static IrqPlugin plugin;
+
+	/**
+	 * The constructor
+	 */
+	public IrqPlugin() {
+		super();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext
+	 * )
+	 */
+	public void start(BundleContext context) throws Exception {
+		super.start(context);
+		plugin = this;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext
+	 * )
+	 */
+	public void stop(BundleContext context) throws Exception {
+		plugin = null;
+		super.stop(context);
+	}
+
+	/**
+	 * Returns the shared instance
+	 * 
+	 * @return the shared instance
+	 */
+	public static IrqPlugin getDefault() {
+		return plugin;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace#getTraceClass()
+	 */
+	@SuppressWarnings("unchecked")
+	public Class getTraceClass() {
+		return IrqTrace.class;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace#getTraceId()
+	 */
+	public int getTraceId() {
+		return 6;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace#getTraceName()
+	 */
+	public String getTraceName() {
+		return Messages.IrqPlugin_0;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace#getTraceTitle()
+	 */
+	public String getTraceTitle() {
+		return Messages.IrqPlugin_5;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace#initialiseTrace
+	 * (com.nokia.carbide.cpp.internal.pi.model.GenericTrace)
+	 */
+	public void initialiseTrace(GenericTrace genericTrace) {
+		trace = (IrqTrace) genericTrace;
+		NpiInstanceRepository.getInstance().activeUidAddTrace(
+				"com.nokia.carbide.cpp.pi.irq", trace); //$NON-NLS-1$
+		trace.gatherDrawData();
+
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace#parseTraceFiles
+	 * (java.io.File[])
+	 */
+	public ParsedTraceData parseTraceFiles(File[] files) throws Exception {
+		throw new UnsupportedOperationException();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace#parseTraceFile(
+	 * java.io.File)
+	 */
+	public ParsedTraceData parseTraceFile(File file) throws Exception {
+		IrqTraceParser irqParser;
+
+		irqParser = new IrqTraceParser();
+		ParsedTraceData ptd = irqParser.parse(file);
+		return ptd;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @seecom.nokia.carbide.cpp.internal.pi.plugin.model.IClassReplacer#
+	 * getReplacedClass(java.lang.String)
+	 */
+	@SuppressWarnings("unchecked")
+	public Class getReplacedClass(String className) {
+		if (className.indexOf(Messages.IrqPlugin_1) != -1
+				|| className.indexOf(Messages.IrqPlugin_2) != -1)
+
+		{
+			return IrqTrace.class;
+		} else if (className
+				.indexOf(Messages.IrqPlugin_3) != -1
+				|| className.indexOf(Messages.IrqPlugin_4) != -1) {
+			return IrqSample.class;
+		} else
+			return null;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.plugin.model.IVisualizable#arePagesCreated
+	 * ()
+	 */
+	public boolean arePagesCreated() {
+		return false;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.plugin.model.IVisualizable#createPage
+	 * (int)
+	 */
+	public ProfileVisualiser createPage(int index) {
+		return null;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @seecom.nokia.carbide.cpp.internal.pi.plugin.model.IVisualizable#
+	 * getCreatePageCount()
+	 */
+	public int getCreatePageCount() {
+		return 0;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @seecom.nokia.carbide.cpp.internal.pi.plugin.model.IVisualizable#
+	 * getCreatePageIndex(int)
+	 */
+	public int getCreatePageIndex(int index) {
+		return 0;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.plugin.model.IVisualizable#getDrawRequest
+	 * (int)
+	 */
+	public GraphDrawRequest getDrawRequest(int graphIndex) {
+		return null;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.plugin.model.IVisualizable#getGraphCount
+	 * ()
+	 */
+	public int getGraphCount() {
+		return GRAPH_COUNT;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.plugin.model.IVisualizable#getLastSample
+	 * (int)
+	 */
+	public Integer getLastSample(int graphIndex) {
+		IrqTrace trace = (IrqTrace) NpiInstanceRepository.getInstance()
+				.activeUidGetTrace("com.nokia.carbide.cpp.pi.irq"); //$NON-NLS-1$
+
+		if (trace != null)
+			return Integer.valueOf(trace.getLastSampleNumber());
+		else
+			return null;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.plugin.model.IVisualizable#getPageNumber
+	 * (int)
+	 */
+	public int getPageNumber(int graphIndex) {
+		// Assumes page 0 has the threads graph, 1 has the binaries, and 2 has
+		// the functions
+		if (graphIndex == 0)
+			return PIPageEditor.THREADS_PAGE;
+		else if (graphIndex == 1)
+			return PIPageEditor.BINARIES_PAGE;
+		else if (graphIndex == 2)
+			return PIPageEditor.FUNCTIONS_PAGE;
+
+		return PIPageEditor.NEXT_AVAILABLE_PAGE;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.plugin.model.IVisualizable#getTraceGraph
+	 * (int)
+	 */
+	public GenericTraceGraph getTraceGraph(int graphIndex) {
+		IrqTrace trace = (IrqTrace) NpiInstanceRepository.getInstance()
+				.activeUidGetTrace("com.nokia.carbide.cpp.pi.irq"); //$NON-NLS-1$
+
+		if (trace != null)
+			return trace.getTraceGraph(graphIndex);
+		else
+			return null;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.plugin.model.IVisualizable#setPageIndex
+	 * (int, int)
+	 */
+	public void setPageIndex(int index, int pageIndex) {
+		return;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.plugin.model.IVisualizable#setPagesCreated
+	 * (boolean)
+	 */
+	public void setPagesCreated(boolean pagesCreated) {
+		return;
+	}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.irq/src/com/nokia/carbide/cpp/pi/irq/IrqReturnPlugin.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2010 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: 
+ *
+ */
+
+package com.nokia.carbide.cpp.pi.irq;
+
+import com.nokia.carbide.cpp.internal.pi.interfaces.IReturnPlugin;
+import com.nokia.carbide.cpp.internal.pi.plugin.model.AbstractPiPlugin;
+
+/**
+ * IrqReturnPlugin class
+ */
+public class IrqReturnPlugin implements IReturnPlugin {
+	public AbstractPiPlugin getPlugin() {
+		return IrqPlugin.getDefault();
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.irq/src/com/nokia/carbide/cpp/pi/irq/IrqSample.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2010 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: 
+ *
+ */
+
+package com.nokia.carbide.cpp.pi.irq;
+
+import com.nokia.carbide.cpp.internal.pi.model.FunctionResolver;
+import com.nokia.carbide.cpp.internal.pi.model.GenericSampleWithFunctions;
+import com.nokia.carbide.cpp.internal.pi.model.IFunction;
+
+/**
+ * Irq sample class
+ */
+public class IrqSample extends GenericSampleWithFunctions {
+
+	/**
+	 * Serial version UID
+	 */
+	private static final long serialVersionUID = 8688982614582925161L;
+
+	public int repeatCount = 0;
+
+	/* irq data */
+	private long[] swiData;
+	private int[] irqData;
+
+	/* function what caused this interrupt(if this is SWI) */
+	private IFunction swiLrFunction;
+
+	/* type of the IRQ */
+	public static final char TYPE_IRQ = 1;
+	public static final char TYPE_SWI = 2;
+	private char type;
+
+	/**
+	 * Constructor for software interrupt
+	 * 
+	 * @param sampleSynchTime
+	 *            time of the interrupt
+	 * @param swiInstr
+	 *            intruction id
+	 * @param swiThread
+	 *            thread id
+	 * @param swiLr
+	 *            lr value
+	 */
+
+	public IrqSample(long sampleSynchTime, long swiInstr, long swiThread,
+			long swiLr) {
+		this.sampleSynchTime = sampleSynchTime;
+		this.type = TYPE_SWI;
+		this.swiData = new long[2];
+
+		/* this.swiData[0] = ((swiInstr<<32)>>>32); Removed, This is not needed */
+
+		this.swiData[0] = ((swiThread << 32) >>> 32);
+		this.swiData[1] = ((swiLr << 32) >>> 32);
+
+	}
+
+	/**
+	 * Constructor for hardware interrupt
+	 * 
+	 * @param sampleSynchTime
+	 *            time of the interrupt
+	 * @param irqLev1
+	 * @param irqLev2
+	 */
+	public IrqSample(long sampleSynchTime, int irqLev1, int irqLev2) {
+		this.sampleSynchTime = sampleSynchTime;
+
+		this.type = TYPE_IRQ;
+		this.irqData = new int[2];
+		this.irqData[0] = irqLev1;
+		this.irqData[1] = irqLev2;
+	}
+
+	/**
+	 * @return swi lf function
+	 */
+	public IFunction getFunction() {
+		return this.swiLrFunction;
+	}
+
+	/**
+	 * @return type of the irq
+	 */
+	public int getType() {
+		return type;
+	}
+
+	/**
+	 * @return lr value
+	 */
+	public long getLrValue() {
+		if (this.swiData != null)
+			return this.swiData[1];
+		else
+			return -1;
+	}
+
+	/**
+	 * @return thread value
+	 */
+	public long getThreadValue() {
+		if (this.swiData != null)
+			return this.swiData[0];
+		else
+			return -1;
+	}
+
+	/**
+	 * @return instruction value
+	 */
+	/*
+	 * public long getInstrValue() { if(this.swiData != null) return
+	 * this.swiData[0]; else return -1; }
+	 */
+
+	/**
+	 * @return l1 value
+	 */
+	public int getIrqL1Value() {
+		if (this.irqData != null)
+			return this.irqData[0];
+		else
+			return -1;
+	}
+
+	/**
+	 * @return l2 value
+	 */
+	public int getIrqL2Value() {
+		if (this.irqData != null)
+			return this.irqData[1];
+		else
+			return -1;
+	}
+
+	/**
+	 * resolves name of the function from functionresolver
+	 */
+	@Override
+	public void resolveFunction(FunctionResolver res) {
+		if (this.type == TYPE_SWI) {
+			if (res.getResolverName().equals(Messages.IrqSample_0)) {
+				this.swiLrFunction = res
+						.findFunctionForAddress(this.swiData[1]);
+			}
+		}
+	}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.irq/src/com/nokia/carbide/cpp/pi/irq/IrqSampleTypeWrapper.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2010 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: 
+ *
+ */
+
+package com.nokia.carbide.cpp.pi.irq;
+
+import java.io.Serializable;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Random;
+import java.util.Vector;
+import org.eclipse.swt.graphics.RGB;
+
+/**
+ * Class for irq sample type wrapper. This class is used for representing one
+ * irq line/sw function
+ */
+public class IrqSampleTypeWrapper implements Serializable {
+	/**
+	 * Serial version uid
+	 */
+	private static final long serialVersionUID = -377498088520328159L;
+
+	/* protorype of this sample type */
+	private IrqSample prototypeSample;
+
+	/* vector containing all samples */
+	public Vector<IrqSample> samples;
+
+	/* color of this irq line/function */
+	public RGB rgb;
+
+	public int count = 0;
+	// 0 = address, 1 = name
+	public int sortMode = 1;
+
+	private boolean selected = true;
+
+	/**
+	 * Constructor
+	 * 
+	 * @param sampleType
+	 *            prototypeSample
+	 * @param colorSet
+	 *            colorset containing all colors that are in use so far
+	 */
+	public IrqSampleTypeWrapper(IrqSample sampleType, HashSet<RGB> colorSet,
+			Hashtable<String, RGB> colorsOfThreadsAndFunctions) {
+		prototypeSample = sampleType;
+		samples = new Vector<IrqSample>();
+		samples.add(prototypeSample);
+
+		String key = Messages.IrqSampleTypeWrapper_0;
+		if (prototypeSample.getType() == IrqSample.TYPE_IRQ) {
+			key = Integer.toString(prototypeSample.getIrqL1Value());
+		} else {
+			if (prototypeSample.getFunction() != null) {
+				key = prototypeSample.getFunction().getFunctionName();
+			}
+		}
+
+		if (!colorsOfThreadsAndFunctions.containsKey(key)) {
+			getRandomColor(colorSet);
+			colorsOfThreadsAndFunctions.put(key, rgb);
+		} else {
+			rgb = colorsOfThreadsAndFunctions.get(key);
+		}
+
+	}
+
+	/**
+	 * Creates random color that is not yet found from given colorset
+	 * 
+	 * @param colorSet
+	 *            colorset that is used
+	 */
+	private void getRandomColor(HashSet<RGB> colorSet) {
+		// Get random color for irq line or thread. Make sure that color is not
+		// yet found from colorset.
+		Random r = new Random();
+		rgb = new RGB(r.nextInt(256), r.nextInt(256), r.nextInt(256));
+		while (colorSet.contains(rgb)) {
+			rgb = new RGB(r.nextInt(256), r.nextInt(256), r.nextInt(256));
+		}
+		colorSet.add(rgb);
+	}
+
+	/**
+	 * Adds one sample into wrapper
+	 * 
+	 * @param sample
+	 *            sample that is added
+	 */
+	public void addSample(IrqSample sample) {
+		if (sample.getType() == prototypeSample.getType()) {
+			if (sample.getType() == IrqSample.TYPE_IRQ) {
+				if (sample.getIrqL1Value() == prototypeSample.getIrqL1Value()
+						&& sample.getIrqL2Value() == prototypeSample
+								.getIrqL2Value()) {
+					samples.add(sample);
+				}
+			} else if (sample.getType() == IrqSample.TYPE_SWI) {
+				if (sample.getLrValue() == prototypeSample.getLrValue()) {
+					samples.add(sample);
+				}
+			}
+		}
+	}
+
+	/**
+	 * @return prototype sample of this wrapper
+	 */
+	public IrqSample getPrototypeSample() {
+		return prototypeSample;
+	}
+
+	/**
+	 * @return all samples of this wrapper
+	 */
+	public Vector<IrqSample> getSamples() {
+		return samples;
+	}
+
+	/**
+	 * @return true if this function/irq line is selected
+	 */
+	public boolean isSelected() {
+		return selected;
+	}
+
+	/**
+	 * @param selected
+	 *            sets selection value
+	 */
+	public void setSelected(boolean selected) {
+		this.selected = selected;
+	}
+
+	public static String getLineText(long lineID) {
+		return Messages.IrqSampleTypeWrapper_1 + Long.toHexString(lineID);
+	}
+
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.irq/src/com/nokia/carbide/cpp/pi/irq/IrqTrace.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,467 @@
+/*
+ * Copyright (c) 2010 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: 
+ *
+ */
+
+package com.nokia.carbide.cpp.pi.irq;
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import org.eclipse.swt.graphics.RGB;
+
+import com.nokia.carbide.cpp.internal.pi.analyser.NpiInstanceRepository;
+import com.nokia.carbide.cpp.internal.pi.model.GenericSample;
+import com.nokia.carbide.cpp.internal.pi.model.GenericSampledTraceWithFunctions;
+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.visual.GenericTraceGraph;
+import com.nokia.carbide.cpp.pi.address.GppTrace;
+import com.nokia.carbide.cpp.pi.editors.PIPageEditor;
+
+/**
+ * Class containing all samples from one Irq trace
+ */
+public class IrqTrace extends GenericSampledTraceWithFunctions {
+
+	private static final long serialVersionUID = 5128848053984932839L;
+
+	private transient IrqTraceGraph[] graphs;
+
+	/* Hashtable containing thread id's and swi offsets */
+	private Hashtable<Long, Integer> threadToOffset;
+
+	/* Hashtable containing thread id's and names */
+	private Hashtable<Long, String> threadToName;
+
+	/* Hashtable containing Irq lines and offsets */
+	private Hashtable<Long, Integer> irqToOffset;
+
+	/* Vector containing all thread wrappers */
+	private transient Vector<SwiThreadWrapper> allThreadWrappers;
+
+	/* Hashtable containing thread id's and all samples from that thread */
+	private transient Hashtable<Long, IrqSampleTypeWrapper> swiTable;
+
+	/* Hashtable containing irq line id's and all samples from that line */
+	private transient Hashtable<Long, IrqSampleTypeWrapper> irqTable;
+
+	/* Hashtable containing thread names functions */
+	private transient Hashtable<String, Hashtable<String, ArrayList<Long>>> threadsToFunctions;
+
+	/* All colors in use */
+	private transient HashSet<RGB> colorSet;
+	
+	/* Colors in functions and irq lines */
+	private Hashtable<String, RGB> colorsOfThreadsAndLines;
+
+	/* maximum amount of swi interrupts at one time frame */
+	private int maxAmountOfSWISamples;
+
+	/* maximum amount of irq interrupts at one time frame */
+	private int maxAmountOfIRQSamples;
+
+	/* Boolean value that is false if no function names is found from trace
+	 * (No Symbol files imported) 
+	 */
+	boolean functionNamesFound = false;
+	
+	/**
+	 * getter for trace graph
+	 * 
+	 * @param graphIndex
+	 *            index of the graph
+	 * @return graph
+	 */
+	public GenericTraceGraph getTraceGraph(int graphIndex) {
+		if (graphs == null) {
+			graphs = new IrqTraceGraph[3];
+		}
+		// note that graphIndex need not match the index sent to TraceGraph
+		if ((graphIndex == PIPageEditor.THREADS_PAGE)
+				|| (graphIndex == PIPageEditor.BINARIES_PAGE)
+				|| (graphIndex == PIPageEditor.FUNCTIONS_PAGE)) {
+			int uid = NpiInstanceRepository.getInstance().activeUid();
+			
+			if(graphs[graphIndex] != null){
+				return graphs[graphIndex];
+			}
+			
+			// get first item that is null in graph array
+			int index = 0;
+			
+			while(index < graphs.length){
+				if( graphs[index] == null){
+					break;
+				}
+				index++;
+			}
+			if(index < graphs.length){
+				graphs[index] = new IrqTraceGraph(index, this, uid);
+				return graphs[index];
+			}
+			
+		}
+		return null;
+	}
+
+	/**
+	 * Fetches thread name for one sample from the address plug-in
+	 * 
+	 * @param sample
+	 *            sample
+	 * @return thread name
+	 */
+	@SuppressWarnings("unchecked")
+	private String getThreadName(IrqSample sample) {
+
+		if (sample.getType() == IrqSample.TYPE_SWI) {
+			// fetch trace information from address plug-in
+			ParsedTraceData ptd = TraceDataRepository.getInstance().getTrace(
+					NpiInstanceRepository.getInstance().activeUid(),
+					GppTrace.class);
+
+			// if trace data or static data cannot be found
+			if (ptd == null || ptd.staticData == null) {
+				return Messages.IrqTrace_0
+						+ Long.toHexString(sample.getThreadValue());
+			}
+
+			// Get that contains name for thread
+			ArrayList al = ptd.staticData.getColumnMatch(Messages.IrqTrace_1,
+					Messages.IrqTrace_2, new Long(sample.getThreadValue()));
+			if (al.size() > 0) {
+				return (String) al.get(0);
+			} else {
+				return Messages.IrqTrace_3
+						+ Long.toHexString(sample.getThreadValue());
+			}
+
+		}
+		return Messages.IrqTrace_4;
+	}
+
+	/**
+	 * Gathers data that is needed for drawing graph.
+	 */
+	public void gatherDrawData() {
+
+		boolean readThreadNamesFromTrace = false;
+
+		// if hash containing thread names is not found(meaning that dat file
+		// has just been imported) load thread names from trace.
+		if (threadToName == null) {
+			threadToName = new Hashtable<Long, String>();
+			readThreadNamesFromTrace = true;
+		}
+		
+		if(colorsOfThreadsAndLines == null){
+			colorsOfThreadsAndLines = new Hashtable<String, RGB>();
+		}
+
+		// reset all vectors and Hashtables that are just for optimizing drawing
+		allThreadWrappers = new Vector<SwiThreadWrapper>();
+		swiTable = new Hashtable<Long, IrqSampleTypeWrapper>();
+		irqTable = new Hashtable<Long, IrqSampleTypeWrapper>();
+		threadToOffset = new Hashtable<Long, Integer>();
+		this.irqToOffset = new Hashtable<Long, Integer>();
+		threadsToFunctions = new Hashtable<String, Hashtable<String, ArrayList<Long>>>();
+		colorSet = new HashSet<RGB>();
+		Hashtable<Long, Hashtable<Long, Integer>> irqLines = new Hashtable<Long, Hashtable<Long, Integer>>();
+
+		int swiOffset = 0;
+		int irqOffset = 0;
+
+		maxAmountOfSWISamples = 1;
+		maxAmountOfIRQSamples = 1;
+		int amountOfSamples = 0;
+		long previousTimeCode = 0;
+
+		// go thru all samples from trace
+		Enumeration<GenericSample> enumeration = this.getSamples();
+		while (enumeration.hasMoreElements()) {
+			IrqSample sample = (IrqSample) enumeration.nextElement();
+			long val = 0;
+			long valL = 0;
+			Hashtable<Long, IrqSampleTypeWrapper> table = new Hashtable<Long, IrqSampleTypeWrapper>();
+
+			// if this is software interrupt
+			if (sample.getType() == IrqSample.TYPE_SWI) {
+				val = sample.getLrValue();
+				table = swiTable;
+
+				String threadName = Messages.IrqTrace_5;
+				// Get thread name
+				if (readThreadNamesFromTrace) {
+					threadName = getThreadName(sample);
+				} else {
+					threadName = threadToName.get(sample.getThreadValue());
+				}
+
+				if(sample.getFunction()!= null){
+					
+					this.functionNamesFound = true;
+					
+					// Add thread into threadsToFunctions hash if needed
+					if (!threadsToFunctions.containsKey(threadName)) {
+						// Create new item into thread section
+						Hashtable<String, ArrayList<Long>> functionTable = new Hashtable<String, ArrayList<Long>>();
+						ArrayList<Long> list = new ArrayList<Long>();
+						list.add(sample.sampleSynchTime);
+						functionTable.put(sample.getFunction().getFunctionName(), list);
+						threadsToFunctions.put(threadName, functionTable);
+						previousTimeCode = sample.sampleSynchTime;
+						amountOfSamples = 1;
+	
+					} else {
+						// add sample to existing thread
+	
+						// check if previous sample from this thread was from same
+						// time frame and increase amountOfSamples if needed
+						if (sample.sampleSynchTime == previousTimeCode) {
+							amountOfSamples++;
+						} else {
+							// check is amount of samples from previous tim frame
+							// was greater than maximum amount of interrupts so far
+							if (amountOfSamples > maxAmountOfSWISamples) {
+								maxAmountOfSWISamples = amountOfSamples;
+							}
+							amountOfSamples = 0;
+							previousTimeCode = sample.sampleSynchTime;
+						}
+	
+						// get thread's hashtable containing all its functions
+						Hashtable<String, ArrayList<Long>> functionSet = threadsToFunctions
+								.get(threadName);
+	
+						String functionName = sample.getFunction().getFunctionName();
+	
+						if (!functionSet.containsKey(functionName)) {
+							// add new function into table
+							ArrayList<Long> list = new ArrayList<Long>();
+							list.add(sample.sampleSynchTime);
+							functionSet
+									.put(sample.getFunction().getFunctionName(), list);
+						} else {
+							functionSet.get(functionName).add(
+									sample.sampleSynchTime);
+						}
+					}
+				}				
+				// if thread is not yet found from threadToOffset
+				if (!this.threadToOffset.containsKey(new Long(sample
+						.getThreadValue()))) {
+					this.threadToOffset.put(new Long(sample.getThreadValue()),
+							Integer.valueOf(swiOffset++));
+
+					// read thread names from trace if needed
+					if (readThreadNamesFromTrace) {
+						try {
+							this.threadToName.put(new Long(sample
+									.getThreadValue()), this
+									.getThreadName(sample));
+						} catch (NullPointerException e1) {
+							this.threadToName
+									.put(new Long(sample.getThreadValue()),
+											Messages.IrqTrace_6
+													+ Long.toHexString(sample
+															.getThreadValue()));
+						}
+					}
+
+					// create thread wrapper for the thread and add it to allThreadWrappers
+					SwiThreadWrapper wrapper = new SwiThreadWrapper();
+					wrapper.threadAddress = new Long(sample.getThreadValue());
+					wrapper.threadName = threadToName.get(sample
+							.getThreadValue());
+					this.allThreadWrappers.add(wrapper);
+				}
+				
+			// if this is hardware interrupt
+			} else if (sample.getType() == IrqSample.TYPE_IRQ) {
+				val = sample.getIrqL1Value() + (sample.getIrqL2Value() << 8);
+				table = irqTable;
+
+				if (!this.irqToOffset.containsKey(new Long(val))) {
+					this.irqToOffset.put(new Long(val),
+							Integer.valueOf(irqOffset++));
+				}
+
+				// if line is already found from irq line hashtable
+				if (!irqLines.containsKey(val)) {
+					Hashtable<Long, Integer> hashTable = new Hashtable<Long, Integer>();
+					hashTable.put(val, 1);
+					irqLines.put(val, hashTable);
+				} else {
+					Hashtable<Long, Integer> interrupts = irqLines.get(val);
+					
+					// if event at this timeframe is not found yet
+					if (!interrupts.containsKey(sample.sampleSynchTime)) {
+						interrupts.put(sample.sampleSynchTime, 1);
+					} else {
+						int previousValue = interrupts
+								.get(sample.sampleSynchTime);
+						interrupts.put(sample.sampleSynchTime,
+								previousValue + 1);
+						
+						// check if value is greater than max amount of interrupts 
+						if (previousValue + 1 > maxAmountOfIRQSamples) {
+							maxAmountOfIRQSamples = previousValue + 1;
+						}
+					}
+				}
+			} else {
+				throw new ArrayIndexOutOfBoundsException();
+			}
+
+			// Add interrupts into its sampleTypeWrapper or create one if needed
+			valL = new Long(val);
+			if (!table.containsKey(valL)) {
+				IrqSampleTypeWrapper w = new IrqSampleTypeWrapper(sample,
+						colorSet, colorsOfThreadsAndLines);
+				table.put(valL, w);
+			} else {
+				IrqSampleTypeWrapper w = (IrqSampleTypeWrapper) table.get(valL);
+				w.addSample(sample);
+			}
+		}
+	}
+
+
+	/**
+	 * @return all thread wrappers vector
+	 */
+	public Vector<SwiThreadWrapper> getAllThreadWrappers() {
+		return allThreadWrappers;
+	}
+
+	/**
+	 * @return irq to offset hashtable
+	 */
+	public Hashtable<Long, Integer> getIrqToOffset() {
+		return irqToOffset;
+	}
+
+	/**
+	 * @return swi hashtable
+	 */
+	public Hashtable<Long, IrqSampleTypeWrapper> getSwiTable() {
+		return swiTable;
+	}
+
+	/**
+	 * @return irq hashtable
+	 */
+	public Hashtable<Long, IrqSampleTypeWrapper> getIrqTable() {
+		return irqTable;
+	}
+
+	/**
+	 * @return threadsToFunctions hashtable
+	 */
+	public Hashtable<String, Hashtable<String, ArrayList<Long>>> getThreadsToFunctions() {
+		return threadsToFunctions;
+	}
+
+	/**
+	 * @return max amount of swi interrupts per one timeframe
+	 */
+	public int getMaxAmountOfSWISamples() {
+		return maxAmountOfSWISamples;
+	}
+
+	/**
+	 * @return max amount of irq interrupts per one timeframe
+	 */
+	public int getMaxAmountOfIRQSamples() {
+		return maxAmountOfIRQSamples;
+	}
+
+	/**
+	 * @return thread and irq line colors
+	 */
+	public Hashtable<String, RGB> getColorsOfThreadsAndLines() {
+		return colorsOfThreadsAndLines;
+	}
+	
+	/**
+	 * @return set containing all colors of the trace
+	 */
+	public HashSet<RGB> getColorSet(){
+		return colorSet;
+	}
+	
+	/**
+	 * changes color of one thread or irq line
+	 * @param wrapper threadwrapper
+	 * @param newColor new color for item
+	 */
+	public void changeColorOfThreadOrIRQLine(IrqSampleTypeWrapper wrapper, RGB newColor){
+		
+		// save color into colorsets at trace information
+		colorSet.remove(wrapper.rgb);
+		colorSet.add(newColor);
+		if(wrapper.getPrototypeSample().getType() == IrqSample.TYPE_IRQ){
+			colorsOfThreadsAndLines.put(Long.toString(wrapper.getPrototypeSample().getIrqL1Value()), newColor);
+		}
+		else{
+			if(wrapper.getPrototypeSample().getFunction() != null){
+				colorsOfThreadsAndLines.put(wrapper.getPrototypeSample().getFunction().getFunctionName(), newColor);
+			}
+		}
+		wrapper.rgb = newColor;
+		
+		for(IrqTraceGraph item : graphs){
+			// refresh table and set editor window dirty so that it can be saved.
+			if(wrapper.getPrototypeSample().getType() == IrqSample.TYPE_IRQ){
+				item.irqLineUnchecked(wrapper);
+				item.irqLineChecked(wrapper);
+			}
+			else{
+				item.recalculateWholeGraph();
+			}
+		}
+		PIPageEditor.currentPageEditor().setDirty();
+	}
+	
+	/**
+	 * updates all table viewers
+	 */
+	public void updateAllTableViewers(){
+		for(IrqTraceGraph item : graphs){
+			item.updateTableViewers();
+		}
+	}
+	
+	/**
+	 * @return all graphs for this trace
+	 */
+	public IrqTraceGraph[] getGraphs() {
+		return graphs;
+	}
+
+	/**
+	 * @return true if function names are found from trace
+	 */
+	public boolean isFunctionNamesFound() {
+		return functionNamesFound;
+	}
+	
+	
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.irq/src/com/nokia/carbide/cpp/pi/irq/IrqTraceGraph.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,1364 @@
+/*
+ * Copyright (c) 2010 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: 
+ *
+ */
+
+package com.nokia.carbide.cpp.pi.irq;
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import java.util.Vector;
+
+import org.eclipse.draw2d.FigureCanvas;
+import org.eclipse.draw2d.Graphics;
+import org.eclipse.draw2d.MouseEvent;
+import org.eclipse.draw2d.MouseMotionListener;
+import org.eclipse.draw2d.Panel;
+import org.eclipse.draw2d.geometry.Point;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.SashForm;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.layout.FormLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Sash;
+import org.eclipse.swt.widgets.TableItem;
+import org.eclipse.ui.PlatformUI;
+
+import com.nokia.carbide.cpp.internal.pi.analyser.NpiInstanceRepository;
+import com.nokia.carbide.cpp.internal.pi.model.GenericSampledTrace;
+import com.nokia.carbide.cpp.internal.pi.plugin.model.ITitleBarMenu;
+import com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph;
+import com.nokia.carbide.cpp.internal.pi.visual.GraphComposite;
+import com.nokia.carbide.cpp.internal.pi.visual.PIEvent;
+import com.nokia.carbide.cpp.internal.pi.visual.PIEventListener;
+import com.nokia.carbide.cpp.pi.editors.PIPageEditor;
+import com.nokia.carbide.cpp.pi.visual.IGenericTraceGraph;
+
+/**
+ * class for irq trace graph
+ */
+public class IrqTraceGraph extends GenericTraceGraph implements ITitleBarMenu,
+		PIEventListener, MouseMotionListener {
+
+	public static final char TYPE_IRQ = 1;
+	public static final char TYPE_SWI = 2;
+	public static final char TYPE_BOTH = 3;
+
+	/* composite where tables are placed */
+	private Composite holder;
+
+	/* Irq trace */
+	private IrqTrace irqTrace;
+	private boolean readyToDraw = false;
+
+	/* margin in the bottom of the graph */
+	private static final int BOTTOM_MARGIN = 20;
+
+	/* tables containing threads, functions and irq lines */
+	private SwiThreadTable tableThreadIRQ;
+	private SwiFunctionTable tableSWIFunction;
+	private IrqLineTable tableIrqLine;
+
+	/* composites for tables */
+	private Composite compositeSWI;
+	private Composite compositeIRQ;
+
+	/* height of the the graph */
+	private int panelHeight;
+
+	/* hashtables that are used for drawing graphs */
+	private Hashtable<String, Hashtable<RGB, TreeMap<Long, Integer>>> swiDrawList;
+	private Hashtable<Long, Hashtable<RGB, TreeMap<Long, Integer>>> irqDrawList;
+
+	/* is swi table shown */
+	private boolean swiTableVisible = true;
+
+	/* places of vectical dash lines */
+	private ArrayList<Integer> interruptLines;
+
+	/**
+	 * Constructor
+	 * 
+	 * @param graphIndex
+	 *            Index of the graph
+	 * @param irqTrace
+	 *            trace that is analysed
+	 * @param uid
+	 *            uid number of the trace
+	 */
+	public IrqTraceGraph(int graphIndex, IrqTrace irqTrace, int uid) {
+		super((GenericSampledTrace) irqTrace);
+
+		swiDrawList = new Hashtable<String, Hashtable<RGB, TreeMap<Long, Integer>>>();
+		irqDrawList = new Hashtable<Long, Hashtable<RGB, TreeMap<Long, Integer>>>();
+
+		this.irqTrace = irqTrace;
+
+		// create the label and a tableviewer
+		holder = new Composite(NpiInstanceRepository.getInstance()
+				.getProfilePage(uid, graphIndex).getBottomComposite(), SWT.NONE);
+		PlatformUI.getWorkbench().getHelpSystem().setHelp(holder, IrqPlugin.HELP_CONTEXT_ID_MAIN_PAGE);
+
+		GridLayout gl = new GridLayout();
+		gl.marginHeight = 0;
+		gl.marginWidth = 0;
+		gl.marginLeft = 0;
+		gl.marginRight = 0;
+		holder.setLayout(gl);
+
+		// titlebar
+		Label label = new Label(holder, SWT.CENTER);
+		label
+				.setBackground(holder.getDisplay().getSystemColor(
+						SWT.COLOR_WHITE));
+		label.setFont(PIPageEditor.helvetica_8);
+		label.setText(Messages.IrqTraceGraph_0);
+		label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+		// Create composite for SWI tables
+		compositeSWI = new Composite(holder, SWT.NONE);
+		compositeSWI.setLayout(new FormLayout());
+		compositeSWI.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+		// Create composite for irq table
+		compositeIRQ = new Composite(holder, SWT.NONE);
+		compositeIRQ.setLayout(new FormLayout());
+		compositeIRQ.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+		// Create Thread table
+		tableThreadIRQ = new SwiThreadTable(this, compositeSWI);
+
+		// vertical sash
+		Sash acrossSash = new Sash(compositeSWI, SWT.VERTICAL);
+
+		// Create SWI function table
+		tableSWIFunction = new SwiFunctionTable(this, compositeSWI);
+
+		// Create Thread table
+		tableIrqLine = new IrqLineTable(this, compositeIRQ);
+
+		// Set layout data for tables and sash
+
+		// FormData for IRQ/Threads
+		FormData formData = new FormData();
+		formData.top = new FormAttachment(0);
+		formData.bottom = new FormAttachment(100);
+		formData.left = new FormAttachment(0);
+		formData.right = new FormAttachment(acrossSash);
+		tableThreadIRQ.getTable().setLayoutData(formData);
+
+		// FormData for SWT functions
+		formData = new FormData();
+		formData.top = new FormAttachment(0);
+		formData.bottom = new FormAttachment(100);
+		formData.left = new FormAttachment(acrossSash);
+		formData.right = new FormAttachment(100);
+		tableSWIFunction.getTable().setLayoutData(formData);
+
+		// FormData for irq table
+		formData = new FormData();
+		formData.left = new FormAttachment(0);
+		formData.right = new FormAttachment(100);
+		formData.top = new FormAttachment(0);
+		formData.bottom = new FormAttachment(100);
+		tableIrqLine.getTable().setLayoutData(formData);
+
+		// FormData for acrossSash
+		// Put it initially in the middle
+		formData = new FormData();
+		formData.left = new FormAttachment(50);
+		formData.top = new FormAttachment(0);
+		formData.bottom = new FormAttachment(100);
+		acrossSash.setLayoutData(formData);
+
+		// add selection listener to sash so that user can change sash's place
+		final FormData acrossSashData = formData;
+		final Composite parentFinal = acrossSash.getParent();
+		acrossSash.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent event) {
+				if (event.detail != SWT.DRAG) {
+					acrossSashData.left = new FormAttachment(0, event.x);
+					parentFinal.layout();
+				}
+			}
+		});
+
+		// initially set swi table visible
+		this.setSwiTableVisible();
+		this.readyToDraw = true;
+
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph#action(java
+	 * .lang.String)
+	 */
+	public void action(String action) {
+
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph#paint(org.
+	 * eclipse.draw2d.Panel, org.eclipse.draw2d.Graphics)
+	 */
+	public void paint(Panel panel, Graphics graphics) {
+
+		// save height for tooltip
+		this.panelHeight = panel.getSize().height;
+
+		if (!this.readyToDraw) {
+			return;
+		}
+
+		this.drawDottedLineBackground(graphics, BOTTOM_MARGIN, false);
+
+		if (this.swiTableVisible) {
+			// draw selected swi threads
+			if (irqTrace.isFunctionNamesFound() == false) {
+				this
+						.drawText(
+								graphics,
+								Messages.IrqTraceGraph_1);
+				return;
+
+			}
+			if (swiDrawList.size() == 0) {
+				this
+						.drawText(graphics,
+								Messages.IrqTraceGraph_2);
+				return;
+			} else {
+				int[] linePlaces = this.drawHorizontalLines(panel, graphics,
+						swiDrawList.size());
+				this.drawLineNames(panel, graphics, linePlaces);
+				this.drawSoftwareInterrupts(panel, graphics, linePlaces);
+			}
+
+		} else {
+			// draw selected irq lines
+			if (irqDrawList.size() == 0) {
+				this
+						.drawText(graphics,
+								Messages.IrqTraceGraph_3);
+				return;
+			} else {
+				int[] linePlaces = this.drawHorizontalLines(panel, graphics,
+						irqDrawList.size());
+				this.drawLineNames(panel, graphics, linePlaces);
+				this.drawHardwareInterrupts(panel, graphics, linePlaces);
+			}
+		}
+
+		// draw dashed lines in the graph
+		this.drawInterruptLines(graphics, panel.getSize().width);
+
+		// draw the same selection as the Address/Thread trace
+		this.drawSelectionSection(graphics, BOTTOM_MARGIN);
+	}
+
+	/**
+	 * Draws interrupt count lines
+	 * 
+	 * @param graphics
+	 *            graphics context
+	 * @param width
+	 *            width of the panel
+	 */
+	private void drawInterruptLines(Graphics graphics, int width) {
+
+		// get color for line
+		Color previousColor = graphics.getForegroundColor();
+		graphics.setForegroundColor(holder.getDisplay().getSystemColor(
+				SWT.COLOR_GRAY));
+
+		if (interruptLines != null) {
+			// draw lines only if space between them is less than 7
+			if (interruptLines.get(0) > 7) {
+				for (Integer item : interruptLines) {
+					graphics.setLineStyle(Graphics.LINE_DASH);
+					graphics.drawLine(0, item - 1, width, item - 1);
+				}
+			}
+		}
+		graphics.setForegroundColor(previousColor);
+	}
+
+	/**
+	 * Draws text into graph
+	 * 
+	 * @param graphics
+	 *            graphics where text is drawn
+	 * @param text
+	 *            text that is drawn
+	 */
+	private void drawText(Graphics graphics, String text) {
+		// get current font and color
+		Font previousFont = graphics.getFont();
+		Color previousColor = graphics.getForegroundColor();
+
+		// Set font size
+		FontData[] fontData = previousFont.getFontData();
+		fontData[0].height = 10;
+		Font newFont = new Font(previousFont.getDevice(), fontData);
+
+		// set text color as black
+		Color newColor = holder.getDisplay().getSystemColor(SWT.COLOR_BLACK);
+		graphics.setForegroundColor(newColor);
+
+		graphics.setFont(newFont);
+		graphics.drawText(text, new Point(5, 5));
+
+		// restore previous values to color and font
+		graphics.setForegroundColor(previousColor);
+		graphics.setFont(previousFont);
+	}
+
+	/**
+	 * Gets places of horizontal lines between threads/irq lines
+	 * 
+	 * @param panelHeight
+	 *            Height of the panel
+	 * @param tableSize
+	 *            amount of threads/irq lines
+	 * @return array containing places of each line
+	 */
+
+	public int[] getHorizontalLinePlaces(double panelHeight, int tableSize) {
+
+		// count height of one thread/irq line in graph
+		int[] array = new int[tableSize];
+		double spaceForOneThread = ((panelHeight - BOTTOM_MARGIN) / (double) tableSize);
+
+		// draw lines
+		int i = 0;
+		while (i < array.length) {
+			array[i] = (int) ((i + 1) * spaceForOneThread);
+			i++;
+		}
+		return array;
+	}
+
+	/**
+	 * Draws horizontal lines between threads/irq lines
+	 * 
+	 * @param panel
+	 *            panel where lines are drawn
+	 * @param graphics
+	 *            graphics that is used for drawing
+	 * @param tablesize
+	 *            table's size which details are used for drawing
+	 * @return array containing places of lines
+	 */
+	public int[] drawHorizontalLines(Panel panel, Graphics graphics,
+			int tableSize) {
+
+		// count height of one thread/irq line in graph
+		int[] array = new int[tableSize];
+		double height = (double) panel.getSize().height;
+		double spaceForOneThread = ((height - BOTTOM_MARGIN) / (double) tableSize);
+
+		// draw lines
+		int i = 0;
+		while (i < array.length) {
+			array[i] = (int) ((i + 1) * spaceForOneThread);
+			graphics.drawLine(new Point(0, array[i]), new Point(
+					panel.getSize().width, array[i]));
+			i++;
+		}
+		return array;
+	}
+
+	/**
+	 * Draws thread names/irq lines into graph
+	 * 
+	 * @param panel
+	 *            panel where names are drawn
+	 * @param graphics
+	 *            graphics that is used for drawing
+	 * @param linePlaces
+	 *            places of lines that are separating each line in the graph
+	 */
+	public void drawLineNames(Panel panel, Graphics graphics, int[] linePlaces) {
+
+		if (linePlaces.length != 0) {
+
+			// calculate font size
+			int fontSize = (int) (linePlaces[0] * 0.7);
+
+			if (fontSize > 10) {
+				fontSize = 10;
+			}
+
+			if (fontSize == 0) {
+				return;
+			}
+
+			Font previousFont = graphics.getFont();
+			FontData[] fontData = previousFont.getFontData();
+			fontData[0].height = fontSize;
+
+			Font newFont = new Font(previousFont.getDevice(), fontData);
+
+			graphics.setFont(newFont);
+
+			int i = 0;
+
+			if (swiTableVisible) {
+
+				Enumeration<String> eventIterator = swiDrawList.keys();
+
+				// go thru threads and draw its name into graph
+				while (eventIterator.hasMoreElements()) {
+					String threadName = eventIterator.nextElement();
+					graphics.drawString(threadName, new Point(5, linePlaces[i]
+							- linePlaces[0]));
+					i++;
+
+				}
+
+			} else {
+				Enumeration<Long> eventIterator = irqDrawList.keys();
+
+				// go thru irq lines and draw its name into graph
+				while (eventIterator.hasMoreElements()) {
+					Long id = eventIterator.nextElement();
+					String printText = IrqSampleTypeWrapper.getLineText(id);
+					graphics.drawString(printText, new Point(5, linePlaces[i]
+							- linePlaces[0]));
+					i++;
+
+				}
+			}
+
+			// restore previous font
+			graphics.setFont(previousFont);
+
+		}
+	}
+
+	/**
+	 * Draws hardware interrupts
+	 * 
+	 * @param panel
+	 *            panel where names are drawn
+	 * @param graphics
+	 *            graphics that is used for drawing
+	 * @param linePlaces
+	 *            places of lines that are separating each irq line in the graph
+	 */
+	public void drawHardwareInterrupts(Panel panel, Graphics graphics,
+			int[] linePlaces) {
+
+		Enumeration<Long> irqLineIterator = irqDrawList.keys();
+		int tableItemIndex = 0;
+
+		// go thru all irq lines
+		while (irqLineIterator.hasMoreElements()) {
+
+			Hashtable<RGB, TreeMap<Long, Integer>> irqLines = irqDrawList
+					.get(irqLineIterator.nextElement());
+
+			// draw this irq lines interrupts into graph
+			this.drawInterrupts(graphics, tableItemIndex, linePlaces, irqLines,
+					irqTrace.getMaxAmountOfIRQSamples());
+			tableItemIndex++;
+
+		}
+
+	}
+
+	/**
+	 * Draws software interrupts
+	 * 
+	 * @param panel
+	 *            panel where names are drawn
+	 * @param graphics
+	 *            graphics that is used for drawing
+	 * @param table
+	 *            table which details are used for drawing
+	 * @param linePlaces
+	 *            places of lines that are separating each irq line in the graph
+	 */
+	public void drawSoftwareInterrupts(Panel panel, Graphics graphics,
+			int[] linePlaces) {
+
+		Enumeration<String> threadIterator = swiDrawList.keys();
+		int tableItemIndex = 0;
+
+		// go thru all threads
+		while (threadIterator.hasMoreElements()) {
+			Hashtable<RGB, TreeMap<Long, Integer>> allThreadsFunctions = swiDrawList
+					.get(threadIterator.nextElement());
+			Hashtable<RGB, TreeMap<Long, Integer>> checkedFunctions = new Hashtable<RGB, TreeMap<Long, Integer>>();
+
+			Enumeration<RGB> functionIterator = allThreadsFunctions.keys();
+
+			// go thru each function from thread and gather draw data into
+			// hashtable
+			while (functionIterator.hasMoreElements()) {
+				RGB thisColor = functionIterator.nextElement();
+				TreeMap<Long, Integer> events = allThreadsFunctions
+						.get(thisColor);
+				checkedFunctions.put(thisColor, events);
+			}
+			// draw threads interrupts into graph
+			this.drawInterrupts(graphics, tableItemIndex, linePlaces,
+					checkedFunctions, irqTrace.getMaxAmountOfSWISamples());
+			tableItemIndex++;
+
+		}
+	}
+
+	/**
+	 * draws one thread/irq lines interrupts into graph
+	 * 
+	 * @param graphics
+	 *            graphics that is used for drawing
+	 * @param tableItemIndex
+	 *            index of the table item
+	 * @param linePlaces
+	 *            places of lines that are separating each thread/irq line in
+	 *            the graph
+	 * @param events
+	 *            events of the thread/irq line
+	 * @param maxAmountOfSamples
+	 *            maximum amount of events in one time frame
+	 */
+	private void drawInterrupts(Graphics graphics, int tableItemIndex,
+			int[] linePlaces, Hashtable<RGB, TreeMap<Long, Integer>> events,
+			int maxAmountOfSamples) {
+
+		// get scale for x axis.
+		double scale = this.getScale();
+
+		// get top and bottom of the irq line that is drawn into screen
+		int top = 0;
+		if (tableItemIndex != 0) {
+			top = linePlaces[tableItemIndex - 1];
+		}
+		int bottom = linePlaces[tableItemIndex] - 1;
+
+		// count one interrupts weight
+		double weightOfOneInterrupt = (double) (bottom - top)
+				/ (double) maxAmountOfSamples;
+
+		Hashtable<Long, Integer> drawnInterrupts = new Hashtable<Long, Integer>();
+		Enumeration<RGB> functionIterator = events.keys();
+
+		Color previousColor = graphics.getForegroundColor();
+
+		// go thru each color
+		while (functionIterator.hasMoreElements()) {
+			RGB thisRGB = functionIterator.nextElement();
+			Color thisColor = new Color(holder.getDisplay(), thisRGB);
+			TreeMap<Long, Integer> eventsFromOneColor = events.get(thisRGB);
+
+			graphics.setForegroundColor(thisColor);
+
+			Set<Long> eventSet = eventsFromOneColor.keySet();
+			Iterator<Long> eventIterator = eventSet.iterator();
+
+			// go thru each interrupt from table and draw them into graph
+			while (eventIterator.hasNext()) {
+
+				// check if this time frame already has events and calculate
+				// place of line if needed
+				Long thisTime = eventIterator.next();
+				int amountOfEvents = eventsFromOneColor.get(thisTime);
+
+				if (!drawnInterrupts.containsKey(thisTime)) {
+
+					graphics.drawLine(new Point(thisTime / scale, bottom
+							- weightOfOneInterrupt * amountOfEvents),
+							new Point(thisTime / scale, bottom));
+					drawnInterrupts.put(thisTime, amountOfEvents);
+				} else {
+					int previousValue = drawnInterrupts.get(thisTime);
+					int newBottom = bottom
+							- (int) (previousValue * weightOfOneInterrupt);
+					graphics.drawLine(new Point(thisTime / scale, newBottom
+							- weightOfOneInterrupt * amountOfEvents),
+							new Point(thisTime / scale, newBottom));
+					drawnInterrupts.put(thisTime, previousValue
+							+ amountOfEvents);
+
+				}
+
+			}
+		}
+		graphics.setForegroundColor(previousColor);
+
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph#paintLeftLegend
+	 * (org.eclipse.draw2d.FigureCanvas, org.eclipse.swt.graphics.GC)
+	 */
+	public void paintLeftLegend(FigureCanvas figureCanvas, GC gc) {
+		int lineItemCount = 0;
+		int maxItemsPerMS = 0;
+
+		if (gc == null) {
+			return;
+		}
+
+		// Left legend not in use
+		if (swiTableVisible) {
+			lineItemCount = swiDrawList.size();
+			maxItemsPerMS = irqTrace.getMaxAmountOfSWISamples();
+		} else {
+			lineItemCount = irqDrawList.size();
+			maxItemsPerMS = irqTrace.getMaxAmountOfIRQSamples();
+
+		}
+
+		if (lineItemCount == 0) {
+			return;
+		}
+
+		Rectangle rect = ((GraphComposite) figureCanvas.getParent()).figureCanvas
+				.getClientArea();
+		double heightOfCanvas = rect.height;
+		int[] linePlaces = getHorizontalLinePlaces(heightOfCanvas,
+				lineItemCount);
+		double heightOfOneLine = (heightOfCanvas - BOTTOM_MARGIN)
+				/ lineItemCount;
+
+		interruptLines = new ArrayList<Integer>();
+
+		this.drawLegendOfOneLine(gc, 0, (int) heightOfOneLine, maxItemsPerMS);
+		for (int index = 1; index < linePlaces.length; index++) {
+			this.drawLegendOfOneLine(gc, linePlaces[index - 1],
+					(int) heightOfOneLine, maxItemsPerMS);
+		}
+
+	}
+
+	/**
+	 * Draws legend of one thread or irq line
+	 * 
+	 * @param graphics
+	 *            graphics context
+	 * @param top
+	 *            place of the top of the line
+	 * @param size
+	 *            size of line
+	 * @param maxValue
+	 *            maximum value of interrupts at one ms
+	 */
+	private void drawLegendOfOneLine(GC graphics, int top, int size,
+			int maxValue) {
+
+		double quarterOfMaxValue = (double) maxValue / 4.0;
+		int drawTop = top;
+		int drawValue = maxValue;
+
+		for (int index = 1; index < 5; index++) {
+
+			String legend = Integer.toString(drawValue) + Messages.IrqTraceGraph_4;
+			org.eclipse.swt.graphics.Point extent = graphics
+					.stringExtent(legend);
+
+			// texts are drawn only if size of line is greater than 50 pixels
+			if (size > 50) {
+				graphics.drawString(legend, IGenericTraceGraph.Y_LEGEND_WIDTH
+						- extent.x - 4, (int) drawTop - 2);
+			}
+
+			// get next draw value
+			drawValue = (int) (maxValue - (double) index * quarterOfMaxValue);
+			double doublevalue = size
+					- ((double) drawValue / (double) maxValue) * size;
+			// get place of the line
+			drawTop = (int) (top + doublevalue);
+
+			// add line place into interruptLines
+			if (index < 4) {
+				interruptLines.add(drawTop);
+			}
+
+		}
+
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph#repaint()
+	 */
+	public void repaint() {
+		if (parentComponent != null) {
+			this.parentComponent.repaintComponent();
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @seecom.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph#
+	 * setLegendTableVisible(boolean)
+	 */
+	public void graphVisibilityChanged(boolean value) {
+		if (holder != null) {
+			holder.setVisible(value);
+			holder.getParent().layout();
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @seecom.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph#
+	 * setLegendTableMaximized(boolean)
+	 */
+	public void graphMaximized(boolean value) {
+		if (holder != null) {
+			if (holder.getParent().getClass() == SashForm.class) {
+				SashForm sashForm = (SashForm) holder.getParent();
+				if (value) {
+					sashForm.setMaximizedControl(holder);
+				} else {
+					sashForm.setMaximizedControl(null);
+
+				}
+			}
+
+		}
+	}
+
+	/**
+	 * @return irq trace
+	 */
+	public IrqTrace getIrqTrace() {
+		return irqTrace;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see com.nokia.carbide.cpp.pi.visual.IGenericTraceGraph#getTitle()
+	 */
+	public String getTitle() {
+		return Messages.IrqTraceGraph_5;
+	}
+
+	/**
+	 * sets Irq table visible
+	 */
+	public void setIrqTableVisible() {
+		this.setSwiTableVisible(false);
+	}
+
+	/**
+	 * sets Swi table visible
+	 */
+	public void setSwiTableVisible() {
+		this.setSwiTableVisible(true);
+
+	}
+
+	/**
+	 * changes swi tables visibility according to parameter
+	 * 
+	 * @param value
+	 */
+	private void setSwiTableVisible(boolean value) {
+
+		this.swiTableVisible = value;
+
+		compositeIRQ.setVisible(!value);
+		compositeSWI.setVisible(value);
+
+		if (compositeIRQ.getLayoutData().getClass() == GridData.class) {
+			((GridData) compositeIRQ.getLayoutData()).exclude = value;
+		}
+		if (compositeSWI.getLayoutData().getClass() == GridData.class) {
+			((GridData) compositeSWI.getLayoutData()).exclude = !value;
+		}
+		holder.layout();
+		this.repaint();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @seecom.nokia.carbide.cpp.internal.pi.plugin.model.ITitleBarMenu#
+	 * addTitleBarMenuItems()
+	 */
+	public Action[] addTitleBarMenuItems() {
+		// Create actions for Title Bar's drop-down list
+
+		ArrayList<Action> actionArrayList = new ArrayList<Action>();
+
+		// Action for showing swi interrupts
+		Action showSwiTable = new Action() {
+			public void run() {
+				setSwiTableVisible();
+			}
+
+		};
+		showSwiTable.setText(Messages.IrqTraceGraph_6);
+		actionArrayList.add(showSwiTable);
+
+		// Action for showing irq interrupts
+		Action showIrqTable = new Action() {
+			public void run() {
+				setIrqTableVisible();
+			}
+
+		};
+		showIrqTable.setText(Messages.IrqTraceGraph_7);
+		actionArrayList.add(showIrqTable);
+
+		return actionArrayList.toArray(new Action[actionArrayList.size()]);
+
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.ITitleBarMenu#getContextHelpId()
+	 */
+	public String getContextHelpId() {
+		return IrqPlugin.HELP_CONTEXT_ID_MAIN_PAGE;
+	}
+
+	/**
+	 * Function that is called when thread is checked from the thread table
+	 * 
+	 * @param threadName
+	 */
+	public void threadChecked(String threadName) {
+
+		Hashtable<RGB, TreeMap<Long, Integer>> hashAllFunctions = new Hashtable<RGB, TreeMap<Long, Integer>>();
+		Hashtable<String, ArrayList<Long>> hash = irqTrace
+				.getThreadsToFunctions().get(threadName);
+
+		if (hash == null) {
+			return;
+		}
+		Enumeration<String> it = hash.keys();
+
+		// go thru function hashtable
+		while (it.hasMoreElements()) {
+			String threadname = it.nextElement();
+
+			IrqSampleTypeWrapper wrapper = tableSWIFunction.getFunctionColors()
+					.get(threadname);
+			if (!wrapper.isSelected()) {
+				continue;
+			}
+
+			// get add events from one function into hashOneFunction map
+			TreeMap<Long, Integer> hashOneFunction = new TreeMap<Long, Integer>();
+			ArrayList<Long> eventList = hash.get(threadname);
+			for (Long item : eventList) {
+				// if interrupt at this time does not yet exist create new map
+				// item
+				if (!hashOneFunction.containsKey(item)) {
+					hashOneFunction.put(item, 1);
+				}
+				// if interrupt exists increase its values
+				else {
+					int previousvalue = hashOneFunction.get(item);
+					hashOneFunction.put(item, previousvalue + 1);
+				}
+			}
+			RGB rgp = wrapper.rgb;
+			// save event into hash
+			hashAllFunctions.put(rgp, hashOneFunction);
+		}
+		// add hashtable into draw list
+		swiDrawList.put(threadName, hashAllFunctions);
+
+	}
+
+	/**
+	 * function that is called when thread is unchecked
+	 * 
+	 * @param threadName
+	 *            name of the thread
+	 */
+	public void threadUnchecked(String threadName) {
+
+		// remove thread from draw list
+		if (swiDrawList.containsKey(threadName)) {
+			swiDrawList.remove(threadName);
+		}
+
+	}
+
+	/**
+	 * function that is called then irq line is checked
+	 * 
+	 * @param irqLine
+	 *            irq line number
+	 */
+	public void irqLineChecked(IrqSampleTypeWrapper irqLine) {
+
+		// get add events from one line into oneLinesInterrupts map
+		TreeMap<Long, Integer> oneLinesInterrupts = new TreeMap<Long, Integer>();
+
+		Vector<IrqSample> samples = irqLine.samples;
+		for (IrqSample item : samples) {
+			// if interrupt at this time does not yet exist create new map item
+			if (!oneLinesInterrupts.containsKey(item.sampleSynchTime)) {
+				oneLinesInterrupts.put(item.sampleSynchTime, 1);
+			}
+			// if interrupt exists increase its values
+
+			else {
+				int previousvalue = oneLinesInterrupts
+						.get(item.sampleSynchTime);
+				oneLinesInterrupts.put(item.sampleSynchTime, previousvalue + 1);
+			}
+		}
+
+		// add hashtable into draw list
+		RGB rgpColor = irqLine.rgb;
+		Hashtable<RGB, TreeMap<Long, Integer>> drawTable = new Hashtable<RGB, TreeMap<Long, Integer>>();
+		drawTable.put(rgpColor, oneLinesInterrupts);
+		irqDrawList.put((long) irqLine.getPrototypeSample().getIrqL1Value(),
+				drawTable);
+
+	}
+
+	/**
+	 * function that is called when irq line is unchecked
+	 * 
+	 * @param irqLine
+	 *            irq line number
+	 */
+	public void irqLineUnchecked(IrqSampleTypeWrapper irqLine) {
+
+		// remove line from the draw list
+		if (irqDrawList.containsKey((long) irqLine.getPrototypeSample()
+				.getIrqL1Value())) {
+			irqDrawList.remove((long) irqLine.getPrototypeSample()
+					.getIrqL1Value());
+		}
+	}
+
+	/**
+	 * recalculated swi draw values for whole graph. This needs be done when
+	 * functions are checked or unchecked
+	 */
+	public void recalculateWholeGraph() {
+
+		// reset draw list
+		swiDrawList = new Hashtable<String, Hashtable<RGB, TreeMap<Long, Integer>>>();
+		Object[] wrappers = tableThreadIRQ.getTableViewer()
+				.getCheckedElements();
+
+		// go thru each checked thread and add them again into draw list
+		for (Object item : wrappers) {
+			if (item.getClass() == SwiThreadWrapper.class) {
+				SwiThreadWrapper wrapper = (SwiThreadWrapper) item;
+				this.threadChecked(wrapper.threadName);
+			}
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.visual.PIEventListener#piEventReceived
+	 * (com.nokia.carbide.cpp.internal.pi.visual.PIEvent)
+	 */
+	public void piEventReceived(PIEvent be) {
+
+		switch (be.getType()) {
+		case PIEvent.SELECTION_AREA_CHANGED:
+
+			// send this message to the 2 other graphs
+			PIEvent be2 = new PIEvent(be.getValueObject(),
+					PIEvent.SELECTION_AREA_CHANGED2);
+
+			for (IrqTraceGraph item : irqTrace.getGraphs()) {
+				if (item != this) {
+					item.piEventReceived(be2);
+				}
+			}
+
+			be = be2;
+
+			// FALL THROUGH
+		case PIEvent.SELECTION_AREA_CHANGED2:
+			double[] values = (double[]) be.getValueObject();
+			this.setSelectionStart(values[0]);
+			this.setSelectionEnd(values[1]);
+			this.updateIrqCountsInLegendsAsynch(TYPE_BOTH);
+			this.repaint();
+			break;
+		default:
+			break;
+		}
+
+	}
+
+	/**
+	 * updates count columns values based on the selected graph area
+	 * asynchronously
+	 * 
+	 * @param updateType
+	 *            value stating which legends need to be updated
+	 */
+	public void updateIrqCountsInLegendsAsynch(final int updateType) {
+
+		Runnable refreshRunnable = new Runnable() {
+			public void run() {
+				updateIrqCountsInLegends(updateType);
+			}
+		};
+
+		Display.getDefault().asyncExec(refreshRunnable);
+
+	}
+
+	/**
+	 * updates count columns values based on the selected graph area
+	 * 
+	 * @param updateType
+	 *            value stating which legends need to be updated
+	 */
+	public void updateIrqCountsInLegends(int updateType) {
+		// get selection area
+		double startTime = PIPageEditor.currentPageEditor().getStartTime();
+		double endTime = PIPageEditor.currentPageEditor().getEndTime();
+		long longStartTime = (long) (startTime * 1000);
+		long longEndTime = (long) (endTime * 1000);
+
+		Hashtable<RGB, Integer> counts = new Hashtable<RGB, Integer>();
+
+		if (updateType == TYPE_BOTH || updateType == TYPE_SWI) {
+			getColorCountsForSWILegend(counts, swiDrawList, longStartTime,
+					longEndTime);
+			setCountsForIrqLegendTable(tableSWIFunction.getTableViewer(),
+					counts);
+			tableSWIFunction.refreshTableViewer();
+		}
+		if (updateType == TYPE_BOTH || updateType == TYPE_IRQ) {
+			getColorCountsForIRQLegend(counts, irqDrawList, longStartTime,
+					longEndTime);
+			setCountsForIrqLegendTable(tableIrqLine.getTableViewer(), counts);
+			tableIrqLine.refreshTableViewer();
+		}
+	}
+
+	/**
+	 * Gets amount of interrupts for each color in the area between starttime
+	 * and endtime
+	 * 
+	 * @param counts
+	 *            amount of interrupts
+	 * @param drawList
+	 *            drawlist in use
+	 * @param startTime
+	 *            start time
+	 * @param endTime
+	 *            end time
+	 */
+	private void getColorCountsForSWILegend(Hashtable<RGB, Integer> counts,
+			Hashtable<String, Hashtable<RGB, TreeMap<Long, Integer>>> drawList,
+			long startTime, long endTime) {
+
+		Enumeration<String> it = drawList.keys();
+		// go thru drawlist and collect amounts for each color
+		while (it.hasMoreElements()) {
+			String threadName = it.nextElement();
+			Hashtable<RGB, TreeMap<Long, Integer>> functionsFromThread = drawList
+					.get(threadName);
+			Enumeration<RGB> colorEnum = functionsFromThread.keys();
+
+			// Go thru each color
+			while (colorEnum.hasMoreElements()) {
+				RGB color = colorEnum.nextElement();
+
+				// get first event after start time
+				TreeMap<Long, Integer> allEvents = functionsFromThread
+						.get(color);
+
+				// get tailmap for it
+				SortedMap<Long, Integer> tailMap = allEvents.tailMap(startTime);
+				Set<Long> set = tailMap.keySet();
+				Iterator<Long> eventIterator = set.iterator();
+
+				// save events into count array until entry is higher that end
+				// time
+				while (eventIterator.hasNext()) {
+					long time = eventIterator.next();
+					if (time > endTime) {
+						break;
+					}
+
+					if (!counts.containsKey(color)) {
+						counts.put(color, tailMap.get(time));
+					} else {
+						int previousValue = counts.get(color);
+						counts.put(color, previousValue + tailMap.get(time));
+					}
+				}
+			}
+		}
+	}
+
+	/**
+	 * Sets amount of interrupts into count column of legend table
+	 * 
+	 * @param tableViewer
+	 *            viewer of the table in use
+	 * @param counts
+	 *            hashtable containing counts for each color
+	 */
+	private void setCountsForIrqLegendTable(TableViewer tableViewer,
+			Hashtable<RGB, Integer> counts) {
+		TableItem[] swItems = tableViewer.getTable().getItems();
+		for (TableItem item : swItems) {
+			if (item.getData().getClass().equals(IrqSampleTypeWrapper.class)) {
+				IrqSampleTypeWrapper wrapper = (IrqSampleTypeWrapper) item
+						.getData();
+
+				RGB rgb = wrapper.rgb;
+
+				if (counts.containsKey(rgb)) {
+					wrapper.count = counts.get(rgb);
+				} else {
+					wrapper.count = 0;
+
+				}
+
+			}
+		}
+	}
+
+	/**
+	 * Gets amount of interrupts for each color in the area between starttime
+	 * and endtime
+	 * 
+	 * @param counts
+	 *            amount of interrupts
+	 * @param drawList
+	 *            drawlist in use
+	 * @param startTime
+	 *            start time
+	 * @param endTime
+	 *            end time
+	 */
+	private void getColorCountsForIRQLegend(Hashtable<RGB, Integer> counts,
+			Hashtable<Long, Hashtable<RGB, TreeMap<Long, Integer>>> drawList,
+			long startTime, long endTime) {
+		Enumeration<Long> it = drawList.keys();
+
+		// go thru drawlist and collect amounts for each color
+		while (it.hasMoreElements()) {
+			Long lineNumber = it.nextElement();
+			Hashtable<RGB, TreeMap<Long, Integer>> colorsFromLine = drawList
+					.get(lineNumber);
+			Enumeration<RGB> colorEnum = colorsFromLine.keys();
+			while (colorEnum.hasMoreElements()) {
+				RGB color = colorEnum.nextElement();
+
+				// get first event after start time
+				TreeMap<Long, Integer> allEvents = colorsFromLine.get(color);
+
+				// get tailmap for it
+				SortedMap<Long, Integer> tailMap = allEvents.tailMap(startTime);
+				Set<Long> set = tailMap.keySet();
+				Iterator<Long> eventIterator = set.iterator();
+
+				// save events into count array until entry is higher that end
+				// time
+				while (eventIterator.hasNext()) {
+					long time = eventIterator.next();
+					if (time > endTime) {
+						break;
+					}
+
+					if (!counts.containsKey(color)) {
+						counts.put(color, tailMap.get(time));
+					} else {
+						int previousValue = counts.get(color);
+						counts.put(color, previousValue + tailMap.get(time));
+					}
+				}
+			}
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.draw2d.MouseMotionListener#mouseDragged(org.eclipse.draw2d
+	 * .MouseEvent)
+	 */
+	public void mouseDragged(MouseEvent arg0) {
+		// nothing to be done
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.draw2d.MouseMotionListener#mouseEntered(org.eclipse.draw2d
+	 * .MouseEvent)
+	 */
+	public void mouseEntered(MouseEvent arg0) {
+		// nothing to be done
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.draw2d.MouseMotionListener#mouseExited(org.eclipse.draw2d
+	 * .MouseEvent)
+	 */
+	public void mouseExited(MouseEvent arg0) {
+		// nothing to be done
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.draw2d.MouseMotionListener#mouseHover(org.eclipse.draw2d.
+	 * MouseEvent)
+	 */
+	public void mouseHover(MouseEvent arg0) {
+		// nothing to be done
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.draw2d.MouseMotionListener#mouseMoved(org.eclipse.draw2d.
+	 * MouseEvent)
+	 */
+	public void mouseMoved(MouseEvent event) {
+
+		// get list sie that is shown
+		double listSize = 0;
+		if (swiTableVisible) {
+			listSize = swiDrawList.size();
+		} else {
+			listSize = irqDrawList.size();
+
+		}
+
+		int graphHeight = panelHeight - BOTTOM_MARGIN;
+
+		if (listSize == 0) {
+			this.setToolTipText(null);
+			return;
+		}
+
+		// get size of one item in the graph are
+		double sizeOfOneItem = (double) graphHeight / listSize;
+
+		// get index of item on top of which mouse is on
+		int index = (int) (event.y / sizeOfOneItem);
+
+		String tooltip = null;
+
+		// go thru needed drawlist and set thread/irq line name as tooltip
+		if (swiTableVisible) {
+			Enumeration<String> enumeration = swiDrawList.keys();
+			int ii = 0;
+			while (enumeration.hasMoreElements()) {
+				if (ii == index) {
+					tooltip = enumeration.nextElement();
+					break;
+				}
+				ii++;
+				enumeration.nextElement();
+			}
+		} else {
+			Enumeration<Long> enumeration = irqDrawList.keys();
+			int ii = 0;
+			while (enumeration.hasMoreElements()) {
+				if (ii == index) {
+					tooltip = IrqSampleTypeWrapper.getLineText(enumeration
+							.nextElement());
+					break;
+				}
+				ii++;
+				enumeration.nextElement();
+			}
+		}
+
+		this.setToolTipText(tooltip);
+
+	}
+
+	/**
+	 * updates all table viewers of the graph
+	 */
+	public void updateTableViewers() {
+		tableIrqLine.refreshTableViewer();
+		tableSWIFunction.refreshTableViewer();
+	}
+
+	/**
+	 * @return swi thread table
+	 */
+	public SwiThreadTable getTableThreadIRQ() {
+		return tableThreadIRQ;
+	}
+
+	/**
+	 * @return swi function table
+	 */
+	public SwiFunctionTable getTableSWIFunction() {
+		return tableSWIFunction;
+	}
+
+	/**
+	 * @return irq line table
+	 */
+	public IrqLineTable getTableIrqLine() {
+		return tableIrqLine;
+	}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.irq/src/com/nokia/carbide/cpp/pi/irq/IrqTraceParser.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,490 @@
+/*
+ * Copyright (c) 2010 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: 
+ *
+ */
+
+package com.nokia.carbide.cpp.pi.irq;
+
+import java.io.*;
+import java.util.*;
+
+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.Parser;
+
+
+/**
+ * Class irq trace parser. 
+ */
+public class IrqTraceParser extends Parser
+{
+//  private String profilerVersion;
+  private Vector completeIrqTrace;
+  private int firstSample,lastSample;
+  private long old_1 = 0;
+  private long old_2 = 0;
+  private long old_3 = 0;
+  private int sampleNum = 0;
+  private int old_irq_lev1 = 0;
+  private int old_irq_lev2 = 0;
+    
+  public IrqTraceParser(/*File irqFile, ProgressBar progressBar*/) throws Exception
+  {
+    this.completeIrqTrace = new Vector();
+  }
+  
+  public ParsedTraceData parse(File f) throws Exception 
+  {
+    
+    if(!f.exists()) //throw new IOException("GFC file does not exist");
+	{
+		setStateOk(false);
+		return null;
+	}
+	else
+    {
+		/*if(progressBar != null) 
+		{
+			setProgressBarString("Analysing IRQ/SWI...");
+		}*/
+		
+		FileInputStream fis = new FileInputStream(f);
+		byte[] data = new byte[(int)f.length()];
+		fis.read(data);
+		//String version = getVersion(data);
+		//System.out.println("IRQ trace version "+version);
+		//profilerVersion = version;
+		ByteArrayInputStream bais = new ByteArrayInputStream(data);
+		DataInputStream dis = new DataInputStream(bais);
+		
+		this.traceVersion = this.getVersion(dis);
+		if (this.traceVersion.indexOf("V1.20") != -1)
+		{
+			// start parsing
+			try
+			{
+				int total = 0;
+				while(true)
+				{
+					total += readEntries(dis);
+					this.sampleNum++;
+					//System.out.println("Sample #"+sampleNum+" "+this.completeIrqTrace.size());
+					//System.out.println("******* Total now "+total+" "+Integer.toHexString(total));
+			  	  	//System.in.read();
+			  	  	//System.in.read();
+				}
+			}
+			catch (EOFException eof)
+			{
+				//eof.printStackTrace();
+			    ParsedTraceData ptd = new ParsedTraceData();
+				ptd.staticData = null;
+				ptd.traceData = this.getTrace();
+				return ptd;
+			}
+			catch (Exception e)
+			{
+				System.out.println("Error in reading IRQ trace file");
+				throw e;				
+			}
+	    }
+		else
+		{
+			System.out.println("Unsupported IRQ version: "+this.traceVersion);
+		    return null;
+		}
+    }
+  	
+  }
+  
+  public String getProfilerVersion()
+  {
+      return this.traceVersion;
+  }
+  
+  private String getVersion(DataInputStream dis) throws IOException
+  {
+  	int length = dis.readUnsignedByte();
+  	byte[] verArray = new byte[length];
+  	dis.read(verArray);
+
+  	String verString = new String(verArray);
+//  	System.out.println("Version string: "+verString);
+	if(verString.indexOf("Bappea") != -1)
+		if(verString.indexOf("IRQ") != -1)
+		{
+  			int index = verString.indexOf("_");
+  			String ver = verString.substring(index,length);
+  			return ver;
+  		}
+	return("Unidentified");
+  }
+  
+  private int readEntries(DataInputStream dis) throws Exception
+  {
+	int b0=0,b1=0,b2=0,b3=0;
+	boolean swi = false;
+  	int read = 0;
+  	//System.out.println("-------------");
+  	b0 = dis.readUnsignedByte();read++;
+  	int length = b0; 
+  	if(length == 0xff)
+  	{
+  		// length encoded in 3 bytes
+  		b1 = dis.readUnsignedByte();read++;
+  		b2 = dis.readUnsignedByte();read++;
+  		b3 = dis.readUnsignedByte();read++;
+  		length = b1;
+  		length |= b2<<8;
+  		length |= b3<<16;
+  		//System.out.println("LONG length "+length);
+  	}
+//  	
+//	System.out.println("SWI len "+Integer.toHexString(b0)+
+//				 " "+Integer.toHexString(b1)+
+//				 " "+Integer.toHexString(b2)+
+//				 " "+Integer.toHexString(b3)+" "+length+" = 0x"+Integer.toHexString(length));
+  	
+  	while(length > 0)
+  	{
+  		int read_val = dis.readUnsignedByte();read++;length--;
+		
+  		//System.out.println("Length "+length);
+  		
+  		int repeat_val = 0;
+  		int header = (read_val & (int)0xff);
+  		int repeat = header>>>6;
+  		
+  		//System.out.println("Header "+Long.toHexString(header)+" "+Long.toBinaryString(header)+" repeat "+repeat);
+  		
+  		if(repeat == 0)
+  		{
+  			repeat_val = 0;
+  			//System.out.println("no repeat "+Long.toHexString(repeat_val));
+  		}
+  		else if(repeat == 1)
+  		{
+  			repeat_val = (header & ((int)0x3F));
+  			
+  			//System.out.println("short repeat "+Long.toHexString(repeat_val));
+  		}
+  		else if(repeat == 2)
+  		{
+  			repeat_val = ((header & ((int)0x3F))<<8) | 
+			(dis.readUnsignedByte());length--;read++;
+  			
+  			//System.out.println("medium repeat"+Long.toHexString(repeat_val));  		
+  		}
+  		else if(repeat == 3)
+  		{
+  			repeat_val = ((header & ((int)0x3F))<<24) | 
+			(dis.readUnsignedByte() << 16) |
+			(dis.readUnsignedByte() << 8) |
+			(dis.readUnsignedByte() );length-=3;read+=3;
+			/*
+			for(int x=0;x<10;x++)
+			{
+				for(int y=0;y<8;y++)
+				{
+					System.out.println(Integer.toHexString(dis.readUnsignedByte()));
+				}
+				System.out.print("\n");
+			}
+			
+			System.in.read();
+			System.in.read();
+			*/
+  		}
+  		
+  		if(repeat_val > 0) 
+  		{
+  			addSwiRepeat(repeat_val);
+  		}
+  		else
+  		{
+  			int bytes_1 = (header & ((int)0x30))>>>4;
+  			int bytes_2 = (header & ((int)0x0C))>>>2;
+  			int bytes_3 = (header & ((int)0x03));
+  			if(bytes_1 == 3) bytes_1 = 4;
+  			if(bytes_2 == 3) bytes_2 = 4;
+  			if(bytes_3 == 3) bytes_3 = 4;
+  			
+  			readSwiEntry(dis,bytes_1,bytes_2,bytes_3);
+  			length-=(bytes_1+bytes_2+bytes_3);
+  			read+=(bytes_1+bytes_2+bytes_3);		
+  		}
+  	}
+  	
+  	if(length == 0)
+  	{
+  		//Sytem.out.println("End of SWI, reading IRQ");
+  	  	b0 = dis.readUnsignedByte();read++;
+  	  	length = b0; 
+  	  	if(length == 0xff)
+  	  	{
+  	  		// length encoded in 3 bytes
+  	  		b1 = dis.readUnsignedByte();read++;
+  	  		b2 = dis.readUnsignedByte();read++;
+  	  		b3 = dis.readUnsignedByte();read++;
+  	  		length = b1;
+  	  		length |= b2<<8;
+  	  		length |= b3<<16;
+  	  		//System.out.println("LONG length "+length);
+  	  	}
+//  		System.out.println("IRQ len "+Integer.toHexString(b0)+
+//				 " "+Integer.toHexString(b1)+
+//				 " "+Integer.toHexString(b2)+
+//				 " "+Integer.toHexString(b3)+" "+length+" = 0x"+Integer.toHexString(length));
+  	  	
+  	  	swi = true;
+  	  	while(length > 0)
+  	  	{
+  	  		//System.out.println("Length "+length);
+  	  		int firstByte = dis.readUnsignedByte();length--;read++;
+  	  		
+  	  		if(firstByte == 0xff)
+  	  		{
+  	  			// this is a repeat of the previous sample
+  	  			int repeat = 	dis.readUnsignedByte() |
+								(dis.readUnsignedByte()<<8) |
+								(dis.readUnsignedByte()<<16);
+  	  			//if(sampleNum == 5918 || sampleNum == 6137 || sampleNum == 7958)
+  	  			//System.out.println(this.sampleNum+" IRQ Repeat of "+repeat+" L1:"+this.old_irq_lev1+" L2:"+this.old_irq_lev2);
+  	  			this.addIrqRepeat(repeat);
+  	  			
+  	  			length-=3;read+=3;
+  	  			
+  	  			if(length > 0)
+  	  			{
+  	  				this.old_irq_lev1 = dis.readUnsignedByte();
+  	  				this.old_irq_lev2 = dis.readUnsignedByte();
+  	  				length-=2; read-=2;
+
+  	  				this.addIrqSample();
+  	  			}
+  	  		}
+  	  		else
+  	  		{
+  	  			this.old_irq_lev1 = firstByte;
+  	  			this.old_irq_lev2 = dis.readUnsignedByte();
+  	  			length--;read++;
+
+  	  			this.addIrqSample();
+  	  		}
+  	  		
+  			//System.out.println(this.sampleNum+" IRQ L1:"+this.old_irq_lev1+" L2:"+this.old_irq_lev2);
+  	  	}
+  	}
+  	else
+  	{
+//  		System.out.println("Parse error "+Integer.toHexString(b0)+
+//  										 " "+Integer.toHexString(b1)+
+//  										 " "+Integer.toHexString(b2)+
+//  										 " "+Integer.toHexString(b3)+" "+swi+" "+read);
+  		
+  		throw new Exception("Parse error "+Integer.toHexString(b0)+
+  										 " "+Integer.toHexString(b1)+
+  										 " "+Integer.toHexString(b2)+
+  										 " "+Integer.toHexString(b3));
+  	}
+
+  	if(length == 0)
+  	{
+  		return read;
+  	}
+  	else
+  	{
+  		throw new Exception("Parse error");
+  	}
+  	
+  }
+     
+  private void readSwiEntry(DataInputStream dis,int b1,int b2,int b3) throws Exception
+  {
+  	//System.out.println("b1: "+b1+" b2:"+b2+" b3:"+b3);
+  
+  	int value = 0;
+  	int fValue = 0;
+  	boolean neg = false;
+	for(int i=0;i<4;i++) 
+	{
+		if(i<b1)
+		{
+			value = dis.readUnsignedByte();
+			if((value & 0x80) > 0) neg = true;
+			else neg = false;
+			value = (value<<(8*i));
+			fValue |= value;
+			//System.out.println("v"+i+":"+Integer.toHexString(value));
+		}
+		else
+		{
+			if(neg == true) value = 0xff;
+			else value = 0x00;
+			value = (value<<(8*i));
+			fValue |= value;
+			//System.out.println("v"+i+":"+Integer.toHexString(value));
+		}
+	}
+	//if(fValue == -1) System.out.println("1:"+fValue); 	
+	this.old_1 += fValue;
+
+	value = 0;
+	fValue = 0;
+	neg = false;
+	for(int i=0;i<4;i++)
+	{
+		if(i<b2)
+		{
+			value = dis.readUnsignedByte();
+			if((value & 0x80) > 0) neg = true;
+			else neg = false;
+			value = (value<<(8*i));
+			fValue |= value;
+			//System.out.println("v"+i+":"+Integer.toHexString(value));
+		}
+		else
+		{
+			if(neg == true) value = 0xff;
+			else value = 0x00;
+			value = (value<<(8*i));
+			fValue |= value;
+			//System.out.println("v"+i+":"+Integer.toHexString(value));
+		}
+	}
+	//if(fValue == -1) System.out.println("2:"+fValue); 	
+	this.old_2 += fValue;
+	
+	value = 0;
+	fValue = 0;
+	neg = false;
+	for(int i=0;i<4;i++) 
+	{
+		if(i<b3)
+		{
+			value = dis.readUnsignedByte();
+			if((value & 0x80) > 0) neg = true;
+			else neg = false;
+			value = (value<<(8*i));
+			fValue |= value;
+			//System.out.println("v"+i+":"+Integer.toHexString(value));
+		}
+		else
+		{
+			if(neg == true) value = 0xff;
+			else value = 0x00;
+			value = (value<<(8*i));
+			fValue |= value;
+			//System.out.println("v"+i+":"+Integer.toHexString(value));
+		}
+	}
+	//if(fValue == -1) System.out.println("3:"+fValue); 	
+	this.old_3 += fValue;
+	
+	this.addSwiSample();
+	/*
+	System.out.println( "#"+this.sampleNum+" "+Integer.toHexString((int)old_1)+
+						" "+Integer.toHexString((int)old_2)+
+						" "+Integer.toHexString((int)old_3)+" "+sfp.getFunctionNameForAddress(((old_3<<32)>>>32)));
+	*/
+ 	return;
+  }
+  
+  private void addSwiSample()
+  {
+	  long temp_1 = ((this.old_1 << 32) >>> 32);
+	  long temp_2 = ((this.old_2 << 32) >>> 32);
+	  long temp_3 = ((this.old_3 << 32) >>> 32)-4;
+	  
+	  IrqSample sample = new IrqSample(this.sampleNum, temp_1, temp_2, temp_3);
+	  /*
+	  String n1 = sfp.getFunctionNameForAddress(temp_3);
+	  
+	  if(n1.indexOf("WaitForAnyRequest") != -1)
+	  {
+		  for(int i=-256;i<256;i++)
+		  {
+			  String n2 = sfp.getFunctionNameForAddress(temp_1+i);
+			  if(n2.indexOf("WaitForAnyRequest") != -1)
+			  {
+				  System.out.print("\n"+i);
+				  
+				  System.out.println("EXEC CALL : "+sfp.getFunctionNameForAddress(temp_3));
+				  System.out.println("Made in : "+sfp.getFunctionNameForAddress(temp_1+i));
+				  break;
+			  }
+		  }
+	  } 
+	  */
+	  this.completeIrqTrace.add(sample);
+  }
+  
+  private void addSwiRepeat(int amount)
+  {
+	  long temp_1 = ((this.old_1 << 32) >>> 32);
+	  long temp_2 = ((this.old_2 << 32) >>> 32);
+	  long temp_3 = ((this.old_3 << 32) >>> 32)-4;
+	  
+	  /*
+	  String n1 = sfp.getFunctionNameForAddress(temp_3);
+	  
+	  if(n1.indexOf("WaitForAnyRequest") != -1)
+	  {
+		  for(int i=-256;i<256;i++)
+		  {
+			  String n2 = sfp.getFunctionNameForAddress(temp_1+i);
+			  if(n2.indexOf("WaitForAnyRequest") != -1)
+			  {
+				  System.out.print("\n"+i);
+				  
+				  System.out.println("EXEC CALL : "+sfp.getFunctionNameForAddress(temp_3));
+				  System.out.println("Made in : "+sfp.getFunctionNameForAddress(temp_1+i));
+				  break;
+			  }
+		  }
+	  } 
+	  */
+	  
+	  IrqSample sample = new IrqSample(this.sampleNum,temp_1,temp_2,temp_3);
+	  sample.repeatCount = amount;
+	  this.completeIrqTrace.add(sample);
+  }
+
+  private void addIrqSample()
+  {
+  	IrqSample sample = new IrqSample(this.sampleNum,this.old_irq_lev1,this.old_irq_lev2);
+  	this.completeIrqTrace.add(sample);
+  }
+  
+  private void addIrqRepeat(int amount)
+  {
+  	  	IrqSample sample = new IrqSample(this.sampleNum,this.old_irq_lev1,this.old_irq_lev2);
+  	  	sample.repeatCount = amount; 
+ 	  	this.completeIrqTrace.add(sample);
+  }
+  
+  private GenericTrace getTrace()
+  {
+  	Enumeration completeEnum = this.completeIrqTrace.elements();
+  	IrqTrace trace = new IrqTrace();
+  	
+  	while(completeEnum.hasMoreElements())
+  	{
+  		IrqSample sample = (IrqSample)completeEnum.nextElement();
+  		trace.addSample(sample);
+  	}
+  	return trace;
+  }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.irq/src/com/nokia/carbide/cpp/pi/irq/Messages.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2010 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: 
+ *
+ */
+
+package com.nokia.carbide.cpp.pi.irq;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS {
+	private static final String BUNDLE_NAME = "com.nokia.carbide.cpp.pi.irq.messages"; //$NON-NLS-1$
+	public static String IrqLineTable_0;
+	public static String IrqLineTable_1;
+	public static String IrqLineTable_2;
+	public static String IrqLineTable_3;
+	public static String IrqLineTable_4;
+	public static String IrqLineTable_5;
+	public static String IrqLineTable_6;
+	public static String IrqPlugin_0;
+	public static String IrqPlugin_1;
+	public static String IrqPlugin_2;
+	public static String IrqPlugin_3;
+	public static String IrqPlugin_4;
+	public static String IrqPlugin_5;
+	public static String IrqSample_0;
+	public static String IrqSampleTypeWrapper_0;
+	public static String IrqSampleTypeWrapper_1;
+	public static String IrqTrace_0;
+	public static String IrqTrace_1;
+	public static String IrqTrace_2;
+	public static String IrqTrace_3;
+	public static String IrqTrace_4;
+	public static String IrqTrace_5;
+	public static String IrqTrace_6;
+	public static String IrqTraceGraph_0;
+	public static String IrqTraceGraph_1;
+	public static String IrqTraceGraph_2;
+	public static String IrqTraceGraph_3;
+	public static String IrqTraceGraph_4;
+	public static String IrqTraceGraph_5;
+	public static String IrqTraceGraph_6;
+	public static String IrqTraceGraph_7;
+	public static String SwiFunctionLabelProvider_0;
+	public static String SwiFunctionLabelProvider_1;
+	public static String SwiFunctionLabelProvider_2;
+	public static String SwiFunctionTable_0;
+	public static String SwiFunctionTable_1;
+	public static String SwiFunctionTable_2;
+	public static String SwiFunctionTable_3;
+	public static String SwiFunctionTable_4;
+	public static String SwiFunctionTable_5;
+	public static String SwiFunctionTable_6;
+	public static String SwiFunctionTable_7;
+	public static String SwiThreadLabelProvider_0;
+	public static String SwiThreadTable_0;
+	public static String SwiThreadTable_1;
+	public static String SwiThreadTable_2;
+	public static String SwiThreadTable_3;
+	static {
+		// initialize resource bundle
+		NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+	}
+
+	private Messages() {
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.irq/src/com/nokia/carbide/cpp/pi/irq/SwiFunctionLabelProvider.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2010 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: 
+ *
+ */
+
+package com.nokia.carbide.cpp.pi.irq;
+
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Table;
+import com.nokia.carbide.cpp.internal.pi.visual.GenericTable;
+
+/**
+ * LabelProvider for software function table
+ */
+public class SwiFunctionLabelProvider extends LabelProvider implements
+		ITableLabelProvider {
+
+	/* function table */
+	Table table;
+
+	/**
+	 * Constructor
+	 * 
+	 * @param table
+	 *            table
+	 */
+	public SwiFunctionLabelProvider(Table table) {
+		super();
+		this.table = table;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java.lang
+	 * .Object, int)
+	 */
+	public String getColumnText(Object element, int columnIndex) {
+		int columnId = ((Integer) table.getColumn(columnIndex).getData())
+				.intValue();
+
+		switch (columnId) {
+		// name of the function
+		case GenericTable.COLUMN_ID_SWI_FUNCTION:
+
+			if (element instanceof IrqSampleTypeWrapper) {
+				IrqSampleTypeWrapper item = (IrqSampleTypeWrapper) element;
+				if (item.getPrototypeSample().getFunction() != null
+						&& item.getPrototypeSample().getFunction().getFunctionName() != null) {
+					return item.getPrototypeSample().getFunction().getFunctionName();
+				} else {
+					return Messages.SwiFunctionLabelProvider_0
+							+ Long.toHexString(item.getPrototypeSample()
+									.getLrValue()) + Messages.SwiFunctionLabelProvider_1;
+				}
+			}
+
+			// return address
+		case GenericTable.COLUMN_ID_RETURN_ADDRESS:
+
+			if (element instanceof IrqSampleTypeWrapper) {
+				IrqSampleTypeWrapper item = (IrqSampleTypeWrapper) element;
+				if (item.getPrototypeSample().getFunction() != null) {
+					return Messages.SwiFunctionLabelProvider_2
+							+ Long.toHexString(item.getPrototypeSample()
+									.getFunction().getStartAddress());
+				}
+			}
+
+			// count of interrupts in selection area
+		case GenericTable.COLUMN_ID_SWI_COUNT:
+			if (element instanceof IrqSampleTypeWrapper) {
+				IrqSampleTypeWrapper profiledItem = (IrqSampleTypeWrapper) element;
+				return Integer.toString(profiledItem.count);
+			}
+		default: {
+			break;
+		}
+		}
+		// should never get here
+		return ""; //$NON-NLS-1$
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang
+	 * .Object, int)
+	 */
+	public Image getColumnImage(Object element, int columnIndex) {
+		return null;
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.irq/src/com/nokia/carbide/cpp/pi/irq/SwiFunctionTable.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,687 @@
+/*
+ * Copyright (c) 2010 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: 
+ *
+ */
+
+package com.nokia.carbide.cpp.pi.irq;
+
+import java.awt.event.MouseEvent;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import org.eclipse.jface.viewers.CheckStateChangedEvent;
+import org.eclipse.jface.viewers.CheckboxTableViewer;
+import org.eclipse.jface.viewers.ICheckStateListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.ColorDialog;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
+import org.eclipse.swt.widgets.MessageBox;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.TableItem;
+
+import com.nokia.carbide.cpp.internal.pi.visual.GenericTable;
+
+/**
+ * Software function interrupt table.
+ * 
+ */
+public class SwiFunctionTable extends GenericTable implements
+		ICheckStateListener {
+
+	// sort direction
+	private boolean sortAscending = true;
+
+	/* irq trace graph */
+	private IrqTraceGraph myGraph;
+
+	/* parent component where all ui components are placed */
+	private Composite parent;
+
+	/* item data for table data */
+	protected Vector<IrqSampleTypeWrapper> tableItemData;
+
+	/* function color */
+	private Hashtable<String, IrqSampleTypeWrapper> functionColors;
+
+	final boolean checkAllWhenOpened = true;
+
+	/**
+	 * Constructor
+	 * 
+	 * @param myGraph
+	 *            irq trace graph
+	 * @param parent
+	 *            parent component where all ui components are placed
+	 */
+	public SwiFunctionTable(IrqTraceGraph myGraph, Composite parent) {
+		this.myGraph = myGraph;
+		this.parent = parent;
+
+		this.tableViewer = CheckboxTableViewer.newCheckList(parent, SWT.BORDER
+				| SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION);
+		this.table = this.tableViewer.getTable();
+		this.table.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+		// add the check state handler, label provider and content provider
+		this.tableViewer.addCheckStateListener(this);
+		this.tableViewer.setLabelProvider(new SwiFunctionLabelProvider(
+				this.table));
+		this.tableViewer.setContentProvider(new FunctionTableContentProvider());
+		this.tableViewer.setSorter(new SharedSorter());
+
+		// create the columns
+		TableColumn column;
+
+		// data associated with the TableViewer will note which columns contain
+		// hex values
+		// Keep this in the order in which columns have been created
+		boolean[] isHex = { false, false, false, false };
+		this.table.setData("isHex", isHex); //$NON-NLS-1$
+
+		// Check and color column
+		column = new TableColumn(this.table, SWT.CENTER);
+		column.setText(Messages.SwiFunctionTable_0);
+		column.setWidth(30 + 15);
+		column.setData(COLOR_COLUMN_INDEX);
+		column.setMoveable(true);
+		column.setResizable(true);
+		column.addSelectionListener(new ColumnSelectionHandler());
+
+		// Function name column
+		column = new TableColumn(this.table, SWT.LEFT);
+		column.setText(Messages.SwiFunctionTable_1);
+		column.setWidth(COLUMN_WIDTH_SWI_FUNCTION + 15);
+		column.setData(COLUMN_ID_SWI_FUNCTION);
+		column.setMoveable(true);
+		column.setResizable(true);
+		column.addSelectionListener(new ColumnSelectionHandler());
+
+		// return address column
+		column = new TableColumn(tableViewer.getTable(), SWT.RIGHT);
+		column.setText(Messages.SwiFunctionTable_2);
+		column.setWidth(COLUMN_WIDTH_RETURN_ADDRESS);//  
+		column.setData(COLUMN_ID_RETURN_ADDRESS);
+		column.setMoveable(true);
+		column.setResizable(true);
+		column.addSelectionListener(new ColumnSelectionHandler());
+
+		// count column
+		column = new TableColumn(tableViewer.getTable(), SWT.RIGHT);
+		column.setText(Messages.SwiFunctionTable_3);
+		column.setWidth(COLUMN_WIDTH_COUNT);
+		column.setData(COLUMN_ID_SWI_COUNT);
+		column.setMoveable(true);
+		column.setResizable(true);
+		column.addSelectionListener(new ColumnSelectionHandler());
+
+		// add mouse listener and set other table settings
+		this.table.addMouseListener(new TableMouseListener());
+		this.table.setHeaderVisible(true);
+		this.table.setLinesVisible(true);
+		this.table.setRedraw(true);
+
+		// format data into table and sort table
+		this.updateItemData(true);
+		((SharedSorter) tableViewer.getSorter()).doSort(COLUMN_ID_SWI_COUNT);
+
+		// initially, all rows are checked
+		this.tableViewer.setAllChecked(checkAllWhenOpened);
+		this.addColor();
+
+		// listen for key sequences such as Ctrl-A and Ctrl-C
+		table.addKeyListener(new TableKeyListener());
+
+		tableViewer.refresh();
+		table.redraw();
+		this.addColor();
+
+	}
+
+	/**
+	 * Function table content provider
+	 */
+	private static class FunctionTableContentProvider implements
+			IStructuredContentProvider {
+		/**
+		 * Constructor
+		 */
+		public FunctionTableContentProvider() {
+			super();
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see
+		 * org.eclipse.jface.viewers.IStructuredContentProvider#getElements(
+		 * java.lang.Object)
+		 */
+		@SuppressWarnings("unchecked")
+		public Object[] getElements(Object inputElement) {
+			return ((Vector<IrqSampleTypeWrapper>) inputElement).toArray();
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see org.eclipse.jface.viewers.IContentProvider#dispose()
+		 */
+		public void dispose() {
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see
+		 * org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse
+		 * .jface.viewers.Viewer, java.lang.Object, java.lang.Object)
+		 */
+		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+		}
+	}
+
+	/**
+	 * updates item data into function table
+	 * 
+	 * @param setInput
+	 *            true if table needs to be refreshed
+	 */
+	public void updateItemData(boolean setInput) {
+
+		// Reset table data
+		tableItemData = new Vector<IrqSampleTypeWrapper>();
+
+		functionColors = new Hashtable<String, IrqSampleTypeWrapper>();
+
+		// Get sample type wrappers from trace
+		Hashtable<Long, IrqSampleTypeWrapper> sampleTypeWrappers = ((IrqTrace) this.myGraph
+				.getTrace()).getSwiTable();
+		if (sampleTypeWrappers == null) {
+			return;
+		}
+
+		// Add sample type wrappers to table data
+		Enumeration<Long> k = sampleTypeWrappers.keys();
+		while (k.hasMoreElements()) {
+			Long key = (Long) k.nextElement();
+			if (sampleTypeWrappers.get(key).getClass() == IrqSampleTypeWrapper.class) {
+				IrqSampleTypeWrapper wrapper = (IrqSampleTypeWrapper) sampleTypeWrappers
+						.get(key);
+				if (wrapper.getPrototypeSample().getFunction() != null) {
+					wrapper.setSelected(checkAllWhenOpened);
+					tableItemData.add(wrapper);
+					functionColors.put(wrapper.getPrototypeSample()
+							.getFunction().getFunctionName(), wrapper);
+				}
+
+			}
+		}
+
+		// refresh the table, if needed
+		if (setInput)
+			refreshTableViewer();
+
+	}
+
+	/**
+	 * refreshes table viewer and adds colors into check box column
+	 */
+	public void refreshTableViewer() {
+		this.tableViewer.setInput(tableItemData);
+		this.addColor();
+
+	}
+
+	/**
+	 * @return hashtable containing all function colors
+	 */
+	public Hashtable<String, IrqSampleTypeWrapper> getFunctionColors() {
+		return functionColors;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.jface.viewers.ICheckStateListener#checkStateChanged(org.eclipse
+	 * .jface.viewers.CheckStateChangedEvent)
+	 */
+	public void checkStateChanged(CheckStateChangedEvent event) {
+		if (event.getElement().getClass() == IrqSampleTypeWrapper.class) {
+			IrqSampleTypeWrapper wrapper = (IrqSampleTypeWrapper) event
+					.getElement();
+			wrapper.setSelected(event.getChecked());
+			myGraph.recalculateWholeGraph();
+			myGraph.repaint();
+			// myGraph.updateIrqCountsInLegends(IrqTraceGraph.TYPE_SWI);
+
+		}
+	}
+
+	/**
+	 * adds function colors into check box column
+	 */
+	public void addColor() {
+		if (this.tableViewer == null)
+			return;
+
+		IrqSampleTypeWrapper wrapper;
+		TableItem[] items = this.table.getItems();
+
+		for (int i = 0; i < items.length; i++) {
+			if (items[i].getData().getClass() == IrqSampleTypeWrapper.class) {
+				wrapper = (IrqSampleTypeWrapper) items[i].getData();
+				items[i].setBackground(COLOR_COLUMN_INDEX, new Color(parent
+						.getDisplay(), wrapper.rgb));
+			}
+		}
+
+		table.redraw();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.visual.GenericTable#action(java.lang
+	 * .String)
+	 */
+	public void action(String actionString) {
+		if (actionString.equals("add")) { //$NON-NLS-1$
+			checkOrUncheckSelectedItems(true);
+		} else if (actionString.equals("remove")) { //$NON-NLS-1$
+			checkOrUncheckSelectedItems(false);
+		} else if (actionString.equals("addall")) { //$NON-NLS-1$
+			checkOrUncheckAllItems(true);
+		} else if (actionString.equals("removeall")) { //$NON-NLS-1$
+			checkOrUncheckAllItems(false);
+		} else if (actionString.equals(Messages.SwiFunctionTable_4)) {
+			actionRecolor();
+		} else if (actionString.equals("copy")) //$NON-NLS-1$
+		{
+			actionCopyOrSave(true, this.table, CHECKBOX_TEXT, false, "\t", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
+			return; // no redraw needed
+		} else if (actionString.equals("copyTable")) //$NON-NLS-1$
+		{
+			actionCopyOrSave(true, this.table, CHECKBOX_TEXT, true, "\t", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
+			return; // no redraw needed
+		} else if (actionString.equals("selectAll")) //$NON-NLS-1$
+		{
+			actionSelectAll();
+			return;
+		}
+
+		else if (actionString.equals("saveTable")) //$NON-NLS-1$
+		{
+			actionCopyOrSave(false, this.table, CHECKBOX_TEXT, true, ",", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
+			return; // no redraw needed
+		}
+	}
+
+	/**
+	 * Checks or unchecks all selected threads from table
+	 * 
+	 * @param value
+	 *            true if items are checked
+	 */
+	private void checkOrUncheckSelectedItems(boolean value) {
+
+		TableItem[] selectedItems = this.table.getSelection();
+		for (int i = 0; i < selectedItems.length; i++) {
+			if (selectedItems[i].getData().getClass() == IrqSampleTypeWrapper.class) {
+				selectedItems[i].setChecked(value);
+				IrqSampleTypeWrapper wrapper = (IrqSampleTypeWrapper) selectedItems[i]
+						.getData();
+				wrapper.setSelected(value);
+			}
+		}
+		myGraph.recalculateWholeGraph();
+		myGraph.repaint();
+
+	}
+
+	/**
+	 * Checks or unchecks all table items
+	 * 
+	 * @param value
+	 *            true if all items are checked
+	 */
+	private void checkOrUncheckAllItems(boolean value) {
+
+		TableItem[] allItems = this.table.getItems();
+		for (int i = 0; i < allItems.length; i++) {
+			if (allItems[i].getData().getClass() == IrqSampleTypeWrapper.class) {
+				allItems[i].setChecked(value);
+				IrqSampleTypeWrapper wrapper = (IrqSampleTypeWrapper) allItems[i]
+						.getData();
+				if (value) {
+					wrapper.setSelected(value);
+				} else {
+					wrapper.setSelected(value);
+
+				}
+			}
+
+		}
+		myGraph.recalculateWholeGraph();
+		myGraph.repaint();
+
+	}
+
+	/**
+	 * Mouselistener for function table
+	 */
+	private class TableMouseListener implements MouseListener {
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see
+		 * org.eclipse.swt.events.MouseListener#mouseDoubleClick(org.eclipse
+		 * .swt.events.MouseEvent)
+		 */
+		public void mouseDoubleClick(org.eclipse.swt.events.MouseEvent e) {
+			if (e.button == MouseEvent.BUTTON1) {
+				/*
+				 * TableItem[] selectedItems = table.getSelection(); if
+				 * (selectedItems.length == 0) return;
+				 * 
+				 * if (selectedItems[0].getData() instanceof MemThread) {
+				 * MemThread pMemThread =
+				 * (MemThread)(selectedItems[0].getData()); if
+				 * (pMemThread.isEnabled(myGraph.getGraphIndex()))
+				 * action("remove"); //$NON-NLS-1$ else action("add");
+				 * //$NON-NLS-1$ }
+				 */
+			}
+			/*
+			 * selectAllAction.setEnabled(table.getItemCount() > 0);
+			 * copyAction.setEnabled(table.getSelectionCount() > 0);
+			 * copyTableAction.setEnabled(table.getItemCount() > 0);
+			 */
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see
+		 * org.eclipse.swt.events.MouseListener#mouseDown(org.eclipse.swt.events
+		 * .MouseEvent)
+		 */
+		public void mouseDown(org.eclipse.swt.events.MouseEvent e) {
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see
+		 * org.eclipse.swt.events.MouseListener#mouseUp(org.eclipse.swt.events
+		 * .MouseEvent)
+		 */
+		public void mouseUp(org.eclipse.swt.events.MouseEvent e) {
+
+			if (e.button == MouseEvent.BUTTON3) {
+				// get rid of last Menu created so we don't have double menu
+				// on click
+				if (contextMenu != null) {
+					contextMenu.dispose();
+				}
+
+				contextMenu = new Menu(table.getShell(), SWT.POP_UP);
+				getCheckRows(contextMenu, table.getSelectionCount() > 0);
+
+				// select all, copy, and copy all
+				new MenuItem(contextMenu, SWT.SEPARATOR);
+				getSelectAllItem(contextMenu, table.getItemCount() > 0);
+				getCopyItem(contextMenu, table.getSelectionCount() > 0);
+				getCopyTableItem(contextMenu, table.getItemCount() > 0);
+
+				// save all
+				new MenuItem(contextMenu, SWT.SEPARATOR);
+				getSaveTableItem(contextMenu, table.getItemCount() > 0);
+
+				// Recolor highlighted items
+				new MenuItem(contextMenu, SWT.SEPARATOR);
+				getRecolorItem(contextMenu, Messages.SwiFunctionTable_5, table
+						.getSelectionCount() > 0);
+
+				contextMenu.setLocation(parent.toDisplay(e.x
+						+ table.getLocation().x, e.y + table.getLocation().y));
+				contextMenu.setVisible(true);
+
+				table.setMenu(contextMenu);
+			}
+		}
+	}
+
+	/**
+	 * columnselectionhandler for function table columns
+	 */
+	private class ColumnSelectionHandler extends SelectionAdapter {
+		public void widgetSelected(SelectionEvent e) {
+			if (!(e.widget instanceof TableColumn))
+				return;
+
+			sortOnColumnSelection((TableColumn) e.widget);
+		}
+	}
+
+	/**
+	 * @param tableColumn
+	 *            which column is sorted
+	 */
+	public void sortOnColumnSelection(TableColumn tableColumn) {
+		int columnID = ((Integer) tableColumn.getData()).intValue();
+		((SharedSorter) tableViewer.getSorter()).doSort(columnID);
+
+		this.refreshTableViewer();
+		this.table.redraw();
+	}
+
+	/**
+	 * Sorter for function column
+	 */
+	private class SharedSorter extends ViewerSorter {
+		// last column sorted
+		private int column = -1;
+
+		/**
+		 * decide on which column to sort by, and the sort ordering
+		 * 
+		 * @param column
+		 *            which column to sort
+		 */
+		public void doSort(int column) {
+			// ignore the column passed in and use the id set by the column
+			// selection handler
+			if (column == this.column) {
+				// sort in other order
+				sortAscending = !sortAscending;
+			} else {
+				// changed columns, so sort in the default order
+				switch (column) {
+				case COLOR_COLUMN_INDEX: {
+					// sort in ascending order
+					sortAscending = true;
+					break;
+				}
+				case COLUMN_ID_SWI_FUNCTION:
+				case COLUMN_ID_RETURN_ADDRESS:
+				case COLUMN_ID_SWI_COUNT: {
+					// sort in descending order
+					sortAscending = false;
+					break;
+				}
+				default: {
+					// ignore the column
+					return;
+				}
+				}
+				this.column = column;
+			}
+
+			// find the TableColumn corresponding to column, and give it a
+			// column direction
+			TableColumn sortByColumn = null;
+			for (int i = 0; i < table.getColumnCount(); i++) {
+				if (table.getColumn(i).getData() instanceof Integer) {
+					if (((Integer) table.getColumn(i).getData()) == column) {
+						sortByColumn = table.getColumn(i);
+						break;
+					}
+				}
+			}
+
+			if (sortByColumn != null) {
+				table.setSortColumn(sortByColumn);
+				table.setSortDirection(sortAscending ? SWT.UP : SWT.DOWN);
+			}
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see
+		 * org.eclipse.jface.viewers.ViewerComparator#compare(org.eclipse.jface
+		 * .viewers.Viewer, java.lang.Object, java.lang.Object)
+		 */
+		public int compare(Viewer viewer, Object e1, Object e2) {
+
+			// compare two items from a table column
+
+			int returnCode = 0;
+
+			IrqSampleTypeWrapper elem1 = (IrqSampleTypeWrapper) e1;
+			IrqSampleTypeWrapper elem2 = (IrqSampleTypeWrapper) e2;
+
+			// find the information for the two functions
+
+			// compare based on the function information
+			switch (column) {
+
+			// color column
+			case COLOR_COLUMN_INDEX:
+				if (tableViewer.getChecked(e1) == true
+						&& tableViewer.getChecked(e2) == false) {
+					returnCode = -1;
+				} else {
+					returnCode = 1;
+				}
+				break;
+			// function name column
+			case COLUMN_ID_SWI_FUNCTION:
+				if (elem1.getPrototypeSample().getFunction() != null
+						&& elem2.getPrototypeSample().getFunction() != null) {
+					returnCode = elem1.getPrototypeSample().getFunction().getFunctionName()
+							.compareToIgnoreCase(elem2.getPrototypeSample()
+									.getFunction().getFunctionName());
+				}
+				break;
+
+			// return address column
+			case COLUMN_ID_RETURN_ADDRESS:
+				if (elem1.getPrototypeSample().getFunction() != null) {
+					returnCode = elem1.getPrototypeSample().getFunction().getStartAddress() > elem2
+							.getPrototypeSample().getFunction().getStartAddress() ? 1
+							: -1;
+				}
+				break;
+
+			// interrupt count column
+			case COLUMN_ID_SWI_COUNT:
+				returnCode = elem1.count > elem2.count ? 1 : -1;
+				break;
+			default:
+				break;
+			}
+
+			// for descending order, reverse the sense of the compare
+			if (!sortAscending)
+				returnCode = -returnCode;
+
+			return returnCode;
+		}
+	}
+
+	/**
+	 * Action for opening color dialog for all selected functions.
+	 */
+	private void actionRecolor() {
+
+		// go thru selected items and open color dialog for each.
+		TableItem[] selection = table.getSelection();
+		for (TableItem item : selection) {
+
+			if (item.getData().getClass() == IrqSampleTypeWrapper.class) {
+
+				IrqSampleTypeWrapper wrapper = (IrqSampleTypeWrapper) item
+						.getData();
+				ColorDialog colorDialog = new ColorDialog(
+						this.table.getShell(), SWT.PRIMARY_MODAL);
+
+				// set name of the irq line as topic of the dialog
+				colorDialog.setText(IrqSampleTypeWrapper.getLineText(wrapper
+						.getPrototypeSample().getIrqL1Value()));
+				RGB color = colorDialog.open();
+
+				// if OK pressed, save new color into trace and set editor as
+				// dirty
+				if (color != null && color != wrapper.rgb) {
+
+					// ensure that color is not yet assigned for another
+					// thread/irq line
+					if (!myGraph.getIrqTrace().getColorSet().contains(color)) {
+						myGraph.getIrqTrace().changeColorOfThreadOrIRQLine(
+								wrapper, color);
+
+					} else {
+						// if same color was alreadyassigned for another
+						// thread/irq line, show error message
+						MessageBox errorDialog = new MessageBox(this.table
+								.getShell(), SWT.ICON_ERROR | SWT.OK);
+						errorDialog.setText(Messages.SwiFunctionTable_6);
+						errorDialog
+								.setMessage(Messages.SwiFunctionTable_7);
+						errorDialog.open();
+					}
+				}
+			}
+
+		}
+		this.myGraph.repaint();
+		this.refreshTableViewer();
+	}
+
+	/**
+	 * sets sort direction
+	 * 
+	 * @param sortAscending
+	 *            new sort direction
+	 */
+	public void setSortAscending(boolean sortAscending) {
+		this.sortAscending = sortAscending;
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.irq/src/com/nokia/carbide/cpp/pi/irq/SwiThreadLabelProvider.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2010 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: 
+ *
+ */
+
+package com.nokia.carbide.cpp.pi.irq;
+
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Table;
+import com.nokia.carbide.cpp.internal.pi.visual.GenericTable;
+
+/**
+ * Label provider for swi thread table
+ */
+public class SwiThreadLabelProvider extends LabelProvider implements
+		ITableLabelProvider {
+
+	/* thread table */
+	Table table;
+
+	/**
+	 * Constructor
+	 * 
+	 * @param table
+	 *            thread table
+	 */
+	public SwiThreadLabelProvider(Table table) {
+		super();
+		this.table = table;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java.lang
+	 * .Object, int)
+	 */
+	public String getColumnText(Object element, int columnIndex) {
+		int columnId = ((Integer) table.getColumn(columnIndex).getData())
+				.intValue();
+
+		switch (columnId) {
+		// thread name
+		case GenericTable.COLUMN_ID_SWI_THREAD:
+
+			if (element instanceof SwiThreadWrapper) {
+				SwiThreadWrapper profiledItem = (SwiThreadWrapper) element;
+				return profiledItem.threadName;
+			}
+			break;
+
+		// address
+		case GenericTable.COLUMN_ID_ADDRESS:
+			if (element instanceof SwiThreadWrapper) {
+				SwiThreadWrapper profiledItem = (SwiThreadWrapper) element;
+				return Messages.SwiThreadLabelProvider_0 + Long.toHexString(profiledItem.threadAddress);
+			}
+		default: {
+			break;
+		}
+		}
+		// should never get here
+		return ""; //$NON-NLS-1$
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang
+	 * .Object, int)
+	 */
+	public Image getColumnImage(Object element, int columnIndex) {
+		return null;
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.irq/src/com/nokia/carbide/cpp/pi/irq/SwiThreadTable.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,497 @@
+/*
+ * Copyright (c) 2010 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: 
+ *
+ */
+
+package com.nokia.carbide.cpp.pi.irq;
+
+import java.awt.event.MouseEvent;
+import java.util.Vector;
+import org.eclipse.jface.viewers.CheckStateChangedEvent;
+import org.eclipse.jface.viewers.CheckboxTableViewer;
+import org.eclipse.jface.viewers.ICheckStateListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.TableItem;
+import com.nokia.carbide.cpp.internal.pi.visual.GenericTable;
+
+/**
+ *	Software thread interrupt table 
+ */
+public class SwiThreadTable extends GenericTable implements ICheckStateListener {
+	
+	private IrqTraceGraph myGraph;
+	private Composite parent;
+	
+    protected Vector<SwiThreadWrapper> tableItemData;
+
+	// sort direction
+	private boolean sortAscending = true;
+	
+	/**
+	 * Constructor
+	 * @param myGraph irq graph
+	 * @param parent parent where table is placed
+	 */
+	public SwiThreadTable(IrqTraceGraph myGraph, Composite parent){
+		this.myGraph = myGraph;
+		this.parent  = parent;
+
+		this.tableViewer = CheckboxTableViewer.newCheckList(parent,
+  				SWT.BORDER | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION);
+		this.table = this.tableViewer.getTable();
+		
+		// add the check state handler, label provider and content provider
+		this.tableViewer.addCheckStateListener(this);
+		this.tableViewer.setLabelProvider(new SwiThreadLabelProvider(this.table));
+		this.tableViewer.setContentProvider(new TableContentProvider());
+		this.tableViewer.setSorter(new SharedSorter());
+
+		// create the columns
+		TableColumn column;
+
+		// data associated with the TableViewer will note which columns contain hex values
+		// Keep this in the order in which columns have been created
+		boolean[] isHex = {false, false, false, false};
+		this.table.setData("isHex", isHex); //$NON-NLS-1$
+
+		// Check column
+		column = new TableColumn(this.table, SWT.CENTER);
+		column.setText(Messages.SwiThreadTable_0);
+		column.setWidth(20);
+		column.setData(COLUMN_ID_SWI_CHECK);
+		column.setMoveable(true);
+		column.setResizable(true);
+		column.addSelectionListener(new ColumnSelectionHandler());
+		
+		// Thread Name column
+		column = new TableColumn(this.table, SWT.LEFT);
+		column.setText(Messages.SwiThreadTable_1);
+		column.setWidth(COLUMN_WIDTH_THREAD_IRQ_LINE);
+		column.setData(COLUMN_ID_SWI_THREAD);
+		column.setMoveable(true);
+		column.setResizable(true);
+		column.addSelectionListener(new ColumnSelectionHandler());
+
+		// Thread address
+		column = new TableColumn(tableViewer.getTable(), SWT.RIGHT);
+		column.setText(Messages.SwiThreadTable_2);
+		column.setWidth(COLUMN_WIDTH_ADDRESS_COUNT);
+		column.setData(COLUMN_ID_ADDRESS);
+		column.setMoveable(true);
+		column.setResizable(true);
+		column.addSelectionListener(new ColumnSelectionHandler());
+
+		// add mouse listener and set other table settings
+		this.table.addMouseListener(new TableMouseListener());
+		this.table.setHeaderVisible(true);
+		this.table.setLinesVisible(true);
+		this.table.setRedraw(true);
+		
+		// format data into table
+		this.updateItemData(true);
+		((SharedSorter) tableViewer.getSorter()).doSort(COLUMN_ID_SWI_THREAD);
+
+		// Select initially no lines
+		this.tableViewer.setAllChecked(false);
+		
+		// listen for key sequences such as Ctrl-A and Ctrl-C
+		table.addKeyListener(new TableKeyListener());
+		
+		tableViewer.refresh();
+		table.redraw();
+	}
+	
+	
+	/**
+	 * Content provider for table
+	 */
+	private static class TableContentProvider implements IStructuredContentProvider {
+		
+		/**
+		 * Constructor
+		 */
+		public TableContentProvider() {
+			super();
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
+		 */
+		@SuppressWarnings("unchecked")
+		public Object[] getElements(Object inputElement) {
+			return ((Vector<SwiThreadWrapper>) inputElement).toArray();
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * @see org.eclipse.jface.viewers.IContentProvider#dispose()
+		 */
+		public void dispose() {
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
+		 */
+		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+		}
+	}
+	
+	/*
+	 * (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.visual.GenericTable#action(java.lang.String)
+	 */
+	public void action(String actionString)
+	{
+		if (actionString.equals("add")){ //$NON-NLS-1$
+			checkOrUncheckSelectedItems(true);
+		}
+		else if (actionString.equals("remove")){ //$NON-NLS-1$
+			checkOrUncheckSelectedItems(false);
+		}
+		else if (actionString.equals("addall")){ //$NON-NLS-1$
+			checkOrUncheckAllItems(true);
+		}
+		else if (actionString.equals("removeall")){ //$NON-NLS-1$
+			checkOrUncheckAllItems(false);
+		}
+	    else if (actionString.equals("copy")) //$NON-NLS-1$
+	    {
+	    	actionCopyOrSave(true, this.table, CHECKBOX_TEXT, false, "\t", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
+	        return; // no redraw needed
+	    }
+	    else if (actionString.equals("copyTable")) //$NON-NLS-1$
+	    {
+	    	actionCopyOrSave(true, this.table, CHECKBOX_TEXT, true, "\t", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
+	        return; // no redraw needed
+	    }
+		else if (actionString.equals("selectAll")) //$NON-NLS-1$
+	    {
+	    	actionSelectAll();
+	        return;
+	    }
+		
+	    else if (actionString.equals("saveTable")) //$NON-NLS-1$
+	    {
+	    	actionCopyOrSave(false, this.table, CHECKBOX_TEXT, true, ",", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
+	        return; // no redraw needed
+	    }
+	}
+	
+	/**
+	 * Checks or unchecks all selected threads from table
+	 * @param value true if items are checked 
+	 */
+	private void checkOrUncheckSelectedItems(boolean value)
+	{
+		
+		TableItem[] selectedItems = this.table.getSelection();
+		for (int i = 0; i < selectedItems.length; i++)
+		{
+			if(selectedItems[i].getData().getClass() == SwiThreadWrapper.class){
+				selectedItems[i].setChecked(value);
+				SwiThreadWrapper wrapper = (SwiThreadWrapper)selectedItems[i].getData();
+				if(value){
+					myGraph.threadChecked(wrapper.threadName);
+				}
+				else{
+					myGraph.threadUnchecked(wrapper.threadName);
+
+				}
+			}
+		}
+		myGraph.updateIrqCountsInLegendsAsynch(IrqTraceGraph.TYPE_SWI);
+		myGraph.repaint();
+
+	}
+	
+	/**
+	 * Checks or unchecks all table items
+	 * @param value true if all items are checked
+	 */
+	private void checkOrUncheckAllItems(boolean value)
+	{
+		
+		TableItem[] allItems = this.table.getItems();
+		for (int i = 0; i < allItems.length; i++)
+		{
+			if(allItems[i].getData().getClass() == SwiThreadWrapper.class){
+				allItems[i].setChecked(value);
+				SwiThreadWrapper wrapper = (SwiThreadWrapper)allItems[i].getData();
+				if(value){
+					myGraph.threadChecked(wrapper.threadName);
+				}
+				else{
+					myGraph.threadUnchecked(wrapper.threadName);
+
+				}
+			}
+
+			
+		}
+		myGraph.repaint();
+		myGraph.updateIrqCountsInLegendsAsynch(IrqTraceGraph.TYPE_SWI);
+
+	}
+	
+	/**
+	 * Formats item data into table
+	 * @param setInput true if table needs to be refreshed
+	 */
+	public void updateItemData(boolean setInput)
+	{
+		tableItemData = ((IrqTrace)this.myGraph.getTrace()).getAllThreadWrappers();
+
+		// refresh the table, if needed
+		if (setInput)
+			refreshTableViewer();
+	}
+	
+	/**
+	 * Refreshes table viewer
+	 */
+	public void refreshTableViewer()
+	{
+		this.tableViewer.setInput(tableItemData);
+	}
+
+	/**
+	 * @return tableviewer of the thread table
+	 */
+	public CheckboxTableViewer getTableViewer(){
+		return this.tableViewer;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.jface.viewers.ICheckStateListener#checkStateChanged(org.eclipse.jface.viewers.CheckStateChangedEvent)
+	 */
+	public void checkStateChanged(CheckStateChangedEvent event) {
+		if(event.getElement().getClass() == SwiThreadWrapper.class){
+			SwiThreadWrapper wrapper = (SwiThreadWrapper) event.getElement();
+			if(event.getChecked()){
+				myGraph.threadChecked(wrapper.threadName);
+			}
+			else{
+				myGraph.threadUnchecked(wrapper.threadName);
+			}
+			myGraph.repaint();
+			myGraph.updateIrqCountsInLegendsAsynch(IrqTraceGraph.TYPE_SWI);
+			
+		}
+		
+	}
+	
+	/**
+	 * Mouse listener of the table
+	 */
+	private class TableMouseListener implements MouseListener
+	{
+		/*
+		 * (non-Javadoc)
+		 * @see org.eclipse.swt.events.MouseListener#mouseDoubleClick(org.eclipse.swt.events.MouseEvent)
+		 */
+		public void mouseDoubleClick(org.eclipse.swt.events.MouseEvent e) {
+			
+		}
+		
+		/*
+		 * (non-Javadoc)
+		 * @see org.eclipse.swt.events.MouseListener#mouseDown(org.eclipse.swt.events.MouseEvent)
+		 */
+		public void mouseDown(org.eclipse.swt.events.MouseEvent e) {
+		}
+		
+		/*
+		 * (non-Javadoc)
+		 * @see org.eclipse.swt.events.MouseListener#mouseUp(org.eclipse.swt.events.MouseEvent)
+		 */
+		public void mouseUp(org.eclipse.swt.events.MouseEvent e) {
+
+			if (e.button == MouseEvent.BUTTON3) {
+				// get rid of last Menu created so we don't have double menu
+				// on click
+				if (contextMenu != null) {
+					contextMenu.dispose();
+				}
+
+				contextMenu = new Menu(table.getShell(), SWT.POP_UP);
+				getCheckRows(contextMenu, table.getSelectionCount() > 0);
+				
+				
+				// select all, copy, and copy all
+				new MenuItem(contextMenu, SWT.SEPARATOR);
+				getSelectAllItem(contextMenu, table.getItemCount() > 0);
+				getCopyItem(contextMenu, table.getSelectionCount() > 0);
+				getCopyTableItem(contextMenu, table.getItemCount() > 0);
+
+				// save all
+				new MenuItem(contextMenu, SWT.SEPARATOR);
+				getSaveTableItem(contextMenu, table.getItemCount() > 0);
+				
+				// Recolor highlighted items
+				new MenuItem(contextMenu, SWT.SEPARATOR);
+				getRecolorItem(contextMenu, Messages.SwiThreadTable_3, table.getSelectionCount() > 0);
+
+				contextMenu.setLocation(parent.toDisplay(e.x + table.getLocation().x, e.y + table.getLocation().y));
+			    contextMenu.setVisible(true);
+
+			    table.setMenu(contextMenu);
+			}
+		}
+	}
+	
+	/**
+	 * Column selection handler for the table
+	 */
+	private class ColumnSelectionHandler extends SelectionAdapter
+	{
+		public void widgetSelected(SelectionEvent e)
+        {
+        	if (!(e.widget instanceof TableColumn))
+        		return;
+        	
+        	sortOnColumnSelection((TableColumn) e.widget);
+        }
+	}
+	
+	/**
+	 * @param tableColumn which column is sorted
+	 */
+	public void sortOnColumnSelection(TableColumn tableColumn) {
+    	int columnID = ((Integer) tableColumn.getData()).intValue();
+    	((SharedSorter) tableViewer.getSorter()).doSort(columnID);
+
+		this.refreshTableViewer();
+		this.table.redraw();
+	}
+	
+	/**
+	 * Sorter for the table
+	 */
+	private class SharedSorter extends ViewerSorter {
+		// last column sorted
+		private int column = -1;
+		
+		/* 
+		 * decide on which column to sort by, and the sort ordering
+		 */
+		public void doSort(int column) {
+			// ignore the column passed in and use the id set by the column selection handler
+			if (column == this.column) {
+				// sort in other order
+				sortAscending = !sortAscending;
+			} else {
+				// changed columns, so sort in the default order
+				switch (column) {
+					case COLUMN_ID_SWI_CHECK:
+					{
+		            	// sort in ascending order
+		            	sortAscending = true;
+		                break;
+					}
+					case COLUMN_ID_SWI_THREAD:
+					case COLUMN_ID_ADDRESS:
+					{
+		            	// sort in descending order
+		            	sortAscending = false;
+		                break;
+					}
+					default:
+					{
+						// ignore the column
+						return;
+					}
+				}
+				this.column = column;
+			}
+
+			// find the TableColumn corresponding to column, and give it a column direction
+			TableColumn sortByColumn = null;
+			for (int i = 0; i < table.getColumnCount(); i++) {
+				if (table.getColumn(i).getData() instanceof Integer) {
+					if (((Integer)table.getColumn(i).getData()) == column) {
+						sortByColumn = table.getColumn(i);
+						break;
+					}
+				}
+			}
+
+			if (sortByColumn != null) {
+				table.setSortColumn(sortByColumn);
+				table.setSortDirection(sortAscending ? SWT.UP : SWT.DOWN);
+			}
+		}
+		
+		/*
+		 * compare two items from a table column
+		 */
+		public int compare(Viewer viewer, Object e1, Object e2) {
+			int returnCode = 0;
+			
+			SwiThreadWrapper elem1 = (SwiThreadWrapper)e1;
+			SwiThreadWrapper elem2 = (SwiThreadWrapper)e2;
+
+			// find the memory information for the two threads
+			
+			// compare based on the memory information
+			switch (column) {
+			case COLUMN_ID_SWI_CHECK:
+				if(tableViewer.getChecked(e1) == true && tableViewer.getChecked(e2) == false){
+					returnCode = -1;
+				}
+				else{
+					returnCode = 1;
+				}
+				break;
+			case COLUMN_ID_SWI_THREAD:
+				returnCode = elem1.threadName.compareToIgnoreCase(elem2.threadName);
+				break;
+			case COLUMN_ID_ADDRESS:
+				returnCode = elem1.threadAddress > elem2.threadAddress ? 1 : -1;
+				break;
+			default:
+				break;
+			}
+
+			// for descending order, reverse the sense of the compare
+			if (!sortAscending)
+				returnCode = -returnCode;
+
+			return returnCode;
+		}
+	}
+	
+	
+	/**
+	 * sets sort direction
+	 * @param sortAscending new sort direction
+	 */
+	public void setSortAscending(boolean sortAscending) {
+		this.sortAscending = sortAscending;
+	}
+	
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.irq/src/com/nokia/carbide/cpp/pi/irq/SwiThreadWrapper.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2010 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: 
+ *
+ */
+
+package com.nokia.carbide.cpp.pi.irq;
+
+import java.io.Serializable;
+
+/**
+ * Wrapper for swi threads
+ */
+public class SwiThreadWrapper implements Serializable {
+	/**
+	 * Serial version uid
+	 */
+	private static final long serialVersionUID = -377498088520328159L;
+
+	/* address of the thread */
+	public Long threadAddress;
+
+	/* name of the thread */
+	public String threadName;
+
+	/**
+	 * Ddefault constructor
+	 */
+	public SwiThreadWrapper() {
+	}
+
+	/**
+	 * Constructor
+	 * 
+	 * @param threadName
+	 *            name of the thread
+	 * @param threadAddress
+	 *            address of the thread
+	 */
+	public SwiThreadWrapper(String threadName, Long threadAddress) {
+		this.threadName = threadName;
+		this.threadAddress = threadAddress;
+	}
+
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.irq/src/com/nokia/carbide/cpp/pi/irq/messages.properties	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,47 @@
+IrqLineTable_0=
+IrqLineTable_1=IRQ line
+IrqLineTable_2=Count
+IrqLineTable_3=recolor
+IrqLineTable_4=IRQ lines
+IrqLineTable_5=Change denied
+IrqLineTable_6=Selected color is already assigned for another IRQ line/function.
+IrqPlugin_0=IRQ
+IrqPlugin_1=com.nokia.s60tools.bappea.model.IrqTrace
+IrqPlugin_2=com.nokia.carbide.cpp.pi.irq.IrqTrace
+IrqPlugin_3=com.nokia.s60tools.bappea.model.IrqSample
+IrqPlugin_4=com.nokia.carbide.cpp.pi.irq.IrqSample
+IrqPlugin_5=Hardware / software interrupt
+IrqSample_0=Symbol
+IrqSampleTypeWrapper_0=
+IrqSampleTypeWrapper_1=IRQ interrupt L1 0x
+IrqTrace_0=Thread object at 0x
+IrqTrace_1=threadname
+IrqTrace_2=address
+IrqTrace_3=Thread object at 0x
+IrqTrace_4=
+IrqTrace_5=
+IrqTrace_6=Testi 
+IrqTraceGraph_0=Interrupts
+IrqTraceGraph_1=No function names found from the data file.\nCorrect symbol files are needed in order to view software interrupts.
+IrqTraceGraph_2=To view interrupts, select threads from the interrupts table.
+IrqTraceGraph_3=To view interrupts, select irq lines from the interrupts table.
+IrqTraceGraph_4=/ms
+IrqTraceGraph_5=Interrupts
+IrqTraceGraph_6=Software interrupts
+IrqTraceGraph_7=Hardware interrupts
+SwiFunctionLabelProvider_0=Function for address 0x
+SwiFunctionLabelProvider_1=\ not found
+SwiFunctionLabelProvider_2=0x
+SwiFunctionTable_0=
+SwiFunctionTable_1=SWI Function
+SwiFunctionTable_2=Return Address
+SwiFunctionTable_3=Count
+SwiFunctionTable_4=recolor
+SwiFunctionTable_5=IRQ lines
+SwiFunctionTable_6=Change denied
+SwiFunctionTable_7=Selected color is already assigned for another IRQ line/function.
+SwiThreadLabelProvider_0=0x
+SwiThreadTable_0=\ 
+SwiThreadTable_1=Thread
+SwiThreadTable_2=Address
+SwiThreadTable_3=IRQ lines
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.memory/META-INF/MANIFEST.MF	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.memory/META-INF/MANIFEST.MF	Wed Apr 21 15:14:16 2010 +0300
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: Carbide.c++ Performance Investigator Memory Usage
 Bundle-SymbolicName: com.nokia.carbide.cpp.pi.memory;singleton:=true
-Bundle-Version: 1.5.0.qualifier
+Bundle-Version: 2.3.0.qualifier
 Bundle-Activator: com.nokia.carbide.cpp.pi.memory.MemoryPlugin
 Bundle-Vendor: Nokia
 Require-Bundle: org.eclipse.ui,
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.memory/src/com/nokia/carbide/cpp/internal/pi/memory/actions/MemoryStatisticsDialog.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.memory/src/com/nokia/carbide/cpp/internal/pi/memory/actions/MemoryStatisticsDialog.java	Wed Apr 21 15:14:16 2010 +0300
@@ -232,9 +232,9 @@
 
 	private static String showTimeInterval(double startTime, double endTime)
 	{
-		return ProfileVisualiser.timeFormat.format(startTime)
-		     + Messages.getString("MemoryStatisticsDialog.interval1") + ProfileVisualiser.timeFormat.format(endTime) //$NON-NLS-1$
-		     + Messages.getString("MemoryStatisticsDialog.interval2") + ProfileVisualiser.timeFormat.format(endTime - startTime) //$NON-NLS-1$
+		return ProfileVisualiser.TIME_FORMAT.format(startTime)
+		     + Messages.getString("MemoryStatisticsDialog.interval1") + ProfileVisualiser.TIME_FORMAT.format(endTime) //$NON-NLS-1$
+		     + Messages.getString("MemoryStatisticsDialog.interval2") + ProfileVisualiser.TIME_FORMAT.format(endTime - startTime) //$NON-NLS-1$
 		     + Messages.getString("MemoryStatisticsDialog.interval3"); //$NON-NLS-1$
 	}
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.memory/src/com/nokia/carbide/cpp/pi/memory/LibraryEventColorPalette.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2010 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: 
+ *
+ */
+
+package com.nokia.carbide.cpp.pi.memory;
+
+import org.eclipse.swt.graphics.RGB;
+
+import com.nokia.carbide.cpp.pi.util.TableColorPalette;
+
+public class LibraryEventColorPalette extends TableColorPalette{
+
+	@Override
+	public RGB getConstantRGB(Object entry) {
+		// use random colors
+		return null;
+	}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.memory/src/com/nokia/carbide/cpp/pi/memory/MemLibraryEventTable.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,942 @@
+/*
+ * Copyright (c) 2010 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: 
+ *
+ */
+
+package com.nokia.carbide.cpp.pi.memory;
+
+import java.awt.Toolkit;
+import java.awt.datatransfer.Clipboard;
+import java.awt.datatransfer.StringSelection;
+import java.awt.event.ActionEvent;
+import java.awt.event.FocusEvent;
+import java.awt.event.MouseEvent;
+import java.text.DecimalFormat;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import java.util.Vector;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.ActionContributionItem;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IContributionManager;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.SubMenuManager;
+import org.eclipse.jface.viewers.CheckStateChangedEvent;
+import org.eclipse.jface.viewers.CheckboxTableViewer;
+import org.eclipse.jface.viewers.ICheckStateListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.FocusListener;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.TableItem;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.actions.ActionFactory;
+import org.eclipse.ui.ide.IIDEActionConstants;
+
+import com.nokia.carbide.cpp.internal.pi.interfaces.ISaveSamples;
+import com.nokia.carbide.cpp.internal.pi.memory.actions.MemoryStatisticsDialog;
+import com.nokia.carbide.cpp.internal.pi.model.ProfiledGeneric;
+import com.nokia.carbide.cpp.internal.pi.visual.GenericTable;
+import com.nokia.carbide.cpp.internal.pi.visual.PIEvent;
+import com.nokia.carbide.cpp.pi.editors.PIPageEditor;
+import com.nokia.carbide.cpp.pi.util.TableColorPalette;
+
+
+public class MemLibraryEventTable extends GenericTable
+{
+	private static final int COLUMN_ID_LIB_LOAD_SIZE  = 14;
+	private static final int COLUMN_ID_LIB_SELECTION_COUNT   = 16;
+	private static final int COLUMN_ID_LIB_NAME    = 17;
+
+	// sort direction
+	private boolean sortAscending = true;
+	
+	private MemTraceGraph myGraph;
+	private Composite parent;
+
+	// override
+    protected Vector<ProfiledLibraryEvent> tableItemData;
+
+    // menu items
+	private Action selectAllAction;
+	private Action copyTableAction;
+	private Action copyAction;
+	private Action saveTableAction;
+	
+	// class to pass sample data to the save wizard
+    public class SaveSampleString implements ISaveSamples {
+    	boolean done = false;
+    	
+    	public SaveSampleString() {
+		}
+
+    	public String getData() {
+    		if (done)
+    			return null;
+    		
+			String returnString = getSampleString();
+			done = true;
+			return returnString;
+		}
+
+		public String getData(int size) {
+			return getData();
+		}
+
+		public int getIndex() {
+			return done ? 1 : 0;
+		}
+
+		public void clear() {
+			done = false;
+		}
+    }
+
+	/*
+	 * return the library event samples selected in the interval 
+	 */
+	protected String getSampleString()
+	{
+		int startTime = (int) (PIPageEditor.currentPageEditor().getStartTime() * 1000.0 + 0.0005);
+		int endTime   = (int) (PIPageEditor.currentPageEditor().getEndTime()   * 1000.0 + 0.0005);
+		
+		TreeMap<Long, ArrayList<MemSample>> sorted = new TreeMap<Long, ArrayList<MemSample>>();		
+		Enumeration<ProfiledLibraryEvent> enume = myGraph.getMemTrace().getLibraryEvents().elements();
+		while(enume.hasMoreElements()){
+			ProfiledLibraryEvent ple = enume.nextElement();	
+			Iterator<MemSample> iterator = ple.getMemSamples().values().iterator();
+			while(iterator.hasNext()) {
+				MemSample memSample = iterator.next();
+				ArrayList<MemSample> memList = sorted.get(memSample.sampleSynchTime);
+				if(memList == null){
+					memList = new ArrayList<MemSample>();
+				}
+				memList.add(memSample);		
+				sorted.put(memSample.sampleSynchTime, memList);
+			}			
+		}
+		SortedMap<Long, ArrayList<MemSample>> selectionAreaMap = sorted.subMap((long)startTime, (long)endTime);
+		Iterator<ArrayList<MemSample>> iterator = selectionAreaMap.values().iterator();
+		String returnString = Messages.getString("MemLibraryEventTable.saveSamplesHeading"); //$NON-NLS-1$
+		
+		while (iterator.hasNext()) {
+			ArrayList<MemSample> memSamples = iterator.next();
+			for(MemSample memSample : memSamples){
+				if (memSample.thread.isEnabled(myGraph.getGraphIndex())) {
+					String libraryName = myGraph.getMemTrace()
+							.getLibraryNameString(memSample.thread.fullName);
+					String process = myGraph.getMemTrace()
+							.getProcessFromLibraryNameString(
+									memSample.thread.fullName);
+					returnString += memSample.sampleSynchTime
+							+ Messages.getString("MemLibraryEventTable.comma") //$NON-NLS-1$
+							+ libraryName
+							+ Messages.getString("MemLibraryEventTable.comma") //$NON-NLS-1$
+							+ process
+							+ Messages.getString("MemLibraryEventTable.comma") //$NON-NLS-1$
+							+ ((memSample.heapSize + 512) / 1024)
+							+ Messages.getString("MemLibraryEventTable.comma") //$NON-NLS-1$
+							+ memSample.sampleNum + "\n"; //$NON-NLS-1$
+
+				}
+			}			
+		}
+		return returnString;
+	}
+
+	protected MenuItem getSaveSamplesItem(Menu menu, boolean enabled) {
+	    MenuItem saveSamplesItem = new MenuItem(menu, SWT.PUSH);
+
+		saveSamplesItem.setText(Messages.getString("MemLibraryEventTable.saveCheckedSamples")); //$NON-NLS-1$
+		saveSamplesItem.setEnabled(enabled);
+		
+		if (enabled) {
+			saveSamplesItem.addSelectionListener(new SelectionAdapter() { 
+				public void widgetSelected(SelectionEvent e) {
+					action("saveSamples"); //$NON-NLS-1$
+				}
+			});
+		}
+	
+		return saveSamplesItem;
+	}
+
+	public MemLibraryEventTable(MemTraceGraph myGraph, Composite parent)
+	{
+		Composite composite = new Composite(parent, SWT.NONE);
+		GridLayout gl = new GridLayout();
+		gl.marginHeight = 0;
+		gl.marginWidth = 0;
+		gl.marginLeft = 0;
+		gl.marginRight = 0;	
+		composite.setLayout(gl);
+		this.myGraph = myGraph;
+		this.parent  = composite;
+
+		Label label = new Label(composite, SWT.CENTER);
+		label
+				.setBackground(composite.getDisplay().getSystemColor(
+						SWT.COLOR_WHITE));
+		label.setFont(PIPageEditor.helvetica_8);
+		label.setText(Messages.getString("MemLibraryEventTable.title"));  //$NON-NLS-1$
+		
+		label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+		this.tableViewer = CheckboxTableViewer.newCheckList(composite,
+  				SWT.BORDER | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION);
+		this.table = this.tableViewer.getTable();
+		this.table.setLayoutData(new GridData(GridData.FILL_BOTH));
+		
+		// add the check state handler, label provider and content provider
+		this.tableViewer.addCheckStateListener(new CheckHandler());
+		this.tableViewer.setLabelProvider(new SharedLabelProvider(this.table));
+		this.tableViewer.setContentProvider(new MemoryTableContentProvider());
+		this.tableViewer.setSorter(new SharedSorter());
+		
+		// give the table a heading for possible use in copying and exported
+		this.table.setData(Messages.getString("MemLibraryEventTable.library"));  //$NON-NLS-1$
+		
+		// create the columns
+		TableColumn column;
+
+		// data associated with the TableViewer will note which columns contain hex values
+		// Keep this in the order in which columns have been created
+		boolean[] isHex = {false, false, false, false};
+		this.table.setData("isHex", isHex); //$NON-NLS-1$
+		
+		// select/deselect column
+		column = new TableColumn(this.table, SWT.CENTER);
+		column.setText(COLUMN_HEAD_SHOW);
+		column.setWidth(COLUMN_WIDTH_SHOW);
+		column.setData(Integer.valueOf(COLUMN_ID_SHOW));
+		column.setMoveable(true);
+		column.setResizable(true);
+		column.addSelectionListener(new ColumnSelectionHandler());
+
+
+		column = new TableColumn(this.table, SWT.LEFT);
+		column.setText(COLUMN_HEAD_LIBRARY_NAME);
+		column.setWidth(COLUMN_WIDTH_LIBRARY_NAME ); 
+		column.setData(Integer.valueOf(COLUMN_ID_LIB_NAME));
+		column.setMoveable(true);
+		column.setResizable(true);
+		column.addSelectionListener(new ColumnSelectionHandler());
+		
+		
+		column = new TableColumn(tableViewer.getTable(), SWT.RIGHT);
+		column.setText(COLUMN_HEAD_LIBRARY_LOAD_SIZE);
+		column.setWidth(COLUMN_WIDTH_LIBRARY_LOAD_SIZE);
+		column.setData(Integer.valueOf(COLUMN_ID_LIB_LOAD_SIZE));
+		column.setMoveable(true);
+		column.setResizable(true);
+		column.addSelectionListener(new ColumnSelectionHandler());
+				
+		column = new TableColumn(tableViewer.getTable(), SWT.RIGHT);
+		column.setText(COLUMN_HEAD_LIBRARY_SELECTION_LOAD_COUNT);
+		column.setWidth(COLUMN_WIDTH_LIBRARY_SELECTION_COUNT);
+		column.setData(Integer.valueOf(COLUMN_ID_LIB_SELECTION_COUNT));
+		column.setMoveable(true);
+		column.setResizable(true);
+		column.addSelectionListener(new ColumnSelectionHandler());
+		
+		// initially, all rows are checked
+		this.tableViewer.setAllChecked(true);
+
+		this.table.addMouseListener(new TableMouseListener());
+		
+		// set background color for the first column
+		this.table.addListener(SWT.EraseItem, new Listener() {
+			public void handleEvent(Event event) {			
+				TableItem item = (TableItem)event.item;			
+				ProfiledLibraryEvent ple = (ProfiledLibraryEvent)item.getData();
+				GC gc = event.gc;
+		        gc.setForeground(ple.getColor());
+			    gc.setBackground(ple.getColor());
+			    gc.fillRectangle(item.getBounds(COLOR_COLUMN_INDEX));
+			}			
+		});
+		
+		this.table.setHeaderVisible(true);
+		this.table.setLinesVisible(true);
+		this.table.setRedraw(true);
+		updateItemData(true);
+		((SharedSorter) tableViewer.getSorter()).doSort(COLUMN_ID_LIB_NAME);
+
+		// initially, all rows are checked
+		this.tableViewer.setAllChecked(true);
+		
+		createDefaultActions();
+
+		// listen for key sequences such as Ctrl-A and Ctrl-C
+		table.addKeyListener(new TableKeyListener());
+		
+		table.addFocusListener(new FocusListener() {
+			IAction oldSelectAllAction = null;
+			IAction oldCopyAction = null;
+
+			public void focusGained(org.eclipse.swt.events.FocusEvent arg0) {
+				IActionBars bars = PIPageEditor.getActionBars();
+				
+				oldSelectAllAction = PIPageEditor.getActionBars().getGlobalActionHandler(ActionFactory.SELECT_ALL.getId());
+				oldCopyAction = PIPageEditor.getActionBars().getGlobalActionHandler(ActionFactory.COPY.getId());
+
+				bars.setGlobalActionHandler(ActionFactory.COPY.getId(), copyAction);
+				bars.setGlobalActionHandler(ActionFactory.SELECT_ALL.getId(), selectAllAction);
+
+				copyAction.setEnabled(table.getSelectionCount() > 0);
+				selectAllAction.setEnabled(table.getItemCount() > 0);
+				bars.updateActionBars();
+				
+				// add to the Edit menu
+		        IMenuManager editMenuManager = bars.getMenuManager().findMenuUsingPath(IIDEActionConstants.M_EDIT);
+
+		        if (editMenuManager instanceof SubMenuManager)
+		        {
+		        	IContributionManager editManager = ((SubMenuManager)editMenuManager).getParent();
+		        	ActionContributionItem item;
+
+					editMenuManager.remove("PICopyTable"); //$NON-NLS-1$
+		        	copyTableAction.setEnabled(table.getItemCount() > 0);
+		        	item = new ActionContributionItem(copyTableAction);
+		        	item.setVisible(true);
+		        	editManager.prependToGroup(IIDEActionConstants.CUT_EXT, item);
+		        }
+				
+				// add to the File menu
+		        IMenuManager fileMenuManager = bars.getMenuManager().findMenuUsingPath(IIDEActionConstants.M_FILE);
+
+		        if (fileMenuManager instanceof SubMenuManager)
+		        {
+		        	IContributionManager fileManager = ((SubMenuManager)fileMenuManager).getParent();
+		        	ActionContributionItem item;
+
+		        	fileMenuManager.remove("PISaveTable"); //$NON-NLS-1$
+		        	saveTableAction.setEnabled(table.getItemCount() > 0);
+		        	item = new ActionContributionItem(saveTableAction);
+		        	item.setVisible(true);
+		        	fileManager.insertAfter("saveAll", item); //$NON-NLS-1$
+		        }
+			}
+
+			public void focusLost(org.eclipse.swt.events.FocusEvent arg0) {
+				IActionBars bars = PIPageEditor.getActionBars();
+				bars.setGlobalActionHandler(ActionFactory.COPY.getId(), oldCopyAction);
+				bars.setGlobalActionHandler(ActionFactory.SELECT_ALL.getId(), oldSelectAllAction);
+				bars.updateActionBars();
+
+				SubMenuManager editMenuManager = (SubMenuManager) PIPageEditor.getMenuManager().find(IIDEActionConstants.M_EDIT);
+				editMenuManager.remove("PICopyTable"); //$NON-NLS-1$
+				editMenuManager.update();
+
+				SubMenuManager fileMenuManager = (SubMenuManager) PIPageEditor.getMenuManager().find(IIDEActionConstants.M_FILE);
+				fileMenuManager.remove("PISaveTable"); //$NON-NLS-1$
+				fileMenuManager.update();
+			}
+		});
+		tableViewer.refresh();
+		table.redraw();
+	}
+
+	private class TableMouseListener implements MouseListener
+	{
+		public void mouseDoubleClick(org.eclipse.swt.events.MouseEvent e) {
+			if (e.button == MouseEvent.BUTTON1)
+			{
+				TableItem[] selectedItems = table.getSelection();
+				if (selectedItems.length == 0)
+					return;
+
+				if (selectedItems[0].getData() instanceof ProfiledLibraryEvent)
+				{
+					ProfiledLibraryEvent ple = (ProfiledLibraryEvent)(selectedItems[0].getData());
+				    if (ple.isEnabled(myGraph.getGraphIndex()))
+				        action("remove"); //$NON-NLS-1$
+				    else
+				        action("add"); //$NON-NLS-1$
+				}
+			}
+			selectAllAction.setEnabled(table.getItemCount() > 0);
+			copyAction.setEnabled(table.getSelectionCount() > 0);
+			copyTableAction.setEnabled(table.getItemCount() > 0);
+		}
+
+		public void mouseDown(org.eclipse.swt.events.MouseEvent e) {
+		}
+
+		public void mouseUp(org.eclipse.swt.events.MouseEvent e) {
+
+			selectAllAction.setEnabled(table.getItemCount() > 0);
+			copyAction.setEnabled(table.getSelectionCount() > 0);
+			copyTableAction.setEnabled(table.getItemCount() > 0);
+
+			if (e.button == MouseEvent.BUTTON3) {
+				// get rid of last Menu created so we don't have double menu
+				// on click
+				if (contextMenu != null) {
+					contextMenu.dispose();
+				}			
+				contextMenu = new Menu(table.getShell(), SWT.POP_UP);
+				getCheckRows(contextMenu, table.getSelectionCount() > 0);
+
+				// select all, copy, and copy all
+				new MenuItem(contextMenu, SWT.SEPARATOR);
+				getSelectAllItem(contextMenu, table.getItemCount() > 0);
+				getCopyItem(contextMenu, table.getSelectionCount() > 0);
+				getCopyTableItem(contextMenu, table.getItemCount() > 0);
+				selectAllAction.setEnabled(table.getItemCount() > 0);
+				copyAction.setEnabled(table.getSelectionCount() > 0);
+				copyTableAction.setEnabled(table.getItemCount() > 0);
+				
+				// save all
+				new MenuItem(contextMenu, SWT.SEPARATOR);
+				getSaveTableItem(contextMenu, table.getItemCount() > 0);
+				saveTableAction.setEnabled(table.getItemCount() > 0);
+
+				// save samples
+				int startTime = (int) (PIPageEditor.currentPageEditor().getStartTime() * 1000.0f);
+				int endTime   = (int) (PIPageEditor.currentPageEditor().getEndTime()   * 1000.0f);
+
+				getSaveSamplesItem(contextMenu,
+					myGraph.haveEnabled() && (startTime != -1) && (endTime != -1) && (startTime != endTime));
+
+				contextMenu.setLocation(parent.toDisplay(e.x + table.getLocation().x, e.y + table.getLocation().y));
+			    contextMenu.setVisible(true);
+
+				if(table.getSelectionCount() > 0){
+					// add recolor menu item
+					new MenuItem(contextMenu, SWT.SEPARATOR);
+					getRecolorItem(contextMenu,"Library",true); //$NON-NLS-1$
+				}
+				new MenuItem(contextMenu, SWT.SEPARATOR);
+
+				MenuItem memoryStatsItem = new MenuItem(contextMenu, SWT.PUSH);
+				memoryStatsItem.setText(Messages.getString("MemoryPlugin.memoryStats")); //$NON-NLS-1$
+				memoryStatsItem.addSelectionListener(new SelectionAdapter() {
+					public void widgetSelected(SelectionEvent e) {
+						new MemoryStatisticsDialog(Display.getCurrent());
+					}
+				});
+			
+				
+
+				table.setMenu(contextMenu);
+			}
+		}
+	}
+
+	private static class MemoryTableContentProvider implements IStructuredContentProvider {
+
+		public MemoryTableContentProvider() {
+			super();
+		}
+
+		public Object[] getElements(Object inputElement) {
+			return ((Vector<ProfiledLibraryEvent>) inputElement).toArray();
+		}
+
+		public void dispose() {
+		}
+
+		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+		}
+	}
+
+	private class CheckHandler implements ICheckStateListener
+	{
+		public void checkStateChanged(CheckStateChangedEvent event) {
+
+       		if (!(event.getElement() instanceof ProfiledLibraryEvent))
+       			return;
+       		
+       		// set the stored value to the checkbox value
+       		ProfiledLibraryEvent ple = (ProfiledLibraryEvent)event.getElement();
+       		ple.setEnabled(myGraph.getGraphIndex(), event.getChecked());
+       		myGraph.repaint();
+       		
+       		table.deselectAll();       		
+		}
+	}
+
+	void selectionChangeNotify() {
+		this.tableViewer.refresh();
+		this.table.redraw();		
+		PIEvent be = new PIEvent(null, PIEvent.CHANGED_LIBRARY_TABLE);
+		piEventReceived(be);
+    }
+
+	private class SharedLabelProvider extends LabelProvider implements ITableLabelProvider {
+		
+        private DecimalFormat decimalFormat = new DecimalFormat(Messages.getString("MemThreadTable.kbFormat")); //$NON-NLS-1$
+
+        Table table;
+
+		public SharedLabelProvider(Table table) {
+			super();
+			this.table = table;
+		}
+
+		public String getColumnText(Object element, int columnIndex) {
+	        int columnId = ((Integer) table.getColumn(columnIndex).getData()).intValue();
+
+			if (!(element instanceof ProfiledLibraryEvent))
+				return ""; //$NON-NLS-1$
+
+			ProfiledLibraryEvent profiledItem = (ProfiledLibraryEvent) element;			
+			MemThread mt = profiledItem.getLastMemThread();
+			
+			switch (columnId)
+			{
+				case COLUMN_ID_LIB_NAME:
+				{
+					return profiledItem.getNameString();
+				}
+				case COLUMN_ID_LIB_LOAD_SIZE:
+			    {
+					double startTime = PIPageEditor.currentPageEditor().getStartTime();
+					double endTime   = PIPageEditor.currentPageEditor().getEndTime();
+
+					if ((startTime == -1) || (endTime   == -1) || (startTime == endTime))
+						return ""; //$NON-NLS-1$
+
+					return decimalFormat.format((mt.maxMemoryItem.maxChunks + 512)/1024);
+			    }
+				case COLUMN_ID_LIB_SELECTION_COUNT:
+			    {	     	
+					double startTime = PIPageEditor.currentPageEditor().getStartTime();
+					double endTime   = PIPageEditor.currentPageEditor().getEndTime();
+
+					if ((startTime == -1) || (endTime   == -1) || (startTime == endTime))
+						return ""; //$NON-NLS-1$	
+					
+					return Long.toString(mt.maxMemoryItem.maxTotal);
+					
+			    }
+				default:
+				{
+					break;
+				}
+			}
+			// should never get here
+			return ""; //$NON-NLS-1$
+		}
+
+		public Image getColumnImage(Object element, int columnIndex) {
+			return null;
+		}
+	}
+
+	/*
+	 * TableViewer sorter for the called-by and called function tableviewers
+	 */
+	private class SharedSorter extends ViewerSorter {
+		// last column sorted
+		private int column = -1;
+		
+		/* 
+		 * decide on which column to sort by, and the sort ordering
+		 */
+		public void doSort(int column) {
+			// ignore the column passed in and use the id set by the column selection handler
+			if (column == this.column) {
+				// sort in other order
+				sortAscending = !sortAscending;
+			} else {
+				// changed columns, so sort in the default order
+				switch (column) {									
+					case COLUMN_ID_LIB_NAME:
+					{
+		            	// sort in ascending order
+		            	sortAscending = true;
+		                break;
+					}
+					case COLUMN_ID_SHOW:
+					case COLUMN_ID_LIB_LOAD_SIZE:
+					case COLUMN_ID_LIB_SELECTION_COUNT:
+					{
+		            	// sort in descending order
+		            	sortAscending = false;
+		                break;
+					}
+					default:
+					{
+						// ignore the column
+						return;
+					}
+				}
+				this.column = column;
+			}
+
+			// find the TableColumn corresponding to column, and give it a column direction
+			TableColumn sortByColumn = null;
+			for (int i = 0; i < table.getColumnCount(); i++) {
+				if (table.getColumn(i).getData() instanceof Integer) {
+					if (((Integer)table.getColumn(i).getData()) == column) {
+						sortByColumn = table.getColumn(i);
+						break;
+					}
+				}
+			}
+
+			if (sortByColumn != null) {
+				table.setSortColumn(sortByColumn);
+				table.setSortDirection(sortAscending ? SWT.UP : SWT.DOWN);
+			}
+		}
+		
+		/*
+		 * compare two items from a table column
+		 */
+		public int compare(Viewer viewer, Object e1, Object e2) {
+			int returnCode = 0;
+			
+			// find the library information for the two threads
+			MemThread elem1 = ((ProfiledLibraryEvent)e1).getLastMemThread();
+			MemThread elem2 = ((ProfiledLibraryEvent)e2).getLastMemThread();
+
+			// compare based on the library information
+			switch (column) {
+			case COLUMN_ID_SHOW:				
+				boolean first = ((ProfiledLibraryEvent)e1).isEnabled(myGraph.getGraphIndex());
+				boolean second = ((ProfiledLibraryEvent)e2).isEnabled(myGraph.getGraphIndex());
+				if(first == second){
+					returnCode = 0;
+				}else if(first == true && second == false){
+					returnCode = 1;
+				}else{
+					returnCode = -1;
+				}	
+				break;
+				
+			case COLUMN_ID_LIB_LOAD_SIZE:			
+				returnCode = elem1.maxMemoryItem.maxChunks >
+									elem2.maxMemoryItem.maxChunks ? 1 : -1;
+				break;
+			case COLUMN_ID_LIB_SELECTION_COUNT:
+				returnCode = elem1.maxMemoryItem.maxTotal >
+									elem2.maxMemoryItem.maxTotal ? 1 : -1;
+				break;
+			case COLUMN_ID_LIB_NAME:
+			{				
+				returnCode = this.getComparator().compare(((ProfiledLibraryEvent)e1).getNameString(), ((ProfiledLibraryEvent)e2).getNameString());
+				break;
+			}
+			default:
+				break;
+			}
+
+			// for descending order, reverse the sense of the compare
+			if (!sortAscending)
+				returnCode = -returnCode;
+				
+			return returnCode;
+		}
+	}
+
+	public void actionPerformed(ActionEvent e) {}
+	
+	public void action(String actionString)
+	{
+		int graphIndex = this.myGraph.getGraphIndex();
+
+		if (   actionString.equals("add") //$NON-NLS-1$
+			|| actionString.equals("remove")) //$NON-NLS-1$
+	    {
+			actionAddRemove(actionString, graphIndex);
+	    }
+		else if (   actionString.equals("addall") //$NON-NLS-1$
+				 || actionString.equals("removeall")) //$NON-NLS-1$
+	    {
+			actionAddRemoveAll(actionString, graphIndex);
+	    }
+	    else if (actionString.equals("copy")) //$NON-NLS-1$
+	    {
+	    	actionCopyOrSave(true, this.table, CHECKBOX_TEXT, false, "\t", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
+	        return; // no redraw needed
+	    }
+	    else if (actionString.equals("copyTable")) //$NON-NLS-1$
+	    {
+	    	actionCopyOrSave(true, this.table, CHECKBOX_TEXT, true, "\t", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
+	        return; // no redraw needed
+	    }
+		else if (actionString.equals("selectAll")) //$NON-NLS-1$
+	    {
+	    	actionSelectAll();
+	        return;
+	    }
+	    else if (actionString.equals("saveTable")) //$NON-NLS-1$
+	    {
+	    	actionCopyOrSave(false, this.table, CHECKBOX_TEXT, true, ",", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
+	        return; // no redraw needed
+	    }
+	    else if (actionString.equals("saveSamples")) //$NON-NLS-1$
+	    {
+	    	SaveSampleString saveSampleString = new SaveSampleString();
+	    	actionSaveSamples(saveSampleString); //$NON-NLS-1$
+	        return;
+	    }
+	    else if (actionString.equals("saveTableTest")) //$NON-NLS-1$
+	    {
+			// copy save file contents to the clipboard for easy viewing
+	        Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
+			SaveTableString getString = new SaveTableString(this.table, CHECKBOX_TEXT, ",", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
+	        String copyString = getString.getData();
+			StringSelection contents = new StringSelection(copyString);
+	        cb.setContents(contents, contents);
+	        return;
+	    }
+	    else if (actionString.equals("recolor")) //$NON-NLS-1$
+		{
+			actionRecolor();
+			return;
+		}
+		
+		tableViewer.refresh();
+	    table.redraw();
+	    this.myGraph.repaint();
+	}
+
+	private void actionAddRemove(String actionString, int graphIndex)
+	{
+		ProfiledLibraryEvent ple;
+		
+		// true for "add", false for "remove"
+		boolean addIt = actionString.equals("add"); //$NON-NLS-1$
+
+		TableItem[] selectedItems = this.table.getSelection();
+		for (int i = 0; i < selectedItems.length; i++)
+		{
+			selectedItems[i].setChecked(addIt);
+			ple = (ProfiledLibraryEvent)((TableItem)selectedItems[i]).getData();
+			ple.setEnabled(graphIndex, addIt);
+		}
+
+        // this table's set of checkbox-selected rows has changed,
+		// so propagate that information
+  		if (selectedItems.length != 0)
+   			selectionChangeNotify();
+
+  		this.table.deselectAll();
+	}
+	
+	private void actionAddRemoveAll(String actionString, int graphIndex)
+	{
+		ProfiledLibraryEvent ple;
+
+		// true for "add", false for "remove"
+		boolean addIt = actionString.equals("addall"); //$NON-NLS-1$
+
+		TableItem[] selectedItems = this.table.getItems();
+		for (int i = 0; i < selectedItems.length; i++)
+		{
+			selectedItems[i].setChecked(addIt);
+			ple = (ProfiledLibraryEvent)((TableItem)selectedItems[i]).getData();
+			ple.setEnabled(graphIndex, addIt);		
+		}
+
+        // this table's set of checkbox-selected rows has changed,
+		// so propagate that information
+		selectionChangeNotify();
+
+		this.table.deselectAll();
+	}
+
+	public void focusGained(FocusEvent e) {}
+
+	public void focusLost(FocusEvent e)	{}
+
+	public void piEventReceived(PIEvent be) 
+	{
+	    if (be.getType() == PIEvent.SELECTION_AREA_CHANGED2)
+		{
+			this.tableViewer.refresh();
+			this.table.redraw();
+		}
+	    else if (be.getType() == PIEvent.CHANGED_LIBRARY_TABLE)
+		{
+			this.tableViewer.refresh();
+			this.table.redraw();
+			
+		}
+	}
+
+	public void updateItemData(boolean setInput)
+	{
+		
+		if (tableItemData == null)
+			tableItemData = new Vector<ProfiledLibraryEvent>();
+		else
+			tableItemData.clear();		
+		
+		Iterator<ProfiledLibraryEvent> iterator = myGraph.getMemTrace().getLibraryEvents().values().iterator();
+		
+		while(iterator.hasNext()){			
+			tableItemData.add(iterator.next());
+		}
+		// refresh the table, if needed
+		if (setInput)
+			refreshTableViewer();
+	}
+
+	public void refreshTableViewer()
+	{
+		this.tableViewer.setInput(tableItemData);
+	}
+	
+	public void sortOnColumnSelection(TableColumn tableColumn) {
+    	int columnID = ((Integer) tableColumn.getData()).intValue();
+    	((SharedSorter) tableViewer.getSorter()).doSort(columnID);
+    	tableViewer.refresh();
+	}
+	
+	private class ColumnSelectionHandler extends SelectionAdapter
+	{
+		public void widgetSelected(SelectionEvent e)
+        {
+        	if (!(e.widget instanceof TableColumn))
+        		return;
+        	sortOnColumnSelection((TableColumn) e.widget);
+        }
+	}
+	
+	public CheckboxTableViewer getTableViewer()
+	{
+		return this.tableViewer;
+	}
+
+	protected void createDefaultActions()
+	{
+		selectAllAction = new Action("SelectAll") { //$NON-NLS-1$
+			public void run() {
+				action("selectAll"); //$NON-NLS-1$
+			}
+		};
+		selectAllAction.setEnabled(true);
+
+		copyAction = new Action("Copy") { //$NON-NLS-1$
+			public void run() {
+				action("copy"); //$NON-NLS-1$
+			}
+		};
+		copyAction.setEnabled(false);
+
+		copyTableAction = new Action("CopyTable") { //$NON-NLS-1$
+			public void run() {
+				action("copyTable"); //$NON-NLS-1$
+			}
+		};
+		copyTableAction.setEnabled(true);
+		copyTableAction.setId("PICopyTable"); //$NON-NLS-1$
+		copyTableAction.setText(Messages.getString("MemThreadTable.copyTable")); //$NON-NLS-1$
+
+		saveTableAction = new Action("SaveTable") { //$NON-NLS-1$
+			public void run() {
+				action("saveTable"); //$NON-NLS-1$
+			}
+		};
+		saveTableAction.setEnabled(true);
+		saveTableAction.setId("PISaveTable"); //$NON-NLS-1$
+		saveTableAction.setText(Messages.getString("MemThreadTable.SaveTable")); //$NON-NLS-1$
+	}
+	
+	public void updateSelection(Object[] checked){
+		
+		actionAddRemoveAll("removeall", myGraph.getGraphIndex());	 //$NON-NLS-1$
+		Vector<ProfiledLibraryEvent> select = new Vector<ProfiledLibraryEvent>();
+		for(Object o : checked){
+			MemThread mt = (MemThread) o;
+			
+			int index = mt.fullName.indexOf("::$CODE"); //$NON-NLS-1$
+			if(index != -1){
+				// if code chunk is selected
+				String process = mt.fullName.substring(0, index);
+				for(ProfiledLibraryEvent ple :tableItemData){
+					Iterator<MemSample> iterator = ple.getMemSamples().values().iterator();
+					while(iterator.hasNext()) {
+						MemSample memSample = iterator.next();
+						if(memSample.thread.fullName.contains(process)){
+							ple.setEnabled(myGraph.getGraphIndex(), true);
+							select.add(ple);
+							break;
+						}
+					}
+					
+				}
+			}	
+		}	
+		tableViewer.setCheckedElements(select.toArray());
+		selectionChangeNotify();
+		
+	}
+	
+	private void actionRecolor()
+	{
+		// recolor selected items
+		boolean didRecolor = false;
+
+		TableItem[] selectedItems = table.getSelection();
+		TableColorPalette palette = ((MemTrace)this.myGraph.getTrace()).getLibraryEventColorPalette();
+		for (int i = 0; i < selectedItems.length;i++)
+		{
+			if (selectedItems[i].getData() instanceof ProfiledGeneric)
+			{
+				ProfiledGeneric pGeneric = (ProfiledGeneric)selectedItems[i].getData();
+				String nameKey = pGeneric.getNameString();
+				if (palette.recolorEntryDialog(table.getShell(), nameKey))
+				{
+					Color color = palette.getColor(nameKey);
+					Color oldColor = pGeneric.getColor();
+					
+					if (color.equals(oldColor))
+						continue;
+					
+					didRecolor = true;					
+					pGeneric.setColor(color);
+				}
+				// recoloring should only be done in a draw mode that displays this table's colors
+				selectedItems[i].setBackground(COLOR_COLUMN_INDEX, palette.getColor(nameKey));
+			}
+		}
+		
+		if (!didRecolor)
+			return;
+
+		table.redraw();
+		this.myGraph.repaint();
+	}
+}
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.memory/src/com/nokia/carbide/cpp/pi/memory/MemSample.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.memory/src/com/nokia/carbide/cpp/pi/memory/MemSample.java	Wed Apr 21 15:14:16 2010 +0300
@@ -50,4 +50,14 @@
 		this.type = type;
 		this.sampleSynchTime = sampleNum;
 	}
+	
+	public MemSample(MemThread thread, int libSize, int libCount, int libThread, int sampleNum, int type)
+	{
+		this.thread = thread;
+		this.heapSize = libSize;
+		this.stackSize = libThread;
+		this.sampleNum = libCount;
+		this.type = type;
+		this.sampleSynchTime = sampleNum;
+	}
 }
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.memory/src/com/nokia/carbide/cpp/pi/memory/MemThreadTable.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.memory/src/com/nokia/carbide/cpp/pi/memory/MemThreadTable.java	Wed Apr 21 15:14:16 2010 +0300
@@ -25,8 +25,12 @@
 import java.awt.event.MouseEvent;
 import java.text.DecimalFormat;
 import java.util.ArrayList;
+import java.util.Enumeration;
 import java.util.HashSet;
+import java.util.Hashtable;
 import java.util.Iterator;
+import java.util.SortedMap;
+import java.util.TreeMap;
 import java.util.Vector;
 
 import org.eclipse.jface.action.Action;
@@ -50,8 +54,10 @@
 import org.eclipse.swt.events.SelectionEvent;
 import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.Menu;
 import org.eclipse.swt.widgets.MenuItem;
 import org.eclipse.swt.widgets.Table;
@@ -130,57 +136,99 @@
 		int endTime   = (int) (PIPageEditor.currentPageEditor().getEndTime()   * 1000.0 + 0.0005);
 		
 		MemTrace trace = this.myGraph.getMemTrace();
-		ArrayList<MemSampleByTime> drawDataByTime = trace.getDrawDataByTime();
-		
-		if (drawDataByTime == null || drawDataByTime.size() == 0)
-			return "";	// should have been checked so this never happens //$NON-NLS-1$
-		
-		String returnString = Messages.getString("MemThreadTable.saveSamplesHeading"); //$NON-NLS-1$
-
-		if (drawDataByTime.get(0).getTime() > startTime) {
-			int graphIndex = this.myGraph.getGraphIndex();
-			TableItem[] items = this.table.getItems();
+		if(trace.getVersion() >= 202){
+			String returnString = Messages.getString("MemThreadTable.saveSamplesHeading"); //$NON-NLS-1$
+	
+			TreeMap<Long, ArrayList<MemSample>> sorted = new TreeMap<Long, ArrayList<MemSample>>();		
+			Enumeration<TreeMap<Long, MemSample>> enume = trace.getDrawDataByMemThread().elements();
+			while(enume.hasMoreElements()){
+				TreeMap<Long, MemSample> map = enume.nextElement();	
+				Iterator<MemSample> iterator = map.values().iterator();
+				while(iterator.hasNext()) {
+					MemSample memSample = iterator.next();
+					ArrayList<MemSample> memList = sorted.get(memSample.sampleSynchTime);
+					if(memList == null){
+						memList = new ArrayList<MemSample>();
+					}
+					memList.add(memSample);		
+					sorted.put(memSample.sampleSynchTime, memList);
+				}			
+			}
+			
+			SortedMap<Long, ArrayList<MemSample>> selectionAreaMap = sorted.subMap((long)startTime, (long)endTime);
+			Iterator<ArrayList<MemSample>> iterator = selectionAreaMap.values().iterator();
+						
+			while (iterator.hasNext()) {
+				ArrayList<MemSample> memSamples = iterator.next();
+				for(MemSample memSample : memSamples){
+					if (memSample.thread.isEnabled(myGraph.getGraphIndex()) && !memSample.thread.fullName.equals("TOTAL_MEMORY::TOTAL_MEMORY_-1162089814")) {
+						
+						returnString += memSample.sampleSynchTime
+								+ Messages.getString("MemThreadTable.comma") //$NON-NLS-1$
+								+ memSample.thread.fullName							
+								+ Messages.getString("MemThreadTable.comma") //$NON-NLS-1$
+								+ ((memSample.heapSize + 512)/1024)
+								+ Messages.getString("MemThreadTable.comma") //$NON-NLS-1$
+								+ ((memSample.stackSize + 512)/1024) + "\n"; //$NON-NLS-1$
+					}
+				}			
+			}
+			
+			return returnString;
+		}else{
+			ArrayList<MemSampleByTime> drawDataByTime = trace.getDrawDataByTime();
+			
+			if (drawDataByTime == null || drawDataByTime.size() == 0)
+				return "";	// should have been checked so this never happens //$NON-NLS-1$
 			
-			for (int i = 0; i < items.length; i++) {
-				Object data = items[i].getData();
-				
-				if (!(data instanceof MemThread))
-					continue;
+			String returnString = Messages.getString("MemThreadTable.saveSamplesHeading"); //$NON-NLS-1$
+
+			if (drawDataByTime.get(0).getTime() > startTime) {
+				int graphIndex = this.myGraph.getGraphIndex();
+				TableItem[] items = this.table.getItems();
 				
-				MemThread pmt = (MemThread) data;
-				
-				if (!pmt.enabled[graphIndex])
-					continue;
-				
-				returnString +=   Messages.getString("MemThreadTable.notRecorded1") + items[i].getText() + Messages.getString("MemThreadTable.notRecorded2"); //$NON-NLS-1$ //$NON-NLS-2$
+				for (int i = 0; i < items.length; i++) {
+					Object data = items[i].getData();
+					
+					if (!(data instanceof MemThread))
+						continue;
+					
+					MemThread pmt = (MemThread) data;
+					
+					if (!pmt.enabled[graphIndex])
+						continue;
+					
+					returnString +=   Messages.getString("MemThreadTable.notRecorded1") + items[i].getText() + Messages.getString("MemThreadTable.notRecorded2"); //$NON-NLS-1$ //$NON-NLS-2$
+				}
 			}
+			
+			// find least sampling time greater than or equal to the start time
+			int i = 0;
+			long sampleTime = 0;
+			for ( ; i < drawDataByTime.size(); i++)	{
+				sampleTime = drawDataByTime.get(i).getTime(); 
+				if (sampleTime > startTime)
+					break;
+			}
+			
+			if (i != 0)
+				i--;
+
+			int graphIndex = myGraph.getGraphIndex();
+			for ( ; i < drawDataByTime.size() && drawDataByTime.get(i).getTime() <= endTime; i++) {
+				ArrayList<MemSample> samples = drawDataByTime.get(i).getSamples();
+				for (MemSample sample : samples) {
+					if (!sample.thread.enabled[graphIndex])
+						continue;
+						
+					returnString +=   sample.sampleSynchTime + Messages.getString("MemThreadTable.comma") + sample.thread.fullName //$NON-NLS-1$
+									+ Messages.getString("MemThreadTable.comma") + (sample.heapSize / 1024) + Messages.getString("MemThreadTable.comma") + (sample.stackSize / 1024) + "\n"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+				}
+			}
+
+			return returnString;
 		}
-		
-		// find least sampling time greater than or equal to the start time
-		int i = 0;
-		long sampleTime = 0;
-		for ( ; i < drawDataByTime.size(); i++)	{
-			sampleTime = drawDataByTime.get(i).getTime(); 
-			if (sampleTime > startTime)
-				break;
-		}
-		
-		if (i != 0)
-			i--;
-
-		int graphIndex = myGraph.getGraphIndex();
-		for ( ; i < drawDataByTime.size() && drawDataByTime.get(i).getTime() <= endTime; i++) {
-			ArrayList<MemSample> samples = drawDataByTime.get(i).getSamples();
-			for (MemSample sample : samples) {
-				if (!sample.thread.enabled[graphIndex])
-					continue;
-					
-				returnString +=   sample.sampleSynchTime + Messages.getString("MemThreadTable.comma") + sample.thread.fullName //$NON-NLS-1$
-								+ Messages.getString("MemThreadTable.comma") + (sample.heapSize / 1024) + Messages.getString("MemThreadTable.comma") + (sample.stackSize / 1024) + "\n"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-			}
-		}
-
-		return returnString;
+	
 	}
 
 	protected MenuItem getSaveSamplesItem(Menu menu, boolean enabled) {
@@ -202,10 +250,27 @@
 
 	public MemThreadTable(MemTraceGraph myGraph, Composite parent)
 	{
+		Composite composite = new Composite(parent, SWT.NONE);
+		GridLayout gl = new GridLayout();
+		gl.marginHeight = 0;
+		gl.marginWidth = 0;
+		gl.marginLeft = 0;
+		gl.marginRight = 0;	
+		composite.setLayout(gl);
 		this.myGraph = myGraph;
-		this.parent  = parent;
+		this.parent  = composite;
 
-		this.tableViewer = CheckboxTableViewer.newCheckList(parent,
+		Label label = new Label(composite, SWT.CENTER);
+		label
+				.setBackground(composite.getDisplay().getSystemColor(
+						SWT.COLOR_WHITE));
+		label.setFont(PIPageEditor.helvetica_8);
+		label.setText(Messages.getString("MemThreadTable.title")); //$NON-NLS-1$
+		
+		label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		
+
+		this.tableViewer = CheckboxTableViewer.newCheckList(composite,
   				SWT.BORDER | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION);
 		this.table = this.tableViewer.getTable();
 		this.table.setLayoutData(new GridData(GridData.FILL_BOTH));
@@ -231,7 +296,7 @@
 		column = new TableColumn(this.table, SWT.CENTER);
 		column.setText(COLUMN_HEAD_MEMORY_NAME);
 		column.setWidth(COLUMN_WIDTH_MEMORY_NAME + 15); // extra space for the checkbox
-		column.setData(new Integer(COLUMN_ID_MEMORY_NAME));
+		column.setData(Integer.valueOf(COLUMN_ID_MEMORY_NAME));
 		column.setMoveable(true);
 		column.setResizable(true);
 		column.addSelectionListener(new ColumnSelectionHandler());
@@ -239,7 +304,7 @@
 		column = new TableColumn(tableViewer.getTable(), SWT.RIGHT);
 		column.setText(COLUMN_HEAD_MEMORY_CHUNKS);
 		column.setWidth(COLUMN_WIDTH_MEMORY_CHUNKS);
-		column.setData(new Integer(COLUMN_ID_MEMORY_CHUNKS));
+		column.setData(Integer.valueOf(COLUMN_ID_MEMORY_CHUNKS));
 		column.setMoveable(true);
 		column.setResizable(true);
 		column.addSelectionListener(new ColumnSelectionHandler());
@@ -247,7 +312,7 @@
 		column = new TableColumn(tableViewer.getTable(), SWT.RIGHT);
 		column.setText(COLUMN_HEAD_MEMORY_STACK);
 		column.setWidth(COLUMN_WIDTH_MEMORY_STACK);
-		column.setData(new Integer(COLUMN_ID_MEMORY_STACK));
+		column.setData(Integer.valueOf(COLUMN_ID_MEMORY_STACK));
 		column.setMoveable(true);
 		column.setResizable(true);
 		column.addSelectionListener(new ColumnSelectionHandler());
@@ -255,7 +320,7 @@
 		column = new TableColumn(tableViewer.getTable(), SWT.RIGHT);
 		column.setText(COLUMN_HEAD_MEMORY_TOTAL);
 		column.setWidth(COLUMN_WIDTH_MEMORY_TOTAL);
-		column.setData(new Integer(COLUMN_ID_MEMORY_TOTAL));
+		column.setData(Integer.valueOf(COLUMN_ID_MEMORY_TOTAL));
 		column.setMoveable(true);
 		column.setResizable(true);
 		column.addSelectionListener(new ColumnSelectionHandler());
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.memory/src/com/nokia/carbide/cpp/pi/memory/MemTrace.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.memory/src/com/nokia/carbide/cpp/pi/memory/MemTrace.java	Wed Apr 21 15:14:16 2010 +0300
@@ -18,15 +18,13 @@
 package com.nokia.carbide.cpp.pi.memory;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Enumeration;
 import java.util.HashSet;
 import java.util.Hashtable;
 import java.util.Iterator;
 import java.util.SortedMap;
 import java.util.TreeMap;
-import java.util.Map.Entry;
-
-import org.eclipse.draw2d.IFigure;
 
 import com.nokia.carbide.cpp.internal.pi.analyser.NpiInstanceRepository;
 import com.nokia.carbide.cpp.internal.pi.model.GenericSampledTrace;
@@ -65,9 +63,15 @@
 	transient private Hashtable<String, TreeMap<Long, MemSample>> drawDataByMemThread = null;
 	transient private ArrayList<MemSampleByTime> drawDataByTime;
 	transient private HashSet<MemThread> noDuplicateMemThreads;
-
+	
+	transient private Hashtable<String, ProfiledLibraryEvent> drawDataByLibraryEvent = null;
+	transient private TreeMap<Long, ArrayList<MemSample>> drawLibraryEventDataByTime = null;
+	
+    transient private LibraryEventColorPalette libraryEventColorPalette = null;
 	transient private long intervalStart = -1;
 	transient private long intervalEnd = -1;
+	
+	
 
 	private int version;
 
@@ -76,10 +80,6 @@
 		lastSynchTimes = new Hashtable<Integer, Integer>();
 	}
 
-	public void addSample(MemSample sample) {
-		this.samples.add(sample);
-	}
-
 	public MemSample getMemSample(int number) {
 		return (MemSample) this.samples.elementAt(number);
 	}
@@ -206,7 +206,12 @@
 				if (memSample.thread.threadId == 0xffffffffbabbeaaaL) {
 					usedMemory = memSample.heapSize;
 					freeMemory = memSample.stackSize;
-					memSample = (MemSample) e.nextElement();
+					if(e.hasMoreElements()){
+						memSample = (MemSample) e.nextElement();
+					}
+					else{
+						break;
+					}
 				}
 
 				// the 2nd sample in each time period has memory model and
@@ -214,7 +219,13 @@
 				if (memSample.thread.threadId == 0xffffffffbabbea20L) {
 					usedMemory = memSample.heapSize;
 					freeMemory = memSample.stackSize;
-					memSample = (MemSample) e.nextElement();
+					if(e.hasMoreElements()){
+						memSample = (MemSample) e.nextElement();
+					}
+					else{
+						break;
+					}
+					
 				}
 
 				// Create MemSampleByTime object based on sample
@@ -269,8 +280,11 @@
 	public void gatherEventBasedDrawData() {
 		if (drawDataByMemThread != null)
 			return; // already initialised
+		drawDataByMemThread = new Hashtable<String, TreeMap<Long, MemSample>>();
+		if(version >= 203){
+			drawDataByLibraryEvent = new Hashtable<String, ProfiledLibraryEvent>();
+		}
 
-		drawDataByMemThread = new Hashtable<String, TreeMap<Long, MemSample>>();
 		memoryModel = MemTrace.MEMORY_UNKNOWN;
 		getThreadsFromTrace();
 
@@ -295,7 +309,12 @@
 					usedMemory = memSample.heapSize;
 					freeMemory = memSample.stackSize;
 					addSampleToThread(memSample);
-					memSample = (MemSample) e.nextElement();
+					if(e.hasMoreElements()){
+						memSample = (MemSample) e.nextElement();
+					}
+					else{
+						break;
+					}
 
 				}
 
@@ -326,6 +345,18 @@
 
 	private void addSampleToThread(MemSample sample) {
 
+		if (version >= 203) {
+			String library = getLibraryNameString(sample.thread.fullName);
+			if (library != null) {
+				ProfiledLibraryEvent ple = drawDataByLibraryEvent.get(library);
+				if (ple != null) {
+					// Add initial sample to library event
+					ple.addMemSample(sample);
+					return;
+				}
+			}
+
+		}
 		// get sample array from thread
 		TreeMap<Long, MemSample> samples = drawDataByMemThread
 				.get(sample.thread.fullName);
@@ -342,7 +373,7 @@
 			return;
 		}
 
-		System.out.println("PI ERROR: Thread not found");
+		System.out.println("PI ERROR: Thread not found"); //$NON-NLS-1$
 
 	}
 
@@ -355,7 +386,7 @@
 		// data
 		for (MemThread memThread : threads) {
 			String processedThreadName = memThread.threadName;
-
+			boolean libraryEvent = false;
 			// Add Thread ID into processedThreadName
 			// looking for _T and _C suffixes and remove them for thread
 			if (processedThreadName.endsWith("_T")) //$NON-NLS-1$
@@ -367,7 +398,12 @@
 				processedThreadName = processedThreadName.substring(0,
 						processedThreadName.length() - 2)
 						+ " [0x" + Integer.toHexString(memThread.threadId) + "]"; //$NON-NLS-1$ //$NON-NLS-2$
-			} else {
+			} else if (processedThreadName.endsWith("_L")) { //$NON-NLS-1$
+				processedThreadName = processedThreadName.substring(0,
+						processedThreadName.length() - 2)
+						+ " [0x" + Integer.toHexString(memThread.threadId) + "]"; //$NON-NLS-1$ //$NON-NLS-2$
+				libraryEvent = true;
+			}else {
 				processedThreadName += "_" + memThread.threadId; //$NON-NLS-1$
 			}
 
@@ -385,10 +421,19 @@
 			memThread.maxMemoryItem.maxStackHeap = 0;
 			memThread.maxMemoryItem.maxTotal = 0;
 
-			if (drawDataByMemThread.get(memThread.fullName) == null) {
-				drawDataByMemThread.put(memThread.fullName,
-						new TreeMap<Long, MemSample>());
-				noDuplicateMemThreads.add(memThread);
+			if (libraryEvent) {
+				String name = getLibraryNameString(memThread.fullName);
+				if (drawDataByLibraryEvent.get(name) == null) {
+					ProfiledLibraryEvent ple = new ProfiledLibraryEvent(name);
+					ple.setColor(getLibraryEventColorPalette().getColor(name));
+					drawDataByLibraryEvent.put(name, ple);
+				}
+			} else {
+				if (drawDataByMemThread.get(memThread.fullName) == null) {
+					drawDataByMemThread.put(memThread.fullName,
+							new TreeMap<Long, MemSample>());
+					noDuplicateMemThreads.add(memThread);
+				}
 			}
 		}
 
@@ -397,8 +442,24 @@
 	public TreeMap<Long, MemSample> getDrawDataByMemThread(MemThread id) {
 		return this.drawDataByMemThread.get(id.fullName);
 	}
+	
+	public Hashtable<String, TreeMap<Long, MemSample>> getDrawDataByMemThread() {
+		return this.drawDataByMemThread;
+	}
 
 	public ArrayList<MemSampleByTime> getDrawDataByTime() {
+		if (drawDataByTime.isEmpty() && getVersion() >= 202) {
+			TreeMap<Long, MemSample> events = drawDataByMemThread
+					.get("TOTAL_MEMORY::TOTAL_MEMORY_-1162089814"); //$NON-NLS-1$
+
+			Iterator<MemSample> iterator = events.values().iterator();
+			while (iterator.hasNext()) {
+				MemSample memSample = iterator.next();
+				drawDataByTime.add(new MemSampleByTime(
+						memSample.sampleSynchTime, memSample.stackSize
+								+ memSample.heapSize, memSample.heapSize));
+			}
+		}
 		return this.drawDataByTime;
 	}
 
@@ -434,7 +495,7 @@
 
 		if (this.getVersion() >= 202) {
 			TreeMap<Long, MemSample> events = drawDataByMemThread
-					.get("TOTAL_MEMORY::TOTAL_MEMORY_-1162089814");
+					.get("TOTAL_MEMORY::TOTAL_MEMORY_-1162089814"); //$NON-NLS-1$
 
 			Iterator<MemSample> values = events.values().iterator();
 
@@ -625,6 +686,16 @@
 
 		return;
 	}
+		
+	public void setMaxMemLibraryEventDataByInterval(long startTime, long endTime) {
+		// update memory usage for each library event that are used during the time slot
+		for (Enumeration<ProfiledLibraryEvent> e = drawDataByLibraryEvent
+				.elements(); e.hasMoreElements();) {
+			ProfiledLibraryEvent ple = (ProfiledLibraryEvent) e
+					.nextElement();
+			ple.updateSelection(startTime, endTime);
+		}
+	}
 
 	public long getMemoryModel() {
 		return this.memoryModel;
@@ -652,5 +723,92 @@
 		}
 
 	}
+	
+	public Hashtable<String, ProfiledLibraryEvent> getLibraryEvents(){
+		return drawDataByLibraryEvent;
+	}
+	
+	public LibraryEventColorPalette getLibraryEventColorPalette(){
+		if(libraryEventColorPalette == null){
+			libraryEventColorPalette = new LibraryEventColorPalette();
+		}
+		return libraryEventColorPalette;
+	}
+	
+	
+	public ArrayList<MemSample> getLibraryEventDataByTime(int graphIndex, long time, long scale) {
+		if(drawLibraryEventDataByTime == null){
+			// find library events by time
+			drawLibraryEventDataByTime = new TreeMap<Long, ArrayList<MemSample>>();
+			Iterator<ProfiledLibraryEvent> iterator = drawDataByLibraryEvent.values().iterator();
+			while(iterator.hasNext()){	
+				ProfiledLibraryEvent ple = iterator.next();	
+				Iterator<MemSample> iteratorMem = ple.getMemSamples().values().iterator();
+				while(iteratorMem.hasNext()){
+					MemSample memSample = iteratorMem.next();
+					ArrayList<MemSample> memSamples = drawLibraryEventDataByTime.get(memSample.sampleSynchTime);
+					if(memSamples == null){
+						memSamples = new ArrayList<MemSample>();
+					}
+					memSamples.add(memSample);					
+					drawLibraryEventDataByTime.put(memSample.sampleSynchTime, memSamples);
+				}		
+			}
+		}		
+		
+		ArrayList<MemSample> retMemSamples = new ArrayList<MemSample>();
+		ArrayList<MemSample> bestChoice = null;
+		scale = (long)scale * 5;
+		
+		if(scale == 0){
+			bestChoice = drawLibraryEventDataByTime.get(time);
+		} else {	
+			SortedMap<Long, ArrayList<MemSample>> sortedMap = drawLibraryEventDataByTime
+					.subMap(time - scale, time + scale);
+			long min = Long.MAX_VALUE;
+			long closest = time;
+			for (Long key : sortedMap.keySet()) {
+				final long diff = Math.abs(key - time);
+				if (diff < min) {
+					Iterator<MemSample> iterator = sortedMap.get(key).iterator();
+					while(iterator.hasNext()){
+						MemSample memSample = iterator.next();
+						if(memSample.thread.isEnabled(graphIndex)){
+							min = diff;
+							closest = key;
+						}
+					}					
+				}
+			}
+			bestChoice = sortedMap.get(closest);			
+		}
+		if(bestChoice != null){
+			Iterator<MemSample> iterator = bestChoice.iterator();
+			while(iterator.hasNext()){
+				MemSample memSample = iterator.next();
+				if(memSample.thread.isEnabled(graphIndex)){
+					retMemSamples.add(memSample);
+				}
+			}
+		}
+		return retMemSamples;
+	}	
+	
+	public String getLibraryNameString(String fullName){
+		int startIndex = fullName.indexOf("::") + 2; //$NON-NLS-1$
+		int lastIndex = fullName.indexOf(" ["); //$NON-NLS-1$
+		if(startIndex != -1 && lastIndex != -1){
+			return fullName.substring(startIndex, lastIndex);
+		}
+		return null;
+	}
+	
+	public String getProcessFromLibraryNameString(String fullName){
+		int lastIndex = fullName.indexOf("::"); //$NON-NLS-1$
+		if(lastIndex != -1){
+			return fullName.substring(0, lastIndex);
+		}
+		return null;
+	}
 
 }
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.memory/src/com/nokia/carbide/cpp/pi/memory/MemTraceGraph.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.memory/src/com/nokia/carbide/cpp/pi/memory/MemTraceGraph.java	Wed Apr 21 15:14:16 2010 +0300
@@ -21,12 +21,13 @@
 import java.awt.event.FocusEvent;
 import java.awt.event.FocusListener;
 import java.text.DecimalFormat;
+import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.Enumeration;
 import java.util.Hashtable;
 import java.util.Iterator;
+import java.util.List;
 import java.util.TreeMap;
-import java.util.Map.Entry;
 
 import org.eclipse.draw2d.ColorConstants;
 import org.eclipse.draw2d.FigureCanvas;
@@ -34,8 +35,11 @@
 import org.eclipse.draw2d.MouseEvent;
 import org.eclipse.draw2d.MouseMotionListener;
 import org.eclipse.draw2d.Panel;
+import org.eclipse.draw2d.geometry.PointList;
+import org.eclipse.jface.action.Action;
 import org.eclipse.jface.viewers.CheckboxTableViewer;
 import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.SashForm;
 import org.eclipse.swt.events.SelectionAdapter;
 import org.eclipse.swt.events.SelectionEvent;
 import org.eclipse.swt.graphics.Color;
@@ -43,28 +47,36 @@
 import org.eclipse.swt.graphics.Point;
 import org.eclipse.swt.graphics.RGB;
 import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.layout.FormLayout;
 import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
 import org.eclipse.swt.widgets.Menu;
 import org.eclipse.swt.widgets.MenuItem;
+import org.eclipse.swt.widgets.Sash;
+import org.eclipse.ui.PlatformUI;
 
 import com.nokia.carbide.cpp.internal.pi.analyser.NpiInstanceRepository;
 import com.nokia.carbide.cpp.internal.pi.memory.actions.MemoryStatisticsDialog;
 import com.nokia.carbide.cpp.internal.pi.model.GenericSampledTrace;
 import com.nokia.carbide.cpp.internal.pi.plugin.model.IContextMenu;
+import com.nokia.carbide.cpp.internal.pi.plugin.model.ITitleBarMenu;
 import com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph;
 import com.nokia.carbide.cpp.internal.pi.visual.GraphComposite;
 import com.nokia.carbide.cpp.internal.pi.visual.PIEvent;
 import com.nokia.carbide.cpp.internal.pi.visual.PIEventListener;
 import com.nokia.carbide.cpp.pi.editors.PIPageEditor;
+import com.nokia.carbide.cpp.pi.memory.ProfiledLibraryEvent.GraphSamplePoint;
 import com.nokia.carbide.cpp.pi.util.ColorPalette;
+import com.nokia.carbide.cpp.pi.visual.IGenericTraceGraph;
 
 public class MemTraceGraph extends GenericTraceGraph implements FocusListener,
-		PIEventListener, MouseMotionListener, IContextMenu {
+		PIEventListener, MouseMotionListener, IContextMenu, ITitleBarMenu {
 	private enum UsageType {
 		CHUNKS, HEAPSTACK, CHUNKS_HEAPSTACK
 	};
@@ -72,6 +84,7 @@
 	private boolean dynamicMemoryVisualisation = false;
 
 	private MemThreadTable memThreadTable;
+	private MemLibraryEventTable memLibraryEventTable;
 	private CheckboxTableViewer memoryTableViewer;
 
 	Hashtable<Integer, Integer> threadList;
@@ -115,15 +128,19 @@
 	private DecimalFormat memMBFloatFormat = new DecimalFormat(Messages
 			.getString("MemTraceGraph.MBformat")); //$NON-NLS-1$
 
-	private static int xLegendHeight = 20;
+	private static int xLegendHeight = 50;
 
 	private boolean firstTimeDrawThreadList = true;
+
+	private Composite holder;
+	private boolean isLibraryEventTrace = false;
+	
+	private final boolean[] lockMouseToolTipResolver ={false}; 
+	private boolean showMemoryUsageLine = true;
 	
 	public MemTraceGraph(int graphIndex, MemTrace memTrace, int uid) {
 		super((GenericSampledTrace) memTrace);
 
-		// 
-
 		if (memTrace != null) {
 
 			// if no version number is found from trace, we can assume
@@ -145,29 +162,72 @@
 			return;
 		}
 
+		if(memTrace.getVersion() >= 203){
+			isLibraryEventTrace = true;
+		}
+		
 		samplingTime = calcSamplingTime();
 		memTrace.gatherDrawData();
 
+		
 		// create the label and a tableviewer
-		Composite holder = new Composite(NpiInstanceRepository.getInstance()
+		holder = new Composite(NpiInstanceRepository.getInstance()
 				.getProfilePage(uid, graphIndex).getBottomComposite(), SWT.NONE);
-
-		GridLayout gl = new GridLayout();
-		gl.marginHeight = 0;
-		gl.marginWidth = 0;
-		gl.marginLeft = 0;
-		gl.marginRight = 0;
-		holder.setLayout(gl);
-
-		Label label = new Label(holder, SWT.CENTER);
-		label
-				.setBackground(holder.getDisplay().getSystemColor(
-						SWT.COLOR_WHITE));
-		label.setFont(PIPageEditor.helvetica_8);
-		label.setText(Messages.getString("MemTraceGraph.graphTitle")); //$NON-NLS-1$
-		label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
-		this.memThreadTable = new MemThreadTable(this, holder);
+		PlatformUI.getWorkbench().getHelpSystem().setHelp(holder, MemoryPlugin.HELP_CONTEXT_ID_MAIN_PAGE);
+		
+		if(isLibraryEventTrace){	
+			FormLayout formLayout = new FormLayout();
+			formLayout.marginHeight = 0;
+			formLayout.marginWidth = 0;
+			formLayout.marginLeft = 0;
+			formLayout.marginRight = 0;
+			holder.setLayout(formLayout);
+			holder.setLayoutData(new GridData(GridData.FILL_BOTH));
+			
+		    final Sash sash = new Sash(holder, SWT.VERTICAL);
+		    final FormData data = new FormData();
+		    data.top = new FormAttachment(0);
+		    data.bottom = new FormAttachment(100); 
+		    data.left = new FormAttachment(50); 
+		    sash.setLayoutData(data);
+		
+		    // Memory usage table
+		    FormData leftData = new FormData();
+		    leftData.top = new FormAttachment(0);
+		    leftData.bottom = new FormAttachment(100);
+		    leftData.left = new FormAttachment(0);
+		    leftData.right = new FormAttachment(sash);		    
+		    SashForm sfLeft = new SashForm(holder, SWT.NONE);
+		    sfLeft.setLayout(formLayout);
+		    sfLeft.setLayoutData(leftData);		 
+		    this.memThreadTable = new MemThreadTable(this, sfLeft);
+			    
+		    
+		    // Library event table
+		    FormData rightData = new FormData();
+		    rightData.top = new FormAttachment(0, 0);
+		    rightData.bottom = new FormAttachment(100, 0);
+		    rightData.left = new FormAttachment(sash, 0);
+		    rightData.right = new FormAttachment(100, 0);
+		    
+		    SashForm sfRight = new SashForm(holder, SWT.NONE);
+		    sfRight.setLayout(formLayout);
+		    sfRight.setLayoutData(rightData);		 
+		    this.memLibraryEventTable = new MemLibraryEventTable(this, sfRight);
+			
+		    // allow to drag the sash
+		    sash.addListener(SWT.Selection, new Listener() {
+				public void handleEvent(Event event) {
+					if (event.detail != SWT.DRAG) {
+						data.left = new FormAttachment(0, event.x);
+						sash.getParent().layout();					
+					}
+				}
+			});
+		}else{				
+			holder.setLayout(new FillLayout());
+			this.memThreadTable = new MemThreadTable(this, holder);
+		}
 		this.memoryTableViewer = this.memThreadTable.getTableViewer();
 
 		this.readyToDraw = true;
@@ -191,7 +251,13 @@
 		{
 			dynamicMemoryVisualisation = false;
 			makeThreadDrawLists();
-		} else {
+		}  else if (actionString.equals("memory_usage_line_on")) //$NON-NLS-1$
+		{
+			showMemoryUsageLine = true;
+		}  else if (actionString.equals("memory_usage_line_off")) //$NON-NLS-1$
+		{
+			showMemoryUsageLine = false;
+		}else {
 			return;
 		}
 
@@ -216,6 +282,11 @@
 
 			memTrace.setMaxMemDataByInterval((int) (startTime * 1000),
 					(int) (endTime * 1000));
+		
+			if(isLibraryEventTrace){
+				memTrace.setMaxMemLibraryEventDataByInterval((int) (startTime * 1000),
+					(int) (endTime * 1000));
+			}
 
 			// send this message to the 2 other graphs
 			PIEvent be2 = new PIEvent(be.getValueObject(),
@@ -237,6 +308,9 @@
 			this.setSelectionStart(values[0]);
 			this.setSelectionEnd(values[1]);
 			this.memThreadTable.piEventReceived(be);
+			if(this.memLibraryEventTable != null){
+				this.memLibraryEventTable.piEventReceived(be);
+			}		
 			this.repaint();
 			break;
 
@@ -245,6 +319,9 @@
 			this.repaint();
 			if (this.leftFigureCanvas != null)
 				this.leftFigureCanvas.redraw();
+			if(memLibraryEventTable != null){				
+				memLibraryEventTable.updateSelection(memThreadTable.getTableViewer().getCheckedElements());	
+			}
 			break;
 
 		case PIEvent.SCALE_CHANGED:
@@ -255,7 +332,7 @@
 
 		case PIEvent.SCROLLED:
 			Event event = ((Event) be.getValueObject());
-			this.parentComponent.setScrolledOrigin(event.x, event.y);
+			this.parentComponent.setScrolledOrigin(event.x, event.y, (FigureCanvas)event.data);
 			this.repaint();
 			break;
 
@@ -278,9 +355,62 @@
 		this.makeThreadDrawLists();
 		this.paintThreads(graphics);
 		this.drawDottedLineBackground(graphics, MemTraceGraph.xLegendHeight);
-
+		
+		if(showMemoryUsageLine){
+			paintMemoryUsageLine(graphics);
+		}		
+		if(isLibraryEventTrace){
+			paintLibraryEvents(graphics);
+		}
+		
 		// draw the same selection as the Address/Thread trace
 		this.drawSelectionSection(graphics, MemTraceGraph.xLegendHeight);
+		
+	}
+	
+	private void paintLibraryEvents(Graphics graphics){
+		Enumeration<ProfiledLibraryEvent> enume = memTrace.getLibraryEvents().elements();	
+		while(enume.hasMoreElements()){
+			ProfiledLibraryEvent ple = enume.nextElement();	
+			if(!ple.isEnabled(graphIndex)){
+				continue;
+			}
+			List<GraphSamplePoint> pointList = ple.getGraphSamplePoints();
+			Iterator<GraphSamplePoint> iterator = pointList.iterator();
+			while (iterator.hasNext()) {
+				GraphSamplePoint samplePoint = iterator.next();
+				graphics.setBackgroundColor(ple.getColor());
+				graphics.setForegroundColor(ple.getColor());
+				drawThreadMarks((int) samplePoint.firstSamplePoint,
+						(int) samplePoint.lastSamplePoint,
+						this.getVisualSize().height, graphics);
+			}
+		}
+	}
+	
+	private void paintMemoryUsageLine(Graphics graphics){
+		Color black = ColorPalette.getColor(new RGB(0, 0, 0));
+		graphics.setBackgroundColor(black);
+		graphics.setForegroundColor(black);
+		PointList pl = new PointList();
+		Iterator<MemSampleByTime> iterator = memTrace.getDrawDataByTime().iterator();
+		while(iterator.hasNext()){
+			MemSampleByTime msbt = iterator.next();	
+			// calculate new x coord's value and round it to integer
+			int xCoord = (int) ((msbt.getTime()/getScale()) + 0.5);
+			int maxBytes;
+			if (dynamicMemoryVisualisation)
+				maxBytes = maxChunks;
+			else
+				maxBytes = memTrace.getTraceMaxChunks();
+			int yMultiplier = prettyMaxBytes(maxBytes) / height;
+			// calculate new y-coord's value and round it to integer
+			int yCoord = (int) (((double) height - (double) msbt.getUsedMemory()
+					/ yMultiplier) + 0.5);				
+			pl.addPoint(xCoord,yCoord);
+		}
+		graphics.setLineWidth(2);
+		graphics.drawPolyline(pl);		
 	}
 
 	private void paintSampledChunks(Graphics graphics) {
@@ -587,8 +717,7 @@
 		// get first event and key from map.
 		Iterator<Long> keys = map.keySet().iterator();
 		Iterator<Integer> values = map.values().iterator();
-		
-	
+
 		int previousXCoord = 0;
 		int countOfSameXCoords = 1;
 
@@ -604,7 +733,8 @@
 			xCoord = (int) (((double) keys.next() / xMultiplier) + 0.5);
 
 			// calculate new y-coord's value and round it to integer
-			yCoord = (int) (((double) height - (double) values.next() / yMultiplier) + 0.5);
+			yCoord = (int) (((double) height - (double) values.next()
+					/ yMultiplier) + 0.5);
 
 			if (xCoord == previousXCoord && index > 3) {
 				// if more than one sample at one point in the screen, count
@@ -721,13 +851,13 @@
 			}
 
 			// create empty sample
-			MemSample previousSample = new MemSample(new MemThread(0, "", ""),
+			MemSample previousSample = new MemSample(new MemThread(0, "", ""), //$NON-NLS-1$ //$NON-NLS-2$
 					0, 0, 0);
 
 			Iterator<MemSample> values = memSamples.values().iterator();
 
 			while (values.hasNext()) {
-				MemSample memSample = values.next(); 
+				MemSample memSample = values.next();
 				// go thru samples from single threas
 				// save changes after last received sample into TreeMaps
 				addEventToTreeMap(this.eventStackListY,
@@ -757,9 +887,10 @@
 			this.memTrace.setTraceMaxChunks(maxChunks);
 			this.memTrace.setTraceMaxStackHeap(maxStack);
 			this.memTrace.setTraceMaxTotal(maxStackHeap);
-			
-			//repaint left legend if this is first time that tread lists are made
-			if(firstTimeDrawThreadList){
+
+			// repaint left legend if this is first time that tread lists are
+			// made
+			if (firstTimeDrawThreadList) {
 				this.parentComponent.paintLeftLegend();
 				firstTimeDrawThreadList = false;
 			}
@@ -781,10 +912,10 @@
 		Iterator<Long> keys = map.keySet().iterator();
 
 		while (values.hasNext()) {
-			
+
 			int memValue = values.next();
 			long memKey = keys.next();
-			
+
 			// go thru array and count actual state of
 			// memory in each event
 			int value = previousValue + memValue;
@@ -902,13 +1033,14 @@
 							+ memSample.stackSize;
 					counter++;
 				}
-				
+
 			}
 
 			// tempListX[0] = (int)
 			// (((MemSample)memSamples.firstEntry().getValue()).sampleSynchTime
 			// / getScale());
-			MemSample firstMemSample = (MemSample)memSamples.get(memSamples.firstKey());
+			MemSample firstMemSample = (MemSample) memSamples.get(memSamples
+					.firstKey());
 			tempListX[0] = (int) ((firstMemSample.sampleSynchTime / getScale()));
 			tempListX[tempListX.length - 1] = tempListX[tempListX.length - 2];
 
@@ -1036,6 +1168,7 @@
 	 */
 	public void addContextMenuItems(Menu menu,
 			org.eclipse.swt.events.MouseEvent me) {
+
 		new MenuItem(menu, SWT.SEPARATOR);
 
 		MenuItem memoryStatsItem = new MenuItem(menu, SWT.PUSH);
@@ -1046,93 +1179,7 @@
 			}
 		});
 
-		new MenuItem(menu, SWT.SEPARATOR);
-
-		boolean showChunk = true;
-		boolean showHeapStack = true;
-
 		Object obj;
-		// if there is a showChunk value associated with the current Analyser
-		// tab, then use it
-		obj = NpiInstanceRepository.getInstance().activeUidGetPersistState(
-				"com.nokia.carbide.cpp.pi.memory.showChunk"); //$NON-NLS-1$
-		if ((obj != null) && (obj instanceof Boolean))
-			// retrieve the current value
-			showChunk = (Boolean) obj;
-		else
-			// set the initial value
-			NpiInstanceRepository.getInstance().activeUidSetPersistState(
-					"com.nokia.carbide.cpp.pi.memory.showChunk", showChunk); //$NON-NLS-1$
-
-		// if there is a showHeapStack value associated with the current
-		// Analyser tab, then use it
-		obj = NpiInstanceRepository.getInstance().activeUidGetPersistState(
-				"com.nokia.carbide.cpp.pi.memory.showHeapStack"); //$NON-NLS-1$
-		if ((obj != null) && (obj instanceof Boolean))
-			// retrieve the current value
-			showHeapStack = (Boolean) obj;
-		else
-			// set the initial value
-			NpiInstanceRepository
-					.getInstance()
-					.activeUidSetPersistState(
-							"com.nokia.carbide.cpp.pi.memory.showHeapStack", showHeapStack); //$NON-NLS-1$
-
-		MenuItem showChunkItem = new MenuItem(menu, SWT.RADIO);
-		showChunkItem.setText(Messages.getString("MemoryPlugin.showChunks")); //$NON-NLS-1$
-		showChunkItem.setSelection(showChunk && !showHeapStack);
-		showChunkItem.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				NpiInstanceRepository.getInstance().activeUidSetPersistState(
-						"com.nokia.carbide.cpp.pi.memory.showChunk", true); //$NON-NLS-1$
-				NpiInstanceRepository.getInstance().activeUidSetPersistState(
-						"com.nokia.carbide.cpp.pi.memory.showHeapStack", false); //$NON-NLS-1$
-
-				for (int i = 0; i < 3; i++) {
-					MemTraceGraph graph = (MemTraceGraph) memTrace
-							.getTraceGraph(i);
-					graph.action("chunk_on"); //$NON-NLS-1$
-				}
-			}
-		});
-
-		MenuItem showHeapItem = new MenuItem(menu, SWT.RADIO);
-		showHeapItem.setText(Messages.getString("MemoryPlugin.showHeapStack")); //$NON-NLS-1$
-		showHeapItem.setSelection(showHeapStack && !showChunk);
-		showHeapItem.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				NpiInstanceRepository.getInstance().activeUidSetPersistState(
-						"com.nokia.carbide.cpp.pi.memory.showChunk", false); //$NON-NLS-1$
-				NpiInstanceRepository.getInstance().activeUidSetPersistState(
-						"com.nokia.carbide.cpp.pi.memory.showHeapStack", true); //$NON-NLS-1$
-
-				for (int i = 0; i < 3; i++) {
-					MemTraceGraph graph = (MemTraceGraph) memTrace
-							.getTraceGraph(i);
-					graph.action("heapstack_on"); //$NON-NLS-1$
-				}
-			}
-		});
-
-		MenuItem showBothItem = new MenuItem(menu, SWT.RADIO);
-		showBothItem.setText(Messages.getString("MemoryPlugin.showAll")); //$NON-NLS-1$
-		showBothItem.setSelection(showChunk && showHeapStack);
-		showBothItem.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				NpiInstanceRepository.getInstance().activeUidSetPersistState(
-						"com.nokia.carbide.cpp.pi.memory.showChunk", true); //$NON-NLS-1$
-				NpiInstanceRepository.getInstance().activeUidSetPersistState(
-						"com.nokia.carbide.cpp.pi.memory.showHeapStack", true); //$NON-NLS-1$
-
-				for (int i = 0; i < 3; i++) {
-					MemTraceGraph graph = (MemTraceGraph) memTrace
-							.getTraceGraph(i);
-					graph.action("chunk_heapstack_on"); //$NON-NLS-1$
-				}
-			}
-		});
-
-		new MenuItem(menu, SWT.SEPARATOR);
 
 		boolean rescale = false;
 
@@ -1170,9 +1217,36 @@
 					MemTraceGraph graph = (MemTraceGraph) memTrace
 							.getTraceGraph(i);
 					graph.action(action);
-				}
+				}		
+				MemoryPlugin.getDefault().updateMenuItems();
 			}
 		});
+		
+		// if there is a show memory usage value associated with the current Analyser tab, then use it		
+		obj = NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.memory.showMemoryUsage");	//$NON-NLS-1$
+		if ((obj != null) && (obj instanceof Boolean))
+			// retrieve the current value
+			showMemoryUsageLine = (Boolean)obj;
+		else
+			// set the initial value
+			NpiInstanceRepository.getInstance().activeUidSetPersistState("com.nokia.carbide.cpp.pi.memory.showMemoryUsage", showMemoryUsageLine);	//$NON-NLS-1$
+		
+		new MenuItem(menu, SWT.SEPARATOR);		
+		MenuItem memoryUsageLine = new MenuItem(menu, SWT.CHECK);
+		memoryUsageLine.setText(Messages.getString("MemTraceGraph.showTotalMemoryUsage")); //$NON-NLS-1$
+		memoryUsageLine.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				showMemoryUsageLine = !showMemoryUsageLine;
+				NpiInstanceRepository
+				.getInstance()
+				.activeUidSetPersistState(
+						"com.nokia.carbide.cpp.pi.memory.showMemoryUsage", showMemoryUsageLine); //$NON-NLS-1$
+				repaint();			
+				MemoryPlugin.getDefault().updateMenuItems();
+			}
+		});
+		memoryUsageLine.setSelection(showMemoryUsageLine);
+		
 	}
 
 	public void paintLeftLegend(FigureCanvas figureCanvas, GC gc) {
@@ -1255,11 +1329,11 @@
 
 			Point extent = gc.stringExtent(legend);
 
-			gc.drawLine(GenericTraceGraph.yLegendWidth - 3, (int) y + 1,
-					GenericTraceGraph.yLegendWidth, (int) y + 1);
+			gc.drawLine(IGenericTraceGraph.Y_LEGEND_WIDTH - 3, (int) y + 1,
+					IGenericTraceGraph.Y_LEGEND_WIDTH, (int) y + 1);
 
 			if (y >= previousBottom) {
-				gc.drawString(legend, GenericTraceGraph.yLegendWidth - extent.x
+				gc.drawString(legend, IGenericTraceGraph.Y_LEGEND_WIDTH - extent.x
 						- 4, (int) y);
 				previousBottom = (int) y + extent.y;
 			}
@@ -1322,16 +1396,11 @@
 		double x = me.x * this.getScale();
 		double y = me.y;
 
-		if (y > this.getVisualSizeY() - MemTraceGraph.xLegendHeight) {
-			this.setToolTipText(null);
-			return;
-		}
-
 		// mouse event may return out of range X, that may
 		// crash when we use it to index data array
 		x = x >= 0 ? x : 0;
 		if (me.x >= this.getVisualSize().width
-				+ this.parentComponent.getScrolledOrigin().x) {
+				+ this.parentComponent.getScrolledOrigin(this).x) {
 			x = (this.getVisualSize().width - 1) * this.getScale();
 		}
 
@@ -1339,17 +1408,48 @@
 			this.setToolTipText(null);
 			return;
 		}
+	
+		if (y > this.getVisualSizeY() - MemTraceGraph.xLegendHeight) {
+			if (isLibraryEventTrace) {
+				final long xPoint = (long) (x + 0.5);
+				if (!lockMouseToolTipResolver[0]) {
+					// Resolve tool tip text in thread
+					new Thread() {
+						@Override
+						public void run() {
+							lockMouseToolTipResolver[0] = true;
+							try {
+								final ArrayList<MemSample> list = memTrace
+										.getLibraryEventDataByTime(graphIndex,
+												xPoint, (long) getScale());
+								Display.getDefault().syncExec(new Runnable() {
+									public void run() {
+										if (list.isEmpty()) {
+											setToolTipText(null);
+										} else {
+											final MemSample ms = list.get(list
+													.size() - 1);										
+											setToolTipText(getLibraryEventToolTipText(ms));											
+										}
+									}
+								});
 
+							} finally {
+								lockMouseToolTipResolver[0] = false;
+							}
+						}
+					}.start();
+				}			
+			} else {
+				this.setToolTipText(null);
+			}
+			return;
+		}
+	
 		long chunkSize = 0;
 		long stackHeapSize = 0;
-		// long totalSize = 0;
-		Entry<Long, Integer> entry;
 		if (memTrace.getVersion() >= 202) {
 			if (eventStackListY != null) {
-				/*
-				 * TODO entry = eventStackListY.floorEntry((long)x); if(entry !=
-				 * null){ stackHeapSize = entry.getValue(); }
-				 */
 				Integer value = (Integer) MemTrace.getFloorEntryFromMap(
 						(long) x, eventStackListY);
 				if (value != null) {
@@ -1357,19 +1457,13 @@
 				}
 			}
 			if (eventChunkListY != null) {
-				/*
-				 * TODO entry = eventChunkListY.floorEntry((long)x); if(entry !=
-				 * null){ chunkSize = entry.getValue(); }
-				 */
 				Integer value = (Integer) MemTrace.getFloorEntryFromMap(
 						(long) x, eventChunkListY);
 				if (value != null) {
 					chunkSize = value;
 				}
 
-			}/*
-			 * if(stackHeapSize == null){ this.setToolTipText(null); return; }
-			 */
+			}
 		} else {
 			ArrayList<MemSample> samples = memTrace
 					.getMemSampleDataByTime((long) x);
@@ -1411,6 +1505,26 @@
 			return;
 
 	}
+	
+	private String getLibraryEventToolTipText(MemSample memSample) {
+		String libraryName = getMemTrace().getLibraryNameString(
+				memSample.thread.fullName);
+		String process = getMemTrace().getProcessFromLibraryNameString(
+				memSample.thread.fullName);
+		if (memSample.stackSize != 0) {
+			return MessageFormat.format(Messages
+					.getString("MemTraceGraph.mouseToolTipLoaded"),
+					libraryName, process, memKBFormat
+							.format(((memSample.heapSize) + 512) / 1024),
+					memSample.sampleNum);
+		} else {
+			return MessageFormat.format(Messages
+					.getString("MemTraceGraph.mouseToolTipUnloaded"),
+					libraryName, process, memKBFormat
+							.format(((memSample.heapSize) + 512) / 1024),
+					memSample.sampleNum);
+		}
+	}
 
 	public void setCurrentThreads(Hashtable<Integer, Integer> threadList) {
 		this.threadList = threadList;
@@ -1486,4 +1600,185 @@
 		return bytes;
 	}
 
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @seecom.nokia.carbide.cpp.internal.pi.plugin.model.ITitleBarMenu#
+	 * addTitleBarMenuItems()
+	 */
+	public Action[] addTitleBarMenuItems() {
+
+		// Create actions for Title Bar's drop-down list 
+		
+		ArrayList<Action> actionArrayList = new ArrayList<Action>();
+
+		// Action for showing only chunks
+		Action actionShowChunk = new Action() {
+			public void run() {
+				NpiInstanceRepository.getInstance().activeUidSetPersistState(
+						"com.nokia.carbide.cpp.pi.memory.showChunk", true); //$NON-NLS-1$
+				NpiInstanceRepository.getInstance().activeUidSetPersistState(
+						"com.nokia.carbide.cpp.pi.memory.showHeapStack", false); //$NON-NLS-1$
+
+				for (int i = 0; i < 3; i++) {
+					MemTraceGraph graph = (MemTraceGraph) memTrace
+							.getTraceGraph(i);
+					graph.action("chunk_on"); //$NON-NLS-1$
+				}
+			}
+		};
+		actionShowChunk.setText(Messages.getString("MemoryPlugin.showChunks")); //$NON-NLS-1$
+
+		// Action for showing only heap/stack
+		Action actionShowHeap = new Action() {
+			public void run() {
+				NpiInstanceRepository.getInstance().activeUidSetPersistState(
+						"com.nokia.carbide.cpp.pi.memory.showChunk", false); //$NON-NLS-1$
+				NpiInstanceRepository.getInstance().activeUidSetPersistState(
+						"com.nokia.carbide.cpp.pi.memory.showHeapStack", true); //$NON-NLS-1$
+
+				for (int i = 0; i < 3; i++) {
+					MemTraceGraph graph = (MemTraceGraph) memTrace
+							.getTraceGraph(i);
+					graph.action("heapstack_on"); //$NON-NLS-1$
+				}
+			}
+		};
+		actionShowHeap
+				.setText(Messages.getString("MemoryPlugin.showHeapStack")); //$NON-NLS-1$
+
+		// Action for showing both heap/stack and chunks
+		Action actionShowBothItem = new Action() {
+			public void run() {
+				NpiInstanceRepository.getInstance().activeUidSetPersistState(
+						"com.nokia.carbide.cpp.pi.memory.showChunk", true); //$NON-NLS-1$
+				NpiInstanceRepository.getInstance().activeUidSetPersistState(
+						"com.nokia.carbide.cpp.pi.memory.showHeapStack", true); //$NON-NLS-1$
+
+				for (int i = 0; i < 3; i++) {
+					MemTraceGraph graph = (MemTraceGraph) memTrace
+							.getTraceGraph(i);
+					graph.action("chunk_heapstack_on"); //$NON-NLS-1$
+				}
+			}
+		};
+		actionShowBothItem.setText(Messages.getString("MemoryPlugin.showAll")); //$NON-NLS-1$
+
+		actionArrayList.add(actionShowChunk);
+		actionArrayList.add(actionShowHeap);
+		actionArrayList.add(actionShowBothItem);
+
+		// check which drawing mode is selected and set its action's state to
+		// checked
+		boolean showChunk = isShowChunkEnabled();
+		boolean showHeapStack = isShowHeapStackEnabled();
+
+		if (showChunk && !showHeapStack) {
+			actionShowChunk.setChecked(true);
+		} else if (showHeapStack && !showChunk) {
+			actionShowHeap.setChecked(true);
+		} else {
+			actionShowBothItem.setChecked(true);
+		}
+
+		return actionArrayList.toArray(new Action[actionArrayList.size()]);
+	}
+	
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.ITitleBarMenu#getContextHelpId()
+	 */
+	public String getContextHelpId() {
+		return MemoryPlugin.HELP_CONTEXT_ID_MAIN_PAGE;
+	}
+
+	/**
+	 * Function for checking if chunk view is enabled
+	 * 
+	 * @return boolean value that is true when chunk view is enabled
+	 */
+
+	private boolean isShowChunkEnabled() {
+		// if there is a showChunk value associated with the current Analyser
+		// tab, then use it
+		Object obj = NpiInstanceRepository.getInstance()
+				.activeUidGetPersistState(
+						"com.nokia.carbide.cpp.pi.memory.showChunk"); //$NON-NLS-1$
+		if ((obj != null) && (obj instanceof Boolean))
+			// retrieve the current value
+			return true;
+		else
+			// set the initial value
+			NpiInstanceRepository.getInstance().activeUidSetPersistState(
+					"com.nokia.carbide.cpp.pi.memory.showChunk", true); //$NON-NLS-1$
+		return false;
+	}
+
+	/**
+	 * Function for checking if stack/heap view is enabled
+	 * 
+	 * @return boolean value that is true when stack/heap view is enabled
+	 */
+	private boolean isShowHeapStackEnabled() {
+		// if there is a showHeapStack value associated with the current
+		// Analyser tab, then use it
+		Object obj = NpiInstanceRepository.getInstance()
+				.activeUidGetPersistState(
+						"com.nokia.carbide.cpp.pi.memory.showHeapStack"); //$NON-NLS-1$
+		if ((obj != null) && (obj instanceof Boolean))
+			// retrieve the current value
+			return true;
+		else
+			// set the initial value
+			NpiInstanceRepository.getInstance().activeUidSetPersistState(
+					"com.nokia.carbide.cpp.pi.memory.showHeapStack", true); //$NON-NLS-1$
+		return false;
+	}
+	
+	/*
+	 * (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph#setLegendTableVisible(boolean)
+	 */
+	public void graphVisibilityChanged(boolean value){
+		if(holder != null){
+			holder.setVisible(value);
+			holder.getParent().layout();
+		}
+	}
+	
+	/*
+	 * (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph#setLegendTableMaximized(boolean)
+	 */
+	public void graphMaximized(boolean value){
+		if(holder != null){
+			if(holder.getParent().getClass() == SashForm.class){
+				SashForm sashForm = (SashForm)holder.getParent();
+				if(value){
+					sashForm.setMaximizedControl(holder);
+				}
+				else{
+					sashForm.setMaximizedControl(null);
+
+				}
+			}
+			
+		}
+	}
+	
+	/*
+	 * (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph#isGraphMinimizedWhenOpened()
+	 */
+	public boolean isGraphMinimizedWhenOpened(){
+		// Memory Graph is shown when view is opened
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.pi.visual.IGenericTraceGraph#getTitle()
+	 */
+	@Override
+	public String getTitle() {
+		return Messages.getString("MemoryPlugin.pluginTitle"); //$NON-NLS-1$
+	}	
 }
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.memory/src/com/nokia/carbide/cpp/pi/memory/MemTraceParser.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.memory/src/com/nokia/carbide/cpp/pi/memory/MemTraceParser.java	Wed Apr 21 15:14:16 2010 +0300
@@ -251,10 +251,10 @@
 				   		threadName = rawName;
 				   	}
 								    	
-					memTrace.addFirstSynchTime(new Integer((int)threadId),new Integer((int)sample));
-				   	memSamples.add(new MemThread(new Integer((int)threadId), threadName, processName));
-				   	priTrace.addFirstSynchTime(new Integer((int)threadId), new Integer(sampleTime));
-				   	priSamples.add(new PriThread(new Integer((int)threadId), threadName, processName));
+					memTrace.addFirstSynchTime(Integer.valueOf((int)threadId),Integer.valueOf((int)sample));
+				   	memSamples.add(new MemThread(Integer.valueOf((int)threadId), threadName, processName));
+				   	priTrace.addFirstSynchTime(Integer.valueOf((int)threadId), Integer.valueOf(sampleTime));
+				   	priSamples.add(new PriThread(Integer.valueOf((int)threadId), threadName, processName));
 
 				   	// read the next length
 					length = dis.readUnsignedByte(); readCount++;
@@ -386,8 +386,8 @@
 				   		threadName = rawName;
 				   	}
 								    	
-					memTrace.addFirstSynchTime(new Integer((int)threadId), new Integer((int)sample));
-				   	memSamples.add(new MemThread(new Integer((int)threadId), threadName, processName));
+					memTrace.addFirstSynchTime(Integer.valueOf((int)threadId), Integer.valueOf((int)sample));
+				   	memSamples.add(new MemThread(Integer.valueOf((int)threadId), threadName, processName));
 
 					length = dis.readUnsignedByte(); readCount++;
 				}
@@ -528,8 +528,8 @@
 						processName = processName.substring(2);
 						threadName += "_C"; //$NON-NLS-1$
 					}
-					memTrace.addFirstSynchTime(new Integer((int)threadId),new Integer((int)sample));
-				   	memSamples.add(new MemThread(new Integer((int)threadId), threadName, processName));
+					memTrace.addFirstSynchTime(Integer.valueOf((int)threadId),Integer.valueOf((int)sample));
+				   	memSamples.add(new MemThread(Integer.valueOf((int)threadId), threadName, processName));
 
 					length = dis.readUnsignedByte();readCount++;
 				}
@@ -659,9 +659,14 @@
 						processName = processName.substring(2);
 						threadName += "_C";
 					}
-					
-					memTrace.addFirstSynchTime(new Integer((int)threadId),new Integer((int)sample));
-					thread = new MemThread(new Integer((int)threadId), threadName, processName);
+					else if (processName.startsWith("L_")) //$NON-NLS-1$
+					{
+						processName = processName.substring(2);
+						threadName += "_L"; //$NON-NLS-1$
+				
+					}
+					memTrace.addFirstSynchTime(Integer.valueOf((int)threadId),Integer.valueOf((int)sample));
+					thread = new MemThread(Integer.valueOf((int)threadId), threadName, processName);
 					memSamples.add(thread);
 			   		createdThread = processName+"::"+threadName;
 			   		if(debug)System.out.println("Name sample: "+sample+", created thread: "+createdThread+", vector size: "+memSamples.size());
@@ -759,7 +764,7 @@
 	@SuppressWarnings("unchecked")
 	private void addRawV157MemSamples(Vector rawV157MemSamples) {
 
-		Hashtable startedThreads;	// store the id/name of the thread for recognizing the right chunk (same chunk id may be reused)
+		Hashtable<Integer, String> startedThreads;	// store the id/name of the thread for recognizing the right chunk (same chunk id may be reused)
 
 		String tempThreadName = "";
 		String str = "";
@@ -803,7 +808,12 @@
 			    		// find corresponding thread ID among the MemThreads
 			    		if (mt.threadId.intValue() == threadId ) {
 			    			// create a new sample to memory trace
-			    			sample = new MemSample(mt, heapSize, stackSize, sampleTime, MemTraceParser.SAMPLE_CODE_INITIAL_CHUNK);
+			    			if(mt.threadName.endsWith("_L")){
+			    				sample = new MemSample(mt, (int)element[1], (int)element[2], heapSize, sampleTime, MemTraceParser.SAMPLE_CODE_INITIAL_CHUNK);
+			    			}else{
+			    				sample = new MemSample(mt, heapSize, stackSize, sampleTime, MemTraceParser.SAMPLE_CODE_INITIAL_CHUNK);
+			    			}			    	
+			    		
 			    			tempThreadName = mt.processName+"::"+mt.threadName;
 			    			
 			    			// add the thread into started hash table
@@ -823,7 +833,11 @@
 			    		// find corresponding thread ID among the MemThreads
 			    		if (mt.threadId.intValue() == threadId && sum(tempThreadName) == nameHash) {
 			    			// create a new sample to memory trace
-			    			sample = new MemSample(mt, heapSize, stackSize, sampleTime, MemTraceParser.SAMPLE_CODE_NEW_CHUNK);
+			    			if(mt.threadName.endsWith("_L")){
+			    				sample = new MemSample(mt, (int)element[1], (int)element[2], heapSize, sampleTime, MemTraceParser.SAMPLE_CODE_NEW_CHUNK);
+			    			}else{
+			    				sample = new MemSample(mt, heapSize, stackSize, sampleTime, MemTraceParser.SAMPLE_CODE_NEW_CHUNK);
+			    			}
 			    			
 			    			// add the thread into started hash table
 			    			startedThreads.put((int)threadId, (String)tempThreadName);
@@ -847,7 +861,11 @@
 			    		if (mt.threadId.intValue() == threadId ) {
 			    			if((str).equalsIgnoreCase(tempThreadName)) {
 				    			// create a new sample to memory trace
-				    			sample = new MemSample(mt, heapSize, stackSize, sampleTime, MemTraceParser.SAMPLE_CODE_UPDATE_CHUNK);
+			    				if(mt.threadName.endsWith("_L")){
+				    				sample = new MemSample(mt, (int)element[1], (int)element[2], heapSize, sampleTime, MemTraceParser.SAMPLE_CODE_UPDATE_CHUNK);
+				    			}else{
+				    				sample = new MemSample(mt, heapSize, stackSize, sampleTime, MemTraceParser.SAMPLE_CODE_UPDATE_CHUNK);
+				    			}			    			
 				    			
 				    			// add sample to main trace data structure
 			    				memTrace.addSample(sample);
@@ -864,9 +882,22 @@
 			    		
 			    		// find corresponding thread ID among the MemThreads
 			    		if (mt.threadId.intValue() == threadId) {
-			    			if(((String)startedThreads.get(threadId)).equalsIgnoreCase(tempThreadName)) {
+			    			String thread = startedThreads.get(threadId);
+			    			if(thread == null){
+			    				if(mt.threadName.endsWith("_L")){
+				    				sample = new MemSample(mt, (int)element[1], (int)element[2], heapSize, sampleTime, MemTraceParser.SAMPLE_CODE_DELETE_CHUNK);
+				    				// add sample to main trace data structure
+				    				memTrace.addSample(sample);
+				    				break;
+			    				}			    			
+			    			}			    			
+			    			else if(thread.equalsIgnoreCase(tempThreadName)) {
 				    			// create a new sample to memory trace
-				    			sample = new MemSample(mt, heapSize, stackSize, sampleTime, MemTraceParser.SAMPLE_CODE_DELETE_CHUNK);
+			    				if(mt.threadName.endsWith("_L")){
+				    				sample = new MemSample(mt, (int)element[1], (int)element[2], heapSize, sampleTime, MemTraceParser.SAMPLE_CODE_DELETE_CHUNK);
+				    			}else{
+				    				sample = new MemSample(mt, heapSize, stackSize, sampleTime, MemTraceParser.SAMPLE_CODE_DELETE_CHUNK);
+				    			}
 				    			
 					    		// remove from the started threads hash table
 					    		if(startedThreads.remove(threadId) == null) {
@@ -885,7 +916,7 @@
 	    	}
 	    	
 	    	// add end mark for the thread
-    		memTrace.addLastSynchTime(new Integer(threadId), new Integer(sampleTime));
+    		memTrace.addLastSynchTime(Integer.valueOf(threadId), Integer.valueOf(sampleTime));
 
 	    }
 	    if (debug) System.out.println("Done parsing, size: "+memTrace.samples.size());
@@ -917,7 +948,7 @@
 	    		}
 	    	}
 	    	
-	    	memTrace.addLastSynchTime(new Integer(threadId), new Integer(sampleTime));
+	    	memTrace.addLastSynchTime(Integer.valueOf(threadId), Integer.valueOf(sampleTime));
 	    }
 	    if (debug) System.out.println(Messages.getString("MemTraceParser.parsingDone")); //$NON-NLS-1$
 	}
@@ -1008,7 +1039,7 @@
 	    		}
 	    	}
 	    	
-	    	memTrace.addLastSynchTime(new Integer(threadId), new Integer(sampleTime));
+	    	memTrace.addLastSynchTime(Integer.valueOf(threadId), Integer.valueOf(sampleTime));
 	    }
 
 	    if (debug) System.out.println(Messages.getString("MemTraceParser.sizeOfParse")+memTrace.samples.size()/*+" largest "+largest*/); //$NON-NLS-1$
@@ -1060,8 +1091,8 @@
 	    			break;
 	    		}
 	    	}
-	    	memTrace.addLastSynchTime(new Integer(threadId), new Integer(sampleTime));
-	    	priTrace.addLastSynchTime(new Integer(threadId), new Integer(sampleTime));
+	    	memTrace.addLastSynchTime(Integer.valueOf(threadId), Integer.valueOf(sampleTime));
+	    	priTrace.addLastSynchTime(Integer.valueOf(threadId), Integer.valueOf(sampleTime));
 	    }
 	    if (debug) System.out.println(Messages.getString("MemTraceParser.parsingDone")); //$NON-NLS-1$
 	}
@@ -1147,8 +1178,8 @@
 				   		threadName = rawName;
 				   	}
 
-				   	priTrace.addFirstSynchTime(new Integer((int)threadId), new Integer(sampleTime));
-				   	priSamples.add(new PriThread(new Integer((int)threadId), threadName, processName));
+				   	priTrace.addFirstSynchTime(Integer.valueOf((int)threadId), Integer.valueOf(sampleTime));
+				   	priSamples.add(new PriThread(Integer.valueOf((int)threadId), threadName, processName));
 
 				   	// read the next length
 					length = dis.readUnsignedByte(); readCount++;
@@ -1232,7 +1263,7 @@
 	    		}
 	    	}
 
-	    	priTrace.addLastSynchTime(new Integer(threadId), new Integer(sampleTime));
+	    	priTrace.addLastSynchTime(Integer.valueOf(threadId), Integer.valueOf(sampleTime));
 	    }
 	    if (debug) System.out.println(Messages.getString("MemTraceParser.parsingDone")); //$NON-NLS-1$
 	}
@@ -1397,6 +1428,11 @@
 		    		parseVersion157Trace(traceArray,s);
 		    		return;
 		    	} 
+	    		else if(s.startsWith("Bappea_V2.03")) 
+	    		{
+		    		parseVersion157Trace(traceArray,s);
+		    		return;
+		    	} 
 
 	    		String version = s.substring(8, 12);
 	    		String traceType = s.substring(13, s.length());
@@ -1471,10 +1507,10 @@
 	    	processName = unparsedName.substring(0, index - 1);
 	    	threadName = unparsedName.substring(index + 1,  j);
 
-	    	memTrace.addFirstSynchTime(new Integer(threadId), new Integer(sampleTime));
-	    	memSamples.add(new MemThread(new Integer(threadId), threadName, processName));
-	    	priTrace.addFirstSynchTime(new Integer(threadId), new Integer(sampleTime));
-	    	priSamples.add(new PriThread(new Integer(threadId), threadName, processName));
+	    	memTrace.addFirstSynchTime(Integer.valueOf(threadId), Integer.valueOf(sampleTime));
+	    	memSamples.add(new MemThread(Integer.valueOf(threadId), threadName, processName));
+	    	priTrace.addFirstSynchTime(Integer.valueOf(threadId), Integer.valueOf(sampleTime));
+	    	priSamples.add(new PriThread(Integer.valueOf(threadId), threadName, processName));
 
 	    	i += buffer.length + 8;
 	    }
@@ -1534,8 +1570,8 @@
 	    			break;
 	    		}
 	    	}
-	    	memTrace.addLastSynchTime(new Integer(threadId), new Integer(sampleTime));
-	    	priTrace.addLastSynchTime(new Integer(threadId), new Integer(sampleTime));
+	    	memTrace.addLastSynchTime(Integer.valueOf(threadId), Integer.valueOf(sampleTime));
+	    	priTrace.addLastSynchTime(Integer.valueOf(threadId), Integer.valueOf(sampleTime));
 	    	k += 16;
 	    }
 	    if (debug) System.out.println(Messages.getString("MemTraceParser.parsingDone")); //$NON-NLS-1$
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.memory/src/com/nokia/carbide/cpp/pi/memory/MemoryPlugin.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.memory/src/com/nokia/carbide/cpp/pi/memory/MemoryPlugin.java	Wed Apr 21 15:14:16 2010 +0300
@@ -28,9 +28,9 @@
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Event;
 import org.osgi.framework.BundleContext;
-import org.osgi.framework.Version;
 
 import com.nokia.carbide.cpp.internal.pi.analyser.NpiInstanceRepository;
+import com.nokia.carbide.cpp.internal.pi.analyser.ProfileReader;
 import com.nokia.carbide.cpp.internal.pi.analyser.ProfileVisualiser;
 import com.nokia.carbide.cpp.internal.pi.memory.actions.MemoryStatisticsDialog;
 import com.nokia.carbide.cpp.internal.pi.model.GenericTrace;
@@ -55,6 +55,7 @@
 	implements IViewMenu, ITrace, IClassReplacer, IVisualizable, IEventListener, IReportable
 {
 	private static final String HELP_CONTEXT_ID = PIPageEditor.PI_ID + ".memory";  //$NON-NLS-1$
+	public static final String HELP_CONTEXT_ID_MAIN_PAGE = HELP_CONTEXT_ID + ".memoryPageContext";  //$NON-NLS-1$
 
 	// There will be 1 graph for editor page 0
 	// This code may assume that page 0 has the threads graph
@@ -64,7 +65,7 @@
 	private static MemoryPlugin plugin;
 	
 	// version number of profiler
-	private String profilerVersion = "";
+	private String profilerVersion = ""; //$NON-NLS-1$
 	
 	private static void setPlugin(MemoryPlugin newPlugin)
 	{
@@ -100,6 +101,14 @@
 	public static MemoryPlugin getDefault() {
 		return plugin;
 	}
+	
+	/**
+	 * Update menu items
+	 */
+	public void updateMenuItems(){
+		int uid = NpiInstanceRepository.getInstance().activeUid();
+		ProfileReader.getInstance().setTraceMenus(NpiInstanceRepository.getInstance().getPlugins(uid), uid);
+	}
 
 	/**
 	 * Returns an image descriptor for the image file at the given
@@ -176,10 +185,24 @@
 		return "Memory"; //$NON-NLS-1$
 	}
 	
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace#getTraceTitle()
+	 */
+	public String getTraceTitle() {
+		return Messages.getString("MemoryPlugin.1"); //$NON-NLS-1$
+	}
+	
 	public int getTraceId() {
 		return 4;
 	}
 
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace#parseTraceFiles(java.io.File[])
+	 */
+	public ParsedTraceData parseTraceFiles(File[] files) throws Exception {
+		throw new UnsupportedOperationException();
+	}
+
 	public ParsedTraceData parseTraceFile(File file) throws Exception 
 	{
 		ParsedTraceData traceData = null;
@@ -294,9 +317,33 @@
 		action.setChecked(rescale);
 		action.setToolTipText(Messages.getString("MemoryPlugin.dynamicRescaleTooltip")); //$NON-NLS-1$
 		manager.add(action);
+		
+		
+		boolean showMemoryUsageLine = true;
+		// if there is a show memory usage value associated with the current Analyser tab, then use it		
+		obj = NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.memory.showMemoryUsage");	//$NON-NLS-1$
+		if ((obj != null) && (obj instanceof Boolean))
+			// retrieve the current value
+			showMemoryUsageLine = (Boolean)obj;
+		else
+			// set the initial value
+			NpiInstanceRepository.getInstance().activeUidSetPersistState("com.nokia.carbide.cpp.pi.memory.showMemoryUsage", showMemoryUsageLine);	//$NON-NLS-1$
+		
+		action = new Action(Messages.getString("MemTraceGraph.showTotalMemoryUsage"), Action.AS_CHECK_BOX) { //$NON-NLS-1$
+			public void run() {
+				if (this.isChecked())
+					receiveSelectionEvent("memory_usage_line_on"); //$NON-NLS-1$
+				else
+					receiveSelectionEvent("memory_usage_line_off"); //$NON-NLS-1$
+			}
+		};
+		action.setChecked(showMemoryUsageLine);
+		action.setToolTipText(Messages.getString("MemoryPlugin.showTotalMemoryUsageToolTip")); //$NON-NLS-1$
+		manager.add(action);
 
 		return manager;
 	}
+	
 
 	public void receiveEvent(String actionString, Event event) {
 		MemTrace trace = (MemTrace)NpiInstanceRepository.getInstance().activeUidGetTrace("com.nokia.carbide.cpp.pi.memory"); //$NON-NLS-1$
@@ -315,10 +362,6 @@
 			((MemTraceGraph)trace.getTraceGraph(PIPageEditor.FUNCTIONS_PAGE)).action(actionString);
 		} else if (actionString.equals("scroll")) //$NON-NLS-1$
 		{
-			if (   !(event.data instanceof String)
-				|| !((String)event.data).equals("FigureCanvas")) //$NON-NLS-1$
-				return;
-			
 			PIEvent be = new PIEvent(event, PIEvent.SCROLLED);
 			
 			((MemTraceGraph)trace.getTraceGraph(PIPageEditor.THREADS_PAGE)).piEventReceived(be);
@@ -345,7 +388,11 @@
 			NpiInstanceRepository.getInstance().activeUidSetPersistState("com.nokia.carbide.cpp.pi.memory.rescale", true); //$NON-NLS-1$
 		} else if (actionString.equals("rescale_off")) { //$NON-NLS-1$
 			NpiInstanceRepository.getInstance().activeUidSetPersistState("com.nokia.carbide.cpp.pi.memory.rescale", false); //$NON-NLS-1$
-		} else {
+		} else if (actionString.equals("memory_usage_line_on")) { //$NON-NLS-1$
+			NpiInstanceRepository.getInstance().activeUidSetPersistState("com.nokia.carbide.cpp.pi.memory.showMemoryUsage", true); //$NON-NLS-1$
+		} else if (actionString.equals("memory_usage_line_off")) { //$NON-NLS-1$
+			NpiInstanceRepository.getInstance().activeUidSetPersistState("com.nokia.carbide.cpp.pi.memory.showMemoryUsage", false); //$NON-NLS-1$
+		}else {
 			return;
 		}
 
@@ -376,7 +423,7 @@
 		MemTrace trace = (MemTrace)NpiInstanceRepository.getInstance().activeUidGetTrace("com.nokia.carbide.cpp.pi.memory"); //$NON-NLS-1$
 
 		if (trace != null)
-			return new Integer(trace.getLastSampleNumber());
+			return Integer.valueOf(trace.getLastSampleNumber());
 		else
 			return null;
 	}
@@ -464,12 +511,4 @@
 	public void setPageIndex(int index, int pageIndex) {
 		return;
 	}
-
-
-	/* (non-Javadoc)
-	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.IVisualizable#getGraphTitle(int)
-	 */
-	public String getGraphTitle(int graphIndex) {
-		return Messages.getString("MemoryPlugin.pluginTitle"); //$NON-NLS-1$
-	}
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.memory/src/com/nokia/carbide/cpp/pi/memory/ProfiledLibraryEvent.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2010 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: 
+ *
+ */
+package com.nokia.carbide.cpp.pi.memory;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+import com.nokia.carbide.cpp.internal.pi.model.ProfiledGeneric;
+
+public class ProfiledLibraryEvent extends ProfiledGeneric {
+	class GraphSamplePoint {
+		long firstSamplePoint;
+		long lastSamplePoint;
+
+		public GraphSamplePoint(long firstSamplePoint, long lastSamplePoint) {
+			this.firstSamplePoint = firstSamplePoint;
+			this.lastSamplePoint = lastSamplePoint;
+		}
+	}
+
+	private TreeMap<Long, MemSample> memSamples;
+	private List<GraphSamplePoint> grapSamplePoints;
+
+	
+	public ProfiledLibraryEvent(String name) {
+		super(-1, 3);
+		setNameString(name);
+		this.memSamples = new TreeMap<Long, MemSample>();	
+	}
+	
+	public void addMemSample(MemSample memSample){
+		if(memSample.stackSize == 0 && memSample.sampleNum == 0){
+			memSample.heapSize = 0;
+		}
+		memSamples.put(memSample.sampleSynchTime, memSample);
+	}
+	
+
+	public void updateSelection(long startTime, long endTime) {
+
+		if (memSamples.size() == 0) {
+			return;
+		}
+	
+		MemSample firstSample = (MemSample) memSamples
+				.get(memSamples.lastKey());
+
+		MemThread thread = firstSample.thread;
+
+		MaxMemoryItem maxMemoryItem = thread.maxMemoryItem;
+
+		SortedMap<Long, MemSample> subMap = memSamples.subMap(startTime,
+				endTime);
+
+		ArrayList<MemSample> samples = new ArrayList<MemSample>(subMap.values());		
+
+		if(samples.isEmpty()){
+			maxMemoryItem.maxChunks = 0;
+			maxMemoryItem.maxTotal = 0;
+		}else{
+			int count = 0;
+			maxMemoryItem.maxChunks = 0;
+			for(MemSample memSample : samples){
+				if(memSample.type != MemTraceParser.SAMPLE_CODE_INITIAL_CHUNK){
+					count++;
+				}		
+				if(memSample.type == MemTraceParser.SAMPLE_CODE_NEW_CHUNK || memSample.type == MemTraceParser.SAMPLE_CODE_UPDATE_CHUNK){
+					maxMemoryItem.maxChunks += memSample.heapSize;
+				}else if(memSample.type == MemTraceParser.SAMPLE_CODE_DELETE_CHUNK ){
+					if(memSample.heapSize == 0){
+						maxMemoryItem.maxChunks = 0;
+					}else{
+						maxMemoryItem.maxChunks -= memSample.heapSize;
+					}					
+				}
+			}
+			if(maxMemoryItem.maxChunks  < 0 ){
+				maxMemoryItem.maxChunks = 0;
+			}
+			maxMemoryItem.maxTotal = count;
+		}	
+	}
+		
+	public MemThread getLastMemThread(){
+		return memSamples.get(memSamples.lastKey()).thread;
+	}
+
+	public TreeMap<Long, MemSample> getMemSamples() {
+		return memSamples;
+	}
+	
+	public List<GraphSamplePoint> getGraphSamplePoints() {
+		if(grapSamplePoints == null){
+			grapSamplePoints = calculateGraphSamplePoints();
+		}
+		return grapSamplePoints;
+	}
+
+	@Override
+	public void setEnabled(int graphIndex, boolean enableValue) {
+		super.setEnabled(graphIndex, enableValue);
+		Iterator<MemSample> iterator = memSamples.values().iterator();
+		while(iterator.hasNext()){
+			MemSample memSample = iterator.next();
+			memSample.thread.setEnabled(graphIndex, enableValue);
+		}
+		
+	}
+
+	private List<GraphSamplePoint> calculateGraphSamplePoints() {
+
+		List<GraphSamplePoint> graphSamples = new ArrayList<GraphSamplePoint>();
+		Iterator<MemSample> iterator = memSamples.values().iterator();
+		while (iterator.hasNext()) {
+			MemSample memSample = iterator.next();	
+			if(memSample.type == MemTraceParser.SAMPLE_CODE_INITIAL_CHUNK){
+				continue;
+			}
+			if (memSamples.values().size() == 1) {
+				if (memSample.stackSize == 0) {
+					// library unloaded
+					graphSamples.add(new GraphSamplePoint(-100, memSample.sampleSynchTime));
+				} else {
+					// library loaded
+					graphSamples.add(new GraphSamplePoint(memSample.sampleSynchTime, -100));
+				}
+			} else {
+				if (memSample.stackSize == 0) {
+					// library unloaded
+					graphSamples.add(new GraphSamplePoint(-100, memSample.sampleSynchTime));
+				} else {
+					// library loaded
+					graphSamples.add(new GraphSamplePoint(memSample.sampleSynchTime, -100));
+				}
+			}
+
+		}
+		return graphSamples;
+	}
+
+}
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.memory/src/com/nokia/carbide/cpp/pi/memory/messages.properties	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.memory/src/com/nokia/carbide/cpp/pi/memory/messages.properties	Wed Apr 21 15:14:16 2010 +0300
@@ -1,3 +1,9 @@
+MemoryPlugin.1=Memory trace
+MemLibraryEventTable.comma=,
+MemLibraryEventTable.library=Library
+MemLibraryEventTable.saveCheckedSamples=Save Library Event Samples for Checked Table Entries...
+MemLibraryEventTable.saveSamplesHeading=Time (ms),Loaded Library,Process,Load Size (KB),Overall Load Count\n
+MemLibraryEventTable.title=Library Events
 MemoryPlugin.memoryGraph=Memory Graph
 MemoryPlugin.memoryStats=Memory Usage Statistics
 MemoryPlugin.memoryStatsTooltip=Show memory usage statistics for the selected interval
@@ -12,7 +18,8 @@
 MemThreadTable.saveSamplesHeading=Time (ms),Thread/Chunk,Chunk Size (KB),Stack/Heap Size (KB)\n
 MemThreadTable.memory=Memory
 MemThreadTable.comma=,
-MemoryPlugin.showChunks=Show Chunk Usage
+MemThreadTable.title=Memory Usage
+MemoryPlugin.showChunks=Chunk Usage
 MemoryPlugin.namesTotal=Total
 MemTraceParser.sampleRead=Read next sample \#
 MemTraceParser.newSample=Length = 0, New sample
@@ -22,8 +29,8 @@
 MemTraceGraph.KBformat=\#\#,\#\#\#,\#\#\# KB
 MemTraceGraph.MBformat=\#\#\#\#\#.0
 MemTraceGraph.graphTitle=Memory Usage
-MemoryPlugin.showAll=Show Chunk and Stack/Heap Usage
-MemoryPlugin.showHeapStack=Show Stack/Heap Usage
+MemoryPlugin.showAll=Chunk and Stack/Heap Usage
+MemoryPlugin.showHeapStack=Stack/Heap Usage
 MemoryPlugin.namesAvgChunk=Average Chunk
 MemoryPlugin.namesAvgStack=Average Stack
 MemoryPlugin.showAllTooltip=Show chunk and heap/stack memory usage
@@ -45,6 +52,8 @@
 MemTraceGraph.totalTooltip2=\ \ \ stack/heap 
 MemTraceGraph.chunkTooltip1=s: chunks 
 MemTraceGraph.chunkTooltip2=KB
+MemTraceGraph.mouseToolTipLoaded={0} loaded by {1}, Load Size: {2}, Overall Load Count: {3}
+MemTraceGraph.mouseToolTipUnloaded={0} unloaded by {1}, Load Size: {2}, Overall Load Count: {3}
 MemoryPlugin.showChunksTooltip=Show only chunk usage memory usage
 MemTraceParser.traceFileLength=Memory trace file length 
 MemTraceParser.readVersionDebug=Read version 
@@ -61,10 +70,12 @@
 MemTraceParser.invalidSample=Parse error, invalid memory sample
 MemTraceParser.bothHeapAndStack=Element has both heap and stack\!\!
 MemTraceGraph.traceDataNotFound=Memory trace data not found\!
+MemTraceGraph.showTotalMemoryUsage=Show Total Memory Usage
 MemTraceGraph.stackHeapTooltip1=s: stack/heap 
 MemTraceGraph.stackHeapTooltip2=KB
 MemTraceParser.shouldNotHappen=Should not happen, memory trace
 MemoryPlugin.showHeapStackTooltip=Show only heap/stack memory usage
+MemoryPlugin.showTotalMemoryUsageToolTip=Show total memory usage on the graph
 MemTraceParser.parsingOldVersion=Parsing old (v.0.85 or older) type memory trace file
 MemTraceGraph.byByte=\ B
 MemTraceParser.cannotOpenTraceFile=Unable to open memory trace file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.peccommon/.classpath	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.peccommon/.settings/org.eclipse.jdt.core.prefs	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,8 @@
+#Tue Jan 19 15:21:41 GMT 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.peccommon/META-INF/MANIFEST.MF	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,17 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Carbide.c++ Performance Counters Common PI Plugin
+Bundle-SymbolicName: com.nokia.carbide.cpp.pi.peccommon;singleton:=true
+Bundle-Version: 2.3.0.qualifier
+Bundle-Activator: com.nokia.carbide.cpp.pi.peccommon.PecCommonPlugin
+Bundle-Vendor: Nokia
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ com.nokia.carbide.cpp.pi;bundle-version="2.2.0",
+ org.eclipse.draw2d,
+ com.nokia.carbide.cpp.pi.util;bundle-version="2.2.0",
+ org.eclipse.ui.ide
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-ActivationPolicy: lazy
+Export-Package: com.nokia.carbide.cpp.pi.peccommon
+Eclipse-ExtensibleAPI: true
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.peccommon/build.properties	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,4 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.peccommon/src/com/nokia/carbide/cpp/pi/peccommon/Messages.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,40 @@
+package com.nokia.carbide.cpp.pi.peccommon;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS {
+	private static final String BUNDLE_NAME = "com.nokia.carbide.cpp.pi.peccommon.messages"; //$NON-NLS-1$
+	public static String PecCommonLegend_0;
+	public static String PecCommonLegend_1;
+	public static String PecCommonLegend_10;
+	public static String PecCommonLegend_11;
+	public static String PecCommonLegend_12;
+	public static String PecCommonLegend_13;
+	public static String PecCommonLegend_14;
+	public static String PecCommonLegend_15;
+	public static String PecCommonLegend_2;
+	public static String PecCommonLegend_3;
+	public static String PecCommonLegend_4;
+	public static String PecCommonLegend_5;
+	public static String PecCommonLegend_6;
+	public static String PecCommonLegend_7;
+	public static String PecCommonLegend_8;
+	public static String PecCommonLegend_9;
+	public static String PecCommonLegendLabelProvider_0;
+	public static String PecCommonLegendLabelProvider_1;
+	public static String PecCommonLegendLabelProvider_2;
+	public static String PecCommonLegendLabelProvider_3;
+	public static String PecCommonSample_0;
+	public static String PecCommonTraceGraph_0;
+	public static String PecCommonTraceGraph_1;
+	public static String PecCommonTraceGraph_2;
+	public static String PecCommonTraceGraph_3;
+	public static String PecCommonTraceGraph_4;
+	static {
+		// initialize resource bundle
+		NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+	}
+
+	private Messages() {
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.peccommon/src/com/nokia/carbide/cpp/pi/peccommon/PecCommonGuiManager.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2010 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: 
+ *
+ */
+
+package com.nokia.carbide.cpp.pi.peccommon;
+
+import com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph;
+import com.nokia.carbide.cpp.pi.editors.PIPageEditor;
+
+/**
+ * This instance manages the IPC graphs of one editor. This functionality
+ * was moved here to avoid putting GUI content into the PecCommonTrace class
+ */
+public class PecCommonGuiManager {
+	/** uid of the editor */
+	protected int uid;
+	/** the PecCommonTrace instance for this editor */
+	protected PecCommonTrace trace;
+	/** the IpcTraceGraphs for this editor*/
+	protected PecCommonTraceGraph[] graphs;
+	/** The title of the graph */
+	protected String graphTitle;
+	
+	
+	/**
+	 * Constructor
+	 * @param uid UId of the editor
+	 * @param trace the PecCommonTrace instance for this editor
+	 * @param graphCount number of this type of graph for the editor
+	 * @param title the graph title
+	 */
+	public PecCommonGuiManager(int uid, PecCommonTrace trace, int graphCount, String title) {
+		super();
+		this.uid = uid;
+		this.trace = trace;
+		this.graphTitle = title;
+
+		graphs = new PecCommonTraceGraph[graphCount];
+	}
+
+
+	/**
+	 * Returns the graph generated for this trace
+	 * @param graphIndex the index of the graph to get
+	 * @param helpContextIdMainPage a help context id
+	 * @return the graph
+	 */
+	public GenericTraceGraph getTraceGraph(int graphIndex, String helpContextIdMainPage) {
+
+		// note that graphIndex need not match the index sent to MemTraceGraph
+		if ((graphIndex == PIPageEditor.THREADS_PAGE)
+				|| (graphIndex == PIPageEditor.BINARIES_PAGE)
+				|| (graphIndex == PIPageEditor.FUNCTIONS_PAGE)) {
+			if (graphs[graphIndex] == null) {
+				graphs[graphIndex] = createTraceGraph(graphIndex, trace, uid, this.graphTitle, helpContextIdMainPage);
+			}
+			return graphs[graphIndex];
+		}
+		
+		throw new IllegalArgumentException("Graph index out of range."); //$NON-NLS-1$
+	}
+
+
+	/**
+	 * Creates the graph. This may be implemented by subclasses.
+	 * @param graphIndex Index of the graph
+	 * @param aTrace The trace model class
+	 * @param aUid the uid of the editor
+	 * @param helpContextIdMainPage a help context id
+	 * @return the newly created graph
+	 */
+	protected PecCommonTraceGraph createTraceGraph(int graphIndex,
+			PecCommonTrace aTrace, int aUid, String aGraphTitle, String helpContextIdMainPage){
+		return new PecCommonTraceGraph(graphIndex, aTrace, aUid, this, aGraphTitle, helpContextIdMainPage);		
+	}
+
+
+	/**
+	 * Passes PIEvent.SELECTION_AREA_CHANGED to all available PEC graphs
+	 * by calling {@link PecCommonTraceGraph#selectionAreaChanged(double, double)}
+	 * @param newStart new start of selected area
+	 * @param newEnd new end of selected area
+	 */
+	void selectionAreaChanged(double newStart, double newEnd) {
+		for (PecCommonTraceGraph graph : graphs) {
+			if (graph != null){
+				graph.selectionAreaChanged(newStart, newEnd);
+			}
+		}
+	}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.peccommon/src/com/nokia/carbide/cpp/pi/peccommon/PecCommonLegend.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,511 @@
+/*
+ * Copyright (c) 2010 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: 
+ *
+ */
+
+package com.nokia.carbide.cpp.pi.peccommon;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.ActionContributionItem;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IContributionManager;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.action.SubMenuManager;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.jface.viewers.CheckStateChangedEvent;
+import org.eclipse.jface.viewers.CheckboxTableViewer;
+import org.eclipse.jface.viewers.ICheckStateListener;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.wizard.WizardDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.SashForm;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.dnd.TextTransfer;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.swt.events.FocusListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.actions.ActionFactory;
+import org.eclipse.ui.ide.IIDEActionConstants;
+
+import com.nokia.carbide.cpp.internal.pi.interfaces.ISaveTable;
+import com.nokia.carbide.cpp.internal.pi.save.SaveTableWizard;
+import com.nokia.carbide.cpp.pi.editors.PIPageEditor;
+
+/**
+ * Manages the legend for Performance Counter traces. 
+ */
+public class PecCommonLegend extends Composite{
+	private static final char QUOTE = '"';
+	private static final String PI_SAVE_TABLE = "PISaveTable";//$NON-NLS-1$
+	private static final String PI_COPY_TABLE = "PICopyTable";//$NON-NLS-1$
+	private static final String SAVE_ALL = "saveAll";//$NON-NLS-1$
+	
+	private final static String NEWLINE = System.getProperty("line.separator"); //$NON-NLS-1$
+	private static final String TAB = "\t"; //$NON-NLS-1$
+	private static final String COMMA = ",";//$NON-NLS-1$
+	
+	/** short description column, such as 'A' */
+	public static final int COLUMN_SHORT_TITLE = 0;
+	/** performance counter name column */
+	public static final int COLUMN_NAME = 1;
+	/** average value column */
+	public static final int COLUMN_AVERAGE = 2;
+	/** sum of values column */
+	public static final int COLUMN_SUM = 3;
+	/** minimum of values column */
+	public static final int COLUMN_MIN = 4;
+	/** maximum of values column */
+	public static final int COLUMN_MAX = 5;
+	
+	protected CheckboxTableViewer viewer;
+	protected PecCommonTraceGraph graph;
+	protected PecCommonTrace trace;
+	
+    // menu items
+	protected Action copyTableAction;
+	protected Action copyAction;
+	protected Action saveTableAction;
+	private IAction checkAllAction;
+	private IAction uncheckAllAction;
+
+	
+	/**
+	 * Constructor
+	 * @param graph the graph that this legend belongs to 
+	 * @param parent the parent composite
+	 * @param title Title for the legend
+	 * @param trace The model containing the samples
+	 */
+	public PecCommonLegend(final PecCommonTraceGraph graph, Composite parent, String title, PecCommonTrace trace){
+		super(parent, SWT.NONE);
+		this.graph = graph;
+		this.trace = trace;
+		
+		setLayout(GridLayoutFactory.fillDefaults().numColumns(1).spacing(0, 0).create());
+
+		Label label = new Label(this, SWT.CENTER);
+		label.setBackground(getDisplay().getSystemColor(SWT.COLOR_WHITE));
+		//label.setFont(PIPageEditor.helvetica_8);
+		label.setText(title);
+		label.setLayoutData(GridDataFactory.fillDefaults().align(SWT.FILL, SWT.BEGINNING).grab(true, false).create());
+		
+		//create table viewer
+		final Table table = new Table(this, SWT.CHECK | SWT.BORDER | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION);
+		this.viewer = new CheckboxTableViewer(table);
+
+		PecCommonLegendLabelProvider labelProvider = createLabelProvider();
+		viewer.setLabelProvider(labelProvider);
+		viewer.setContentProvider(new PecCommonLegendContentProvider(trace));
+
+        PecCommonLegendViewerSorter columnSorter = createLegendSorter();
+        createColumns(this.viewer, columnSorter);
+
+		table.setHeaderVisible(true);
+		table.setLinesVisible(true);
+        columnSorter.setSortColumn(COLUMN_SHORT_TITLE);
+        viewer.setComparator(columnSorter);
+		
+		viewer.addSelectionChangedListener(new ISelectionChangedListener() {
+			public void selectionChanged(SelectionChangedEvent arg0) {
+				if (copyAction == null)
+					return;
+
+				// when selection changes, the ability to copy may change
+				copyAction.setEnabled(table.getSelectionCount() > 0);
+				PIPageEditor.getActionBars().updateActionBars();
+			}
+		});
+		
+		viewer.addCheckStateListener(new ICheckStateListener() {
+			
+			/* (non-Javadoc)
+			 * @see org.eclipse.jface.viewers.ICheckStateListener#checkStateChanged(org.eclipse.jface.viewers.CheckStateChangedEvent)
+			 */
+			public void checkStateChanged(CheckStateChangedEvent event) {
+				PecCommonLegendElement el = (PecCommonLegendElement)event.getElement();
+				graph.addOrRemoveSeries(el.getId(), event.getChecked());
+			}
+		});
+		
+        viewer.setInput(trace);
+        viewer.getTable().setLayoutData(GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).grab(true, true).create());
+        addActions(viewer);
+        viewer.getTable().addFocusListener(new PecCommonLegendFocusListener(viewer));
+        addContextMenu(viewer);
+        viewer.setAllChecked(true); //default
+
+        PlatformUI.getWorkbench().getHelpSystem().setHelp(this, graph.getContextHelpId());
+	}
+	
+
+
+	/**
+	 * Creates the LabelProvider for the legend table
+	 * @return
+	 */
+	protected PecCommonLegendLabelProvider createLabelProvider() {
+		return new PecCommonLegendLabelProvider();
+	}
+
+
+
+	/**
+	 * Refreshes content of the legend
+	 */
+	public void refreshLegend(){
+		viewer.refresh();
+	}
+	
+	protected void createColumns(final TableViewer aViewer, final PecCommonLegendViewerSorter columnSorter)
+ {
+		final Table table = aViewer.getTable();
+
+		TableColumn column = new TableColumn(table, SWT.LEFT);
+		column.setText(Messages.PecCommonLegend_0);
+		column.setWidth(50);
+		column.setMoveable(true);
+		column.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				columnSorter.setSortColumn(COLUMN_SHORT_TITLE);
+				aViewer.refresh();
+			}
+		});
+
+		column = new TableColumn(table, SWT.LEFT);
+		column.setText(Messages.PecCommonLegend_1);
+		column.setWidth(150);
+		column.setMoveable(true);
+		column.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				columnSorter.setSortColumn(COLUMN_NAME);
+				aViewer.refresh();
+			}
+		});
+
+		column = new TableColumn(table, SWT.RIGHT);
+		column.setText(String.format(Messages.PecCommonLegend_2, trace.getSamplingInterval()));
+		column.setWidth(100);
+		column.setMoveable(true);
+		column.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				columnSorter.setSortColumn(COLUMN_AVERAGE);
+				aViewer.refresh();
+			}
+		});
+
+		column = new TableColumn(table, SWT.RIGHT);
+		column.setText(Messages.PecCommonLegend_3);
+		column.setWidth(100);
+		column.setMoveable(true);
+		column.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				columnSorter.setSortColumn(COLUMN_SUM);
+				aViewer.refresh();
+			}
+		});
+
+		column = new TableColumn(table, SWT.RIGHT);
+		column.setText(String.format(Messages.PecCommonLegend_4, trace.getSamplingInterval()));
+		column.setWidth(100);
+		column.setMoveable(true);
+		column.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				columnSorter.setSortColumn(COLUMN_MIN);
+				aViewer.refresh();
+			}
+		});
+
+		column = new TableColumn(table, SWT.RIGHT);
+		column.setText(String.format(Messages.PecCommonLegend_5, trace.getSamplingInterval()));
+		column.setWidth(100);
+		column.setMoveable(true);
+		column.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				columnSorter.setSortColumn(COLUMN_MAX);
+				aViewer.refresh();
+			}
+		});
+	}
+
+	/**
+	 * Maximises or restores the legend table viewer
+	 * @param maximise true for maximise, false for restore
+	 */
+	public void setLegendMaximised(boolean maximise) {
+		((SashForm)this.getParent()).setMaximizedControl(maximise ? this : null);		
+	}
+
+	/**
+	 * Minimises or restores legend view
+	 * @param visible true for setting visible, false for hiding
+	 */
+	public void setLegendVisible(boolean visible) {
+		this.setVisible(visible);
+		
+	}
+	
+	private void addActions(final TableViewer legendViewer) {	
+		
+		checkAllAction = new Action(Messages.PecCommonLegend_6){
+			@Override
+			public void run() {
+				viewer.setAllChecked(true);
+				graph.showAllSeries();
+			}			
+		};
+		checkAllAction.setEnabled(true);
+		checkAllAction.setText(Messages.PecCommonLegend_7);
+		
+		uncheckAllAction = new Action(Messages.PecCommonLegend_8){
+			@Override
+			public void run() {
+				viewer.setAllChecked(false);
+				graph.removeAllSeries();
+			}			
+		};
+		uncheckAllAction.setEnabled(true);
+		uncheckAllAction.setText(Messages.PecCommonLegend_9);
+		
+		copyAction = new Action(Messages.PecCommonLegend_10) {
+			@Override
+			public void run() {
+				copyToClipboard(legendContentToString(((IStructuredSelection)legendViewer.getSelection()).toArray(), false, TAB));
+			}
+		};
+		copyAction.setEnabled(false);
+		copyAction.setText(Messages.PecCommonLegend_11);
+
+		copyTableAction = new Action(Messages.PecCommonLegend_12) {
+			@Override
+			public void run() {
+				Object[] elements = ((IStructuredContentProvider)legendViewer.getContentProvider()).getElements(null); 
+				legendViewer.getComparator().sort(legendViewer, elements);
+				copyToClipboard(legendContentToString(elements, true, TAB));
+			}
+		};
+		copyTableAction.setEnabled(true);
+		copyTableAction.setId(PI_COPY_TABLE); 
+		copyTableAction.setText(Messages.PecCommonLegend_13);
+
+		saveTableAction = new Action(Messages.PecCommonLegend_14) { 
+			@Override
+			public void run() {
+				
+				WizardDialog dialog = new WizardDialog(PlatformUI.getWorkbench().getDisplay().getActiveShell(), new SaveTableWizard(new ISaveTable(){
+					public String getData() {
+						Object[] elements = ((PecCommonLegendContentProvider)legendViewer.getContentProvider()).getElements(null); 
+						legendViewer.getComparator().sort(legendViewer, elements);
+						return legendContentToString(elements, true, COMMA).toString();
+					}
+				}));
+		    	dialog.open();
+			}
+		};
+		saveTableAction.setEnabled(true);
+		saveTableAction.setId(PI_SAVE_TABLE);
+		saveTableAction.setText(Messages.PecCommonLegend_15);
+		
+}
+	
+	/**
+	 * Copies the content of the given StringBuilder to the clipboard. 
+	 */
+	protected void copyToClipboard(StringBuilder sb) {
+		
+		if (sb.length() > 0) {
+			TextTransfer textTransfer = TextTransfer.getInstance();
+			Clipboard cb = new Clipboard(this.getDisplay());
+			try {
+				cb.setContents(new Object[] { sb.toString() },
+						new Transfer[] { textTransfer });
+			} finally {
+				cb.dispose();
+			}
+		}
+		
+	}
+	
+	/**
+	 * Returns the content of the given objects in human-readable format.
+	 * Optionally includes column headers. Columns are separated by tabs. Elements are separated
+	 * by newlines. 
+	 * @param objects Array of objects. Elements of the array are assumed to be of type PecCommonLegendElement
+	 * @param includeHeader true if column headers are to be included	 
+	 * @return 
+	 */
+	protected StringBuilder legendContentToString(Object[] objects, boolean includeHeader, String separator) {
+		StringBuilder sb = new StringBuilder();
+		
+		if (includeHeader){
+			for (int i = 0; i < viewer.getTable().getColumnCount(); i++) {
+				if (i != 0){
+					sb.append(separator);
+				}
+				sb.append(viewer.getTable().getColumn(i).getText());
+			}
+			sb.append(NEWLINE);
+		}
+		
+		PecCommonLegendLabelProvider labelProvider = (PecCommonLegendLabelProvider)viewer.getLabelProvider();
+		for (Object o : objects) {
+			PecCommonLegendElement pecLegendElement = (PecCommonLegendElement) o;
+			for (int i = 0; i < viewer.getTable().getColumnCount(); i++) {
+				if (i != 0){
+					sb.append(separator);
+				}
+				String s = labelProvider.getColumnText(pecLegendElement, i);
+				if (s.indexOf(separator) >= 0){
+					sb.append(QUOTE).append(s).append(QUOTE);	//quote if the separator occurs in the value string				
+				} else {
+					sb.append(s);
+				}
+			}
+			sb.append(NEWLINE);
+		}
+		return sb;
+	}
+
+
+	/**
+	 * Updates enabled-state of actions
+	 * @param table the table that the actions apply to
+	 */
+	protected void updateActionStatus(Table table) {
+		copyAction.setEnabled(table.getSelectionCount() > 0);
+		copyTableAction.setEnabled(table.getItemCount() > 0);
+		saveTableAction.setEnabled(table.getItemCount() > 0);		
+	}
+
+
+	private void addContextMenu(final TableViewer aViewer) {
+		final MenuManager mgr = new MenuManager();
+		mgr.add(new Separator());
+		mgr.add(checkAllAction);
+		mgr.add(uncheckAllAction);
+		mgr.add(new Separator());
+		mgr.add(copyAction);
+		mgr.add(copyTableAction);
+		mgr.add(new Separator());
+		mgr.add(saveTableAction);
+		aViewer.getControl().setMenu(mgr.createContextMenu(aViewer.getControl()));		
+	}
+	
+
+	/**
+	 * On gaining focus, we add copy / save actions to the top file and edit menu, 
+	 * on losing it, we remove those actions again.   
+	 *
+	 */
+	private class PecCommonLegendFocusListener implements FocusListener {
+		private TableViewer legendViewer;
+		private IAction oldCopyAction;
+
+		public PecCommonLegendFocusListener(TableViewer legendViewer) {
+			this.legendViewer = legendViewer;
+		}
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see
+		 * org.eclipse.swt.events.FocusListener#focusGained(org.eclipse.
+		 * swt.events.FocusEvent)
+		 */
+		public void focusGained(org.eclipse.swt.events.FocusEvent arg0) {
+			IActionBars bars = PIPageEditor.getActionBars();
+
+			oldCopyAction = PIPageEditor.getActionBars().getGlobalActionHandler(ActionFactory.COPY.getId());
+			bars.setGlobalActionHandler(ActionFactory.COPY.getId(),	copyAction);
+			bars.updateActionBars();
+
+			// add copyTableAction to the Edit menu
+			IMenuManager editMenuManager = bars.getMenuManager().findMenuUsingPath(IIDEActionConstants.M_EDIT);
+
+			if (editMenuManager instanceof SubMenuManager) {
+				IContributionManager editManager = ((SubMenuManager) editMenuManager).getParent();
+				editMenuManager.remove(PI_COPY_TABLE);
+				ActionContributionItem item = new ActionContributionItem(copyTableAction);
+				item.setVisible(true);
+				editManager.prependToGroup(IIDEActionConstants.CUT_EXT, item);
+			}
+
+			// add saveTableAction to the File menu
+			IMenuManager fileMenuManager = bars.getMenuManager().findMenuUsingPath(IIDEActionConstants.M_FILE);
+
+			if (fileMenuManager instanceof SubMenuManager) {
+				IContributionManager fileManager = ((SubMenuManager) fileMenuManager).getParent();
+
+				fileMenuManager.remove(PI_SAVE_TABLE);
+				ActionContributionItem item = new ActionContributionItem(saveTableAction);
+				item.setVisible(true);
+				fileManager.insertAfter(SAVE_ALL, item);
+			}
+			
+			updateActionStatus(legendViewer.getTable());
+		}
+
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see
+		 * org.eclipse.swt.events.FocusListener#focusLost(org.eclipse.swt
+		 * .events.FocusEvent)
+		 */
+		public void focusLost(org.eclipse.swt.events.FocusEvent arg0) {
+			IActionBars bars = PIPageEditor.getActionBars();
+			bars.setGlobalActionHandler(ActionFactory.COPY.getId(),
+					oldCopyAction);
+			bars.updateActionBars();
+
+			SubMenuManager editMenuManager = (SubMenuManager) PIPageEditor
+					.getMenuManager().find(IIDEActionConstants.M_EDIT);
+			editMenuManager.remove(PI_COPY_TABLE);
+			editMenuManager.update();
+
+			SubMenuManager fileMenuManager = (SubMenuManager) PIPageEditor
+					.getMenuManager().find(IIDEActionConstants.M_FILE);
+			fileMenuManager.remove(PI_SAVE_TABLE);
+			fileMenuManager.update();
+		}
+	}		
+
+	/**
+	 * Creates the sorter used for the legend view. Sub classes may override this
+	 * @return PecCommonLegendViewerSorter
+	 */
+	protected PecCommonLegendViewerSorter createLegendSorter(){
+		return new PecCommonLegendViewerSorter();
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.peccommon/src/com/nokia/carbide/cpp/pi/peccommon/PecCommonLegendContentProvider.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2010 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: 
+ *
+ */
+
+package com.nokia.carbide.cpp.pi.peccommon;
+
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+
+/**
+ * Performance Counter Legend: ContentProvider for TableViewer 
+ */
+public class PecCommonLegendContentProvider implements IStructuredContentProvider {
+
+	private PecCommonTrace trace; //PecCommonTrace manages the model
+
+
+    /**
+     * SimpleListContentProvider constructor comment.
+     * @param trace The trace model
+     */
+    public PecCommonLegendContentProvider(PecCommonTrace trace) {
+        super();
+        this.trace = trace;
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.jface.viewers.IContentProvider#dispose()
+     */
+    public void dispose() {
+    	//nothing to do
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
+     */
+    public Object[] getElements(Object inputElement) {
+        return trace.getLegendElements();
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
+     */
+    public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+    	//we don't expect the input to change during the lifetime of this object
+    }
+	
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.peccommon/src/com/nokia/carbide/cpp/pi/peccommon/PecCommonLegendElement.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2010 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: 
+ *
+ */
+
+package com.nokia.carbide.cpp.pi.peccommon;
+
+/**
+ * An element for the Performance Counter Trace legend view.
+ * Represented in one line of the legend table viewer.
+ */
+public class PecCommonLegendElement {
+	private int id; // id of this trace event
+	private String name; //name of performance counter
+	private char character; //short name, such as 'A' used to refer to in column headings
+	private long sum; //sum off all values in time frame
+	private long cnt; //number of samples in time frame
+	private int min; //the lowest value in the time frame
+	private int max; //the highest value in the time frame
+	private boolean coreValuesOnly; //show only 
+	
+	/**
+	 * Constructor
+	 * @param id trace event id
+	 * @param name the name of the event
+	 * @param character character representing the event, i.e. A for the first event, B for the second etc.
+	 * @param coreValuesOnly Calculate / show only average, min, and max
+	 */
+	public PecCommonLegendElement(int id, String name, char character, boolean coreValuesOnly) {
+		this.id = id;
+		this.name = name;
+		this.character = character;
+		this.coreValuesOnly = coreValuesOnly;
+	}
+	/**
+	 * @return the trace event id
+	 */
+	public int getId() {
+		return id;
+	}
+	/**
+	 * @return the sum
+	 */
+	public long getSum() {
+		return sum;
+	}
+	/**
+	 * @param sum the sum to set
+	 */
+	public void setSum(long sum) {
+		this.sum = sum;
+	}
+	/**
+	 * @return the cnt
+	 */
+	public long getCnt() {
+		return cnt;
+	}
+	/**
+	 * @param cnt the cnt to set
+	 */
+	public void setCnt(long cnt) {
+		this.cnt = cnt;
+	}
+	/**
+	 * @return the min
+	 */
+	public int getMin() {
+		return min;
+	}
+	/**
+	 * @param min the min to set
+	 */
+	public void setMin(int min) {
+		this.min = min;
+	}
+	/**
+	 * @return the max of sample values in the selected area. 
+	 */
+	public int getMax() {
+		return max;
+	}
+	/**
+	 * @param max the max to set
+	 */
+	public void setMax(int max) {
+		this.max = max;
+	}
+	/**
+	 * @return the name
+	 */
+	public String getName() {
+		return name;
+	}
+	/**
+	 * @return the character
+	 */
+	public char getCharacter() {
+		return character;
+	}
+	/**
+	 * @return true, if only average, min, and max values are to be displayed; false otherwise
+	 */
+	public boolean isCoreValuesOnly() {
+		return coreValuesOnly;
+	}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.peccommon/src/com/nokia/carbide/cpp/pi/peccommon/PecCommonLegendLabelProvider.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2010 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: 
+ *
+ */
+
+package com.nokia.carbide.cpp.pi.peccommon;
+
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * Performance Counter Legend: LabelProvider for TableViewer 
+ */
+public class PecCommonLegendLabelProvider extends LabelProvider implements ITableLabelProvider {
+	
+	private static final String EMPTY_STRING = ""; //$NON-NLS-1$
+	
+	public Image getColumnImage(Object element, int columnIndex) {
+		return null;
+	}
+
+	public String getColumnText(Object element, int columnIndex) {
+		String s = null;
+		
+		if (element instanceof PecCommonLegendElement){
+			PecCommonLegendElement le = (PecCommonLegendElement)element;
+			
+			switch (columnIndex) {
+			
+			case PecCommonLegend.COLUMN_SHORT_TITLE:
+				s = String.valueOf(le.getCharacter());
+				break;
+				
+			case PecCommonLegend.COLUMN_NAME:
+				s = le.getName(); 
+				break;
+				
+			case PecCommonLegend.COLUMN_AVERAGE:
+				if (le.getCnt() > 0){
+					s = String.format(Messages.PecCommonLegendLabelProvider_0, le.getSum() / (float)le.getCnt());					
+				}
+				break;
+				
+			case PecCommonLegend.COLUMN_SUM:
+				if (le.getCnt() > 0 && !le.isCoreValuesOnly()){
+					s = String.format(Messages.PecCommonLegendLabelProvider_1, le.getSum());
+				}
+				break;
+				
+			case PecCommonLegend.COLUMN_MIN:
+				if (le.getCnt() > 0){
+					s = String.format(Messages.PecCommonLegendLabelProvider_2, le.getMin());
+				}
+				break;
+				
+			case PecCommonLegend.COLUMN_MAX:
+				if (le.getCnt() > 0){
+					s = String.format(Messages.PecCommonLegendLabelProvider_3, le.getMax());
+				}
+				break;
+				
+			default:
+				break;
+			}
+			
+		}
+		return s == null ? EMPTY_STRING : s;
+	}
+	
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.peccommon/src/com/nokia/carbide/cpp/pi/peccommon/PecCommonLegendViewerSorter.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2010 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: 
+ *
+ */
+
+package com.nokia.carbide.cpp.pi.peccommon;
+
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerComparator;
+
+/**
+ * Sorter for the IPC legend
+ */
+public class PecCommonLegendViewerSorter extends ViewerComparator {
+	protected int columnIdx;
+	protected boolean sortUp;
+	
+	/**
+	 * Constructor
+	 */
+	public PecCommonLegendViewerSorter() {
+		super();
+		sortUp = false;
+		columnIdx = -1;
+	}
+	
+	/**
+	 * Sets the column to be sorted for subsequent sorts. This will also 
+	 * reverse sort order. 
+	 * @param columnIdx the column to sort on next
+	 */
+	public void setSortColumn(int columnIdx){
+		if (this.columnIdx == columnIdx){
+			sortUp = !sortUp;//change sort order	
+		} else {
+			this.columnIdx = columnIdx;
+			sortUp = true; //default sort order		
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.viewers.ViewerComparator#compare(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
+	 */
+	@Override
+	public int compare(Viewer viewer, Object e1, Object e2) {
+		PecCommonLegendElement le1 = (PecCommonLegendElement)e1;
+		PecCommonLegendElement le2 = (PecCommonLegendElement)e2;
+		int ret = 0;
+
+		switch (columnIdx) {
+		case PecCommonLegend.COLUMN_SHORT_TITLE:
+			ret = le1.getCharacter() - le2.getCharacter();
+			break;
+		case PecCommonLegend.COLUMN_NAME:
+			ret = le1.getName().compareTo(le2.getName()); 
+			break;
+		case PecCommonLegend.COLUMN_AVERAGE:
+			float a1 = le1.getSum() / (le1.getCnt() > 0 ? le1.getCnt() : 1); 
+			float a2 = le2.getSum() / (le2.getCnt() > 0 ? le2.getCnt() : 1); 
+			ret = Float.compare(a1, a2);
+			break;
+		case PecCommonLegend.COLUMN_SUM:
+			ret = (int)(le1.getSum() - le2.getSum());
+			break;
+		case PecCommonLegend.COLUMN_MIN:
+			ret = le1.getMin() - le2.getMin(); 
+			break;
+		case PecCommonLegend.COLUMN_MAX:
+			ret = le1.getMax() - le2.getMax(); 
+			break;
+		default:
+			throw new IllegalStateException("Unknown column index in legend"); //$NON-NLS-1$
+		}
+		
+		return sortUp? ret : (ret * -1);
+		
+	}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.peccommon/src/com/nokia/carbide/cpp/pi/peccommon/PecCommonPlugin.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,78 @@
+package com.nokia.carbide.cpp.pi.peccommon;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+
+import com.nokia.carbide.cpp.internal.pi.plugin.model.AbstractPiPlugin;
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class PecCommonPlugin extends AbstractPiPlugin {
+
+	/** The plug-in ID */
+	public static final String PLUGIN_ID = "com.nokia.carbide.cpp.pi.peccommon"; //$NON-NLS-1$
+
+	// The shared instance
+	private static PecCommonPlugin plugin;
+
+	/**
+	 * The constructor
+	 */
+	public PecCommonPlugin() {
+		super();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+	 */
+	@Override
+	public void start(BundleContext context) throws Exception {
+		super.start(context);
+		plugin = this;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+	 */
+	@Override
+	public void stop(BundleContext context) throws Exception {
+		plugin = null;
+		super.stop(context);
+	}
+
+	/**
+	 * Returns the shared instance
+	 *
+	 * @return the shared instance
+	 */
+	public static PecCommonPlugin getDefault() {
+		return plugin;
+	}
+
+	/**
+	 * Returns a File corresponding to the given bundle relative path.
+	 * @param path the bundle relative path to resource to locate
+	 * @return the File corresponding to the given bundle relative path, or null
+	 * @throws IOException
+	 */
+	public File locateFileInBundle(final String path) throws IOException {
+		Bundle myBundle= getDefault().getBundle();
+		IPath ppath= new Path(path);
+		ppath= ppath.makeRelative();
+		URL[] urls= FileLocator.findEntries(myBundle, ppath);
+		if(urls.length != 1) {
+			return null;
+		}
+		return new File(FileLocator.toFileURL(urls[0]).getFile());
+	}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.peccommon/src/com/nokia/carbide/cpp/pi/peccommon/PecCommonSample.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2010 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: 
+ *
+ */
+
+package com.nokia.carbide.cpp.pi.peccommon;
+
+import java.util.Arrays;
+
+import com.nokia.carbide.cpp.internal.pi.model.GenericSample;
+
+
+/**
+ * Represents a Performance Counter Sample
+ */
+public class PecCommonSample extends GenericSample 
+{
+	private static final long serialVersionUID = 84123271817196064L;
+	
+	/**
+	 * Sample values for the captured performance counter events
+	 */
+	public int[] values;
+	
+	/**
+	 * Constructor
+	 * @param values Sample values for the captured events
+	 * @param time Time the sample was taken
+	 */
+	public PecCommonSample(int[] values, long time)
+	{
+		super();
+		this.sampleSynchTime = time;
+		this.values = values;
+	}
+
+	@Override
+	public String toString() {
+		return String.format(Messages.PecCommonSample_0, sampleSynchTime, Arrays.toString(values));
+	}
+	
+	
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.peccommon/src/com/nokia/carbide/cpp/pi/peccommon/PecCommonTrace.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2010 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: 
+ *
+ */
+
+package com.nokia.carbide.cpp.pi.peccommon;
+
+import java.util.Arrays;
+import java.util.Vector;
+
+import com.nokia.carbide.cpp.internal.pi.model.GenericSample;
+import com.nokia.carbide.cpp.internal.pi.model.GenericSampledTrace;
+
+/**
+ * The model class for Performance Counter traces. This manages the data
+ * for the IPC trace graphs, and is responsible for creating the graphs. 
+ */
+public class PecCommonTrace extends GenericSampledTrace {
+	private static final long serialVersionUID = 4425739452429422333L;
+
+	private int samplingInterval;
+	
+	/**
+	 * hold the event types which have been traced
+	 */
+	private String[] valueTypes;
+
+	// the following is needed for calculations for the legend (depend on
+	// selected area). We keep it here since the selected area is the same for all graphs.
+	// If this assumption ever changes, the calculations need to be moved into
+	// the LegendContentProvider
+	private double selectionStart;
+	private double selectionEnd;
+	private transient boolean needsRecalc;
+
+	private transient PecCommonLegendElement[] legendElements;
+	
+	/**
+	 * Constructor
+	 */
+	public PecCommonTrace() {
+		super();
+		selectionStart = -1;
+		selectionEnd = -1;
+		needsRecalc = true;
+	}
+	
+	
+
+	/**
+	 * Set the event types present in the interconnect performance counter trace.
+	 * @param valueTypes the event types to set
+	 */
+	public void setValueTypes(String[] valueTypes) {
+		this.valueTypes = valueTypes;
+	}
+
+	/**
+	 * Get the event types present in the interconnect performance counter trace.
+	 * @return the event types present in the trace
+	 */
+	public String[] getValueTypes() {
+		return valueTypes;
+	}
+
+	/**
+	 * @return the sampling interval in milliseconds
+	 */
+	public int getSamplingInterval() {
+		return samplingInterval;
+	}
+
+	/**
+	 * Setter for the sampling interval in milliseconds
+	 * @param samplingInterval the sampling interval to set
+	 */
+	public void setSamplingInterval(int samplingInterval) {
+		this.samplingInterval = samplingInterval;
+	}
+	
+	/**
+	 * Callback for PIEvent.SELECTION_AREA_CHANGED
+	 * @param newStart new selection start
+	 * @param newEnd new selection end
+	 */
+	public void selectionAreaChanged(double newStart, double newEnd) {
+		if (newStart != selectionStart || newEnd != selectionEnd){
+			selectionStart = newStart;
+			selectionEnd = newEnd;
+			needsRecalc = true;
+		}
+	}    
+	
+    /**
+	 * @return the legendElements
+	 */
+	public PecCommonLegendElement[] getLegendElements() {
+		if (needsRecalc || legendElements == null){
+			needsRecalc = false;
+			calculateValues();
+		}
+		return legendElements;
+	}
+	
+	/**
+	 * calculates values for the legend depending on the selected time frame
+	 */
+	private void calculateValues() {
+    	int c = this.valueTypes.length;
+		int[] cnts = new int[c];
+		long[] sums = new long[c];
+		int[] mins = new int[c];
+		int[] maxs = new int[c];
+
+		if (selectionStart >= 0 && selectionEnd >= 0){
+			
+			Arrays.fill(mins, Integer.MAX_VALUE);
+			Arrays.fill(maxs, Integer.MIN_VALUE);
+			
+			int start = (int) ((selectionStart + 0.5f));
+			int end = (int) ((selectionEnd + 0.5f));
+			
+			Vector<GenericSample> selectedSamples = this.getSamplesInsideTimePeriod(start, end);
+			
+			for (GenericSample genericSample : selectedSamples) {
+				PecCommonSample sample = (PecCommonSample)genericSample;
+				
+				//average, sum, min, max
+				for (int i = 0; i < sample.values.length; i++) {
+					int value = sample.values[i];
+					
+					cnts[i] ++;
+					sums[i] += value;
+					if (value < mins[i]){
+						mins[i] = value;					
+					} 
+					if (value > maxs[i]){
+						maxs[i] = value;					
+					}
+				}
+			}
+		}
+		
+		legendElements = createLegendElements(legendElements, this.valueTypes, cnts, sums, mins, maxs);
+	}
+	
+	/**
+	 * Creates or updates all legend elements
+	 * @param existingElements Existing elements, if they need updating. If null, new elements are to be created.
+	 * @param typeStrings Array of all trace event strings present in the trace 
+	 * @param cnts Array of all count values (one per graph)
+	 * @param sums Array of all sum values (one per graph)
+	 * @param mins Array of all minimum values (one per graph)
+	 * @param maxs Array of all maximum values (one per graph)
+	 * @return Array of legend elements created or updated
+	 */
+	protected PecCommonLegendElement[] createLegendElements(PecCommonLegendElement[] existingElements, String[] typeStrings, int[] cnts,
+			long[] sums, int[] mins, int[] maxs) {
+		
+    	int c = typeStrings.length;
+    	boolean create = existingElements == null;    	
+    	PecCommonLegendElement[] les = create ? new PecCommonLegendElement[c] : existingElements;
+		char shortTitle = 'A';
+		
+		for (int i = 0; i < c; i++) {
+			
+			PecCommonLegendElement legendElement = create ? new PecCommonLegendElement(i, typeStrings[i], shortTitle, false) : existingElements[i];
+			legendElement.setCnt(cnts[i]);
+			legendElement.setSum(sums[i]);
+			legendElement.setMax(maxs[i]);
+			legendElement.setMin(mins[i]);
+			les[i] = legendElement;
+			shortTitle ++;
+		}
+		return les;
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.peccommon/src/com/nokia/carbide/cpp/pi/peccommon/PecCommonTraceGraph.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,669 @@
+/*
+ * Copyright (c) 2010 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: 
+ *
+ */
+
+package com.nokia.carbide.cpp.pi.peccommon;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Vector;
+
+import org.eclipse.draw2d.ColorConstants;
+import org.eclipse.draw2d.FigureCanvas;
+import org.eclipse.draw2d.Graphics;
+import org.eclipse.draw2d.MouseEvent;
+import org.eclipse.draw2d.MouseMotionListener;
+import org.eclipse.draw2d.Panel;
+import org.eclipse.draw2d.Viewport;
+import org.eclipse.jface.action.Action;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+
+import com.nokia.carbide.cpp.internal.pi.analyser.NpiInstanceRepository;
+import com.nokia.carbide.cpp.internal.pi.analyser.ProfileVisualiser;
+import com.nokia.carbide.cpp.internal.pi.model.GenericSample;
+import com.nokia.carbide.cpp.internal.pi.plugin.model.ITitleBarMenu;
+import com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph;
+import com.nokia.carbide.cpp.internal.pi.visual.GraphComposite;
+import com.nokia.carbide.cpp.internal.pi.visual.PIEvent;
+import com.nokia.carbide.cpp.internal.pi.visual.PIEventListener;
+import com.nokia.carbide.cpp.pi.editors.PIPageEditor;
+import com.nokia.carbide.cpp.pi.util.ColorPalette;
+import com.nokia.carbide.cpp.pi.visual.IGenericTraceGraph;
+
+/**
+ * The performance counter graph class, responsible for drawing the several graphs
+ * based on performance counters as well as managing the legend views to some extend
+ */
+public class PecCommonTraceGraph extends GenericTraceGraph implements 
+		MouseMotionListener, PIEventListener,  ITitleBarMenu  {
+
+	private static int X_LEGEND_HEIGHT = 20;
+
+	/** for tooltip: margin for search area for finding a domain object */
+	private static final int MARGIN_IN_PIXELS = 5;
+	
+	/** the graph index; there is one graph per editor page (with identical content)*/
+	//private int graphIndex;
+	protected PecCommonTrace trace;
+	private String graphTitle;
+	private String helpContextId;
+
+	/** number of series to draw; each in a separate graph section */
+	private int typeAmount = 0;
+	protected List<Integer> drawSeries;
+	
+	private int[][] origYCoords;
+	private int[][] points;
+
+	private int[] exact_mins;
+	private int[] exact_maxs;
+
+	private int[] mins;
+	private int[] maxs;
+	
+	private double currentlyCalcFinalScale = -1;
+	private int currentlyCalcFinalHeight = -1;
+
+	protected FigureCanvas leftFigureCanvas;
+
+	/** marks graph as dirty so it gets re-drawn */
+	protected boolean dirty;
+
+	private PecCommonLegend legend;
+	
+	/** GUI manager has knowledge off all IpcTraceGraphs; can broadcast some of the events */
+	private PecCommonGuiManager guiManager;
+	
+	/**
+	 * Constructor
+	 * @param graphIndex the index of the graph (corresponds to the page in the editor)
+	 * @param pecTrace the trace class
+	 * @param uid the uid to identify the current editor
+	 * @param guiManager IpcGuiManager which manages all graphs
+	 * @param title The title of the graph
+	 * @param helpContextIdMainPage 
+	 */
+	public PecCommonTraceGraph(int graphIndex, PecCommonTrace pecTrace, int uid, PecCommonGuiManager guiManager, String title, String helpContextIdMainPage) {
+		super(pecTrace);
+
+//		this.graphIndex = graphIndex;
+		this.trace = pecTrace;
+		this.guiManager = guiManager;
+		this.graphTitle = title;
+		this.helpContextId = helpContextIdMainPage;
+		
+		typeAmount = pecTrace.getValueTypes().length;
+
+		int sampleCount = pecTrace.getSampleAmount();
+		origYCoords = new int[typeAmount][sampleCount];
+		points = new int[typeAmount][sampleCount*2];
+		exact_mins = new int[typeAmount];
+		exact_maxs = new int[typeAmount];
+		mins = new int[typeAmount];
+		maxs = new int[typeAmount];
+		
+		drawSeries = new ArrayList<Integer>();
+		//by default, draw all graphs on screen
+		showAll();
+		
+		this.initialiseData();
+		
+		ProfileVisualiser pV = NpiInstanceRepository.getInstance().getProfilePage(uid, graphIndex);
+		legend = createLegend(pV.getBottomComposite());
+	}
+	
+	/**
+	 * Creates the legend
+	 * @param bottomComposite The composite to create the legend in
+	 */
+	protected PecCommonLegend createLegend(Composite bottomComposite) {		
+		return new PecCommonLegend(this, bottomComposite, getTitle(), trace);
+	}
+
+	/**
+	 * Fill mins, maxs, and origYCoords arrays
+	 */
+	private void initialiseData() {
+		Vector<GenericSample> sv = trace.samples;
+
+		Arrays.fill(exact_mins, Integer.MAX_VALUE);
+		Arrays.fill(exact_maxs, Integer.MIN_VALUE);
+
+		for (int x = 0; x < sv.size(); x++) {
+			PecCommonSample s = (PecCommonSample) sv.get(x);
+
+			for (int i = 0; i < typeAmount; i++) {
+				int value = s.values[i];
+
+				if (value < exact_mins[i]){
+					exact_mins[i] = value;					
+				} 
+				if (value > exact_maxs[i]){
+					exact_maxs[i] = value;					
+				}
+
+				origYCoords[i][x] = value;
+			}
+		}
+		
+		//let the graph draw in area [0, prettyMaxValue]
+		for (int i = 0; i < typeAmount; i++) {
+			mins[i] = 0;
+			maxs[i] = prettyMaxValue(exact_maxs[i]);
+		}
+	}
+	
+	private void showAll(){
+		drawSeries.clear();
+		for (int i = 0; i < typeAmount; i++) {
+			drawSeries.add(i);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph#repaint()
+	 */
+	@Override
+	public void repaint() {
+		this.parentComponent.repaintComponent();
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph#paint(org.eclipse.draw2d.Panel, org.eclipse.draw2d.Graphics)
+	 */
+	@Override
+	public void paint(org.eclipse.draw2d.Panel panel,
+			org.eclipse.draw2d.Graphics graphics) {
+		this.setSize(this.getSize().width, getVisualSize().height);
+		this.drawDottedLineBackground(graphics, X_LEGEND_HEIGHT);
+		
+		drawGraphs(panel, graphics);
+		drawLabelsInGraph(panel, graphics);
+
+		this.drawSelectionSection(graphics, X_LEGEND_HEIGHT);
+	}
+
+	private void drawLabelsInGraph(Panel panel, Graphics graphics) {
+
+		float sectionHeight = getSectionHeight();
+		
+		if (sectionHeight > 60f){ //only draw the label if the section has a decent height
+			
+			int edgeX = ((Viewport) panel.getParent()).getViewLocation().x;
+
+			for (int i = 0; i < drawSeries.size(); i++) {
+				int seriesIdx = drawSeries.get(i);
+				int y = (int) sectionHeight * i;
+
+				graphics.setForegroundColor(ColorConstants.black);
+				graphics.drawString(trace.getValueTypes()[seriesIdx],
+						edgeX + 10, y + 6);
+				if (sectionHeight > 80f){
+					graphics.drawString(String.format(Messages.PecCommonTraceGraph_0,
+							this.exact_mins[seriesIdx], this.exact_maxs[seriesIdx]),
+							edgeX + 10, y + 18);					
+				}
+			}
+		}
+	}
+
+	private void drawGraphs(Panel panel, Graphics graphics) {
+		int visY = this.getVisualSize().height;
+		double scale = getScale();
+
+		if (dirty || this.currentlyCalcFinalHeight != visY
+				|| this.currentlyCalcFinalScale != scale) {
+
+			Vector<GenericSample> sv = trace.samples;
+			float sectionHeight = getSectionHeight();
+			
+			for (int sampleIdx = 0; sampleIdx < sv.size(); sampleIdx++) {
+				// calculate x-coordinate per sample
+				int xCoord = (int) (sampleIdx / scale);
+
+				for (int seriesIdx : drawSeries) {
+					points[seriesIdx][sampleIdx * 2] = xCoord;
+					points[seriesIdx][sampleIdx * 2 + 1] = convertValueToYCoordinate(origYCoords[seriesIdx][sampleIdx], mins[seriesIdx], maxs[seriesIdx], drawSeries.indexOf(seriesIdx), sectionHeight);
+				}
+			}
+			
+			dirty = false;
+			this.currentlyCalcFinalHeight = visY;
+			this.currentlyCalcFinalScale = scale;
+		}
+
+		graphics.setForegroundColor(ColorConstants.blue);
+
+		for (int seriesIdx : drawSeries) {
+			graphics.drawPolyline(points[seriesIdx]);
+		}
+	}
+	
+	/**
+	 * Converts a y coordinate into the actual value.
+	 * @param yCoordinate the y coordinate to convert
+	 * @param minValue the lowest value in the series
+	 * @param maxValue the highest value in the series
+	 * @param section the number of the section (for 3 sections this would be 0, 1, or 2)
+	 * @param sectionHeight the height of the section in pixels. All sections are of equal height
+	 * @return the converted value
+	 */
+	static int convertYCoordinateToValue(int yCoordinate, int minValue, int maxValue, int section, float sectionHeight){
+		float offset = sectionHeight * section;
+		
+		float location = sectionHeight - (yCoordinate - offset) ;
+		return (int)(location * (maxValue - minValue) / sectionHeight ) + minValue;
+	} 
+	
+	/**
+	 * Converts a value into a y coordinate; the opposite of convertYCoordinateToValue()
+	 * @param value the value to convert
+	 * @param minValue the lowest value in the series
+	 * @param maxValue the highest value in the series
+	 * @param section the number of the section (for 3 sections this would be 0, 1, or 2)
+	 * @param sectionHeight the height of the section in points. All sections are of equal height
+	 * @return the converted value
+	 */
+	static int convertValueToYCoordinate(int value, int minValue, int maxValue, int section, float sectionHeight){
+		float offset = sectionHeight * section;
+		
+		float location = (value - minValue) * sectionHeight / (maxValue - minValue); //lowest shown value is min (not 0)
+		return(int) ((sectionHeight - location) + offset);
+	}
+	
+	/**
+	 * Returns the height of a section in pixels. All sections are of equal height.
+	 * @return
+	 */
+	private float getSectionHeight(){
+		int visualHeight = getVisualSize().height - X_LEGEND_HEIGHT;
+		return drawSeries.size() == 0 ? visualHeight :  visualHeight / drawSeries.size();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph#paintLeftLegend
+	 * (org.eclipse.draw2d.FigureCanvas, org.eclipse.swt.graphics.GC)
+	 */
+	@Override
+	public void paintLeftLegend(FigureCanvas figureCanvas, GC gc) {
+		GC localGC = gc;
+
+		if (gc == null)
+			gc = new GC(PIPageEditor.currentPageEditor().getSite().getShell());
+
+		Rectangle rect = ((GraphComposite) figureCanvas.getParent()).figureCanvas
+				.getClientArea();
+
+		int visY = rect.height;
+
+		float visYfloat = visY - X_LEGEND_HEIGHT;
+
+		if (visYfloat < 0f)
+			visYfloat = 0f;
+
+		gc.setForeground(ColorPalette.getColor(new RGB(100, 100, 100)));
+		gc.setBackground(ColorPalette.getColor(new RGB(255, 255, 255)));
+		
+		int legendsToDraw = drawSeries.size();
+		float legendHeight = visYfloat / legendsToDraw;
+		double yIncrement = legendHeight / 10;
+		int previousBottom = 0;
+		
+		for (int section = 0; section < legendsToDraw; section++) {
+			int seriesIdx = drawSeries.get(section);
+			int maxValue = maxs[seriesIdx];
+
+			float valuePerPixel = maxValue / legendHeight;
+
+			for (int k = 10; k >= 0; k--) {
+				// location for the value indicator is k * 1/10 the height of
+				// the
+				// height of the section
+				int y = (int) (legendHeight * (section+1) - (yIncrement * k));
+				int value = (int) ((((legendHeight * valuePerPixel) / 10.0) * k));
+
+				// construct the text for each scale
+				//use grouping for small numbers, then without grouping to fit the text
+				String sValue = String.format(value < 1000000 ? Messages.PecCommonTraceGraph_1 : Messages.PecCommonTraceGraph_2, value);
+
+				Point extent = gc.stringExtent(sValue);
+
+				gc.drawLine(IGenericTraceGraph.Y_LEGEND_WIDTH - 3,  y + 1,
+						IGenericTraceGraph.Y_LEGEND_WIDTH, y + 1);
+
+				if (y >= previousBottom) {
+					gc.drawString(sValue, IGenericTraceGraph.Y_LEGEND_WIDTH
+							- extent.x - 4, y);
+					previousBottom = y + extent.y;
+				}
+			}
+		}
+
+		if (localGC == null) {
+			gc.dispose();
+			figureCanvas.redraw();
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph#getTitle()
+	 */
+	@Override
+	public String getTitle() {
+		return this.graphTitle;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.draw2d.MouseMotionListener#mouseDragged(org.eclipse.draw2d.MouseEvent)
+	 */
+	public void mouseDragged(MouseEvent arg0) {
+		// no-op		
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.draw2d.MouseMotionListener#mouseEntered(org.eclipse.draw2d.MouseEvent)
+	 */
+	public void mouseEntered(MouseEvent arg0) {
+		// no-op		
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.draw2d.MouseMotionListener#mouseExited(org.eclipse.draw2d.MouseEvent)
+	 */
+	public void mouseExited(MouseEvent arg0) {
+		// no-op		
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.draw2d.MouseMotionListener#mouseHover(org.eclipse.draw2d.MouseEvent)
+	 */
+	public void mouseHover(MouseEvent arg0) {
+		// no-op		
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.draw2d.MouseMotionListener#mouseMoved(org.eclipse.draw2d.MouseEvent)
+	 */
+	public void mouseMoved(MouseEvent me) {
+		//setting the tooltip
+		float sectionHeight = getSectionHeight();
+		int section = (int) (me.y / sectionHeight);
+		if (section < 0 || section >= drawSeries.size()){
+			this.setToolTipText(null);
+			return;
+		}
+		int seriesIdx = drawSeries.get(section);
+		
+		PecCommonSample sample = getSampleUnderMouse(me);
+
+		if (sample != null){
+			setToolTipText(String.format(Messages.PecCommonTraceGraph_3, trace.getValueTypes()[seriesIdx], sample.sampleSynchTime /1000f, sample.values[seriesIdx]));			
+		} else {
+			String tooltip = null;
+
+			//display default values
+			
+			if (section < drawSeries.size()) {
+				double time = me.x * this.getScale();
+				if (time >= 0 && time <= trace.getLastSampleTime()){
+					int value = convertYCoordinateToValue(me.y, mins[seriesIdx], maxs[seriesIdx], section, sectionHeight);
+					tooltip = String.format(Messages.PecCommonTraceGraph_4, time / 1000f, value);
+				}
+			}
+			
+			this.setToolTipText(tooltip);			
+		}
+	}
+
+	/**
+	 * Returns the sample for the given mouse location, or null
+	 * @param me mouse event for the mouse location
+	 * @return the sample if found, or null
+	 */
+	private PecCommonSample getSampleUnderMouse(MouseEvent me) {
+		PecCommonSample ret = null;
+		
+		if (drawSeries.size() == 0){
+			return ret; //no graphs are being drawn so no samples can be found
+		}
+
+		int mex = me.x;
+		int mey = me.y;
+		float sectionHeight = getSectionHeight();
+		int section = (int) (mey / sectionHeight);
+		
+		if (section >= 0 && section < drawSeries.size()) {
+			int seriesIdx = drawSeries.get(section);
+			double idealTime = mex * this.getScale();
+			if (idealTime < 0 || idealTime > trace.getLastSampleTime()){
+				return null; 
+			}
+			int idealValue = convertYCoordinateToValue(mey, mins[seriesIdx], maxs[seriesIdx], section, sectionHeight);
+
+			//calculate the boundary of the area in which to look for a sample
+			double leftBoudaryTime =  ((mex - MARGIN_IN_PIXELS) * getScale());
+			if (leftBoudaryTime < 0){
+				leftBoudaryTime = 0;
+			}
+			double rightBoundaryTime = ((mex + MARGIN_IN_PIXELS) * getScale());
+			if (rightBoundaryTime < 0){
+				return null; 
+			} else if (rightBoundaryTime > trace.getLastSampleTime()){
+				rightBoundaryTime = trace.getLastSampleTime();
+			}
+			 
+			int topBoundaryValue = convertYCoordinateToValue(Math.max((int)(section * sectionHeight), mey - MARGIN_IN_PIXELS), mins[seriesIdx], maxs[seriesIdx], section, sectionHeight);
+			int bottomBoundaryValue = convertYCoordinateToValue(Math.min((int)((section +1) * sectionHeight), mey + MARGIN_IN_PIXELS), mins[seriesIdx], maxs[seriesIdx], section, sectionHeight);
+			
+			int leftSample = (int)(leftBoudaryTime / trace.getSamplingInterval());
+			int rightSample = (int)(rightBoundaryTime+.5 / trace.getSamplingInterval());
+			
+			for (int i = leftSample; i <= rightSample; i++) {
+				PecCommonSample sample = (PecCommonSample)trace.getSample(i);
+				if (sample.values[seriesIdx] < topBoundaryValue && sample.values[seriesIdx] > bottomBoundaryValue){
+					//System.out.println("Cur: "+ sample.values[seriesIdx]+" Range: "+topBoundaryValue+", "+bottomBoundaryValue); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+					//check whether we have found a closer match to mid-point
+					if (ret == null 
+							|| (Math.abs(sample.sampleSynchTime - idealTime) < Math.abs(ret.sampleSynchTime - idealTime))
+							|| (ret.sampleSynchTime == sample.sampleSynchTime 
+									&& Math.abs(sample.values[seriesIdx] - idealValue) < Math.abs(ret.values[seriesIdx]	- idealValue))){
+						ret = sample;
+					}
+				}
+			} 
+		}
+		
+		return ret;
+	}
+
+	/**
+	 * Converts the passed X-coordiate into a time value (in milliseconds) using
+	 * the scale provided. Makes sure the return value is non-negative.
+	 * 
+	 * @param x
+	 *            the x coordinate to use
+	 * @param scale
+	 *            the scale to use
+	 * @return time in milliseconds
+	 */
+	protected static double getTimeForXCoordinate(int x, double scale) {
+		double time = x * scale;
+		// mouse event may return out of range X, that may
+		// crash when we use it to index data array
+		time = time >= 0 ? time : 0;
+		return time;
+	}
+	
+	/**
+	 * Make the input value a pretty value to display, such as 423,345 => 500,000
+	 * @param value the value to convert
+	 * @return the prettier value
+	 */
+	static int prettyMaxValue(final int value) {
+		double prettyVal = value;
+		int len = 0;
+
+		while (prettyVal >= 10) {
+			prettyVal/= 10;
+			len++;
+		}
+		
+		prettyVal = Math.ceil(prettyVal);
+		
+		if (prettyVal <= 1){
+			prettyVal = 1;
+		} else if (prettyVal <= 2){
+			prettyVal = 2;
+		} else if (prettyVal <= 3){
+			prettyVal = 3;
+		} else if (prettyVal <= 5){
+			prettyVal = 5;
+		} else {
+			prettyVal = 10;
+		}
+		
+		return (int)(prettyVal * Math.pow(10, len));
+	}
+
+	/**
+	 * Callback for PIEvent.SELECTION_AREA_CHANGED
+	 * @param newStart new selection start
+	 * @param newEnd new selection end
+	 */
+	void selectionAreaChanged(double newStart, double newEnd) {
+		this.setSelectionStart(newStart);
+		this.setSelectionEnd(newEnd);
+		
+		trace.selectionAreaChanged(newStart, newEnd);
+		legend.refreshLegend();
+		
+		this.repaint();				
+	}
+	
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.visual.PIEventListener#piEventReceived(com.nokia.carbide.cpp.internal.pi.visual.PIEvent)
+	 */
+	public void piEventReceived(PIEvent be) {
+		switch (be.getType()) {
+		
+		case PIEvent.SELECTION_AREA_CHANGED:
+			double[] values = (double[]) be.getValueObject();
+			//broadcast to all IPC graphs
+			guiManager.selectionAreaChanged(values[0], values[1]);				
+			break;
+
+		case PIEvent.SCROLLED:
+			Event event = ((Event) be.getValueObject());
+			//this broadcasts to all graphs on this PICompositePanel
+			this.parentComponent.setScrolledOrigin(event.x, event.y, (FigureCanvas)event.data);
+			this.repaint();
+			break;
+
+		default:
+			break;
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph#graphMaximized(boolean)
+	 */
+	@Override
+	public void graphMaximized(boolean value) {
+		legend.setLegendMaximised(value);
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph#graphVisibilityChanged(boolean)
+	 */
+	@Override
+	public void graphVisibilityChanged(boolean value) {
+		legend.setLegendVisible(value);
+	}
+
+	@Override
+	public void action(String action) {
+		// TODO Auto-generated method stub
+		
+	}
+	
+	/**
+	 * Adds or removes a series to be drawn
+	 * @param seriesId series id of the series to add or remove
+	 * @param add true if series is to be added, false for remove
+	 */
+	public void addOrRemoveSeries(int seriesId, boolean add){
+		if (add){
+			if (!drawSeries.contains(seriesId)){
+				drawSeries.add(seriesId);
+				Collections.sort(drawSeries);
+			}
+		} else {
+			drawSeries.remove(Integer.valueOf(seriesId));
+		}
+		
+		//repaint graphs
+		redrawGraphArea();
+	}
+	
+	private void redrawGraphArea() {
+		dirty = true;
+		setGraphImageChanged(true);
+		repaint();		
+	}
+
+	/**
+	 * Removes all series from display
+	 */
+	public void removeAllSeries(){
+		drawSeries.clear();
+		redrawGraphArea();
+		
+	}
+
+	/**
+	 * Shows all series in graph area
+	 */
+	public void showAllSeries(){
+		showAll();
+		redrawGraphArea();
+	}
+
+	
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.ITitleBarMenu#addTitleBarMenuItems()
+	 */
+	public Action[] addTitleBarMenuItems() {
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.ITitleBarMenu#getContextHelpId()
+	 */
+	public String getContextHelpId() {
+		return this.helpContextId;
+	}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.peccommon/src/com/nokia/carbide/cpp/pi/peccommon/messages.properties	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,26 @@
+PecCommonLegend_0=Char
+PecCommonLegend_1=Name
+PecCommonLegend_10=Copy
+PecCommonLegend_11=Copy\tCtrl+C
+PecCommonLegend_12=CopyTable
+PecCommonLegend_13=Copy Table
+PecCommonLegend_14=SaveTable
+PecCommonLegend_15=Save Table
+PecCommonLegend_2=Average (%d/ms)
+PecCommonLegend_3=Sum
+PecCommonLegend_4=Min (%d/ms)
+PecCommonLegend_5=Max (%d/ms)
+PecCommonLegend_6=CheckAll
+PecCommonLegend_7=Check All Rows
+PecCommonLegend_8=UncheckAll
+PecCommonLegend_9=Uncheck All Rows
+PecCommonLegendLabelProvider_0=%,.2f
+PecCommonLegendLabelProvider_1=%,d
+PecCommonLegendLabelProvider_2=%,d
+PecCommonLegendLabelProvider_3=%,d
+PecCommonSample_0=PEC [Time=%d ms, values=%s]
+PecCommonTraceGraph_0=[Min : Max] = [%,d : %,d]
+PecCommonTraceGraph_1=%,d
+PecCommonTraceGraph_2=%d
+PecCommonTraceGraph_3=%s @%.3fs - value: %,d
+PecCommonTraceGraph_4=time: %.3fs - value: %,d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.perfcounters/.classpath	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.perfcounters/.settings/org.eclipse.jdt.core.prefs	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,8 @@
+#Tue Jan 19 15:21:41 GMT 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.perfcounters/META-INF/MANIFEST.MF	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,17 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Carbide.c++ Performance Counters PI Plugin
+Bundle-SymbolicName: com.nokia.carbide.cpp.pi.perfcounters;singleton:=true
+Bundle-Version: 2.3.0.qualifier
+Bundle-Activator: com.nokia.carbide.cpp.pi.perfcounters.PecPlugin
+Bundle-Vendor: Nokia
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ com.nokia.carbide.cpp.pi;bundle-version="2.2.0",
+ org.eclipse.draw2d,
+ com.nokia.carbide.cpp.pi.util;bundle-version="2.2.0",
+ org.eclipse.ui.ide,
+ com.nokia.carbide.cpp.pi.peccommon;bundle-version="2.2.0"
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-ActivationPolicy: lazy
+Eclipse-ExtensibleAPI: true
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.perfcounters/build.properties	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,5 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               plugin.xml
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.perfcounters/plugin.xml	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+   <extension
+         point="com.nokia.carbide.cpp.pi.piPluginData">
+      <plugin
+            pluginClass="com.nokia.carbide.cpp.pi.perfcounters.PecReturnPlugin">
+      </plugin>
+   </extension>
+
+</plugin>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.perfcounters/src/com/nokia/carbide/cpp/pi/internal/perfcounters/Messages.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2010 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: 
+ *
+ */
+package com.nokia.carbide.cpp.pi.internal.perfcounters;
+
+import org.eclipse.osgi.util.NLS;
+public class Messages extends NLS {
+	private static final String BUNDLE_NAME = "com.nokia.carbide.cpp.pi.internal.perfcounters.messages"; //$NON-NLS-1$
+	public static String PecLegend_6;
+	public static String PecLegend_7;
+	public static String PecLegend_8;
+	public static String PecLegendLabelProvider_4;
+	public static String PecLegendLabelProvider_5;
+	public static String PecLegendLabelProvider_6;
+	public static String PecSample_0;
+	public static String PecTrace_0;
+	public static String PecTraceParser_0;
+	public static String PecTraceParser_1;
+	public static String PecTraceParser_10;
+	public static String PecTraceParser_11;
+	public static String PecTraceParser_12;
+	public static String PecTraceParser_13;
+	public static String PecTraceParser_14;
+	public static String PecTraceParser_15;
+	public static String PecTraceParser_16;
+	public static String PecTraceParser_17;
+	public static String PecTraceParser_18;
+	public static String PecTraceParser_19;
+	public static String PecTraceParser_2;
+	public static String PecTraceParser_20;
+	public static String PecTraceParser_21;
+	public static String PecTraceParser_22;
+	public static String PecTraceParser_3;
+	public static String PecTraceParser_4;
+	public static String PecTraceParser_5;
+	public static String PecTraceParser_6;
+	public static String PecTraceParser_7;
+	public static String PecTraceParser_8;
+	public static String PecTraceParser_9;
+	static {
+		// initialize resource bundle
+		NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+	}
+
+	private Messages() {
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.perfcounters/src/com/nokia/carbide/cpp/pi/internal/perfcounters/PecGuiManager.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2010 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: 
+ *
+ */
+
+package com.nokia.carbide.cpp.pi.internal.perfcounters;
+
+import com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph;
+import com.nokia.carbide.cpp.pi.editors.PIPageEditor;
+import com.nokia.carbide.cpp.pi.peccommon.PecCommonGuiManager;
+
+/**
+ * This instance manages the PEC graphs of one editor. This functionality
+ * was moved here to avoid putting GUI content into the PecTrace class
+ */
+public class PecGuiManager extends PecCommonGuiManager {
+	
+	
+	/**
+	 * Constructor
+	 * @param uid UId of the editor
+	 * @param trace the PecTrace instance for this editor
+	 * @param graphCount number of graphs for this editor
+	 * @param graphTitle the title of the graph
+	 */
+	public PecGuiManager(int uid, PecTrace trace, int graphCount, String graphTitle) {
+		super(uid, trace, graphCount, graphTitle);
+	}
+
+
+	/**
+	 * Returns the graph generated for this trace
+	 * @param graphIndex the index of the graph to get
+	 * @param helpContextIdMainPage a help context id
+	 * @return the graph
+	 */
+	@Override
+	public GenericTraceGraph getTraceGraph(int graphIndex, String helpContextIdMainPage) {
+
+		// note that graphIndex need not match the index sent to MemTraceGraph
+		if ((graphIndex == PIPageEditor.THREADS_PAGE)
+				|| (graphIndex == PIPageEditor.BINARIES_PAGE)
+				|| (graphIndex == PIPageEditor.FUNCTIONS_PAGE)) {
+			if (graphs[graphIndex] == null) {
+				graphs[graphIndex] = new PecTraceGraph(graphIndex, (PecTrace)trace, uid, this, this.graphTitle, helpContextIdMainPage);
+			}
+			return graphs[graphIndex];
+		}
+		
+		throw new IllegalArgumentException("Graph index out of range."); //$NON-NLS-1$
+	}
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.perfcounters/src/com/nokia/carbide/cpp/pi/internal/perfcounters/PecLegend.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2010 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: 
+ *
+ */
+
+package com.nokia.carbide.cpp.pi.internal.perfcounters;
+
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+
+import com.nokia.carbide.cpp.pi.peccommon.PecCommonLegend;
+import com.nokia.carbide.cpp.pi.peccommon.PecCommonLegendLabelProvider;
+import com.nokia.carbide.cpp.pi.peccommon.PecCommonLegendViewerSorter;
+
+/**
+ * Manages the legend for Performance Counter traces. 
+ */
+public class PecLegend extends PecCommonLegend{
+	
+	//the first few columns are in PecCommonLegend
+	
+	/** column containing average value divided by column A average value */
+	public static final int COLUMN_PER_A = 6;
+	/** column containing average value divided by column B average value */
+	public static final int COLUMN_PER_B = 7;
+	/** column containing average value divided by column C average value */
+	public static final int COLUMN_PER_C = 8;
+
+	
+	/**
+	 * Constructor
+	 * @param graph the graph that this legend belongs to 
+	 * @param parent the parent composite
+	 * @param title Title for the legend
+	 * @param trace The model containing the samples
+	 */
+	public PecLegend(final PecTraceGraph graph, Composite parent, String title, PecTrace trace){
+		super(graph,  parent, title, trace);
+	}
+	
+
+	/**
+	 * Creates the LabelProvider for the legend table
+	 * @return
+	 */
+	@Override
+	protected PecCommonLegendLabelProvider createLabelProvider() {
+		return new PecLegendLabelProvider();
+	}
+
+	/**
+	 * Creates the sorter used for the legend view. Sub classes may override this
+	 * @return PecCommonLegendViewerSorter
+	 */
+	@Override
+	protected PecCommonLegendViewerSorter createLegendSorter(){
+		return new PecLegendViewerSorter();
+	}
+	
+	@Override
+	protected void createColumns(final TableViewer aViewer, final PecCommonLegendViewerSorter columnSorter)
+ {
+		super.createColumns(aViewer, columnSorter);
+		
+		final Table table = aViewer.getTable();
+
+		TableColumn column = new TableColumn(table, SWT.RIGHT);
+		column.setText(Messages.PecLegend_6);
+		column.setWidth(100);
+		column.setMoveable(true);
+		column.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				columnSorter.setSortColumn(COLUMN_PER_A);
+				aViewer.refresh();
+			}
+		});
+
+		column = new TableColumn(table, SWT.RIGHT);
+		column.setText(Messages.PecLegend_7);
+		column.setWidth(100);
+		column.setMoveable(true);
+		column.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				columnSorter.setSortColumn(COLUMN_PER_B);
+				aViewer.refresh();
+			}
+		});
+
+		column = new TableColumn(table, SWT.RIGHT);
+		column.setText(Messages.PecLegend_8);
+		column.setWidth(100);
+		column.setMoveable(true);
+		column.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				columnSorter.setSortColumn(COLUMN_PER_C);
+				aViewer.refresh();
+			}
+		});
+	}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.perfcounters/src/com/nokia/carbide/cpp/pi/internal/perfcounters/PecLegendContentProvider.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2010 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: 
+ *
+ */
+
+package com.nokia.carbide.cpp.pi.internal.perfcounters;
+
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+
+/**
+ * Performance Counter Legend: ContentProvider for TableViewer 
+ */
+public class PecLegendContentProvider implements IStructuredContentProvider {
+
+	private PecTrace trace;
+
+
+    /**
+     * SimpleListContentProvider constructor comment.
+     * @param trace The trace model
+     */
+    public PecLegendContentProvider(PecTrace trace) {
+        super();
+        this.trace = trace;
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.jface.viewers.IContentProvider#dispose()
+     */
+    public void dispose() {
+    	//Do nothing when disposing,
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
+     */
+    public Object[] getElements(Object inputElement) {
+        return trace.getLegendElements();
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
+     */
+    public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+    	//we don't expect the input to change during the lifetime of this object
+    }
+
+	
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.perfcounters/src/com/nokia/carbide/cpp/pi/internal/perfcounters/PecLegendElement.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2010 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: 
+ *
+ */
+
+package com.nokia.carbide.cpp.pi.internal.perfcounters;
+
+import com.nokia.carbide.cpp.pi.peccommon.PecCommonLegendElement;
+
+/**
+ * An element for the Performance Counter Trace legend view.
+ * Represented in one line of the legend table viewer.
+ */
+public class PecLegendElement extends PecCommonLegendElement {
+	
+	/** 
+	 * Calculated value which unfortunately we have to store here as it requires
+	 * access to the other performance counters 
+	 */
+	private float[] xOverY;
+	
+	/**
+	 * Constructor
+	 * @param id trace event id
+	 * @param name the name of the event
+	 * @param character character representing the event, i.e. A for the first event, B for the second etc.
+	 * @param coreValuesOnly Calculate / show only average, min, and max
+	 */
+	public PecLegendElement(int id, String name, char character, boolean coreValuesOnly) {
+		super(id, name, character, coreValuesOnly);
+	}
+	/**
+	 * @param idx index of the element to use, such as 0 for per A, 1 for per B
+	 * @return the x over y for for the given element index
+	 */
+	public float getxOverY(int idx) {
+		return xOverY[idx];
+	}
+	/**
+	 * @param xOverY the xOverY to set
+	 */
+	public void setxOverY(float[] xOverY) {
+		this.xOverY = xOverY;
+	}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.perfcounters/src/com/nokia/carbide/cpp/pi/internal/perfcounters/PecLegendLabelProvider.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2010 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: 
+ *
+ */
+
+package com.nokia.carbide.cpp.pi.internal.perfcounters;
+
+import com.nokia.carbide.cpp.pi.peccommon.PecCommonLegendLabelProvider;
+
+/**
+ * Performance Counter Legend: LabelProvider for TableViewer 
+ */
+public class PecLegendLabelProvider extends PecCommonLegendLabelProvider {
+	private static final String EMPTY_STRING = ""; //$NON-NLS-1$
+
+	@Override
+	public String getColumnText(Object element, int columnIndex) {
+		String s = null;
+		
+		if (element instanceof PecLegendElement){
+			PecLegendElement le = (PecLegendElement)element;
+			
+			switch (columnIndex) {
+							
+			case PecLegend.COLUMN_PER_A:
+				if (le.getCnt() > 0 && !le.isCoreValuesOnly()){
+					s = String.format(Messages.PecLegendLabelProvider_4, le.getxOverY(0));
+				}
+				break;
+				
+			case PecLegend.COLUMN_PER_B:
+				if (le.getCnt() > 0 && !le.isCoreValuesOnly()){
+					s = String.format(Messages.PecLegendLabelProvider_5, le.getxOverY(1));
+				}
+				break;
+				
+			case PecLegend.COLUMN_PER_C:
+				if (le.getCnt() > 0 && !le.isCoreValuesOnly()){
+					s = String.format(Messages.PecLegendLabelProvider_6, le.getxOverY(2));
+				}
+				break;
+				
+			default:
+				return super.getColumnText(element, columnIndex);
+			}
+			
+		}
+		return s == null ? EMPTY_STRING : s;
+	}
+	
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.perfcounters/src/com/nokia/carbide/cpp/pi/internal/perfcounters/PecLegendViewerSorter.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2010 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: 
+ *
+ */
+
+package com.nokia.carbide.cpp.pi.internal.perfcounters;
+
+import org.eclipse.jface.viewers.Viewer;
+
+import com.nokia.carbide.cpp.pi.peccommon.PecCommonLegendViewerSorter;
+
+/**
+ * Sorter for the PEC legend
+ */
+public class PecLegendViewerSorter extends PecCommonLegendViewerSorter {
+	
+	/**
+	 * Constructor
+	 */
+	public PecLegendViewerSorter() {
+		super();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.viewers.ViewerComparator#compare(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
+	 */
+	@Override
+	public int compare(Viewer viewer, Object e1, Object e2) {
+		PecLegendElement le1 = (PecLegendElement)e1;
+		PecLegendElement le2 = (PecLegendElement)e2;
+		int ret = 0;
+
+		switch (columnIdx) {
+		case PecLegend.COLUMN_PER_A:
+			ret = Float.compare(le1.getxOverY(0), le2.getxOverY(0));
+			break;
+		case PecLegend.COLUMN_PER_B:
+			ret = Float.compare(le1.getxOverY(1), le2.getxOverY(1));
+			break;
+		case PecLegend.COLUMN_PER_C:
+			ret = Float.compare(le1.getxOverY(2), le2.getxOverY(2));
+			break;
+		default:
+			return super.compare(viewer, e1, e2);
+		}
+		
+		return sortUp? ret : (ret * -1);
+		
+	}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.perfcounters/src/com/nokia/carbide/cpp/pi/internal/perfcounters/PecSample.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2010 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: 
+ *
+ */
+
+package com.nokia.carbide.cpp.pi.internal.perfcounters;
+
+import java.util.Arrays;
+
+import com.nokia.carbide.cpp.pi.peccommon.PecCommonSample;
+
+
+/**
+ * Represents a Performance Counter Sample
+ */
+public class PecSample extends PecCommonSample 
+{
+	private static final long serialVersionUID = 84123271817196064L;
+	
+	/**
+	 * Constructor
+	 * @param values Sample values for the captured events
+	 * @param time Time the sample was taken
+	 */
+	public PecSample(int[] values, long time){
+		super(values, time);
+	}
+
+	@Override
+	public String toString() {
+		return String.format(Messages.PecSample_0, sampleSynchTime, Arrays.toString(values));
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.perfcounters/src/com/nokia/carbide/cpp/pi/internal/perfcounters/PecTrace.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2010 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: 
+ *
+ */
+
+package com.nokia.carbide.cpp.pi.internal.perfcounters;
+
+import com.nokia.carbide.cpp.pi.peccommon.PecCommonLegendElement;
+import com.nokia.carbide.cpp.pi.peccommon.PecCommonTrace;
+
+/**
+ * The model class for Performance Counter traces. This manages the data
+ * for the PEC trace graphs, and is responsible for creating the graphs. 
+ */
+public class PecTrace extends PecCommonTrace {
+	private static final long serialVersionUID = 4425739452429422333L;
+	
+	private boolean generateMipsGraph = false;
+	/** Name of the MIPS graph */
+	public static final  String MIPS_NAME = Messages.PecTrace_0;
+
+	/**
+	 * Constructor
+	 */
+	public PecTrace() {
+		super();
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.pi.peccommon.PecCommonTrace#createLegendElements(com.nokia.carbide.cpp.pi.peccommon.PecCommonLegendElement[], java.lang.String[], int[], long[], int[], int[])
+	 */
+	@Override
+	protected PecCommonLegendElement[] createLegendElements(
+			PecCommonLegendElement[] existingElements, String[] typeStrings,
+			int[] cnts, long[] sums, int[] mins, int[] maxs) {
+    	int c = typeStrings.length;
+    	boolean create = existingElements == null;    	
+    	PecLegendElement[] les = create ? new PecLegendElement[c] : (PecLegendElement[])existingElements;
+		char shortTitle = 'A';
+		
+		for (int i = 0; i < c; i++) {
+			
+			PecLegendElement legendElement = create ? new PecLegendElement(i, typeStrings[i], shortTitle, typeStrings[i].equals(MIPS_NAME)) : (PecLegendElement)existingElements[i];
+			legendElement.setCnt(cnts[i]);
+			legendElement.setSum(sums[i]);
+			legendElement.setMax(maxs[i]);
+			legendElement.setMin(mins[i]);
+			float[] xOverY = new float[c];
+			for (int j = 0; j < c; j++) {
+				if (i == j){
+					xOverY[j] = 1f;
+				} else if (sums[j] == 0){
+					xOverY[j] = 0;
+				} else {
+					xOverY[j] = sums[i] / (float)sums[j];
+				}
+			}
+			legendElement.setxOverY(xOverY);
+			les[i] = legendElement;
+			shortTitle ++;
+		}
+		return les;
+	}
+
+	/**
+	 * @param generateMipsGraph true, if the MIPS graph is to be generated, false otherwise
+	 */
+	public void setGenerateMipsGraph(boolean generateMipsGraph) {
+		this.generateMipsGraph = generateMipsGraph;
+	}
+
+	/**
+	 * @return true, if the MIPS graph is to be generated, false otherwise
+	 */
+	public boolean generateMipsGraph() {
+		return generateMipsGraph;
+	}
+	
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.perfcounters/src/com/nokia/carbide/cpp/pi/internal/perfcounters/PecTraceGraph.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2010 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: 
+ *
+ */
+
+package com.nokia.carbide.cpp.pi.internal.perfcounters;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.swt.widgets.Composite;
+
+import com.nokia.carbide.cpp.pi.peccommon.PecCommonLegend;
+import com.nokia.carbide.cpp.pi.peccommon.PecCommonTraceGraph;
+import com.nokia.carbide.cpp.pi.perfcounters.PecPlugin;
+
+/**
+ * The performance counter graph class, responsible for drawing the several graphs
+ * based on performance counters as well as managing the legend views to some extend
+ */
+public class PecTraceGraph extends PecCommonTraceGraph{
+
+	/**
+	 * Constructor
+	 * @param graphIndex the index of the graph (corresponds to the page in the editor)
+	 * @param pecTrace the trace class
+	 * @param uid the uid to identify the current editor
+	 * @param guiManager PecGuiManager which manages all graphs
+	 * @param title Title of graph
+	 * @param helpContextIdMainPage 
+	 */
+	public PecTraceGraph(int graphIndex, PecTrace pecTrace, int uid, PecGuiManager guiManager, String title, String helpContextIdMainPage) {
+		super(graphIndex, pecTrace, uid, guiManager, title, helpContextIdMainPage);
+	}
+	
+	@Override
+	protected PecCommonLegend createLegend(Composite bottomComposite) {		
+		return new PecLegend(this, bottomComposite, getTitle(), (PecTrace)trace);
+	}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.perfcounters/src/com/nokia/carbide/cpp/pi/internal/perfcounters/PecTraceParser.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,290 @@
+/*
+ * Copyright (c) 2010 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: 
+ *
+ */
+
+package com.nokia.carbide.cpp.pi.internal.perfcounters;
+
+import java.io.DataInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.PlatformUI;
+
+import com.nokia.carbide.cpp.internal.pi.model.ParsedTraceData;
+import com.nokia.carbide.cpp.internal.pi.model.Parser;
+import com.nokia.carbide.cpp.pi.internal.perfcounters.ui.ProcessorSpeedInputDialog;
+
+
+/**
+ * Parser for performance counter event traces in binary format.
+ * Converts parsed content into PecSamples.
+ */
+public class PecTraceParser extends Parser {
+	private static final int INSTRUCTIONS_EXECUTED = 0x7;
+	private static final int CPU_CLOCK_TICK_DIV64 = 0xFFFF;
+	private static final int DUMMY_MIPS_ID = -1;
+	
+	
+	private boolean debug = false;
+	
+	private long time = 0;
+	
+	/** true if dialogs etc is allowed here, false for quiet mode */
+	private boolean allowUserInteraction;
+	
+	/** produce MIPS graph data */
+	protected boolean mipsEnabled;
+	/** the processor speed to use for MIPS graph calculations */
+	protected int processorSpeed;
+	
+	/**
+	 * Constructor
+	 * @param allowUserInteraction true, if user interactions such as dialogs are allowed
+	 */
+	public PecTraceParser(boolean allowUserInteraction) {
+		super();
+		this.allowUserInteraction = allowUserInteraction;
+	}
+
+	private static final Map<Integer, String> eventTypeTable = new HashMap<Integer, String>();
+	static {
+		eventTypeTable.put(0x0,Messages.PecTraceParser_0);
+		eventTypeTable.put(0x1,Messages.PecTraceParser_1);
+		eventTypeTable.put(0x2,Messages.PecTraceParser_2);
+		eventTypeTable.put(0x3,Messages.PecTraceParser_3);
+		eventTypeTable.put(0x4, Messages.PecTraceParser_4);
+		eventTypeTable.put(0x5, Messages.PecTraceParser_5);
+		eventTypeTable.put(0x6, Messages.PecTraceParser_6);
+		eventTypeTable.put(INSTRUCTIONS_EXECUTED, Messages.PecTraceParser_7);
+		eventTypeTable.put(0x9, Messages.PecTraceParser_8);
+		eventTypeTable.put(0xA, Messages.PecTraceParser_9);
+		eventTypeTable.put(0xB, Messages.PecTraceParser_10);
+		eventTypeTable.put(0xC, Messages.PecTraceParser_11);
+		eventTypeTable.put(0xD, Messages.PecTraceParser_12);
+		eventTypeTable.put(0xF, Messages.PecTraceParser_13);
+		eventTypeTable.put(0x10, Messages.PecTraceParser_14);
+		eventTypeTable.put(0x11, Messages.PecTraceParser_15);
+		eventTypeTable.put(0x12, Messages.PecTraceParser_16);
+		eventTypeTable.put(0x20, Messages.PecTraceParser_17);
+		eventTypeTable.put(0x21, Messages.PecTraceParser_18);
+		eventTypeTable.put(0x22, Messages.PecTraceParser_19);
+		eventTypeTable.put(0xFF, Messages.PecTraceParser_20);
+		eventTypeTable.put(CPU_CLOCK_TICK_DIV64, Messages.PecTraceParser_21);
+		eventTypeTable.put(DUMMY_MIPS_ID, PecTrace.MIPS_NAME);
+	}
+				
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.model.Parser#parse(java.io.File)
+	 */
+	@Override
+	public ParsedTraceData parse(File file) throws FileNotFoundException 
+	{
+		ParsedTraceData ptd = new ParsedTraceData();
+		ptd.functionResolvers = null;
+		ptd.staticData = null;
+		PecTrace pecTrace = new PecTrace();
+		ptd.traceData = pecTrace;
+		doParsing(file, pecTrace);
+		time = 0;
+		
+		return ptd;
+	}
+	
+	private void doParsing(File f, PecTrace trace) throws FileNotFoundException
+	{
+		DataInputStream dis = new DataInputStream(new FileInputStream(f));
+		try
+		{
+			int len = dis.readByte();
+			byte[] versionString = new byte[len];
+			dis.read(versionString);
+			this.traceVersion = new String(versionString);
+			if(debug)System.out.println("PEC trace version:"+this.traceVersion); //$NON-NLS-1$
+			
+			int firstData = dis.readUnsignedByte();
+			int secondData = dis.readUnsignedByte();
+			int thirdData = CPU_CLOCK_TICK_DIV64;
+			
+			if (allowUserInteraction && (firstData == INSTRUCTIONS_EXECUTED || secondData == INSTRUCTIONS_EXECUTED)){
+				Display.getDefault().syncExec( new Runnable() {
+
+					public void run () {
+						// in future, if we don't want to have a dialog in the core parser class
+						// we could call into an interface which ProcessorSpeedInputDialog would have to implement
+						ProcessorSpeedInputDialog dialog = new ProcessorSpeedInputDialog(
+								PlatformUI.getWorkbench()
+										.getActiveWorkbenchWindow().getShell());
+						if (dialog.open() == Window.OK){
+							processorSpeed = dialog.getIntValue();
+							mipsEnabled = true;
+						}
+					}
+				});
+				
+				
+			}
+
+			Integer[] valueTypeVector = new Integer[mipsEnabled ? 4 : 3];
+			valueTypeVector[0] = Integer.valueOf(firstData);
+			valueTypeVector[1] = Integer.valueOf(secondData);
+			// this type is always the cpu clock tick div 64
+			valueTypeVector[2] = Integer.valueOf(thirdData);
+			
+			if (mipsEnabled){
+				valueTypeVector[3] = DUMMY_MIPS_ID;
+			}
+			
+			trace.setValueTypes(this.parseValueTypes(valueTypeVector));
+			
+			PecSample s = null;			
+			while(true)
+			{
+				s = readSample(dis,s);
+				trace.addSample(s);
+			}
+		}
+		catch (IOException ioe)
+		{
+			//TODO: should we log this or handle it?
+			//my guess is this signifies the end of file
+		}
+	}
+
+	private PecSample readSample(DataInputStream dis,PecSample prevSample) throws IOException
+	{
+		int headerByte = (dis.readByte() << 24) >>> 24;
+		int neg0 = 0;
+		int neg1 = 0;
+		int neg2 = 0;
+		
+		int prev0 = 0;
+		int prev1 = 0;
+		int prev2 = 0;
+		
+		if(prevSample != null)
+		{
+			prev0 = prevSample.values[0];
+			prev1 = prevSample.values[1];
+			prev2 = prevSample.values[2]/64;
+		}
+		if(debug) if(this.time > 7820 && this.time < 7830) System.out.println("header: "+Long.toHexString(headerByte)+" = "+Integer.toBinaryString(headerByte));  //$NON-NLS-1$//$NON-NLS-2$
+		
+		if( ((headerByte >>> 7)&1) != 0)
+		{
+			neg0 = 1;
+		}
+		
+		if( ((headerByte >>> 6)&1) != 0)
+		{
+			neg1 = 1;
+		}
+		
+		if( ((headerByte >>> 5)&1) != 0)
+		{
+			neg2 = 1;
+		}
+		
+		int len0 = (((headerByte >> 3) << 30) >>> 30)+1;
+		int len1 = (((headerByte >> 1) << 30) >>> 30)+1;
+		int len2 = ((((headerByte) << 31) >>> 31)+1)*2;
+		
+		if(debug) if(this.time > 7820 && this.time < 7830) System.out.println("T:"+this.time+" len0:"+len0+" len1:"+len1+" len2:"+len2); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+		if(debug) if(this.time > 7900 && this.time < 7900) System.out.println("H: "+Integer.toBinaryString(headerByte)+" N0:"+neg0+" N1:"+neg1+" N2:"+neg2);   //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ //$NON-NLS-4$
+		
+		long val0 = readVal(neg0,len0,dis);
+		long val1 = readVal(neg1,len1,dis);
+		long val2 = readVal(neg2,len2,dis);
+		
+		if(debug) if(this.time > 7820 && this.time < 7900) System.out.println("READ T:"+this.time+"   V0:"+Long.toHexString(val0)+" V1:"+Long.toHexString(val1)+" V2:"+Long.toHexString(val2));   //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ //$NON-NLS-4$
+		val0 = prev0-val0;
+		val1 = prev1-val1;
+		val2 = prev2-val2;
+		
+		int[] values;
+		if (mipsEnabled){
+			values = new int[]{(int)val0,(int)val1,((int)val2)*64, (int)(processorSpeed * val1 / (val2*64))};
+		} else {
+			values = new int[]{(int)val0,(int)val1,((int)val2)*64};			
+		}
+		
+		PecSample ps = new PecSample(values, this.time);		
+		
+		if(debug) if(this.time > 7820 && this.time < 7900) System.out.println("T:"+this.time+"   V0:"+Long.toHexString(val0)+" V1:"+Long.toHexString(val1)+" V2:"+Long.toHexString(val2));  //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+		if(debug) if(this.time > 7820 && this.time < 7900) System.out.println("T:"+this.time+" "+val0+" "+val1+" "+val2);   //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$//$NON-NLS-4$
+		this.time++;
+		
+		return ps;
+	}
+
+	private long readVal(int neg,int len,DataInputStream dis) throws IOException
+	{
+		byte[] array = new byte[len];
+		dis.read(array);
+		
+		if(debug)
+			for(int k=0;k<array.length;k++)
+			{
+				if(this.time > 7820 && this.time < 7900) System.out.println(" "+Integer.toHexString(array[k])); //$NON-NLS-1$
+			}
+		
+		long total = 0;
+		for(int i=0;i<len;i++)
+		{
+			int value = ((array[i] << 24) >>> 24) << (i*8);			
+			total |= value;
+		}
+		
+		if(debug) if(this.time > 7820 && this.time < 7900) System.out.println("\n"+Long.toHexString(total)); //$NON-NLS-1$
+
+		if(debug) if(this.time > 7820 && this.time < 7900) System.out.println("T:"+this.time+" "+Long.toHexString(total));  //$NON-NLS-1$//$NON-NLS-2$
+		
+		if(neg != 0) total = ~total;
+		
+		return total;
+	}
+		
+	/**
+	 * Converts the given event type identifiers into the appropriate event type strings.
+	 * @param valueTypeIntegers list of event type identifiers
+	 * @return String[] of event type strings
+	 */
+	private String[] parseValueTypes(Integer[] valueTypeIntegers){
+		String[] s = new String[valueTypeIntegers.length];
+		for (int i = 0; i < valueTypeIntegers.length; i++) {
+			s[i] = convertValueType(valueTypeIntegers[i]);
+		}
+		
+		return s;
+	}
+	
+	private String convertValueType(int value) {
+		String s = eventTypeTable.get(Integer.valueOf(value));
+		if (s == null){
+			s = String.format(
+					Messages.PecTraceParser_22,
+					value);			
+		}
+		return s;
+
+	}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.perfcounters/src/com/nokia/carbide/cpp/pi/internal/perfcounters/messages.properties	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,31 @@
+PecLegend_6=Per A
+PecLegend_7=Per B
+PecLegend_8=Per C
+PecLegendLabelProvider_4=%,.2f
+PecLegendLabelProvider_5=%,.2f
+PecLegendLabelProvider_6=%,.2f
+PecSample_0=PEC [Time=%d ms, values=%s]
+PecTrace_0=[MIPS (Million Instructions Per Second)] / [1 sampled ms]
+PecTraceParser_0=[Instruction cache miss to a cachable location requires fetch from external memory] / [1 sampled ms]
+PecTraceParser_1=[Stall because instruction buffer cannot deliver an instruction] / [1 sampled ms]
+PecTraceParser_10=[Data cache miss] / [1 sampled ms]
+PecTraceParser_11=[Data cache Write-Back] / [1 sampled ms]
+PecTraceParser_12=[Software changed the PC] / [1 sampled ms]
+PecTraceParser_13=[Main TLB miss] / [1 sampled ms]
+PecTraceParser_14=[External memory request (Cache Refill, Noncachable, Write-Through, Write-Back)] / [1 sampled ms]
+PecTraceParser_15=[Stall because of Load Store Unit request queue being full] / [1 sampled ms]
+PecTraceParser_16=[Write Buffer was drained because of a Drain Write Buffer command or Strongly Ordered operation] / [1 sampled ms]
+PecTraceParser_17=[ETMEXTOUT[0] signal was asserted for a cycle] / [1 sampled ms]
+PecTraceParser_18=[ETMEXTOUT[1] signal was asserted for a cycle] / [1 sampled ms]
+PecTraceParser_19=[Both ETMEXTOUT[0] and ETMEXTOUT[1] signals assigned] / [1 sampled ms]
+PecTraceParser_2=[Stall because of a data dependency] / [1 sampled ms]
+PecTraceParser_20=[Precise CPU Cycles] / [1 sampled ms]
+PecTraceParser_21=[CPU Cycles (64 cycle accuracy)] / [1 sampled ms]
+PecTraceParser_22=Value %d not identified as Performance counter event\!
+PecTraceParser_3=[Instruction MicroTLB miss] / [1 sampled ms]
+PecTraceParser_4=[Data MicroTLB miss] / [1 sampled ms]
+PecTraceParser_5=[Branch instruction executed] / [1 sampled ms]
+PecTraceParser_6=[Branch mispredicted] / [1 sampled ms]
+PecTraceParser_7=[Instruction executed] / [1 sampled ms]
+PecTraceParser_8=[Data cache access for cachable locations] / [1 sampled ms]
+PecTraceParser_9=[Data cache access for all locations] / [1 sampled ms]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.perfcounters/src/com/nokia/carbide/cpp/pi/internal/perfcounters/ui/Messages.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,19 @@
+package com.nokia.carbide.cpp.pi.internal.perfcounters.ui;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS {
+	private static final String BUNDLE_NAME = "com.nokia.carbide.cpp.pi.internal.perfcounters.ui.messages"; //$NON-NLS-1$
+	public static String ProcessorSpeedInputDialog_0;
+	public static String ProcessorSpeedInputDialog_1;
+	public static String ProcessorSpeedInputDialog_3;
+	public static String ProcessorSpeedInputDialog_4;
+	public static String ProcessorSpeedInputDialog_5;
+	static {
+		// initialize resource bundle
+		NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+	}
+
+	private Messages() {
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.perfcounters/src/com/nokia/carbide/cpp/pi/internal/perfcounters/ui/ProcessorSpeedInputDialog.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2010 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: 
+ *
+ */
+package com.nokia.carbide.cpp.pi.internal.perfcounters.ui;
+
+import org.eclipse.jface.dialogs.IInputValidator;
+import org.eclipse.jface.dialogs.InputDialog;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * Input dialog for the processor speed, specified in MHz.
+ *
+ */
+public class ProcessorSpeedInputDialog extends InputDialog {
+	
+	private static final String DIALOG_TITLE = Messages.ProcessorSpeedInputDialog_0;
+	private static final String DIALOG_MESSAGE = Messages.ProcessorSpeedInputDialog_1;
+	private static final String EMPTY_STRING = ""; //$NON-NLS-1$
+	
+	private static final int LOW_VALUE = 100;
+	private static final int HIGH_VALUE = 1000;
+	
+
+	/**
+	 * Constructor
+	 * @param parentShell The shell for this dialog to open in
+	 */
+	public ProcessorSpeedInputDialog(Shell parentShell) {
+		super(parentShell, DIALOG_TITLE, DIALOG_MESSAGE, EMPTY_STRING, new IInputValidator(){
+
+			public String isValid(String newText) {
+				if (newText.length() == 0){
+					return Messages.ProcessorSpeedInputDialog_3;
+				}
+				
+				try {
+					int value = Integer.parseInt(newText);
+					if (value < LOW_VALUE || value > HIGH_VALUE){
+						return String.format(Messages.ProcessorSpeedInputDialog_4, LOW_VALUE, HIGH_VALUE);
+					}
+				} catch (NumberFormatException e) {
+					return Messages.ProcessorSpeedInputDialog_5;
+				}
+				return null;
+			}
+		});
+	}
+
+
+	/**
+	 * Returns the processor speed as an int value
+	 * @return the processor speed
+	 */
+	public int getIntValue() {
+		return Integer.parseInt(getValue());
+	}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.perfcounters/src/com/nokia/carbide/cpp/pi/internal/perfcounters/ui/messages.properties	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,5 @@
+ProcessorSpeedInputDialog_0=PI PEC: MIPS Graph Generation
+ProcessorSpeedInputDialog_1=The performance counter trace contains data for MIPS graph generation but the processor speed is missing.\n\nPlease enter the hardware's processor speed in MHz manually if you wish to see a MIPS graph.
+ProcessorSpeedInputDialog_3=Please enter a value or cancel.
+ProcessorSpeedInputDialog_4=The value is out of range [%d, %d]
+ProcessorSpeedInputDialog_5=The value has to be an integer number.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.perfcounters/src/com/nokia/carbide/cpp/pi/perfcounters/Messages.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,16 @@
+package com.nokia.carbide.cpp.pi.perfcounters;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS {
+	private static final String BUNDLE_NAME = "com.nokia.carbide.cpp.pi.perfcounters.messages"; //$NON-NLS-1$
+	public static String PecPlugin_0;
+	public static String PecPlugin_1;
+	static {
+		// initialize resource bundle
+		NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+	}
+
+	private Messages() {
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.perfcounters/src/com/nokia/carbide/cpp/pi/perfcounters/PecPlugin.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,319 @@
+package com.nokia.carbide.cpp.pi.perfcounters;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.swt.widgets.Event;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+
+import com.nokia.carbide.cpp.internal.pi.analyser.NpiInstanceRepository;
+import com.nokia.carbide.cpp.internal.pi.analyser.ProfileVisualiser;
+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.plugin.model.AbstractPiPlugin;
+import com.nokia.carbide.cpp.internal.pi.plugin.model.IEventListener;
+import com.nokia.carbide.cpp.internal.pi.plugin.model.IFinalizeTrace;
+import com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace;
+import com.nokia.carbide.cpp.internal.pi.plugin.model.IVisualizable;
+import com.nokia.carbide.cpp.internal.pi.visual.GraphDrawRequest;
+import com.nokia.carbide.cpp.pi.editors.PIPageEditor;
+import com.nokia.carbide.cpp.pi.internal.perfcounters.PecGuiManager;
+import com.nokia.carbide.cpp.pi.internal.perfcounters.PecSample;
+import com.nokia.carbide.cpp.pi.internal.perfcounters.PecTrace;
+import com.nokia.carbide.cpp.pi.internal.perfcounters.PecTraceParser;
+import com.nokia.carbide.cpp.pi.visual.IGenericTraceGraph;
+import com.nokia.carbide.cpp.internal.pi.plugin.model.IClassReplacer;
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class PecPlugin extends AbstractPiPlugin implements ITrace, IEventListener, IVisualizable, IFinalizeTrace, IClassReplacer {
+
+	/** number of graphs created (one on each page)*/
+	public static final int GRAPH_COUNT = 3;
+
+	/** The plug-in ID */
+	public static final String PLUGIN_ID = "com.nokia.carbide.cpp.pi.perfcounters"; //$NON-NLS-1$
+
+	private static final String HELP_CONTEXT_ID = PIPageEditor.PI_ID + ".perfcounters";  //$NON-NLS-1$
+	/** context help id of the main page */
+	public static final String HELP_CONTEXT_ID_MAIN_PAGE = HELP_CONTEXT_ID + ".pecPageContext";  //$NON-NLS-1$
+	
+	/** the trace id for PEC traces */
+	private static final int PEC_TRACE_ID = 10;
+	
+	/** Persistable preference for the performance counter trace draw mode (show single graph or all graphs)  */
+	public static final String PECTRACE_DRAWMODE = "com.nokia.carbide.cpp.pi.perfcounters.drawmode";//$NON-NLS-1$
+	/** draw mode for showing all graphs */
+	public static final String PECTRACE_DRAWMODE_SHOW_ALL = "ShowAll";//$NON-NLS-1$
+
+	// The shared instance
+	private static PecPlugin plugin;
+	
+	private static final Map<Integer, PecGuiManager> guiManagerMap = new HashMap<Integer, PecGuiManager>();
+
+	/**
+	 * The constructor
+	 */
+	public PecPlugin() {
+		super();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+	 */
+	@Override
+	public void start(BundleContext context) throws Exception {
+		super.start(context);
+		plugin = this;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+	 */
+	@Override
+	public void stop(BundleContext context) throws Exception {
+		plugin = null;
+		super.stop(context);
+	}
+
+	/**
+	 * Returns the shared instance
+	 *
+	 * @return the shared instance
+	 */
+	public static PecPlugin getDefault() {
+		return plugin;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace#getTraceClass()
+	 */
+	public Class getTraceClass() {
+		return PecTrace.class;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace#initialiseTrace(com.nokia.carbide.cpp.internal.pi.model.GenericTrace)
+	 */
+	public void initialiseTrace(GenericTrace trace) {
+		if (!(trace instanceof PecTrace)){
+			throw new IllegalArgumentException();
+		}
+			
+		PecTrace parsedTrace = (PecTrace)trace;
+		
+		int samplingInterval = 1; //in milliseconds
+		if (parsedTrace.samples.size() > 2) {
+			samplingInterval = (int) ((parsedTrace.samples.get(1)).sampleSynchTime - (parsedTrace.samples.get(0)).sampleSynchTime); 
+		}
+		parsedTrace.setSamplingInterval(samplingInterval);
+		
+		
+		NpiInstanceRepository.getInstance().activeUidAddTrace(PLUGIN_ID, trace);
+		
+		//create the GUI class which manages the graphs
+		int uid = NpiInstanceRepository.getInstance().activeUid();
+		guiManagerMap.put(uid, new PecGuiManager(uid, parsedTrace, GRAPH_COUNT, Messages.PecPlugin_0));
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace#getTraceName()
+	 */
+	public String getTraceName() {
+		return "PEC"; //$NON-NLS-1$
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace#getTraceTitle()
+	 */
+	public String getTraceTitle() {
+		return Messages.PecPlugin_1;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace#getTraceId()
+	 */
+	public int getTraceId() {
+		return PEC_TRACE_ID;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace#parseTraceFile(java.io.File)
+	 */
+	public ParsedTraceData parseTraceFile(File file) throws Exception {
+		PecTraceParser p = new PecTraceParser(true);
+		ParsedTraceData ptd = p.parse(file);
+		
+		return ptd;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace#parseTraceFiles(java.io.File[])
+	 */
+	public ParsedTraceData parseTraceFiles(File[] files) throws Exception {
+		throw new UnsupportedOperationException();
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.IEventListener#receiveEvent(java.lang.String, org.eclipse.swt.widgets.Event)
+	 */
+	public void receiveEvent(String action, Event event) {
+		//no-op
+		
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.IVisualizable#arePagesCreated()
+	 */
+	public boolean arePagesCreated() {
+		return false; //PEC traces add graphs to existing pages
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.IVisualizable#createPage(int)
+	 */
+	public ProfileVisualiser createPage(int index) {
+		return null; //PEC traces add graphs to existing pages
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.IVisualizable#getCreatePageCount()
+	 */
+	public int getCreatePageCount() {
+		return 0; //PEC traces don't create pages
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.IVisualizable#getCreatePageIndex(int)
+	 */
+	public int getCreatePageIndex(int index) {
+		throw new UnsupportedOperationException(); //PEC traces don't create pages
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.IVisualizable#getDrawRequest(int)
+	 */
+	public GraphDrawRequest getDrawRequest(int graphIndex) {
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.IVisualizable#getGraphCount()
+	 */
+	public int getGraphCount() {
+		return GRAPH_COUNT;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.IVisualizable#getLastSample(int)
+	 */
+	public Integer getLastSample(int graphIndex) {
+		PecTrace trace = (PecTrace) NpiInstanceRepository.getInstance().activeUidGetTrace(PLUGIN_ID);
+		if(trace == null){
+			return 0;
+		}
+		
+		return trace.getLastSampleNumber();
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.IVisualizable#getPageNumber(int)
+	 */
+	public int getPageNumber(int graphIndex) {
+		if (graphIndex == 0) {
+			return PIPageEditor.THREADS_PAGE;
+		} else if (graphIndex == 1) {
+			return PIPageEditor.BINARIES_PAGE;
+		} else if (graphIndex == 2) {
+			return PIPageEditor.FUNCTIONS_PAGE;
+		}
+
+		return PIPageEditor.NEXT_AVAILABLE_PAGE;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.IVisualizable#getTraceGraph(int)
+	 */
+	public IGenericTraceGraph getTraceGraph(int graphIndex) {
+		int uid = NpiInstanceRepository.getInstance().activeUid();
+		PecGuiManager guiManager = guiManagerMap.get(uid);
+		
+		if (guiManager != null){
+			return guiManager.getTraceGraph(graphIndex, HELP_CONTEXT_ID_MAIN_PAGE);			
+		}
+		
+		throw new IllegalStateException();
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.IVisualizable#setPageIndex(int, int)
+	 */
+	public void setPageIndex(int index, int pageIndex) {
+		//no-op
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.IVisualizable#setPagesCreated(boolean)
+	 */
+	public void setPagesCreated(boolean pagesCreated) {
+		//no-op
+	}
+	
+	/**
+	 * Returns a File corresponding to the given bundle relative path.
+	 * @param path the bundle relative path to resource to locate
+	 * @return the File corresponding to the given bundle relative path, or null
+	 * @throws IOException
+	 */
+	public File locateFileInBundle(final String path) throws IOException {
+		Bundle myBundle= getDefault().getBundle();
+		IPath ppath= new Path(path);
+		ppath= ppath.makeRelative();
+		URL[] urls= FileLocator.findEntries(myBundle, ppath);
+		if(urls.length != 1) {
+			return null;
+		}
+		return new File(FileLocator.toFileURL(urls[0]).getFile());
+	}
+
+	
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.IFinalizeTrace#runOnDispose()
+	 */
+	public void runOnDispose() {
+		// called when editor closes
+		
+		// Do any cleanup work here when the editor closes
+		int uid = NpiInstanceRepository.getInstance().activeUid();
+		guiManagerMap.remove(uid);
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.IFinalizeTrace#runOnPartOpened()
+	 */
+	public void runOnPartOpened() {
+		//no-op
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.IClassReplacer#getReplacedClass(java.lang.String)
+	 */
+	public Class getReplacedClass(String className) {
+		if (className.startsWith("com.nokia.carbide.cpp.pi.internal.perfcounters.PecTrace")){ //$NON-NLS-1$
+			return PecTrace.class;
+		} else if (className.startsWith("com.nokia.carbide.cpp.pi.internal.perfcounters.PecSample")){//$NON-NLS-1$
+			return PecSample.class;
+		}
+		return null;
+	}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.perfcounters/src/com/nokia/carbide/cpp/pi/perfcounters/PecReturnPlugin.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2010 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: 
+ *
+ */
+
+package com.nokia.carbide.cpp.pi.perfcounters;
+
+import com.nokia.carbide.cpp.internal.pi.interfaces.IReturnPlugin;
+import com.nokia.carbide.cpp.internal.pi.plugin.model.AbstractPiPlugin;
+
+/**
+ * Implements the extension point piPluginData to register this plugin as a PI plugin
+ */
+public class PecReturnPlugin implements IReturnPlugin {
+	public AbstractPiPlugin getPlugin() {
+		return PecPlugin.getDefault();
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.perfcounters/src/com/nokia/carbide/cpp/pi/perfcounters/messages.properties	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,2 @@
+PecPlugin_0=Performance Counters
+PecPlugin_1=Performance counter
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.power/META-INF/MANIFEST.MF	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.power/META-INF/MANIFEST.MF	Wed Apr 21 15:14:16 2010 +0300
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: Carbide.c++ Performance Investigator Power Usage
 Bundle-SymbolicName: com.nokia.carbide.cpp.pi.power;singleton:=true
-Bundle-Version: 1.5.0.qualifier
+Bundle-Version: 2.3.0.qualifier
 Bundle-Activator: com.nokia.carbide.cpp.pi.power.PowerPlugin
 Bundle-Vendor: Nokia
 Bundle-Localization: plugin
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.power/src/com/nokia/carbide/cpp/internal/pi/power/actions/PowerStatisticsDialog.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.power/src/com/nokia/carbide/cpp/internal/pi/power/actions/PowerStatisticsDialog.java	Wed Apr 21 15:14:16 2010 +0300
@@ -216,9 +216,9 @@
 
 	private static String showTimeInterval(double startTime, double endTime)
 	{
-		return ProfileVisualiser.timeFormat.format(startTime)
-		     + Messages.getString("PowerStatisticsDialog.interval1") + ProfileVisualiser.timeFormat.format(endTime) //$NON-NLS-1$
-		     + Messages.getString("PowerStatisticsDialog.interval2")  + ProfileVisualiser.timeFormat.format(endTime - startTime) //$NON-NLS-1$
+		return ProfileVisualiser.TIME_FORMAT.format(startTime)
+		     + Messages.getString("PowerStatisticsDialog.interval1") + ProfileVisualiser.TIME_FORMAT.format(endTime) //$NON-NLS-1$
+		     + Messages.getString("PowerStatisticsDialog.interval2")  + ProfileVisualiser.TIME_FORMAT.format(endTime - startTime) //$NON-NLS-1$
 		     + Messages.getString("PowerStatisticsDialog.interval3"); //$NON-NLS-1$
 	}
 
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.power/src/com/nokia/carbide/cpp/pi/power/PowerPlugin.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.power/src/com/nokia/carbide/cpp/pi/power/PowerPlugin.java	Wed Apr 21 15:14:16 2010 +0300
@@ -48,7 +48,13 @@
 public class PowerPlugin extends AbstractPiPlugin
 		implements IViewMenu, ITrace, IClassReplacer, IVisualizable, IEventListener
 {
+
+	/** The plug-in ID */
+	public static final String PLUGIN_ID = "com.nokia.carbide.cpp.pi.power"; //$NON-NLS-1$
+
 	private static final String HELP_CONTEXT_ID = PIPageEditor.PI_ID + ".power";  //$NON-NLS-1$
+	/** context help id of the main page */
+	public static final String HELP_CONTEXT_ID_MAIN_PAGE = HELP_CONTEXT_ID + ".powerPageContext";  //$NON-NLS-1$
 
 	// There will be three graphs - one each for editor pages 0, 1, 2
 	// This code may assume that page 0 has the threads graph, 1 the binaries, and 2 the functions
@@ -145,10 +151,24 @@
 		return "Power"; //$NON-NLS-1$
 	}
 
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace#getTraceTitle()
+	 */
+	public String getTraceTitle() {
+		return Messages.getString("PowerPlugin.0"); //$NON-NLS-1$
+	}
+
 	public int getTraceId() {
 		return 11;
 	}
 
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace#parseTraceFiles(java.io.File[])
+	 */
+	public ParsedTraceData parseTraceFiles(File[] files) throws Exception {
+		throw new UnsupportedOperationException();
+	}
+
 	public ParsedTraceData parseTraceFile(File file) throws Exception 
 	{
 		try
@@ -234,11 +254,7 @@
 			((PowerTraceGraph)trace.getTraceGraph(PIPageEditor.BINARIES_PAGE,  uid)).action(actionString);	
 			((PowerTraceGraph)trace.getTraceGraph(PIPageEditor.FUNCTIONS_PAGE, uid)).action(actionString);	
 		} else if (actionString.equals("scroll")) //$NON-NLS-1$
-		{
-			if (   !(event.data instanceof String)
-				|| !((String)event.data).equals("FigureCanvas")) //$NON-NLS-1$
-				return;
-			
+		{			
 			PIEvent be = new PIEvent(event, PIEvent.SCROLLED);
 			
 			((PowerTraceGraph)trace.getTraceGraph(PIPageEditor.THREADS_PAGE,   uid)).piEventReceived(be);
@@ -295,7 +311,7 @@
 		PwrTrace trace = (PwrTrace) NpiInstanceRepository.getInstance().activeUidGetTrace("com.nokia.carbide.cpp.pi.power"); //$NON-NLS-1$
 
 		if (trace != null)
-			return new Integer(trace.getLastSampleNumber());
+			return Integer.valueOf(trace.getLastSampleNumber());
 		else
 			return null;
 	}
@@ -346,11 +362,4 @@
 	public void setPageIndex(int index, int pageIndex) {
 		return;
 	}
-
-	/* (non-Javadoc)
-	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.IVisualizable#getGraphTitle(int)
-	 */
-	public String getGraphTitle(int graphIndex) {
-		return Messages.getString("PowerPlugin.pluginTitle"); //$NON-NLS-1$
-	}
 }
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.power/src/com/nokia/carbide/cpp/pi/power/PowerTraceGraph.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.power/src/com/nokia/carbide/cpp/pi/power/PowerTraceGraph.java	Wed Apr 21 15:14:16 2010 +0300
@@ -31,6 +31,7 @@
 import org.eclipse.draw2d.MouseEvent;
 import org.eclipse.draw2d.MouseMotionListener;
 import org.eclipse.draw2d.Panel;
+import org.eclipse.jface.action.Action;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.SelectionAdapter;
 import org.eclipse.swt.events.SelectionEvent;
@@ -49,6 +50,7 @@
 import com.nokia.carbide.cpp.internal.pi.interfaces.ISaveSamples;
 import com.nokia.carbide.cpp.internal.pi.model.GenericSampledTrace;
 import com.nokia.carbide.cpp.internal.pi.plugin.model.IContextMenu;
+import com.nokia.carbide.cpp.internal.pi.plugin.model.ITitleBarMenu;
 import com.nokia.carbide.cpp.internal.pi.power.actions.PowerSettingsDialog;
 import com.nokia.carbide.cpp.internal.pi.power.actions.PowerStatisticsDialog;
 import com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph;
@@ -60,12 +62,14 @@
 import com.nokia.carbide.cpp.pi.address.GppTrace;
 import com.nokia.carbide.cpp.pi.editors.PIPageEditor;
 import com.nokia.carbide.cpp.pi.util.ColorPalette;
+import com.nokia.carbide.cpp.pi.visual.IGenericTraceGraph;
 
 
 public class PowerTraceGraph extends GenericTraceGraph implements ActionListener,
 																  PIEventListener,
 																  MouseMotionListener,
-																  IContextMenu
+																  IContextMenu,
+																  ITitleBarMenu
 {
 	
     private int[] DTrace; // used for synchronizing the power and gpptraces.
@@ -341,7 +345,7 @@
 
 		case PIEvent.SCROLLED:
 			Event event = ((Event)be.getValueObject());
-			this.parentComponent.setScrolledOrigin(event.x, event.y);
+			this.parentComponent.setScrolledOrigin(event.x, event.y, (FigureCanvas)event.data);
 			this.repaint();
 			break;
 
@@ -349,10 +353,6 @@
         	break;
 	    }
 	}
-	
-	public void refreshDataFromTrace()
-	{
-	}
 
 	public void enablePowerLine( boolean state )
 	{
@@ -702,7 +702,7 @@
 
 		// this does cause some overhead and could be removed since it only provides some aesthetics.
 		updateVisibleBorders();
-		leftBorder = this.parentComponent.getScrolledOrigin().x;
+		leftBorder = this.parentComponent.getScrolledOrigin(this).x;
 //		leftBorder = this.getVisibleLeftBorder();
 		if( leftBorder < 0 )
 			leftBorder = 0;	
@@ -914,8 +914,8 @@
 						                  + (sample.thread.threadName != null ? sample.thread.threadName
 											   : Messages.getString("PowerTraceGraph.11")) + Messages.getString("PowerTraceGraph.12") //$NON-NLS-1$ //$NON-NLS-2$
 					   							   + sample.thread.threadId + Messages.getString("PowerTraceGraph.13") //$NON-NLS-1$
-					   							   + sample.currentFunctionSym.functionName + Messages.getString("PowerTraceGraph.14") //$NON-NLS-1$
-					   							   + Long.toHexString(sample.currentFunctionSym.startAddress.longValue()) ),
+					   							   + sample.getCurrentFunctionSym().getFunctionName() + Messages.getString("PowerTraceGraph.14") //$NON-NLS-1$
+					   							   + Long.toHexString(sample.getCurrentFunctionSym().getStartAddress().longValue()) ),
 					   			Messages.getString("PowerTraceGraph.15") ) == null ) //$NON-NLS-1$
 			{
 				numTransitions++;
@@ -1138,11 +1138,11 @@
 			
 			Point extent = gc.stringExtent(legend);
 			
-			gc.drawLine(GenericTraceGraph.yLegendWidth - 3, (int)y + 1, GenericTraceGraph.yLegendWidth, (int)y + 1);
+			gc.drawLine(IGenericTraceGraph.Y_LEGEND_WIDTH - 3, (int)y + 1, IGenericTraceGraph.Y_LEGEND_WIDTH, (int)y + 1);
 
 			if (y >= previousBottom)
 			{
-				gc.drawString(legend, GenericTraceGraph.yLegendWidth - extent.x - 4, (int)y);
+				gc.drawString(legend, IGenericTraceGraph.Y_LEGEND_WIDTH - extent.x - 4, (int)y);
 				previousBottom = (int)y + extent.y;
 			}
 		}
@@ -1152,4 +1152,26 @@
 			figureCanvas.redraw();
 		}
 	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.pi.visual.IGenericTraceGraph#getTitle()
+	 */
+	@Override
+	public String getTitle() {
+		return Messages.getString("PowerPlugin.pluginTitle"); //$NON-NLS-1$
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.ITitleBarMenu#addTitleBarMenuItems()
+	 */
+	public Action[] addTitleBarMenuItems() {
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.ITitleBarMenu#getContextHelpId()
+	 */
+	public String getContextHelpId() {
+		return PowerPlugin.HELP_CONTEXT_ID_MAIN_PAGE;
+	}
 }
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.power/src/com/nokia/carbide/cpp/pi/power/PwrTraceGraph.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.power/src/com/nokia/carbide/cpp/pi/power/PwrTraceGraph.java	Wed Apr 21 15:14:16 2010 +0300
@@ -57,10 +57,6 @@
 	{
 	}
 
-	public void refreshDataFromTrace() 
-	{
-	}
-
 	public void mouseMoved(MouseEvent me)
 	{
 		if(!selected) return;
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.power/src/com/nokia/carbide/cpp/pi/power/messages.properties	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.power/src/com/nokia/carbide/cpp/pi/power/messages.properties	Wed Apr 21 15:14:16 2010 +0300
@@ -18,6 +18,7 @@
 PowerTraceGraph.23=Power Usage Statistics
 PowerTraceGraph.24=mW
 PowerTraceGraph.comma=,
+PowerPlugin.0=Power usage
 PowerPlugin.powerGraph=Power Graph
 PowerPlugin.powerSettingsAction=Power Usage Settings\u2026
 PowerPlugin.powerSettingsTooltip=Change power usage graph settings
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.priority/META-INF/MANIFEST.MF	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.priority/META-INF/MANIFEST.MF	Wed Apr 21 15:14:16 2010 +0300
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: Carbide.c++ Performance Investigator Thread Priorities
 Bundle-SymbolicName: com.nokia.carbide.cpp.pi.priority;singleton:=true
-Bundle-Version: 1.5.0.qualifier
+Bundle-Version: 2.3.0.qualifier
 Bundle-Activator: com.nokia.carbide.cpp.pi.priority.PriorityPlugin
 Bundle-Vendor: Nokia
 Bundle-Localization: plugin
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.priority/src/com/nokia/carbide/cpp/pi/priority/PriTrace.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.priority/src/com/nokia/carbide/cpp/pi/priority/PriTrace.java	Wed Apr 21 15:14:16 2010 +0300
@@ -22,7 +22,7 @@
 import com.nokia.carbide.cpp.internal.pi.model.GenericSampledTrace;
 import com.nokia.carbide.cpp.internal.pi.model.GenericThread;
 import com.nokia.carbide.cpp.internal.pi.model.TraceWithThreads;
-import com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph;
+import com.nokia.carbide.cpp.pi.visual.IGenericTraceGraph;
 
 
 public class PriTrace extends GenericSampledTrace implements TraceWithThreads
@@ -50,7 +50,7 @@
 		return (PriSample)this.samples.elementAt(number);
 	}
 	  
-	public GenericTraceGraph getTraceGraph()
+	public IGenericTraceGraph getTraceGraph()
 	{
 	  	return null;
 	}
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.priority/src/com/nokia/carbide/cpp/pi/priority/PriTraceParser.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.priority/src/com/nokia/carbide/cpp/pi/priority/PriTraceParser.java	Wed Apr 21 15:14:16 2010 +0300
@@ -201,8 +201,8 @@
 				   		threadName = rawName;
 				   	}
 								    	
-				   	priTrace.addFirstSynchTime(new Integer((int)threadId), new Integer(sampleNum));
-				   	priSamples.add(new PriThread(new Integer((int)threadId), threadName, processName));
+				   	priTrace.addFirstSynchTime(Integer.valueOf((int)threadId), Integer.valueOf(sampleNum));
+				   	priSamples.add(new PriThread(Integer.valueOf((int)threadId), threadName, processName));
 
 				   	// read the next length
 					length = dis.readUnsignedByte();readCount++;
@@ -290,8 +290,8 @@
 	    			break;
 	    		}
 	    	}
-//	    	memTrace.addLastSynchTime(new Integer(threadId), new Integer(sampleNum));
-	    	priTrace.addLastSynchTime(new Integer(threadId), new Integer(sampleNum));
+//	    	memTrace.addLastSynchTime(Integer.valueOf(threadId), Integer.valueOf(sampleNum));
+	    	priTrace.addLastSynchTime(Integer.valueOf(threadId), Integer.valueOf(sampleNum));
 	    }
 	    System.out.println(Messages.getString("PriTraceParser.done")); //$NON-NLS-1$
 	}
@@ -384,10 +384,10 @@
 				   		threadName = rawName;
 				   	}
 								    	
-					//memTrace.addFirstSynchTime(new Integer((int)threadId),new Integer((int)sample));
-				   	//memSamples.add(new MemThread(new Integer((int)threadId), threadName, processName));
-				   	priTrace.addFirstSynchTime(new Integer((int)threadId), new Integer(sampleNum));
-				   	priSamples.add(new PriThread(new Integer((int)threadId), threadName, processName));
+					//memTrace.addFirstSynchTime(Integer.valueOf((int)threadId),Integer.valueOf((int)sample));
+				   	//memSamples.add(new MemThread(Integer.valueOf((int)threadId), threadName, processName));
+				   	priTrace.addFirstSynchTime(Integer.valueOf((int)threadId), Integer.valueOf(sampleNum));
+				   	priSamples.add(new PriThread(Integer.valueOf((int)threadId), threadName, processName));
 
 				   	// read the next length
 					length = dis.readUnsignedByte();readCount++;
@@ -485,8 +485,8 @@
 	    			break;
 	    		}
 	    	}
-//	    	memTrace.addLastSynchTime(new Integer(threadId), new Integer(sampleNum));
-	    	priTrace.addLastSynchTime(new Integer(threadId), new Integer(sampleNum));
+//	    	memTrace.addLastSynchTime(Integer.valueOf(threadId), Integer.valueOf(sampleNum));
+	    	priTrace.addLastSynchTime(Integer.valueOf(threadId), Integer.valueOf(sampleNum));
 	    }
 	    System.out.println(Messages.getString("PriTraceParser.done")); //$NON-NLS-1$
 	}
@@ -724,10 +724,10 @@
 	    	processName = unparsedName.substring(0,index-1);
 	    	threadName = unparsedName.substring(index+1, j);
 //	    	int tmp = threadName.length();
-//	    	memTrace.addFirstSynchTime(new Integer(threadId), new Integer(sampleNum));
-//	    	memSamples.add(new MemThread(new Integer(threadId), threadName, processName));
-	    	priTrace.addFirstSynchTime(new Integer(threadId), new Integer(sampleNum));
-	    	priSamples.add(new PriThread(new Integer(threadId), threadName, processName));
+//	    	memTrace.addFirstSynchTime(Integer.valueOf(threadId), Integer.valueOf(sampleNum));
+//	    	memSamples.add(new MemThread(Integer.valueOf(threadId), threadName, processName));
+	    	priTrace.addFirstSynchTime(Integer.valueOf(threadId), Integer.valueOf(sampleNum));
+	    	priSamples.add(new PriThread(Integer.valueOf(threadId), threadName, processName));
 	    	//buffer = null; int threadId, String threadName, String processName
 	    	i += buffer.length + 8;
 	    }
@@ -778,8 +778,8 @@
 	    			break;
 	    		}
 	    	}
-//	    	memTrace.addLastSynchTime(new Integer(threadId), new Integer(sampleNum));
-	    	priTrace.addLastSynchTime(new Integer(threadId), new Integer(sampleNum));
+//	    	memTrace.addLastSynchTime(Integer.valueOf(threadId), Integer.valueOf(sampleNum));
+	    	priTrace.addLastSynchTime(Integer.valueOf(threadId), Integer.valueOf(sampleNum));
 	    	k += 16;
 	    }
 	    System.out.println(Messages.getString("PriTraceParser.done")); //$NON-NLS-1$
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.priority/src/com/nokia/carbide/cpp/pi/priority/PriorityPlugin.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.priority/src/com/nokia/carbide/cpp/pi/priority/PriorityPlugin.java	Wed Apr 21 15:14:16 2010 +0300
@@ -163,10 +163,24 @@
 		return "Priority"; //$NON-NLS-1$
 	}
 
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace#getTraceTitle()
+	 */
+	public String getTraceTitle() {
+		return Messages.getString("PriorityPlugin.0"); //$NON-NLS-1$
+	}
+
 	public int getTraceId() {
 		return 4;	//same id than MEM trace has because PRI trace is parsed from a MEM trace file
 	}
 
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace#parseTraceFiles(java.io.File[])
+	 */
+	public ParsedTraceData parseTraceFiles(File[] files) throws Exception {
+		throw new UnsupportedOperationException();
+	}
+
 	public ParsedTraceData parseTraceFile(File file /*, ProgressBar progressBar*/) throws Exception 
 	{
 		 try
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.priority/src/com/nokia/carbide/cpp/pi/priority/messages.properties	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.priority/src/com/nokia/carbide/cpp/pi/priority/messages.properties	Wed Apr 21 15:14:16 2010 +0300
@@ -18,6 +18,7 @@
 PriTraceParser.foundVersion3=\ trace file 
 PriTraceParser.wrongTraceType1=Wrong trace type 
 PriTraceParser.wrongTraceType2=\ as memory trace file
+PriorityPlugin.0=Priority trace
 PriorityPlugin.unsolvedPriority=Unsolved
 PriorityPlugin.priorityString1=\ 
 PriorityPlugin.priorityString2=(
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.priority2/META-INF/MANIFEST.MF	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.priority2/META-INF/MANIFEST.MF	Wed Apr 21 15:14:16 2010 +0300
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: Carbide.c++ Performance Investigator Thread Priorities 2
 Bundle-SymbolicName: com.nokia.carbide.cpp.pi.priority2;singleton:=true
-Bundle-Version: 1.5.0.qualifier
+Bundle-Version: 2.3.0.qualifier
 Bundle-Activator: com.nokia.carbide.cpp.pi.priority2.Priority2Plugin
 Bundle-Vendor: Nokia
 Bundle-Localization: plugin
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.priority2/src/com/nokia/carbide/cpp/pi/priority2/NewPriTrace.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.priority2/src/com/nokia/carbide/cpp/pi/priority2/NewPriTrace.java	Wed Apr 21 15:14:16 2010 +0300
@@ -22,7 +22,7 @@
 import com.nokia.carbide.cpp.internal.pi.model.GenericSampledTrace;
 import com.nokia.carbide.cpp.internal.pi.model.GenericThread;
 import com.nokia.carbide.cpp.internal.pi.model.TraceWithThreads;
-import com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph;
+import com.nokia.carbide.cpp.pi.visual.IGenericTraceGraph;
 
 
 public class NewPriTrace extends GenericSampledTrace implements TraceWithThreads
@@ -50,7 +50,7 @@
 		return (NewPriSample)this.samples.elementAt(number);
 	}
 	  
-	public GenericTraceGraph getTraceGraph()
+	public IGenericTraceGraph getTraceGraph()
 	{
 	  	return null;
 	}
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.priority2/src/com/nokia/carbide/cpp/pi/priority2/NewPriTraceParser.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.priority2/src/com/nokia/carbide/cpp/pi/priority2/NewPriTraceParser.java	Wed Apr 21 15:14:16 2010 +0300
@@ -166,8 +166,8 @@
 				   		threadName = rawName;
 				   	}
 								    	
-				   	priTrace.addFirstSynchTime(new Integer((int)threadId), new Integer(sampleNum));
-				   	priSamples.add(new NewPriThread(new Integer((int)threadId), threadName, processName));
+				   	priTrace.addFirstSynchTime(Integer.valueOf((int)threadId), Integer.valueOf(sampleNum));
+				   	priSamples.add(new NewPriThread(Integer.valueOf((int)threadId), threadName, processName));
 
 				   	// read the next length
 					length = dis.readUnsignedByte();readCount++;
@@ -234,7 +234,7 @@
 	    			break;
 	    		}
 	    	}
-	    	priTrace.addLastSynchTime(new Integer(threadId), new Integer(sampleNum));
+	    	priTrace.addLastSynchTime(Integer.valueOf(threadId), Integer.valueOf(sampleNum));
 	    }
 	    System.out.println(Messages.getString("NewPriTraceParser.doneParsing")); //$NON-NLS-1$
 	}
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.priority2/src/com/nokia/carbide/cpp/pi/priority2/Priority2Plugin.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.priority2/src/com/nokia/carbide/cpp/pi/priority2/Priority2Plugin.java	Wed Apr 21 15:14:16 2010 +0300
@@ -157,11 +157,25 @@
 		return "Priority"; //$NON-NLS-1$
 	}
 
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace#getTraceTitle()
+	 */
+	public String getTraceTitle() {
+		return Messages.getString("Priority2Plugin.0"); //$NON-NLS-1$
+	}
+
 	public int getTraceId() {
 		return 5;
 	}
 
 
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace#parseTraceFiles(java.io.File[])
+	 */
+	public ParsedTraceData parseTraceFiles(File[] files) throws Exception {
+		throw new UnsupportedOperationException();
+	}
+
 	public ParsedTraceData parseTraceFile(File file /*, ProgressBar progressBar*/) throws Exception 
 	{
 		 try
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.priority2/src/com/nokia/carbide/cpp/pi/priority2/messages.properties	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.priority2/src/com/nokia/carbide/cpp/pi/priority2/messages.properties	Wed Apr 21 15:14:16 2010 +0300
@@ -19,6 +19,7 @@
 NewPriTraceParser.lengthIs0=Data element length is 0
 NewPriTraceParser.wrongVersionforPRI=Wrong trace version for PRI file
 NewPriTraceParser.wrongTypeforPRI=Wrong trace type for PRI file
+Priority2Plugin.0=Priority trace
 Priority2Plugin.unsolvedPriority=Unsolved
 Priority2Plugin.priorityString1=\ 
 Priority2Plugin.priorityString2=(
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.ui/META-INF/MANIFEST.MF	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.ui/META-INF/MANIFEST.MF	Wed Apr 21 15:14:16 2010 +0300
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: Carbide.c++ Performance Investigator UI
 Bundle-SymbolicName: com.nokia.carbide.cpp.pi.ui;singleton:=true
-Bundle-Version: 1.5.0.qualifier
+Bundle-Version: 2.3.0.qualifier
 Bundle-Vendor: Nokia
 Bundle-Localization: plugin
 Require-Bundle: org.eclipse.ui,
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.util/META-INF/MANIFEST.MF	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.util/META-INF/MANIFEST.MF	Wed Apr 21 15:14:16 2010 +0300
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: Carbide.c++ Performance Investigator Utilities
 Bundle-SymbolicName: com.nokia.carbide.cpp.pi.util;singleton:=true
-Bundle-Version: 1.5.0.qualifier
+Bundle-Version: 2.3.0.qualifier
 Bundle-Vendor: Nokia
 Bundle-Localization: plugin
 Require-Bundle: org.eclipse.swt,
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.util/src/com/nokia/carbide/cpp/pi/util/TestDataMiningPalette.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.util/src/com/nokia/carbide/cpp/pi/util/TestDataMiningPalette.java	Wed Apr 21 15:14:16 2010 +0300
@@ -103,7 +103,7 @@
 			button.setBackground(new Color(Display.getCurrent(), palette.getRGB(entry)));
 			button.addSelectionListener(new SelectionAdapter() {
             	public void widgetSelected(SelectionEvent e) {
-            		Integer index = new Integer(button.getText());
+            		Integer index = Integer.valueOf(button.getText());
             		if(palette.recolorEntryDialog(sShell, index))
             		{
             			RGB newRGB = palette.getRGB(index);
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.util/src/com/nokia/carbide/cpp/pi/util/ThreadColorPalette.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.util/src/com/nokia/carbide/cpp/pi/util/ThreadColorPalette.java	Wed Apr 21 15:14:16 2010 +0300
@@ -57,7 +57,7 @@
 		
 		pro_string = pro_string.substring(0, mark);
 		
-	    if (pro_string.equalsIgnoreCase("EKern") && thr_string.equalsIgnoreCase("NULL")) { //$NON-NLS-1$ //$NON-NLS-2$
+	    if (pro_string.equalsIgnoreCase("EKern") && thr_string.toUpperCase().startsWith("NULL")) { //$NON-NLS-1$ //$NON-NLS-2$
 	    	return new RGB(192,192,192); // AWT Color.lightGray
 	    }
 	    if (pro_string.equalsIgnoreCase("CarbideProf") && thr_string.equalsIgnoreCase("Profiler")) { //$NON-NLS-1$ //$NON-NLS-2$
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.wizards/META-INF/MANIFEST.MF	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.wizards/META-INF/MANIFEST.MF	Wed Apr 21 15:14:16 2010 +0300
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: Carbide.c++ Performance Investigator Import Wizards
 Bundle-SymbolicName: com.nokia.carbide.cpp.pi.wizards;singleton:=true
-Bundle-Version: 1.5.0.qualifier
+Bundle-Version: 2.3.0.qualifier
 Bundle-Activator: com.nokia.carbide.cpp.pi.wizards.WizardsPlugin
 Bundle-Vendor: Nokia
 Bundle-Localization: plugin
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.wizards/src/com/nokia/carbide/cpp/internal/pi/wizards/ui/AbstractBaseGroup.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,315 @@
+/*
+ * Copyright (c) 2010 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: 
+ *
+ */
+package com.nokia.carbide.cpp.internal.pi.wizards.ui;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.IOException;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.TableItem;
+
+import com.nokia.carbide.cpp.internal.pi.analyser.StreamFileParser;
+import com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace;
+import com.nokia.carbide.cpp.internal.pi.utils.PIUtilities;
+
+/**
+ * Base group for the profiler data importers
+ * 
+ */
+public abstract class AbstractBaseGroup extends Group {
+
+	abstract class AbstractBaseSorter extends ViewerSorter {
+		Table table;
+		int column = 0;
+		boolean sortAscending;
+
+		public AbstractBaseSorter(Table table, int defaultColumn) {
+			this.table = table;
+			doSort(defaultColumn);
+		}
+
+		public void doSort(int column) {
+			sortAscending = !sortAscending;
+
+			// find the TableColumn corresponding to column, and give it a
+			// column direction
+			TableColumn sortByColumn = table.getColumn(column);
+			if (sortByColumn != null) {
+				table.setSortColumn(sortByColumn);
+				table.setSortDirection(sortAscending ? SWT.UP : SWT.DOWN);
+			}
+			this.column = column;
+		}
+
+		@Override
+		abstract public int compare(Viewer viewer, Object e1, Object e2);
+
+	}
+
+	abstract class AbstractLabelProvider extends LabelProvider implements
+			ITableLabelProvider {
+		public Image getColumnImage(Object element, int columnIndex) {
+			return null;
+		}
+	}
+
+	private List<ProfilerDataPlugins> profilerDataFiles = new ArrayList<ProfilerDataPlugins>();
+	protected INewPIWizardSettings wizardSettings;
+
+	/**
+	 * Constructor
+	 * 
+	 * @param parent
+	 *            instance of parent Composite
+	 * @param wizardSettings
+	 *            instance of the INewPIWizardSettings
+	 */
+	public AbstractBaseGroup(Composite parent,
+			INewPIWizardSettings wizardSettings) {
+		super(parent, SWT.NONE);
+		this.wizardSettings = wizardSettings;
+		// set default layout
+		this.setLayout(new GridLayout(1, false));
+		this.setLayoutData(new GridData(GridData.FILL_BOTH));
+		createContent();
+
+	}
+
+	// allow subclassing
+	protected void checkSubclass() {
+	}
+
+	/**
+	 * Implement content for the group
+	 */
+	protected abstract void createContent();
+
+	protected abstract Table getTable();
+
+	/**
+	 * Set this visible and hide given composite
+	 * 
+	 * @param hideComposite
+	 *            to hide
+	 */
+	public void setVisible(Composite hideComposite) {
+		setVisible(true);
+		setLocation(hideComposite.getLocation());
+		setSize(hideComposite.getSize());
+		hideComposite.setVisible(false);
+	}
+
+	/**
+	 * Add given profile data file into store
+	 * 
+	 * @param path
+	 *            selected profile data file
+	 * @throws IllegalArgumentException
+	 *             if given file is not valid profile data file
+	 */
+	public void addProfileDataFile(IPath path) throws IllegalArgumentException {
+		boolean exists = false;
+		for (ProfilerDataPlugins pdp : profilerDataFiles) {
+			if (pdp.getProfilerDataPath().equals(path)) {
+				exists = true;
+			}
+		}
+		if (!exists) {
+			// check whether selected file a valid profile data file or not
+			try {
+				File file = path.toFile();
+				if (!file.isFile() || file.length() <= 0) {
+					throw new IllegalArgumentException();
+				}
+				new StreamFileParser(file).allTraceType();
+				profilerDataFiles.add(new ProfilerDataPlugins(path,
+						getPluginsForTraceFile(path)));
+			} catch (Exception e) {
+				throw new IllegalArgumentException(MessageFormat.format(
+						Messages.getString("AbstractBaseGroup.isNotValidProfilerFile"), path //$NON-NLS-1$
+								.lastSegment()));
+			}
+		} else {
+			throw new IllegalArgumentException(MessageFormat.format(
+					Messages.getString("AbstractBaseGroup.profilerFileIsExisted"), path.lastSegment())); //$NON-NLS-1$
+		}
+	}
+
+	/**
+	 * Add all valid profile data file from given directory's path
+	 * 
+	 * @param path
+	 *            directory
+	 * @return
+	 */
+	public void addDirectory(IPath path) throws IllegalArgumentException {
+		if (path != null && path.toFile().isDirectory()) {
+			boolean addedValidFile = false;
+			try {
+				File directory = path.toFile();
+				if (!directory.isDirectory()) {
+					throw new IllegalArgumentException();
+				}
+				File[] fileArray = directory.listFiles(new FileFilter() {
+					public boolean accept(File file) {
+						if (file.isFile()) {
+							if (file.getPath().endsWith(".dat")) { //$NON-NLS-1$
+								return true;
+							}
+						}
+						return false;
+					}
+				});
+
+				for (File file : fileArray) {
+					try {
+						addProfileDataFile(new Path(file.toString()));
+						addedValidFile = true;
+					} catch (Exception e) {
+						// do nothing
+					}
+				}
+
+			} catch (Exception e) {
+				throw new IllegalArgumentException(MessageFormat.format(
+						Messages.getString("AbstractBaseGroup.failedToImportFromFolder"), path //$NON-NLS-1$
+								.toOSString()));
+			}
+			if (!addedValidFile) {
+				throw new IllegalArgumentException(MessageFormat.format(
+						Messages.getString("AbstractBaseGroup.notFoundProfilerDataFiles"), path //$NON-NLS-1$
+								.toOSString()));
+			}
+		}
+	}
+
+	/**
+	 * Remove selected item form given TableViewer
+	 * 
+	 * @param tableViewer
+	 *            instance of the TableViewer
+	 */
+	public void removeSelectedItem(TableViewer tableViewer) {
+		for (TableItem item : tableViewer.getTable().getSelection()) {
+			if (item.getData() instanceof IPath) {
+				IPath path = (IPath) item.getData();
+				for (ProfilerDataPlugins pdp : profilerDataFiles) {
+					if (pdp.getProfilerDataPath().equals(path)) {
+						profilerDataFiles.remove(pdp);
+						break;
+					}
+				}
+			}
+		}
+	}
+
+	/**
+	 * Remove all item
+	 */
+	public void removeAll() {
+		profilerDataFiles.clear();
+	}
+
+	/**
+	 * Get list of the ProfilerDataPlugins
+	 * 
+	 * @return list of the ProfilerDataPlugins
+	 */
+	public List<ProfilerDataPlugins> getProfilerDataFiles() {
+		return profilerDataFiles;
+	}
+
+	/**
+	 * Get selected item from the table
+	 * 
+	 * @return instance of the ProfilerDataPlugins if found otherwise null is
+	 *         returned
+	 */
+	public ProfilerDataPlugins getSelectedItem() {
+		Table table = getTable();
+		if (table.getSelectionCount() == 1) {
+			IPath path = (IPath) table.getSelection()[0].getData();
+			return getProfilerDataPlugins(path);
+		}
+		return null;
+	}
+
+	/**
+	 * Updates given TableViewer so that it contains same data that
+	 * ProfilerDataPlugins list.
+	 * 
+	 * @param tableViewer
+	 *            instance of the TableViewer
+	 */
+	public void refreshTable(TableViewer tableViewer) {
+		Table table = tableViewer.getTable();
+		List<IPath> pathList = new ArrayList<IPath>();
+		for (ProfilerDataPlugins pdp : profilerDataFiles) {
+			pathList.add(pdp.getProfilerDataPath());
+		}
+		tableViewer.setInput(pathList);
+		table.setSelection(0);
+		tableViewer.refresh();
+		wizardSettings.validatePage();
+	}
+
+	/**
+	 * Get plugins list from given file
+	 * 
+	 * @param profilerPath profiler data file
+	 * @return available plugins list from given file
+	 * @throws IOException
+	 */
+	private List<ITrace> getPluginsForTraceFile(IPath profilerPath)
+			throws IOException {
+		return PIUtilities.getPluginsForTraceFile(profilerPath.toString());
+	}
+
+	/**
+	 * Get ProfilerDataPlugins by given profiler data file
+	 * 
+	 * @param path 
+	 * @return instance of the ProfilerDataPlugins if found otherwise null is
+	 *         returned
+	 */
+	private ProfilerDataPlugins getProfilerDataPlugins(IPath path) {
+		for (ProfilerDataPlugins pdp : profilerDataFiles) {
+			if (pdp.getProfilerDataPath().equals(path)) {
+				return pdp;
+			}
+		}
+		return null;
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.wizards/src/com/nokia/carbide/cpp/internal/pi/wizards/ui/FileSelectionGroup.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,280 @@
+/*
+ * Copyright (c) 2010 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: 
+ *
+ */
+
+package com.nokia.carbide.cpp.internal.pi.wizards.ui;
+
+import java.util.List;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.DirectoryDialog;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+
+import com.nokia.carbide.cpp.pi.PiPlugin;
+
+/**
+ * Provides content of the profile data file selection from file system group
+ */
+public class FileSelectionGroup extends AbstractBaseGroup {
+	
+	private TableViewer profileDataTable;
+	
+	/**
+	 * Constructor 
+	 * 
+	 * @param parent instance of the parent composite 
+	 * @param wizardSettings instance of the INewPIWizardSettings
+	 */
+	public FileSelectionGroup(Composite parent,
+			INewPIWizardSettings wizardSettings) {
+		super(parent, wizardSettings);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.wizards.ui.AbstractBaseGroup#createContent()
+	 */
+	protected void createContent() {
+		GridLayout gridLayout = new GridLayout();
+		gridLayout.numColumns = 2;
+		this.setLayout(gridLayout);
+		this.setLayoutData(new GridData(GridData.FILL_BOTH));
+		this.setText(Messages.getString("FileSelectionGroup.title")); //$NON-NLS-1$
+		
+		
+		profileDataTable = new TableViewer(this, SWT.BORDER| SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL
+				| SWT.FULL_SELECTION);
+				
+		TableColumn column = new TableColumn(profileDataTable.getTable(), SWT.NONE);
+		column.setText(Messages.getString("FileSelectionGroup.profilerDataFileName")); //$NON-NLS-1$
+		column.setWidth(200);
+		column.setResizable(true);
+		column.setMoveable(true);
+		column.addSelectionListener(new SelectionAdapter(){
+			public void widgetSelected(SelectionEvent e)
+	        {
+	        	if (!(e.widget instanceof TableColumn))
+	        		return;
+	        	((AbstractBaseSorter)profileDataTable.getSorter()).doSort(0);
+	        	profileDataTable.refresh();
+	        	
+	        }
+		});		
+		
+		column = new TableColumn(profileDataTable.getTable(), SWT.NONE);
+		column.setText(Messages.getString("FileSelectionGroup.profilerDataFilePath")); //$NON-NLS-1$
+		column.setWidth(300);
+		column.setResizable(true);
+		column.setMoveable(true);
+		column.addSelectionListener(new SelectionAdapter(){
+			public void widgetSelected(SelectionEvent e)
+	        {
+	        	if (!(e.widget instanceof TableColumn))
+	        		return;
+	        	((AbstractBaseSorter)profileDataTable.getSorter()).doSort(1);
+	        	profileDataTable.refresh();
+	        	
+	        }
+		});
+	
+		GridData fileLogsTableGridData = new GridData(GridData.FILL_BOTH);
+		profileDataTable.getTable().setLayoutData(fileLogsTableGridData);
+		profileDataTable.getTable().setHeaderVisible(true);
+		profileDataTable.getTable().setLinesVisible(true);
+		profileDataTable.setContentProvider(new IStructuredContentProvider(){
+			public Object[] getElements(Object inputElement) {
+				if (inputElement instanceof List<?>){
+					return ((List<?>)inputElement).toArray();
+				}
+				return new Object[0];
+			}
+			public void dispose() {
+			}
+			public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+			}
+			
+		});
+	
+		profileDataTable.addSelectionChangedListener(new ISelectionChangedListener() {
+			public void selectionChanged(SelectionChangedEvent event) {
+				if(profileDataTable.getTable().getSelectionCount() == 1){
+					wizardSettings.validatePage();				
+					
+				}				
+			}
+		});
+		
+		
+		profileDataTable.setSorter(	new AbstractBaseSorter(profileDataTable.getTable(), 0){
+			@Override
+			public int compare(Viewer viewer, Object e1, Object e2) {
+				IPath path1 = (IPath)e1;
+				IPath path2 = (IPath)e2;
+				int returnCode = 0;
+				switch (column) {
+				case 0:
+					returnCode = path1.lastSegment().compareTo(path2.lastSegment());
+					break;
+				case 1:
+					returnCode = path1.removeLastSegments(1).toOSString().compareTo(path2.removeLastSegments(1).toOSString());
+					break;
+
+				default:
+					break;
+				}
+				if (!sortAscending)
+					returnCode = -returnCode;
+				return returnCode;
+			}			
+		});		
+	
+		profileDataTable.setLabelProvider(new AbstractLabelProvider() {
+			public String getColumnText(Object element, int columnIndex) {
+				IPath path = (IPath)element;
+				switch (columnIndex) {
+				case 0:	
+					return path.lastSegment();
+				case 1:
+					return path.removeLastSegments(1).toOSString();
+				default:
+					break;
+				}
+				return ""; //$NON-NLS-1$
+			}			
+		});
+
+
+		Composite fileSelectionButtonComposite = new Composite(this, SWT.NONE);
+		GridLayout threadButtonLayout = new GridLayout();
+		GridData fileSelectionButtonGridData = new GridData(
+				GridData.HORIZONTAL_ALIGN_FILL);
+		fileSelectionButtonComposite.setLayoutData(fileSelectionButtonGridData);
+		fileSelectionButtonComposite.setLayout(threadButtonLayout);
+		threadButtonLayout.numColumns = 1;
+
+		// Add file button
+		Button addFileButton = new Button(fileSelectionButtonComposite,
+				SWT.PUSH);
+		addFileButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		addFileButton.setText(Messages.getString("FileSelectionGroup.actionAddFile")); //$NON-NLS-1$
+		addFileButton.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				// open file dialog for selecting a crash file
+				FileDialog dialog = new FileDialog(getShell(), SWT.MULTI);
+				dialog.setText(Messages.getString("FileSelectionGroup.dialogFileTitle")); //$NON-NLS-1$
+				String[] filterExt = { "*.dat", "*.*" }; //$NON-NLS-1$ //$NON-NLS-2$
+				dialog.setFilterExtensions(filterExt);
+				String path = dialog.open();
+				if(path != null){
+					IPath folder = new Path(path).removeLastSegments(1);					
+					for(String fileName: dialog.getFileNames()){
+						try {
+							addProfileDataFile(folder.append(fileName));						
+						} catch (IllegalArgumentException iae) {
+							IStatus status = new Status(Status.ERROR,
+									PiPlugin.PLUGIN_ID, iae.getMessage());
+							ErrorDialog.openError(getShell(),
+									Messages.getString("FileSelectionGroup.performanceInvestigator"), null, status); //$NON-NLS-1$
+						}					
+					}
+					refreshTable(profileDataTable);
+				}			
+			}
+		});
+
+		// Add folder button
+		Button addDirectoryButton = new Button(fileSelectionButtonComposite,
+				SWT.PUSH);
+		addDirectoryButton
+				.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		addDirectoryButton.setText(Messages.getString("FileSelectionGroup.actionAddDirectory")); //$NON-NLS-1$
+		addDirectoryButton.addSelectionListener(new SelectionAdapter() {
+
+			public void widgetSelected(SelectionEvent e) {
+				// open file dialog for selecting a crash file
+				DirectoryDialog dialog = new DirectoryDialog(getShell());
+				dialog
+						.setText(Messages.getString("FileSelectionGroup.dialogDirectoryTitle")); //$NON-NLS-1$
+				String result = dialog.open();
+				if (result != null) {
+					try {
+						addDirectory(new Path(result));			
+						refreshTable(profileDataTable);
+						
+					} catch (IllegalArgumentException iae) {
+						IStatus status = new Status(Status.ERROR,
+								PiPlugin.PLUGIN_ID, iae.getMessage());
+						ErrorDialog.openError(getShell(),
+								Messages.getString("FileSelectionGroup.performanceInvestigator"), null, status); //$NON-NLS-1$
+					}
+				}
+			}
+		});
+
+		// Remove one file button
+		Button removeOneButton = new Button(fileSelectionButtonComposite,
+				SWT.PUSH);
+		removeOneButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		removeOneButton.setText(Messages.getString("FileSelectionGroup.actionRemove")); //$NON-NLS-1$
+		removeOneButton.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				removeSelectedItem(profileDataTable);
+				refreshTable(profileDataTable);
+			}
+
+		});
+
+		// Remove all files and folders button
+		Button removeAllButton = new Button(fileSelectionButtonComposite,
+				SWT.PUSH);
+		removeAllButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		removeAllButton.setText(Messages.getString("FileSelectionGroup.actionRemoveAll")); //$NON-NLS-1$
+		removeAllButton.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				removeAll();
+				refreshTable(profileDataTable);
+			}
+
+		});
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.wizards.ui.AbstractBaseGroup#getTable()
+	 */
+	@Override
+	public Table getTable() {
+		return profileDataTable.getTable();
+	}
+}
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.wizards/src/com/nokia/carbide/cpp/internal/pi/wizards/ui/NewPIWizard.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.wizards/src/com/nokia/carbide/cpp/internal/pi/wizards/ui/NewPIWizard.java	Wed Apr 21 15:14:16 2010 +0300
@@ -18,11 +18,11 @@
 package com.nokia.carbide.cpp.internal.pi.wizards.ui;
 
 import java.io.IOException;
+import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 import java.util.Map.Entry;
 
 import org.eclipse.core.resources.IFile;
@@ -30,8 +30,11 @@
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IConfigurationElement;
 import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.SubProgressMonitor;
 import org.eclipse.jface.dialogs.DialogSettings;
 import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.operation.IRunnableWithProgress;
 import org.eclipse.jface.viewers.IStructuredSelection;
 import org.eclipse.jface.wizard.IWizardPage;
 import org.eclipse.jface.wizard.Wizard;
@@ -40,16 +43,21 @@
 import org.eclipse.ui.IImportWizard;
 import org.eclipse.ui.INewWizard;
 import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.progress.IProgressService;
 
 import com.nokia.carbide.cdt.builder.builder.CarbideCPPBuilder;
 import com.nokia.carbide.cdt.builder.project.ICarbideBuildConfiguration;
 import com.nokia.carbide.cdt.builder.project.ISISBuilderInfo;
 import com.nokia.carbide.cpp.internal.api.sdk.SymbianBuildContext;
+import com.nokia.carbide.cpp.internal.pi.analyser.AnalyserDataProcessor;
+import com.nokia.carbide.cpp.internal.pi.utils.PIUtilities;
 import com.nokia.carbide.cpp.internal.pi.wizards.ui.util.IPkgEntry;
 import com.nokia.carbide.cpp.internal.pi.wizards.ui.util.RofsObySymbolPair;
 import com.nokia.carbide.cpp.pi.button.BupEventMapManager;
 import com.nokia.carbide.cpp.pi.button.ButtonPlugin;
 import com.nokia.carbide.cpp.pi.importer.SampleImporter;
+import com.nokia.carbide.cpp.pi.util.GeneralMessages;
 import com.nokia.carbide.cpp.pi.wizards.WizardsPlugin;
 import com.nokia.carbide.cpp.sdk.core.ISymbianBuildContext;
 import com.nokia.carbide.cpp.ui.CarbideUIPlugin;
@@ -76,13 +84,14 @@
 	private NewPIWizardPageBupMapTask pageBupMap;
 	private NewPIWizardPageOutputTask pageOutput;
 	private ArrayList<IFile> tmpPkgList = new ArrayList<IFile>();
-	private Set<Integer> traceSet;
 	
 	protected IProject piProject;
 	IWorkbench workbench;
 	
 	NewPIWizardSettings wizardSettings = NewPIWizardSettings.getInstance();
 
+	private List<ProfilerDataPlugins> profilerDataPlugins;
+
 	/**
 	 * Constructor for NewPIWizard.
 	 */
@@ -145,7 +154,6 @@
 	 * will create an operation and run it using wizard as execution context.
 	 */
 	public boolean performFinish() {
-		pageOutput.regenerateOutputIfIntputChanged(); // this must stay out of asyncExec() since it require treeviewer selection
 		Display.getDefault().asyncExec( new Runnable() {
 			public void run () {
 				//DialogSettings dialogSettings = (DialogSettings) WizardsPlugin.getDefault().getDialogSettings();
@@ -206,12 +214,12 @@
 	}
 
 	private void createNewProject() {
-		SampleImporter sampleImporter = SampleImporter.getInstance();
+		
+		final SampleImporter sampleImporter = SampleImporter.getInstance();
 		NewPIWizardSettings wizardSettings = NewPIWizardSettings.getInstance();
 		Map<Object, IFile> preprocessedMap = new HashMap<Object, IFile>();
 		sampleImporter.clear();
 		
-		sampleImporter.setDatFileName(wizardSettings.sampleFileName);
 		String container = wizardSettings.outputContainer.getFullPath().toString();
 		if (container.startsWith("/")) //$NON-NLS-1$
 			container = container.substring(1, container.length());
@@ -305,9 +313,45 @@
 				sampleImporter.setBupMapIsWorkspace(true);
 			}			
 		}
+		
 
-		sampleImporter.importSamples(false);	// not waiting NPI save complete for responsive UI, save NPI on background
-		
+		if(profilerDataPlugins.size() <= 1){
+			for(ProfilerDataPlugins pdp : profilerDataPlugins){
+				sampleImporter.setDatFileName(pdp.getProfilerDataPath().toString());	
+				// due to PI shortcomings (i.e. plugins that create pages have to come first)
+				// the plugins have to be sorted by trace id
+				sampleImporter.importSamples(false, PIUtilities.sortPlugins(pdp.getSelectedPlugins()), true, null, null);						
+				break;
+			}
+		}	
+		else{		
+			final int[] i={1};
+			final int count = profilerDataPlugins.size();
+			IProgressService progressService = PlatformUI.getWorkbench().getProgressService();
+			IRunnableWithProgress runnable= new IRunnableWithProgress() {
+
+				public void run(IProgressMonitor progressMonitor) {					
+					progressMonitor.beginTask("", count*AnalyserDataProcessor.TOTAL_PROGRESS_COUNT); //$NON-NLS-1$
+					String suffixTaskName;
+					for (ProfilerDataPlugins pdp : profilerDataPlugins) {
+						if(progressMonitor.isCanceled()){
+							break;
+						}						
+						suffixTaskName = MessageFormat.format(Messages.getString("NewPIWizard.suffixTaskName"), i[0]++, count);						 //$NON-NLS-1$
+						sampleImporter.setDatFileName(pdp.getProfilerDataPath().toString());	
+						sampleImporter.importSamples(false, PIUtilities
+								.sortPlugins(pdp.getSelectedPlugins()), false, suffixTaskName,
+								new SubProgressMonitor(progressMonitor, AnalyserDataProcessor.TOTAL_PROGRESS_COUNT));
+					}		
+				}
+
+			};
+			try {
+				progressService.busyCursorWhile(runnable);
+			} catch (Exception e) {
+				GeneralMessages.showErrorMessage(e.getMessage());
+			}
+		}
 		cleanTempPkgFile();
 	}
 	
@@ -340,21 +384,11 @@
 		return true;
 	}
 	
-	// all trace ID, we can check this for trace specific handling
-	public Set<Integer> getTraceSet() {
-		return traceSet;
-	}
-	
-	// all trace ID, we can do trace specific handling later
-	public void setTraceSet(Set<Integer> myTraceSet) {
-		traceSet = myTraceSet;
-	}
-	
 	public IWizardPage getPreviousPage (IWizardPage page) {
 		NewPIWizardSettings settings = NewPIWizardSettings.getInstance();
 		if (page == pageOutput && settings.enableCust == false) {
 			return getPreviousPage(pageCustom);
-		} else if (page == pageCustom && getTraceSet().contains(ButtonPlugin.getDefault().getTraceId()) == false){
+		} else if (page == pageCustom && isButtonPluginUsed() == false){
 			return getPreviousPage(pageBupMap);
 		} else if (page == pageBupMap && wizardSettings.haveRomOnly == false && wizardSettings.haveAppRom == false) {
 			return getPreviousPage(pageObySym);
@@ -370,12 +404,27 @@
 			return getNextPage(pagePkgList);
 		} else if (page == pagePkgList && wizardSettings.haveRomOnly == false && wizardSettings.haveAppRom == false) {
 			return getNextPage(pageObySym);
-		} else if (page == pageObySym && getTraceSet().contains(ButtonPlugin.getDefault().getTraceId()) == false) {
+		} else if (page == pageObySym && isButtonPluginUsed() == false) {
 			return getNextPage(pageBupMap);
 		} else if (page == pageBupMap && wizardSettings.enableCust == false) {
 			return getNextPage(pageCustom);
 		}
 		return super.getNextPage(page);
 	}
+	
+	public void setProfilerDataFiles(List<ProfilerDataPlugins> profilerDataPlugins){
+		this.profilerDataPlugins = profilerDataPlugins;
+	}
+	
+	private boolean isButtonPluginUsed(){
+		if(profilerDataPlugins != null){
+			for(ProfilerDataPlugins pdp : profilerDataPlugins){
+				if(pdp.getSelectedPlugins().contains(ButtonPlugin.getDefault())){
+					return true;
+				}
+			}
+		}
+		return false;
+	}
 
 }
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.wizards/src/com/nokia/carbide/cpp/internal/pi/wizards/ui/NewPIWizardPageBupMapTask.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.wizards/src/com/nokia/carbide/cpp/internal/pi/wizards/ui/NewPIWizardPageBupMapTask.java	Wed Apr 21 15:14:16 2010 +0300
@@ -24,7 +24,9 @@
 
 import org.eclipse.jface.layout.GridDataFactory;
 import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.jface.viewers.AbstractTreeViewer;
 import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
 import org.eclipse.jface.viewers.SelectionChangedEvent;
 import org.eclipse.jface.viewers.StructuredSelection;
 import org.eclipse.swt.SWT;
@@ -105,9 +107,9 @@
 	 */
 	public void setupPageFromFromNewPIWizardSettings() {
 		if (settings.keyMapProfile != null) {
-			profileTreeViewer.collapseAll();
+			profileTreeViewer.expandAll();
+			profileTreeViewer.setSelection(new StructuredSelection(settings.keyMapProfile));
 			profileTreeViewer.reveal(settings.keyMapProfile);
-			profileTreeViewer.setSelection(new StructuredSelection(settings.keyMapProfile));
 		}
 	}
 
@@ -169,9 +171,8 @@
 			if (profiles.size() == 1) {
 				IBupEventMapProfile profile = profiles.get(0);
 				rationaleText.setText(Messages.getString("NewPIWizardPageBupMapTask.6") + profile.getProfileId() + Messages.getString("NewPIWizardPageBupMapTask.7") + profile.getSDK().getUniqueId()+ Messages.getString("NewPIWizardPageBupMapTask.8")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-				profileTreeViewer.collapseAll();
+				profileTreeViewer.setSelection(new StructuredSelection(profile));
 				profileTreeViewer.reveal(profile);
-				profileTreeViewer.setSelection(new StructuredSelection(profile));
 				return true;
 
 			} else {
@@ -203,9 +204,8 @@
 				if (profiles.size() == 1) {
 					IBupEventMapProfile profile = profiles.get(0);
 					rationaleText.setText(Messages.getString("NewPIWizardPageBupMapTask.11") + profile.getProfileId() + Messages.getString("NewPIWizardPageBupMapTask.12") + profile.getSDK().getUniqueId()+ Messages.getString("NewPIWizardPageBupMapTask.13")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-					profileTreeViewer.collapseAll();
+					profileTreeViewer.setSelection(new StructuredSelection(profile));
 					profileTreeViewer.reveal(profile);
-					profileTreeViewer.setSelection(new StructuredSelection(profile));
 					return true;
 				} else {
 					rationaleText.setText(Messages.getString("NewPIWizardPageBupMapTask.14") + sdks.get(0).getUniqueId()+ Messages.getString("NewPIWizardPageBupMapTask.15")); //$NON-NLS-1$ //$NON-NLS-2$
@@ -219,10 +219,10 @@
 			}	
 		}
 		
-		profileTreeViewer.collapseAll();
-		profileTreeViewer.reveal(BupEventMapManager.getInstance().getPrefSelectedProfile());
-		profileTreeViewer.setSelection(new StructuredSelection(BupEventMapManager.getInstance().getPrefSelectedProfile()));
-
+		IBupEventMapProfile profile = BupEventMapManager.getInstance().getPrefSelectedProfile();
+		profileTreeViewer.setSelection(new StructuredSelection(profile));
+		profileTreeViewer.reveal(profile);
+		
 		return false;
 	}
 	
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.wizards/src/com/nokia/carbide/cpp/internal/pi/wizards/ui/NewPIWizardPageInputTask.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.wizards/src/com/nokia/carbide/cpp/internal/pi/wizards/ui/NewPIWizardPageInputTask.java	Wed Apr 21 15:14:16 2010 +0300
@@ -17,147 +17,113 @@
 
 package com.nokia.carbide.cpp.internal.pi.wizards.ui;
 
-import java.io.File;
-import java.io.IOException;
-
 import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.SelectionAdapter;
 import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Combo;
 import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.FileDialog;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Text;
+import org.eclipse.swt.widgets.Group;
 import org.eclipse.ui.PlatformUI;
 
-import com.nokia.carbide.cpp.internal.pi.analyser.StreamFileParser;
 import com.nokia.carbide.cpp.internal.pi.wizards.ui.util.CarbidePiWizardHelpIds;
 
-
-
-public class NewPIWizardPageInputTask
-extends NewPIWizardPage
-implements INewPIWizardSettings
-{
-	private final static String UID_PROPERTY= ".uid"; //$NON-NLS-1$
-	private final static String DAT_EXTENSION= "dat"; //$NON-NLS-1$
-	private boolean visableBefore = false;
+public class NewPIWizardPageInputTask extends NewPIWizardPage implements
+		INewPIWizardSettings {
+	private FileSelectionGroup fileSelectionGroup;
+	private TraceSelectionGroup traceSelectionGroup;
 
 	protected NewPIWizardPageInputTask(final NewPIWizard wizard) {
-		super(Messages.getString("NewPIWizardPageSampleFile.name")); //$NON-NLS-1$
+		super(Messages.getString("NewPIWizardPageSampleFile.title")); //$NON-NLS-1$
+		super.setWizard(wizard);
 		setTitle(Messages.getString("NewPIWizardPageSampleFile.title")); //$NON-NLS-1$
 	    setDescription(Messages.getString("NewPIWizardPageSampleFile.description")); //$NON-NLS-1$
 	}
 
-	// controls
-	Composite container;
-	private Text sampleFileTexti;
-	private Combo sampleFileCombo;
-
 	public void createControl(Composite parent) {
 		super.createControl(parent);
-		container = new Composite(parent, SWT.NULL);
-		container.setData(UID_PROPERTY, "container"); //$NON-NLS-1$
+		Composite container = new Composite(parent, SWT.NULL);
 		GridLayout layout = new GridLayout();
 		container.setLayout(layout);
 		layout.numColumns = 1;
-		layout.verticalSpacing = 9;
+
+		//createRadioButtonGroup(container); // not implemented yet
+		fileSelectionGroup = new FileSelectionGroup(container, this);
+		fileSelectionGroup.setVisible(true);
 
-		Label labelSampleFile = new Label(container, SWT.NONE);
-		labelSampleFile.setText(Messages.getString("NewPIWizardPageSampleFile.dat.file.name")); //$NON-NLS-1$
-		
-		// subcomposite with textbox/button
-		Composite subContainer = new Composite(container, SWT.NULL);
-		subContainer.setData(UID_PROPERTY, "subContainer"); //$NON-NLS-1$
-		GridLayout subLayout = new GridLayout();
-		subContainer.setLayout(subLayout);
-		subContainer.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
-		subLayout.numColumns = 2;
-		subLayout.verticalSpacing = 9;
+		traceSelectionGroup = new TraceSelectionGroup(container,this);
+		setControl(container);
+		PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(),
+				CarbidePiWizardHelpIds.PI_IMPORT_WIZARD_INPUT);
+	}
 
-		/*
-		sampleFileText = new Text(subContainer, SWT.BORDER | SWT.SINGLE);
-		sampleFileText.setData(UID_PROPERTY, "sampleFileText"); //$NON-NLS-1$
-		sampleFileText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
-		sampleFileText.addModifyListener(new ModifyListener() {
-			public void modifyText(ModifyEvent e) {
-				// write back to our status
-				NewPIWizardSettings.getInstance().sampleFileName = sampleFileText.getText();
-				NewPIWizardSettings.getInstance().sampleFileNameModifiedNanoTime = System.nanoTime();
-				validatePage();
+	private void createRadioButtonGroup(Composite parent) {
+		// Radio button group
+		GridLayout radioButtonGroupGridLayout = new GridLayout();
+		Group radioButtonGroup = new Group(parent, SWT.NONE);
+		radioButtonGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		radioButtonGroup.setText(Messages.getString("NewPIWizardPageInputTask.profilerDataSourceGroupTitle")); //$NON-NLS-1$
+		radioButtonGroup.setLayout(radioButtonGroupGridLayout);
+		GridData radioButtonGridData = new GridData(GridData.FILL_HORIZONTAL);
+		radioButtonGridData.horizontalSpan = 2;
+
+		// File radio button
+		final Button fileRadioButton = new Button(radioButtonGroup, SWT.RADIO);
+		fileRadioButton.setText(Messages.getString("NewPIWizardPageInputTask.fromFileSystem")); //$NON-NLS-1$
+		fileRadioButton.setLayoutData(radioButtonGridData);
+		fileRadioButton.addSelectionListener(new SelectionListener() {
+
+			public void widgetSelected(SelectionEvent e) {
+				if (fileRadioButton.getSelection()) {
+					fileSelectionGroup.setVisible(true);
+				}
+
 			}
-		});*/
-		
-		sampleFileCombo = new Combo(subContainer, SWT.BORDER | SWT.SINGLE);
-		sampleFileCombo.setData(UID_PROPERTY, "sampleFileText"); //$NON-NLS-1$
-		sampleFileCombo.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
-		sampleFileCombo.addModifyListener(new ModifyListener() {
-			public void modifyText(ModifyEvent e) {
-				// write back to our status
-				NewPIWizardSettings.getInstance().sampleFileName = sampleFileCombo.getText();
-				NewPIWizardSettings.getInstance().sampleFileNameModifiedNanoTime = System.nanoTime();
-				validatePage();
+
+			public void widgetDefaultSelected(SelectionEvent e) {
 			}
 		});
+		fileRadioButton.setSelection(true);
 
-		Button button = new Button(subContainer, SWT.PUSH);
-		button.setText(Messages.getString("NewPIWizardPageSampleFile.browse")); //$NON-NLS-1$
-		button.addSelectionListener(new SelectionAdapter() {
+		// From Device via TraceViewer radio button
+		final Button deviceRadioButton = new Button(radioButtonGroup, SWT.RADIO);
+		deviceRadioButton
+				.setText(Messages.getString("NewPIWizardPageInputTask.fromDevice")); //$NON-NLS-1$
+		deviceRadioButton.setLayoutData(radioButtonGridData);
+		deviceRadioButton.addSelectionListener(new SelectionListener() {
+
 			public void widgetSelected(SelectionEvent e) {
-				handleBrowse();
+				if (deviceRadioButton.getSelection()) {
+				}
+			}
+
+			public void widgetDefaultSelected(SelectionEvent e) {
 			}
 		});
-			
-		// top tap get focus
-		sampleFileCombo.setFocus();
+		deviceRadioButton.setSelection(false);
 
-
-		setControl(container);
-		PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(), CarbidePiWizardHelpIds.PI_IMPORT_WIZARD_INPUT);
+		// not implemented yet
+		deviceRadioButton.setEnabled(false);
 	}
 
 	public void validatePage() {
-		if (sampleFileCombo.getText() == null || sampleFileCombo.getText().length() < 1) {
-			
-			updateStatus(null);
-			setPageComplete(false);
-			return;		// blank should be OK, consistent with Eclipse guideline
+		if(traceSelectionGroup != null){
+			traceSelectionGroup.updateTraceIds(fileSelectionGroup.getSelectedItem());					
+			((NewPIWizard)getWizard()).setProfilerDataFiles(fileSelectionGroup.getProfilerDataFiles()); 
 		}
-		
-		int dotLoc = sampleFileCombo.getText().lastIndexOf('.');
-
-		if (dotLoc != -1) {
-			String ext = sampleFileCombo.getText().substring(dotLoc + 1);
-
-			if (ext.equalsIgnoreCase(DAT_EXTENSION) == false) {
-				updateStatus(Messages.getString("NewPIWizardPageSampleFile.dat.file.extension.must.be.dat")); //$NON-NLS-1$
-				return;
-			}
+		if(fileSelectionGroup.getProfilerDataFiles().size() > 1){
+			setMessage(Messages.getString("NewPIWizardPageInputTask.noteImportMayTakeSeveralMinutes")); //$NON-NLS-1$
+		}else{
+			setMessage(Messages.getString("NewPIWizardPageSampleFile.description"));
+		}
+		if(fileSelectionGroup.getProfilerDataFiles().isEmpty()){
+			setPageComplete(false);
+		} else {	
+			setPageComplete(true);
+			updateStatus(null);
 		}
 
-		if (!(new File(sampleFileCombo.getText()).exists())) {
-			updateStatus(Messages.getString("NewPIWizardPageSampleFile.dat.file.name.does.not.exist")); //$NON-NLS-1$
-			return;
-		}
-		if (!(new File(sampleFileCombo.getText()).isFile())) {
-
-			updateStatus(Messages.getString("NewPIWizardPageSampleFile.dat.must.be.a.file")); //$NON-NLS-1$
-			return;		
-		}
-
-		try {
-			((NewPIWizard)getWizard()).setTraceSet(new StreamFileParser(new File(sampleFileCombo.getText())).allTraceType());
-
-		} catch (IOException e) {
-			// just ignore
-		}
-		setPageComplete(true);
-		updateStatus(null);
 	}
 
 	private void updateStatus(String message) {
@@ -165,59 +131,15 @@
 		setErrorMessage(message);
 		setPageComplete(message == null);
 	}
-		
-	private void handleBrowse() {
-		FileDialog dialog = new FileDialog(getShell());
-		String[] datExtensions = {"*.dat", //$NON-NLS-1$
-//									"*.base64",
-									"*.*"}; //$NON-NLS-1$
-		String[] datNames = {Messages.getString("NewPIWizardPageSampleFile.sample.filter.name"), //$NON-NLS-1$
-//								"Profiler Sample Files (*.base64)",
-								Messages.getString("NewPIWizardPageSampleFile.all.filter.name")}; //$NON-NLS-1$
-		dialog.setFilterExtensions(datExtensions);
-		dialog.setFilterNames(datNames);
-		// Try guiding user to path user is trying to fill
-		File clueFile = new File(sampleFileCombo.getText());
 
-		String cluePath = null;
-		if (clueFile.isDirectory()) {
-			cluePath = clueFile.getAbsolutePath();
-		} else {
-			cluePath = clueFile.getParent();
-		}
-		if (cluePath != null) {
-			dialog.setFilterPath(cluePath);
-		}
-		String filePath = dialog.open();
-
-		if (filePath != null) {
-			if (filePath.length() > 0) {
-				sampleFileCombo.setText(filePath);
-
-			}
-		}		
-	}
-
-	public void setupPageFromFromNewPIWizardSettings() {
-		
-		String[] items = NewPIWizardSettings.getInstance().sampleFileNames;
-		if (items != null){
-			sampleFileCombo.setItems(items);
-			sampleFileCombo.select(0);
+	public void setVisible(boolean visable) {
+		super.setVisible(visable);
+		if (visable) {
+			validatePage();
 		}
 	}
 
-	public void setVisible(boolean visable) {
-		super.setVisible(visable);
-		
-		if (visable) {
-			// block the text if it's wrong on startup, so user know what's wrong
-			if (visableBefore == false && getErrorMessage() != null) {
-				sampleFileCombo.select(0);
-
-			}
-		}
-		visableBefore = visable;
+	public void setupPageFromFromNewPIWizardSettings() {		
+		// do nothing
 	}
 }
-
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.wizards/src/com/nokia/carbide/cpp/internal/pi/wizards/ui/NewPIWizardPageOutputTask.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.wizards/src/com/nokia/carbide/cpp/internal/pi/wizards/ui/NewPIWizardPageOutputTask.java	Wed Apr 21 15:14:16 2010 +0300
@@ -28,7 +28,6 @@
 import org.eclipse.core.resources.IWorkspaceRoot;
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.Path;
 import org.eclipse.jface.viewers.DecoratingLabelProvider;
 import org.eclipse.jface.viewers.ISelection;
 import org.eclipse.jface.viewers.ISelectionChangedListener;
@@ -41,16 +40,12 @@
 import org.eclipse.jface.viewers.Viewer;
 import org.eclipse.jface.wizard.WizardDialog;
 import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
 import org.eclipse.swt.events.SelectionEvent;
 import org.eclipse.swt.events.SelectionListener;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.Button;
 import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Text;
 import org.eclipse.ui.IViewSite;
 import org.eclipse.ui.IWorkbenchWizard;
 import org.eclipse.ui.PlatformUI;
@@ -61,9 +56,6 @@
 import com.nokia.carbide.cpp.internal.pi.wizards.ui.util.CarbidePiWizardHelpIds;
 
 public class NewPIWizardPageOutputTask extends NewPIWizardPage implements INewPIWizardSettings {
-	
-	private final static String DOT_NPI= ".npi"; //$NON-NLS-1$
-	private final static String EMPTY_STRING = ""; //$NON-NLS-1$
 
 	// Provides all folder in workspace
 	private class ProjectContentProvider
@@ -124,8 +116,6 @@
 	private Composite buttonComposite = null;
 	private TreeViewer outputChooserTreeViewer = null;
 	private Button createButton = null;
-	private Label fileLabel = null;
-	private Text outputText = null;
 	
 	protected NewPIWizardPageOutputTask() {
 		super(""); //$NON-NLS-1$
@@ -134,7 +124,7 @@
 	}
 
 	public void validatePage() {
-		if (outputText.getText().length() < 1 || outputChooserTreeViewer.getTree().getSelection().length < 1) {
+		if (outputChooserTreeViewer.getTree().getSelection().length < 1) {
 			setErrorMessage(Messages.getString("NewPIWizardPageOutputTask.choose.output.project")); //$NON-NLS-1$
 			setPageComplete(false);
 			return;
@@ -152,26 +142,6 @@
 		composite.setLayout(gridLayout1);
 		composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
 		createProjectComposite();
-		fileLabel = new Label (composite, SWT.NONE);
-		fileLabel.setText(Messages.getString("NewPIWizardPageOutputTask.output.file.name")); //$NON-NLS-1$
-		outputText = new Text(composite, SWT.BORDER);
-		outputText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
-		outputText.addSelectionListener(new SelectionListener () {
-			public void widgetDefaultSelected(SelectionEvent arg0) {
-			}
-
-			public void widgetSelected(SelectionEvent arg0) {
-				validatePage();
-			}	
-		});
-		outputText.addModifyListener(new ModifyListener() {
-
-			public void modifyText(ModifyEvent arg0) {
-				NewPIWizardSettings.getInstance().piFileName = outputText.getText();		
-				NewPIWizardSettings.getInstance().piFileNameModifiedNanoTime = System.nanoTime();
-			}
-			
-		});
 		
 		validatePage();
 
@@ -201,8 +171,7 @@
 			public void widgetDefaultSelected(SelectionEvent arg0) {
 			}
 
-			public void widgetSelected(SelectionEvent arg0) {
-				outputText.setText(generateNpiFileName(outputText.getText()));
+			public void widgetSelected(SelectionEvent arg0) {	
 				validatePage();
 			}
 		});
@@ -243,88 +212,13 @@
 				wizard.init(PlatformUI.getWorkbench(), new TreeSelection());
 				WizardDialog dialog = new WizardDialog(getShell(), wizard);
 				dialog.open();
-				if (outputChooserTreeViewer.getTree().getItemCount() == 1) {
-					outputText.setText(generateNpiFileName(outputText.getText()));
+				if (outputChooserTreeViewer.getTree().getItemCount() == 1) {					
 					validatePage();
 				}
 			}
 			
 		});
-	}
-	
-	private boolean isPositiveLong(String x) {
-		try {
-			if (Long.parseLong(x) >= 0) {
-				return true;
-			}
-		} catch (NumberFormatException e) {
-			return false;
-		}
-		return false;
-	}
-	
-	private String generateNpiFileName(String initialFilename) {
-		// First look for the container
-		IContainer container = NewPIWizardSettings.getInstance().outputContainer;
-		
-		TreeSelection selection = (TreeSelection) outputChooserTreeViewer.getSelection();
-		if (selection == null)
-			return EMPTY_STRING;
-		if (selection.getFirstElement() == null)
-			return EMPTY_STRING;
-		if ((selection.getFirstElement() instanceof IContainer) == false)
-			return EMPTY_STRING;
-		container = (IContainer) selection.getFirstElement();				
-		try {
-			// in case user dump a file of the same name without telling eclipse
-			container.refreshLocal(1, null);
-		} catch (CoreException e) {
-			// this is likely harmless
-			e.printStackTrace();
-		}
-
-		// Then see if we find a matching file name
-		initialFilename.trim();
-		if (initialFilename.length()==0) {
-			// generate from sample file if input file is empty
-			initialFilename = NewPIWizardSettings.getInstance().sampleFileName;
-		}
-		// get just the file name(last part)
-		initialFilename = new java.io.File(initialFilename).getName();
-		
-		String baseName;
-		Long suffixNumber = new Long(0);
-		
-		int dot = initialFilename.lastIndexOf("."); //$NON-NLS-1$
-		if (dot > 1) {
-			baseName = initialFilename.substring(0, dot); //$NON-NLS-1$
-		} else {
-			baseName = initialFilename;
-		}
-		
-		if (initialFilename.endsWith(".npi")) {	//$NON-NLS-1$
-			// the input is a .npi doesn't exist in container, user should have manually typed it
-			if (container.getFile(new Path(initialFilename)).exists() == false) {
-				return initialFilename;
-			}
-			
-			// this is probably an ***_<number>.npi we need to increament
-			// just suffix _<number> if the name was derived from input sample name
-			if (baseName.lastIndexOf("_") > 1 && 	//$NON-NLS-1$
-				isPositiveLong(baseName.substring(baseName.lastIndexOf("_") + 1)))	//$NON-NLS-1$
-			{
-				suffixNumber = Long.parseLong(baseName.substring(baseName.lastIndexOf("_") + 1)); //$NON-NLS-1$
-				baseName = baseName.substring(0, baseName.lastIndexOf("_"));	//$NON-NLS-1$
-			}
-		}
-				
-		// check existing npi and bump number
-		while (container.getFile(new Path(baseName + "_" + suffixNumber.toString() + DOT_NPI)).exists()) { //$NON-NLS-1$
-			suffixNumber++;
-		}
-
-		return baseName + "_" + suffixNumber.toString() + DOT_NPI; //$NON-NLS-1$
-	}
+	}	
 
 	public void setupPageFromFromNewPIWizardSettings() {
 		outputChooserTreeViewer.getTree().deselectAll();
@@ -349,7 +243,6 @@
 		// setup using last session persisted. If user changed input file, 
 		// regenerateOutputIfIntputChanged() will derive the new output name base on input 
 		// upon finish, or output page become visible
-		outputText.setText(generateNpiFileName(NewPIWizardSettings.getInstance().piFileName));
 		validatePage();
 	}
 
@@ -380,21 +273,11 @@
 		}
 		return result;
 	}
-
-	public void regenerateOutputIfIntputChanged() {
-		// if both time stamps are set and input sample is later than NPI, regenerate it
-		if (NewPIWizardSettings.getInstance().sampleFileNameModifiedNanoTime != 0 &&
-			NewPIWizardSettings.getInstance().piFileNameModifiedNanoTime != 0 &&
-			NewPIWizardSettings.getInstance().sampleFileNameModifiedNanoTime - NewPIWizardSettings.getInstance().piFileNameModifiedNanoTime > 0) {
-			outputText.setText(generateNpiFileName(NewPIWizardSettings.getInstance().sampleFileName));
-		}
-	}
 	
 	public void setVisible(boolean visable) {
 		super.setVisible(visable);
 		if (visable) {
 			// see if we input changed
-			regenerateOutputIfIntputChanged();
 			validatePage();
 		}
 	}
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.wizards/src/com/nokia/carbide/cpp/internal/pi/wizards/ui/NewPIWizardPagePkgListTask.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.wizards/src/com/nokia/carbide/cpp/internal/pi/wizards/ui/NewPIWizardPagePkgListTask.java	Wed Apr 21 15:14:16 2010 +0300
@@ -59,6 +59,8 @@
 	private Composite buttonComposite = null;	
 	private Button addPkgButton = null;
 	private Button removeButton = null;
+	private boolean isSisBuilderConfigurationChecked;
+	private PkgListTreeContentProvider pkgListTreeContentProvider;
 	
 	// data model
 	PkgListTree pkgListRoot = null;
@@ -96,7 +98,7 @@
 		projectTreeViewer = new PkgListTreeViewer(filelistComposite, SWT.H_SCROLL | SWT.BORDER);
 		pkgListRoot = new PkgListTree();
 		projectTreeViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
-		projectTreeViewer.setContentProvider(new PkgListTreeContentProvider(pkgListRoot));
+		projectTreeViewer.setContentProvider(pkgListTreeContentProvider = new PkgListTreeContentProvider(pkgListRoot));
 		projectTreeViewer.setLabelProvider(new DecoratingLabelProvider(
 				new PkgListTreeLabelProvider(), PlatformUI.getWorkbench()
                         .getDecoratorManager().getLabelDecorator()));
@@ -283,4 +285,15 @@
 
 	public void validatePage() {
 	}
+
+	@Override
+	public void setVisible(boolean visable) {
+		super.setVisible(visable);
+		// show possible sis builder configuration warnings once during the wizard session
+		if(visable && !isSisBuilderConfigurationChecked){
+			isSisBuilderConfigurationChecked = true;
+			pkgListTreeContentProvider.getCarbideCppProjects(true);
+		}
+	}
+	
 }
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.wizards/src/com/nokia/carbide/cpp/internal/pi/wizards/ui/NewPIWizardSettings.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.wizards/src/com/nokia/carbide/cpp/internal/pi/wizards/ui/NewPIWizardSettings.java	Wed Apr 21 15:14:16 2010 +0300
@@ -75,10 +75,6 @@
 	static final String KEY_PROFILE_KEY = "keyProfile";								//$NON-NLS-1$
 	static final String SAMPLEFILENAMES_KEY = "sampleFileName";						//$NON-NLS-1$
 
-	
-//	start version 2
-	String sampleFileName;
-	String[] sampleFileNames;
 	boolean haveAppOnly = false;
 	boolean haveRomOnly = false;
 	boolean haveAppRom = false;
@@ -110,7 +106,6 @@
 //	end internal states not saved
 	
 	public void clear() {
-		sampleFileName = "";			//$NON-NLS-1$
 		haveAppOnly = false;
 		haveRomOnly = false;
 		haveAppRom = false;
@@ -148,9 +143,6 @@
 	public void saveState(IDialogSettings dialogSettings) {
 		try {
 			dialogSettings.put(IMPORTER_SETTING_VERSION, CURRENT_VERSION);
-			dialogSettings.put(SAMPLEFILENAME_KEY, sampleFileName);
-			saveFileNameToArray();
-			dialogSettings.put(SAMPLEFILENAMES_KEY, sampleFileNames);
 			dialogSettings.put(ENABLE_CUST_KEY, enableCust);
 			
 			{	// traverse all entries of app config and pkg file
@@ -221,8 +213,6 @@
 				return;
 			}
 			if (dialogSettings.getInt(IMPORTER_SETTING_VERSION) == CURRENT_VERSION) {
-				sampleFileName = dialogSettings.get(SAMPLEFILENAME_KEY);
-				sampleFileNames = dialogSettings.getArray(SAMPLEFILENAMES_KEY);
 //				if(!(new java.io.File(sampleFileName).exists()))
 //					sampleFileName = "";	//$NON-NLS-1$
 				enableCust = dialogSettings.getBoolean(ENABLE_CUST_KEY);
@@ -341,60 +331,5 @@
 		} catch (Exception e) {
 			e.printStackTrace();
 		}
-	}
-	
-	
-	
-	
-	/**
-	 * @param sampleFileName path to save
-	 * @param array name of the array which contains correct values
-	 * @param section section which has array 
-	 */
-	protected void saveFileNameToArray() {
-			
-		// No previous values exist
-		if (sampleFileNames == null) {
-			sampleFileNames = new String[1];
-			sampleFileNames[0] = sampleFileName;
-		// Previous values exists
-		} else {
-			int valuesCount = sampleFileNames.length;
-			
-			boolean valueExisted = false;
-			// see if passed value already exist.
-			for (int i = 0; i < valuesCount; i++) {
-				if (sampleFileNames[i].compareToIgnoreCase(sampleFileName) == 0) {
-					valueExisted = true;
-					
-					// passed value exists, move it to first position
-					for (int j = i; j > 0; j--) {
-						sampleFileNames[j] = sampleFileNames[j-1];
-					}
-					sampleFileNames[0] = sampleFileName;
-					
-					break;
-				}
-			}
-			
-			// passed value did not exist, add it to first position (and move older values "down")
-			if (!valueExisted) {
-				if (valuesCount >= COMBO_MAX_ITEM_VALUES) {
-					for (int i = valuesCount-1; i > 0; i--) {
-						sampleFileNames[i] = sampleFileNames[i-1];
-					}
-					sampleFileNames[0] = sampleFileName;
-				} else {
-					String[] values = new String[valuesCount + 1];
-					values[0] = sampleFileName;
-					for (int i = 0; i < valuesCount; i++) {
-						values[i+1] = sampleFileNames[i];
-					}
-					sampleFileNames = values;
-				}
-			}
-		}
-		
-	}
-	
+	}	
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.wizards/src/com/nokia/carbide/cpp/internal/pi/wizards/ui/ProfilerDataPlugins.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2010 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: 
+ *
+ */
+package com.nokia.carbide.cpp.internal.pi.wizards.ui;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IPath;
+
+import com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace;
+
+
+public class ProfilerDataPlugins {
+	private Map<ITrace, Boolean> pluginsSelectionMap;
+	private final IPath profilerDataPath;
+	
+	/**
+	 * Constructor
+	 * 
+	 * @param profilerDataPath profiler data file
+	 * @param plugins list of the plugins 
+	 */
+	public ProfilerDataPlugins(IPath profilerDataPath, List<ITrace> plugins){
+		this.profilerDataPath = profilerDataPath;
+		initPlugins(plugins);
+	}
+	
+	/**
+	 * Initialize plugins 
+	 * 
+	 * @param plugins list of the plugins
+	 */
+	public void initPlugins(List<ITrace> plugins){
+		pluginsSelectionMap = new HashMap<ITrace, Boolean>();
+		removeDuplicatePriorityPlugin(plugins);
+		for(ITrace trace : plugins){
+			pluginsSelectionMap.put(trace, true);
+		}
+	}
+	
+	/**
+	 * Get list of the plugins
+	 * 
+	 * @return list of the plugins
+	 */
+	public List<ITrace> getPlugins() {
+		List<ITrace> traceList = new ArrayList<ITrace>();
+		Iterator<ITrace> iterator = pluginsSelectionMap.keySet().iterator();
+		while(iterator.hasNext()){
+			traceList.add(iterator.next());
+		}		
+		return traceList;
+	}
+	
+	/**
+	 * Get list of the selected plugins
+	 * 
+	 * @return list of the selected plugins
+	 */
+	public List<ITrace> getSelectedPlugins() {
+		List<ITrace> traceList = new ArrayList<ITrace>();
+		Iterator<ITrace> iterator = pluginsSelectionMap.keySet().iterator();
+		while(iterator.hasNext()){
+			ITrace trace = iterator.next();
+			if(isChecked(trace)){
+				traceList.add(trace);
+			}			
+		}		
+		return traceList;
+	}
+	
+	/**
+	 * Check whether given trace selected or not
+	 * 
+	 * @param trace
+	 * @return
+	 */
+	public boolean isChecked(ITrace trace){
+		if(pluginsSelectionMap.containsKey(trace)){
+			return pluginsSelectionMap.get(trace);
+		}
+		return false;
+	}
+	
+	/**
+	 * Set given selection value for given trace
+	 * 
+	 * @param trace
+	 * @return
+	 */
+	public void setChecked(ITrace trace, boolean checked){
+		if(pluginsSelectionMap.containsKey(trace)){
+			pluginsSelectionMap.put(trace, new Boolean(checked));
+		}
+	}
+	
+	/**
+	 * Check all
+	 * 
+	 */
+	public void checkAll(){
+		for(ITrace trace : getPlugins()){
+			setChecked(trace, true);
+		}
+	}
+	
+	/**
+	 * Uncheck all
+	 * 
+	 */
+	public void unCheckAll(){
+		for(ITrace trace : getPlugins()){
+			if(!isMandatory(trace)){
+				setChecked(trace, false);
+			}
+		}
+	}
+	
+	/**
+	 * Check whether given trace mandatory or not
+	 * @param trace
+	 * @return
+	 */
+	public boolean isMandatory(ITrace trace){
+		if(pluginsSelectionMap.containsKey(trace)){
+			if(trace.getTraceId() == 1){
+				return true;
+			}		
+		}
+		return false;
+	}
+		
+	/**
+	 * Get profiler data file's path
+	 * 
+	 * @return
+	 */
+	public IPath getProfilerDataPath() {
+		return profilerDataPath;
+	}
+	
+	/**
+	 * If both priority plugins are present in the given list, remove the old-style plugin 
+	 * @param plugins List of plugins to check
+	 */
+	private void removeDuplicatePriorityPlugin(List<ITrace> plugins) {
+		//There is no elegant way of doing this, we'll just have to hard-code it		
+		ITrace plugin = null;
+		for (ITrace iTrace : plugins) {
+			if (iTrace.getTraceId() == 4 && iTrace.getTraceName().startsWith("P")){ //$NON-NLS-1$
+				//old style priority plugin (shares the trace id with the memory plugin)
+				plugin = iTrace;
+			} else if (iTrace.getTraceId() == 5 && plugin != null){
+				plugins.remove(plugin);
+				break;
+			}
+		}
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.wizards/src/com/nokia/carbide/cpp/internal/pi/wizards/ui/TraceSelectionGroup.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,288 @@
+/*
+ * Copyright (c) 2010 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: 
+ *
+ */
+package com.nokia.carbide.cpp.internal.pi.wizards.ui;
+
+import java.text.MessageFormat;
+import java.util.List;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.layout.TableColumnLayout;
+import org.eclipse.jface.viewers.CheckStateChangedEvent;
+import org.eclipse.jface.viewers.CheckboxTableViewer;
+import org.eclipse.jface.viewers.ColumnLabelProvider;
+import org.eclipse.jface.viewers.ColumnViewerToolTipSupport;
+import org.eclipse.jface.viewers.ColumnWeightData;
+import org.eclipse.jface.viewers.ICheckStateListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.TableViewerColumn;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.jface.window.ToolTip;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Table;
+
+import com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace;
+
+public class TraceSelectionGroup extends AbstractBaseGroup {
+
+	private CheckboxTableViewer viewerTraceSelection;
+	private ProfilerDataPlugins profilerDataPlugins;
+
+	/**
+	 * Constructor
+	 * 
+	 * @param parent
+	 *            instance of the parent composite
+	 * @param wizardSettings
+	 *            instance of the INewPIWizardSettings
+	 */
+	public TraceSelectionGroup(Composite parent,
+			INewPIWizardSettings wizardSettings) {
+		super(parent, wizardSettings);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.wizards.ui.AbstractBaseGroup#createContent
+	 * ()
+	 */
+	public void createContent() {
+		GridLayout gridLayout = new GridLayout();
+		gridLayout.numColumns = 2;
+		this.setLayout(gridLayout);
+		this.setLayoutData(new GridData(GridData.FILL_BOTH));
+		this.setText(Messages.getString("TraceSelectionGroup.groupTitle")); //$NON-NLS-1$
+
+		final Composite tablePanel = new Composite(this, SWT.NONE);
+		final GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true);
+		tablePanel.setLayoutData(layoutData);
+
+		viewerTraceSelection = CheckboxTableViewer.newCheckList(tablePanel,
+				SWT.BORDER | SWT.FULL_SELECTION);
+		viewerTraceSelection
+				.setContentProvider(new IStructuredContentProvider() {
+
+					public Object[] getElements(Object inputElement) {
+						if (inputElement instanceof List<?>) {
+							return ((List<?>) inputElement).toArray();
+						}
+						return new Object[0];
+					}
+
+					public void dispose() {
+					}
+
+					public void inputChanged(Viewer viewer, Object oldInput,
+							Object newInput) {
+					}
+
+				});
+		viewerTraceSelection.setSorter(new ViewerSorter() {
+
+			@Override
+			public int compare(Viewer viewer, Object e1, Object e2) {
+				if (profilerDataPlugins == null) {
+					return 0;
+				}
+				ITrace trace1 = (ITrace) e1;
+				ITrace trace2 = (ITrace) e2;
+				int returnCode = 0;
+				if (profilerDataPlugins.isMandatory(trace1) == true
+						&& profilerDataPlugins.isMandatory(trace2) == true) {
+					returnCode = 0;
+				} else if (profilerDataPlugins.isMandatory(trace1) == true
+						&& profilerDataPlugins.isMandatory(trace2) == false) {
+					returnCode = -1;
+				} else if (profilerDataPlugins.isMandatory(trace1) == false
+						&& profilerDataPlugins.isMandatory(trace2) == true) {
+					returnCode = 1;
+				} else {
+					returnCode = trace1.getTraceTitle().compareTo(
+							trace2.getTraceTitle());
+				}
+				return returnCode;
+			}
+
+		});
+		Table table = viewerTraceSelection.getTable();
+		table.setLinesVisible(true);
+		table.setHeaderVisible(true);
+		addActions();
+
+		ColumnViewerToolTipSupport.enableFor(viewerTraceSelection,
+				ToolTip.NO_RECREATE);
+
+		TableViewerColumn column = new TableViewerColumn(viewerTraceSelection,
+				SWT.NONE);
+		column.setLabelProvider(new ColumnLabelProvider() {
+			@Override
+			public String getText(final Object element) {
+				if (element instanceof ITrace) {
+					return ((ITrace) element).getTraceTitle();
+				}
+				return element.toString();
+			}
+
+			@Override
+			public String getToolTipText(Object element) {
+				StringBuilder sb = new StringBuilder(((ITrace) element)
+						.getTraceTitle());
+				if (((ITrace) element).getTraceId() == 1) {
+					sb.append(Messages.getString("TraceSelectionGroup.mandatory")); //$NON-NLS-1$
+				}
+				return sb.toString();
+			}
+
+			@Override
+			public Color getForeground(Object element) {
+				if (((ITrace) element).getTraceId() == 1) {
+					return Display.getCurrent().getSystemColor(
+							SWT.COLOR_DARK_GRAY);
+				}
+				return null;
+			}
+
+			@Override
+			public Point getToolTipShift(Object object) {
+				return new Point(5, 5);
+			}
+
+			@Override
+			public int getToolTipTimeDisplayed(Object object) {
+				return 5000;
+			}
+		});
+
+		column.getColumn().setText(Messages.getString("TraceSelectionGroup.piView")); //$NON-NLS-1$
+
+		TableColumnLayout tableColumnLayout = new TableColumnLayout();
+		tablePanel.setLayout(tableColumnLayout);
+		tableColumnLayout.setColumnData(column.getColumn(),
+				new ColumnWeightData(1));// column weight 1 to fill the whole
+		// table width
+
+		viewerTraceSelection.setAllChecked(true);
+		viewerTraceSelection.addCheckStateListener(new ICheckStateListener() {
+
+			/*
+			 * (non-Javadoc)
+			 * 
+			 * @see
+			 * org.eclipse.jface.viewers.ICheckStateListener#checkStateChanged
+			 * (org.eclipse.jface.viewers.CheckStateChangedEvent)
+			 */
+			public void checkStateChanged(CheckStateChangedEvent event) {
+				if (event.getChecked() == false
+						&& viewerTraceSelection.getGrayed(event.getElement())) {
+					// mandatory view; don't allow to deselect it
+					viewerTraceSelection.setChecked(event.getElement(), true);
+				} else {
+					ITrace plugin = (ITrace) event.getElement();
+					profilerDataPlugins.setChecked(plugin, event.getChecked());
+				}
+			}
+		});
+	}
+
+	/**
+	 * Update group's title
+	 * 
+	 * @param fileName for the group title
+	 */
+	private void updateTitle(String fileName){
+		if(fileName == null){
+			this.setText(Messages.getString("TraceSelectionGroup.groupTitle"));
+		}else{
+			this.setText(MessageFormat.format(Messages.getString("TraceSelectionGroup.groupTitleFor"), fileName));
+		}
+		
+	}
+	
+	/**
+	 * Add actions 
+	 */
+	private void addActions() {
+		final MenuManager mgr = new MenuManager();
+		Action checkAllAction = new Action(Messages.getString("TraceSelectionGroup.actionCheckAll")) {  //$NON-NLS-1$
+			@Override
+			public void run() {				
+				if (profilerDataPlugins != null) {
+					profilerDataPlugins.checkAll();	
+					viewerTraceSelection.setAllChecked(true);		
+				}
+			}
+		};
+		checkAllAction.setEnabled(true);
+
+		Action uncheckAllAction = new Action(Messages.getString("TraceSelectionGroup.actionUncheckAll")) {  //$NON-NLS-1$
+			@Override
+			public void run() {				
+				if (profilerDataPlugins != null) {
+					profilerDataPlugins.unCheckAll();	
+					for(ITrace trace : profilerDataPlugins.getPlugins()){
+						viewerTraceSelection.setChecked(trace, profilerDataPlugins.isChecked(trace));
+					}
+				}
+			}
+		};
+		uncheckAllAction.setEnabled(true);
+		mgr.add(checkAllAction);
+		mgr.add(uncheckAllAction);
+		viewerTraceSelection.getControl().setMenu(
+				mgr.createContextMenu(viewerTraceSelection.getControl()));
+	}
+
+	/**
+	 * Update trace ids
+	 * 
+	 * @param profilerDataPlugins
+	 */
+	public void updateTraceIds(ProfilerDataPlugins profilerDataPlugins) {
+		this.profilerDataPlugins = profilerDataPlugins;
+		if(profilerDataPlugins == null){
+			viewerTraceSelection.setInput(null);
+			updateTitle(null);
+		}else{			
+			viewerTraceSelection.setInput(profilerDataPlugins.getPlugins());
+			viewerTraceSelection.setAllChecked(true);
+			for (ITrace trace : profilerDataPlugins.getPlugins()) {
+				if (profilerDataPlugins.isMandatory(trace)) {
+					viewerTraceSelection.setGrayed(trace, true);
+				} else {
+					viewerTraceSelection.setChecked(trace, profilerDataPlugins
+							.isChecked(trace));
+				}
+			}			
+			updateTitle(profilerDataPlugins.getProfilerDataPath().lastSegment());
+		}
+
+	}
+
+	@Override
+	public Table getTable() {
+		return viewerTraceSelection.getTable();
+	}
+}
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.wizards/src/com/nokia/carbide/cpp/internal/pi/wizards/ui/messages.properties	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.wizards/src/com/nokia/carbide/cpp/internal/pi/wizards/ui/messages.properties	Wed Apr 21 15:14:16 2010 +0300
@@ -1,5 +1,36 @@
+#Eclipse messages class
+#Mon Mar 01 13:04:47 GMT 2010
+AbstractBaseGroup.isNotValidProfilerFile={0} is not valid profiler data file.
+AbstractBaseGroup.notFoundProfilerDataFiles=No profiler data files were found from {0}.
+AbstractBaseGroup.profilerFileIsExisted={0} already exists on the list.
+AbstractBaseGroup.failedToImportFromFolder=Failed to import profiler data files from {0}.
+FileSelectionGroup.actionAddDirectory=Add Directory
+FileSelectionGroup.actionAddFile=Add File
+FileSelectionGroup.actionRemove=Remove
+FileSelectionGroup.actionRemoveAll=Remove All
+FileSelectionGroup.dialogDirectoryTitle=Define location of directory that contains profile data files
+FileSelectionGroup.dialogFileTitle=Define location of profiler data file
+FileSelectionGroup.performanceInvestigator=Performance Investigator
+FileSelectionGroup.profilerDataFileName=Name
+FileSelectionGroup.profilerDataFilePath=Path
+FileSelectionGroup.title=From File System
+NewPIWizard.failed.convertFileToIFile=\ failed converFileToIFile
+NewPIWizard.suffixTaskName=({0}/{1})
 NewPIWizard.window.title=Performance Investigator Import Wizard
-
+NewPIWizardCustomTask.dat.file.name.must.be.specified=File name must be specified.
+NewPIWizardObySymbolPairDialog.browse=Browse...
+NewPIWizardObySymbolPairDialog.build.file.extension=Build file (.oby)
+NewPIWizardObySymbolPairDialog.does.not.exist.in.file.system=\ does not exist in file system.
+NewPIWizardObySymbolPairDialog.does.not.exist.in.file.system.2=\ does not exist in file system.
+NewPIWizardObySymbolPairDialog.oby.file=OBY file 
+NewPIWizardObySymbolPairDialog.oby.file.extension.error=OBY file must have .oby extension.
+NewPIWizardObySymbolPairDialog.rofs.oby.file=ROFS OBY File (mandatory)\:
+NewPIWizardObySymbolPairDialog.rofs.oby.rofs.symbol=ROFS OBY/ROFS Symbol
+NewPIWizardObySymbolPairDialog.rofs.symbol.file=ROFS symbol file
+NewPIWizardObySymbolPairDialog.shell.title=Add ROFS OBY/ROFS Symbol File
+NewPIWizardObySymbolPairDialog.symbol.extension.error=Symbol file must have .symbol extension.
+NewPIWizardObySymbolPairDialog.symbol.file=Symbol file (.symbol)
+NewPIWizardObySymbolPairDialog.symbol.file.2=Symbol file 
 NewPIWizardPageBupMapTask.0=Select Key Press Mapping Profile
 NewPIWizardPageBupMapTask.1=Select Key Press Mapping Profile
 NewPIWizardPageBupMapTask.10=) associated
@@ -16,120 +47,110 @@
 NewPIWizardPageBupMapTask.20=) associated
 NewPIWizardPageBupMapTask.21=None, there is no key press profile among ROM SDK (
 NewPIWizardPageBupMapTask.22=) associated.
-NewPIWizardPageBupMapTask.3=Profile:
-NewPIWizardPageBupMapTask.4=Recommended Profile:
+NewPIWizardPageBupMapTask.3=Profile\:
+NewPIWizardPageBupMapTask.4=Recommended Profile\:
 NewPIWizardPageBupMapTask.5=Please select a key press profile corresponding to your device.
 NewPIWizardPageBupMapTask.6=Profile (
 NewPIWizardPageBupMapTask.7=) is the only profile in ROM SDK (
 NewPIWizardPageBupMapTask.8=) associated
 NewPIWizardPageBupMapTask.9=None, there are multiple profiles among ROM SDK (
+NewPIWizardPageConfigSelectorTask.description=Select an import method based on the information available.
+NewPIWizardPageConfigSelectorTask.labelApp2=Carbide project or package (.pkg) files of profiled application.
+NewPIWizardPageConfigSelectorTask.labelAppTitle=1. Project importer
+NewPIWizardPageConfigSelectorTask.labelCustomTrace=Have additional custom trace.
+NewPIWizardPageConfigSelectorTask.labelNone2=Have neither Carbide project or a ROM image.
+NewPIWizardPageConfigSelectorTask.labelNone3=NOTE\: CPU load by function is unavailable, and by binary is incomplete.
+NewPIWizardPageConfigSelectorTask.labelNoneTitle=4. Unknown importer
+NewPIWizardPageConfigSelectorTask.labelRom2=ROM image symbol file of profiled phone.
+NewPIWizardPageConfigSelectorTask.labelRomApp2=Carbide project or package (.pkg) files of profiled application
+NewPIWizardPageConfigSelectorTask.labelRomApp3=+ ROM image symbol file of profiled phone.
+NewPIWizardPageConfigSelectorTask.labelRomAppTitle=2. Project and ROM importer
+NewPIWizardPageConfigSelectorTask.labelRomTitle=3. ROM importer
+NewPIWizardPageConfigSelectorTask.option.group=Available information\:
+NewPIWizardPageConfigSelectorTask.title=Available Information
+NewPIWizardPageCustomTask.13=C\:\\temp\\my_custom.trace.dat
+NewPIWizardPageCustomTask.14=0;name;1.4343;\n0;another_name;9.343
+NewPIWizardPageCustomTask.base.group=File type\:
+NewPIWizardPageCustomTask.button.comma=, Comma
+NewPIWizardPageCustomTask.button.name=Name based
+NewPIWizardPageCustomTask.button.semicolon=; Semicolon
+NewPIWizardPageCustomTask.button.space=Space character
+NewPIWizardPageCustomTask.button.value=Value based
+NewPIWizardPageCustomTask.description=Custom data file (*.dat)
+NewPIWizardPageCustomTask.detail.label=Select a custom sample data file (*.dat) produced by the on-device Carbide.c++ Profiler.
+NewPIWizardPageCustomTask.example.group=Example\:
+NewPIWizardPageCustomTask.format.group=Custom trace data format
+NewPIWizardPageCustomTask.seperator.group=Seperator\:
+NewPIWizardPageCustomTask.super.label=Select Custom Sample Data File
+NewPIWizardPageCustomTask.title=Select Custom Sample Data File
+NewPIWizardPageInputTask.1=I/O or parse exception: Trace types in profiler data file cannot be determined.
+NewPIWizardPageInputTask.3=Invalid profiler data file.
+NewPIWizardPageInputTask.4=Please select at least one PI view.
+NewPIWizardPageInputTask.fromDevice=By executing the profiler on device via TraceViewer
+NewPIWizardPageInputTask.fromFileSystem=From File System
+NewPIWizardPageInputTask.noteImportMayTakeSeveralMinutes=Note: It may take several minutes to import multiple profiler data files
+NewPIWizardPageInputTask.profilerDataSourceGroupTitle=Get profiler data:
+NewPIWizardPageInputTask.tblclmnTraceType.text=PI View
+NewPIWizardPageInputTask.title=Select approach for analysis
+NewPIWizardPageOutputTask.choose.output.project=Choose Output Project.
+NewPIWizardPageOutputTask.create.empty.project=Create Empty Project...
+NewPIWizardPageOutputTask.output.file.and.project=Output File And Project
+NewPIWizardPageOutputTask.output.file.name=Output File Name\:
+NewPIWizardPageOutputTask.select.folder.or.create.new.project.as.output.file.container=Select the folder or create a new project to store the output file container.
+NewPIWizardPagePkgListTask.all.filter.name=All Files (*.*)
+NewPIWizardPagePkgListTask.description=Add project configurations or package (.pkg) files that built installation files (.sis) used in Carbide.c++ Profiler session.\nOnly configurations that have been built may be selected.
+NewPIWizardPagePkgListTask.pkg.button=Add PKG File...
+NewPIWizardPagePkgListTask.pkg.filter.name=PKG Files (*.pkg)
+NewPIWizardPagePkgListTask.remove.button=Remove PKG Files...
+NewPIWizardPagePkgListTask.title=Associated Project and Package(.pkg) File
+NewPIWizardPagePkgSdkDialog.shell.title=SDK Associated With This PKG File
+NewPIWizardPageRomSdkSubTask.description=Select the SDK or EPOCROOT of the SDK, if any, that was used to build the ROM of the phone profiled.
+NewPIWizardPageRomSdkSubTask.title=Select SDK or specify EPOCROOT
+NewPIWizardPageRomSubTask.add=Add...
+NewPIWizardPageRomSubTask.add.rofs.pair=Add ROFS OBY/symbol file pair
+NewPIWizardPageRomSubTask.description=Select the build files corresponding to the ROM on the device.
+NewPIWizardPageRomSubTask.entry.already.exisits=Entry already exists
 NewPIWizardPageRomSubTask.error.1=Please select a SDK that builds the ROM image.
 NewPIWizardPageRomSubTask.error.2=is not a valid filename.
-
-NewPIWizardPageSampleFile.name=Select Profiler Data File
-NewPIWizardPageSampleFile.title=Select Profiler Data File
-NewPIWizardPageSampleFile.description=Select the Carbide Profiler data file (.dat) for conversion to a Performance Investigator file (.npi).
-NewPIWizardPageSampleFile.browse=Profiler Sample File...
-NewPIWizardPageSampleFile.dat.file.name=&Profiler Sample File:
-NewPIWizardPageSampleFile.dat.file.extension.must.be.dat=Carbide.c++ Profiler data file extension must be "dat".
-NewPIWizardObySymbolPairDialog.does.not.exist.in.file.system=\ does not exist in file system.
-NewPIWizardObySymbolPairDialog.does.not.exist.in.file.system.2=\ does not exist in file system.
-NewPIWizardPageSampleFile.dat.file.name.does.not.exist=Carbide.c++ Profiler data file specified does not exist.
-NewPIWizardObySymbolPairDialog.oby.file.extension.error=OBY file must have .oby extension.
-NewPIWizardPageSampleFile.dat.must.be.a.file=Please enter a Carbide.c++ Profiler data file.
-NewPIWizardPageSampleFile.sample.filter.name=Profiler Sample Files (*.dat)
-NewPIWizardPageSampleFile.all.filter.name=All Files (*.*)
-
-NewPIWizardPageOutputTask.output.file.and.project=Output File And Project
-
-NewPIWizardPageRomSubTask.oby.label=ROM OBY File:
-NewPIWizardPageRomSdkSubTask.title=Select SDK or specify EPOCROOT
-
-NewPIWizardPageCustomTask.13=C:\\temp\\my_custom.trace.dat
-NewPIWizardPageCustomTask.14=0;name;1.4343;\n0;another_name;9.343
-NewPIWizardPageCustomTask.title=Select Custom Sample Data File
-NewPIWizardPageRomSubTask.title=Select build files for ROM
-NewPIWizardPageRomSubTask.add=Add...
+NewPIWizardPageRomSubTask.name.filter=All Files (*.*)
+NewPIWizardPageRomSubTask.oby.button=ROM OBY File...
+NewPIWizardPageRomSubTask.oby.filter=*.oby
+NewPIWizardPageRomSubTask.oby.filter.text=Build file (.oby)
+NewPIWizardPageRomSubTask.oby.label=ROM OBY File\:
 NewPIWizardPageRomSubTask.remove=Remove...
-NewPIWizardPageRomSubTask.symbol.filter.text=Symbol File(*.symbol)
-NewPIWizardObySymbolPairDialog.rofs.oby.file=ROFS OBY File (mandatory):
-
-NewPIWizardRemovePkgDialog.sdk=\ / SDK: 
-
-NewPIWizard.failed.convertFileToIFile=\ failed converFileToIFile
-NewPIWizardRemovePkgDialog.sample.file=sample file: 
-NewPIWizardRemovePkgDialog.shell.title=Remove PKG Files From Import
-
-UiFileFilter.object.file.extensions=Object file (.axf;.elf)
-UiFileFilter.source.file.extensions=Source file (.c;,cpp;.h)
-UiFileFilter.executable.file.extensions=Symbian executable (.exe;.dll;,.pdd)
-UiFileFilter.symbol.file.extensions=Symbian OS symbol files (.symbol)
-UiFileFilter.build.file.extensions=Build file (.oby)
-UiFileFilter.pi.analysis.file.extensions=Saved profiler analysis file (.bap)
-UiFileFilter.raw.pi.measurement.file.extensions=Raw profiler measurement file (.dat)
-UiFileFilter.comma.separated.text.file.extensions=Comma separated text file (.csv)
-UiFileFilter.file.extensions=Text file (.txt)
-UiFileFilter.no.description.error1=No description for the file type (.
-UiFileFilter.no.description.error2=)
-NewPIWizardPageConfigSelectorTask.title=Available Information
-NewPIWizardPageCustomTask.example.group=Example:
 NewPIWizardPageRomSubTask.rofs.pairs=ROFS OBY/Symbol File Pairs
 NewPIWizardPageRomSubTask.symbol.button=ROM Symbol File...
 NewPIWizardPageRomSubTask.symbol.filter=*.symbol
-NewPIWizardPageRomSubTask.add.rofs.pair=Add ROFS OBY/symbol file pair
-NewPIWizardObySymbolPairDialog.oby.file=OBY file 
-NewPIWizardPageConfigSelectorTask.description=Select an import method based on the information available.
-NewPIWizardPageConfigSelectorTask.option.group=Available information:
-NewPIWizardPageConfigSelectorTask.labelAppTitle=1. Project importer
-NewPIWizardPageConfigSelectorTask.labelApp2=Carbide project or package (.pkg) files of profiled application.
-NewPIWizardPageConfigSelectorTask.labelRomAppTitle=2. Project and ROM importer
-NewPIWizardPageConfigSelectorTask.labelRomApp2=Carbide project or package (.pkg) files of profiled application
-NewPIWizardPageConfigSelectorTask.labelRomApp3=+ ROM image symbol file of profiled phone.
-NewPIWizardPageRomSubTask.entry.already.exisits=Entry already exists
-NewPIWizardPageConfigSelectorTask.labelRomTitle=3. ROM importer
-NewPIWizardPageConfigSelectorTask.labelRom2=ROM image symbol file of profiled phone.
-NewPIWizardPageConfigSelectorTask.labelNoneTitle=4. Unknown importer
-NewPIWizardPageConfigSelectorTask.labelNone2=Have neither Carbide project or a ROM image.
-NewPIWizardPageConfigSelectorTask.labelNone3=NOTE: CPU load by function is unavailable, and by binary is incomplete.
-NewPIWizardPageCustomTask.seperator.group=Seperator:
-NewPIWizardPageRomSubTask.oby.filter.text=Build file (.oby)
-NewPIWizardPageCustomTask.button.semicolon=; Semicolon
-NewPIWizardPageConfigSelectorTask.labelCustomTrace=Have additional custom trace.
-NewPIWizardObySymbolPairDialog.rofs.oby.rofs.symbol=ROFS OBY/ROFS Symbol
-NewPIWizardObySymbolPairDialog.build.file.extension=Build file (.oby)
-NewPIWizardObySymbolPairDialog.symbol.extension.error=Symbol file must have .symbol extension.
-NewPIWizardPageOutputTask.choose.output.project=Choose Output Project.
-NewPIWizardObySymbolPairDialog.rofs.symbol.file=ROFS symbol file
-NewPIWizardPageOutputTask.create.empty.project=Create Empty Project...
-
-NewPIWizardPagePkgListTask.pkg.filter.name=PKG Files (*.pkg)
-NewPIWizardPagePkgListTask.all.filter.name=All Files (*.*)
-NewPIWizardPagePkgListTask.pkg.button=Add PKG File...
-NewPIWizardPageCustomTask.super.label=Select Custom Sample Data File
-NewPIWizardPageCustomTask.description=Custom data file (*.dat)
-NewPIWizardPageCustomTask.base.group=File type:
-NewPIWizardPageRomSubTask.oby.button=ROM OBY File...
-NewPIWizardPageRomSubTask.oby.filter=*.oby
-NewPIWizardPageCustomTask.button.name=Name based
-NewPIWizardPageRomSubTask.description=Select the build files corresponding to the ROM on the device.
-NewPIWizardPageRomSubTask.name.filter=All Files (*.*)
-NewPIWizardObySymbolPairDialog.browse=Browse...
-NewPIWizardPageOutputTask.output.file.name=Output File Name:
-NewPIWizardPagePkgListTask.title=Associated Project and Package(.pkg) File
-NewPIWizardPagePkgListTask.description=Add project configurations or package (.pkg) files that built installation files (.sis) used in Carbide.c++ Profiler session.\nOnly configurations that have been built may be selected.
-NewPIWizardPageCustomTask.detail.label=Select a custom sample data file (*.dat) produced by the on-device Carbide.c++ Profiler.
-NewPIWizardPageCustomTask.format.group=Custom trace data format
-NewPIWizardPageCustomTask.button.value=Value based
-NewPIWizardPageCustomTask.button.comma=, Comma
-NewPIWizardPageCustomTask.button.space=Space character
-NewPIWizardPageRomSubTask.symbol.label=ROM Symbol File:
-NewPIWizardPagePkgListTask.remove.button=Remove PKG Files...
-NewPIWizardPagePkgSdkDialog.shell.title=SDK Associated With This PKG File
-NewPIWizardPageRomSdkSubTask.description=Select the SDK or EPOCROOT of the SDK, if any, that was used to build the ROM of the phone profiled.
+NewPIWizardPageRomSubTask.symbol.filter.text=Symbol File(*.symbol)
+NewPIWizardPageRomSubTask.symbol.label=ROM Symbol File\:
+NewPIWizardPageRomSubTask.title=Select build files for ROM
+NewPIWizardPageSampleFile.all.filter.name=All Files (*.*)
+NewPIWizardPageSampleFile.browse=Profiler Sample File...
+NewPIWizardPageSampleFile.dat.file.extension.must.be.dat=Carbide.c++ Profiler data file extension must be "dat".
+NewPIWizardPageSampleFile.dat.file.name=&Profiler Sample File\:
+NewPIWizardPageSampleFile.dat.file.name.does.not.exist=Carbide.c++ Profiler data file specified does not exist.
+NewPIWizardPageSampleFile.dat.must.be.a.file=Please enter a Carbide.c++ Profiler data file.
+NewPIWizardPageSampleFile.description=Select the Carbide Profiler data file (.dat) for conversion to a Performance Investigator file (.npi).
+NewPIWizardPageSampleFile.sample.filter.name=Profiler Sample Files (*.dat)
+NewPIWizardPageSampleFile.title=Select Profiler Data File(s)
 NewPIWizardRemovePkgDialog.check.pkg.label=Please check PKG file you want to remove from the list.
-NewPIWizardObySymbolPairDialog.symbol.file=Symbol file (.symbol)
-NewPIWizardObySymbolPairDialog.shell.title=Add ROFS OBY/ROFS Symbol File
-NewPIWizardObySymbolPairDialog.symbol.file.2=Symbol file 
-NewPIWizardPageOutputTask.select.folder.or.create.new.project.as.output.file.container=Select the folder or create a new project to store the output file container.
-
-NewPIWizardCustomTask.dat.file.name.must.be.specified=File name must be specified.
+NewPIWizardRemovePkgDialog.sample.file=sample file\: 
+NewPIWizardRemovePkgDialog.sdk=\ / SDK\: 
+NewPIWizardRemovePkgDialog.shell.title=Remove PKG Files From Import
+TraceSelectionGroup.actionCheckAll=Check All
+TraceSelectionGroup.actionUncheckAll=Uncheck All
+TraceSelectionGroup.groupTitle=PI views included in analysis
+TraceSelectionGroup.groupTitleFor=PI views included in analysis for {0}
+TraceSelectionGroup.mandatory=\ (mandatory view)
+TraceSelectionGroup.piView=PI View
+UiFileFilter.build.file.extensions=Build file (.oby)
+UiFileFilter.comma.separated.text.file.extensions=Comma separated text file (.csv)
+UiFileFilter.executable.file.extensions=Symbian executable (.exe;.dll;,.pdd)
+UiFileFilter.file.extensions=Text file (.txt)
+UiFileFilter.no.description.error1=No description for the file type (.
+UiFileFilter.no.description.error2=)
+UiFileFilter.object.file.extensions=Object file (.axf;.elf)
+UiFileFilter.pi.analysis.file.extensions=Saved profiler analysis file (.bap)
+UiFileFilter.raw.pi.measurement.file.extensions=Raw profiler measurement file (.dat)
+UiFileFilter.source.file.extensions=Source file (.c;,cpp;.h)
+UiFileFilter.symbol.file.extensions=Symbian OS symbol files (.symbol)
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.wizards/src/com/nokia/carbide/cpp/internal/pi/wizards/ui/util/PkgListTreeContentProvider.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.wizards/src/com/nokia/carbide/cpp/internal/pi/wizards/ui/util/PkgListTreeContentProvider.java	Wed Apr 21 15:14:16 2010 +0300
@@ -17,6 +17,7 @@
 
 package com.nokia.carbide.cpp.internal.pi.wizards.ui.util;
 
+import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -34,6 +35,7 @@
 import com.nokia.carbide.cdt.builder.CarbideBuilderPlugin;
 import com.nokia.carbide.cdt.builder.project.ICarbideBuildConfiguration;
 import com.nokia.carbide.cdt.builder.project.ICarbideProjectInfo;
+import com.nokia.carbide.cpp.pi.util.GeneralMessages;
 
 public class PkgListTreeContentProvider implements ITreeContentProvider {
 	PkgListTree tree;
@@ -50,9 +52,9 @@
 		if (parentElement instanceof IPkgEntry) {
 			return null;
 		} else if (parentElement instanceof IViewSite) {
-			return getCarbideCppProjects();
+			return getCarbideCppProjects(false);
 		} else if (parentElement instanceof IWorkspaceRoot) {
-			return getCarbideCppProjects();
+			return getCarbideCppProjects(false);
 		} else if (parentElement instanceof IProject) {
 			return getConfigs((IProject)parentElement).toArray();
 		} else if (parentElement instanceof PkgListTree) {
@@ -95,7 +97,7 @@
 		cp.inputChanged(viewer, oldInput, newInput);
 	}
 
-	private Object[] getCarbideCppProjects() {
+	public Object[] getCarbideCppProjects(boolean logWarnings) {
 		// lifted from com.nokia.carbide.cpp.project.ui.views.SPNViewContentProvider
 		IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
 		List<IProject> list = new ArrayList<IProject>();
@@ -115,8 +117,12 @@
 								break;
 							}
 						}
-						if (haveConfigWithPKG == false)
+						if (haveConfigWithPKG == false){
+							if(logWarnings){						
+								GeneralMessages.PiLog(MessageFormat.format(Messages.getString("PkgListTreeContentProvider.warning.sisBuilderConfiguration.missing"),projects[i].getName()), GeneralMessages.WARNING); //$NON-NLS-1$
+							}
 							continue;	// must have buildconfig with good PKG to show up
+						}							
 						list.add(projects[i]);
 					}
 				}
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.wizards/src/com/nokia/carbide/cpp/internal/pi/wizards/ui/util/SdkChooserBase.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.wizards/src/com/nokia/carbide/cpp/internal/pi/wizards/ui/util/SdkChooserBase.java	Wed Apr 21 15:14:16 2010 +0300
@@ -194,7 +194,27 @@
 			if (sdk != null) {
 				directoryDataLabel.setText(sdk.getEPOCROOT());
 				osVersionDataLabel.setText(sdk.getOSVersion().toString());
-				platformDataLabel.setText(sdk.getAvailablePlatforms().toString());
+				
+				// separate too long lines 
+				String platforms = ""; //$NON-NLS-1$
+				final int maxLineLength = 80;
+				int count = 1;
+				for(String platform : sdk.getAvailablePlatforms()){						
+					platforms += platform;
+					platforms += ", ";			 //$NON-NLS-1$
+					if((platforms.length() / maxLineLength) == count){
+						platforms += "\n";					 //$NON-NLS-1$
+						count++;
+					}
+				}
+				int index = platforms.lastIndexOf(",");  //$NON-NLS-1$
+				if(index != -1){
+					platforms = platforms.substring(0, index);	
+				}			
+				else{
+					platforms = "-";
+				}
+				platformDataLabel.setText(platforms);
 			}
 		} else {
 			directoryDataLabel.setText(Messages.getString("SdkChooserBase.directorydata.label")); //$NON-NLS-1$
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.wizards/src/com/nokia/carbide/cpp/internal/pi/wizards/ui/util/messages.properties	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.wizards/src/com/nokia/carbide/cpp/internal/pi/wizards/ui/util/messages.properties	Wed Apr 21 15:14:16 2010 +0300
@@ -1,3 +1,4 @@
+PkgListTreeContentProvider.warning.sisBuilderConfiguration.missing=Project {0} does not have a SIS builder configuration. Please define the SIS builder configuration for the project.
 PkgListTreeLabelProvider.sample.file=sample file: 
 PkgListTreeViewer.invalid.content.provider=Invalid content provider in importer
 PkgListTreeLabelProvider.sdk=\ / SDK: 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/BackupOfccbuild.xml	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,1197 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="com.nokia.carbide.cpp.pi" default="cc" basedir=".">
+
+	
+	<!-- Build PI only: -->
+	<!--<target name="cc" depends="build, analyze, feature, zip" description="Build, instrument and analyze code"/>-->
+	
+	<!-- Build PI and tests and run tests: -->
+	<!--<target name="cc" depends="clean, build, analyze, feature, pde_test, generate_report, check_results,zip" description="Build, instrument, run unit tests and analyze code"/>-->
+
+	<!-- Build and run tests: -->
+	<target name="cc" depends="pde_test, generate_report, check_results,zip" description="Build and run unit tests"/>
+
+	
+
+	<property name="basews" value="${ws}"/>
+	<property name="baseos" value="${os}"/>
+	<property name="basearch" value="${arch}"/>
+	<property name="basenl" value="${nl}"/>
+
+	<!-- Compiler settings -->
+	<property name="javacFailOnError" value="true"/>
+	<property name="javacDebugInfo" value="on"/>
+	<property name="javacVerbose" value="false"/>
+	<property name="logExtension" value=".log"/>
+	<property name="compilerArg" value=""/>
+	<property name="javacSource" value="5"/>
+	<property name="javacTarget" value="5"/>
+	
+	<property name="bootclasspath" refid="path_bootclasspath"/>
+	<property name="bundleJavacSource" value="${javacSource}"/>
+	<property name="bundleJavacTarget" value="${javacTarget}"/>
+	<property name="bundleBootClasspath" value="${bootclasspath}"/>
+	
+	<property name="help.project.name" value="${ant.project.name}.help"/>
+	<property name="core.project.name" value="${ant.project.name}.corecomponents"/>
+	<property name="trace.project.name" value="${ant.project.name}.trace"/>
+	<property name="internal.project.name" value="${ant.project.name}.internal"/>
+	<property name="feature.project.folder" location="../com.nokia.carbide.cpp.pi-feature"/>
+	<property name="feature.project.name" value="com.nokia.carbide.cpp.pi-feature"/>
+	<property name="feature.name" value="PIAnalyser"/>
+	<property name="test.plugin.name" 					 value="com.nokia.carbide.cpp.pi.tests"/>
+  	<property name="feature.project.name" 		 	 value="com.nokia.carbide.cpp.pi-feature"/>
+	<property name="jar.filename" value="${ant.project.name}.jar"/>
+	
+	<!-- Folder definitions -->
+	<property name="carbide.sym.folder" location="g:/Sym_240/plugins"/>
+	<property name="carbide.idl.folder" location="g:/IDL/plugins"/>
+	<property name="carbide.adt.folder" location="g:/ADT/plugins"/>
+	<property name="test.eclipse.folder" location="C:/eclipse"/>
+	<property name="binaries.folder" location="${basedir}/../${feature.name}.binaries"/>
+	<property name="reports.folder" location="../reports"/>
+	<property name="reports.emma" location="${reports.folder}/emma"/>
+	<property name="instr.folder" location="instr"/>
+	
+	<!-- PI Analyser plug-ins -->
+	<property name="address.folder" location="../${ant.project.name}.address"/>
+	<property name="address.name" value="${ant.project.name}.address"/>
+	<property name="button.folder" location="../${ant.project.name}.button"/>
+	<property name="button.name" value="${ant.project.name}.button"/>
+	<property name="call.folder" location="../${ant.project.name}.call"/>
+	<property name="call.name" value="${ant.project.name}.call"/>
+	<property name="core.folder" location="../${ant.project.name}.core"/>
+	<property name="core.name" value="${ant.project.name}.core"/>
+	<property name="func.folder" location="../${ant.project.name}.function"/>
+	<property name="func.name" value="${ant.project.name}.function"/>
+	<property name="inst.folder" location="../${ant.project.name}.instr"/>
+	<property name="inst.name" value="${ant.project.name}.instr"/>
+	<property name="memory.folder" location="../${ant.project.name}.memory"/>
+	<property name="memory.name" value="${ant.project.name}.memory"/>
+	<property name="power.folder" location="../${ant.project.name}.power"/>
+	<property name="power.name" value="${ant.project.name}.power"/>
+	<property name="priority.folder" location="../${ant.project.name}.priority"/>
+	<property name="priority.name" value="${ant.project.name}.priority"/>
+	<property name="priority2.folder" location="../${ant.project.name}.priority2"/>
+	<property name="priority2.name" value="${ant.project.name}.priority2"/>
+	<property name="ui.folder" location="../${ant.project.name}.ui"/>
+	<property name="ui.name" value="${ant.project.name}.ui"/>
+	<property name="util.folder" location="../${ant.project.name}.util"/>
+	<property name="util.name" value="${ant.project.name}.util"/>
+	<property name="wizards.folder" location="../${ant.project.name}.wizards"/>
+	<property name="wizards.name" value="${ant.project.name}.wizards"/>
+	
+	<property name="perfcounters.folder" location="../${ant.project.name}.perfcounters"/>
+	<property name="perfcounters.name" value="${ant.project.name}.perfcounters"/>
+	<property name="peccommon.folder" location="../${ant.project.name}.peccommon"/>
+	<property name="peccommon.name" value="${ant.project.name}.peccommon"/>
+	<property name="ipc.folder" location="../${ant.project.name}.ipc"/>
+	<property name="ipc.name" value="${ant.project.name}.ipc"/>
+	<property name="irq.folder" location="../${ant.project.name}.irq"/>
+	<property name="irq.name" value="${ant.project.name}.irq"/>
+	
+	<!-- TEST plug-ins -->
+	<property name="address.tests" location="../tests/com.nokia.carbide.cpp.pi.address.tests"/>
+	<property name="classes.address.tests.folder" location="${address.tests}/classes"/>
+
+	<property name="button.tests" location="../tests/com.nokia.carbide.cpp.pi.button.tests"/>
+	<property name="classes.button.tests.folder" location="${button.tests}/classes"/>
+
+	<property name="call.tests" location="../tests/com.nokia.carbide.cpp.pi.call.tests"/>
+	<property name="classes.call.tests.folder" location="${call.tests}/classes"/>
+
+	<property name="core.tests" location="../tests/com.nokia.carbide.cpp.pi.core.tests"/>
+	<property name="classes.core.tests.folder" location="${core.tests}/classes"/>
+
+	<property name="instr.tests" location="../tests/com.nokia.carbide.cpp.pi.instr.tests"/>
+	<property name="classes.instr.tests.folder" location="${instr.tests}/classes"/>
+
+	<property name="util.tests" location="../tests/com.nokia.carbide.cpp.pi.util.tests"/>
+	<property name="classes.util.tests.folder" location="${util.tests}/classes"/>
+
+	<property name="memory.tests" location="../tests/com.nokia.carbide.cpp.pi.memory.tests"/>
+	<property name="classes.memory.tests.folder" location="${memory.tests}/classes"/>
+	
+	<property name="pi.tests" location="../tests/com.nokia.carbide.cpp.pi.tests"/>
+	<property name="classes.pi.tests.folder"  location="${pi.tests}/classes"/>
+	
+	<property name="testsupport" location="../tests/com.nokia.carbide.cpp.pi.testsupport"/>
+	<property name="classes.testsupport.folder"  location="${testsupport}/classes"/>
+
+	<property name="wizards.tests" location="../tests/com.nokia.carbide.cpp.pi.wizards.tests"/>
+	<property name="classes.wizards.tests.folder"              location="${wizards.tests}/classes"/>
+
+	<property name="irq.tests" location="../tests/com.nokia.carbide.cpp.pi.irq.tests"/>
+	<property name="classes.irq.tests.folder"              location="${irq.tests}/classes"/>
+
+	<property name="perfcounters.tests" location="../tests/com.nokia.carbide.cpp.pi.perfcounters.tests"/>
+	<property name="classes.perfcounters.tests.folder"              location="${perfcounters.tests}/classes"/>
+
+	<property name="peccommon.tests" location="../tests/com.nokia.carbide.cpp.pi.peccommon.tests"/>
+	<property name="classes.peccommon.tests.folder"              location="${peccommon.tests}/classes"/>
+	
+	<property name="ipc.tests" location="../tests/com.nokia.carbide.cpp.pi.ipc.tests"/>
+	<property name="classes.ipc.tests.folder"              location="${ipc.tests}/classes"/>
+
+	
+	<!-- Tests build classpath -->
+	<path id="test.build.class.path">
+ 
+        <!-- Instrumented class files -->
+		   			<pathelement location="${instr.folder}"/>
+       
+       			<!--<pathelement location="${test.folder}/src"/>-->
+			
+    				<!-- Normal class files -->
+    				<pathelement path="${binaries.folder}/${jar.filename}"/>
+    		
+		   			<!-- EMMA -->
+		   			<pathelement path="${ant.home}/lib/emma.jar"/>
+		   	
+        <fileset dir="${carbide.idl.folder}" includes="**/*.jar">
+        
+        </fileset>
+  </path>
+		
+	<!--  pde.test.listener.class.path -->
+	<path id="pde.test.listener.class.path">
+        <!--<path refid="build.pde.class.path"/>-->
+        <pathelement location="${binaries.folder}/pde.test.utils.jar"/>
+        <fileset dir="${test.eclipse.folder}/plugins" includes="**/*.jar"/>
+  </path>
+		
+	<!--  pde.test.port.locator.classpath -->
+	<path id="pde.test.port.locator.class.path">
+        <pathelement location="${binaries.folder}/pde.test.utils.jar"/>
+        <fileset dir="${carbide.idl.folder}">
+            <include name="org.junit_4.*/**/junit.jar"/>
+        </fileset>
+  </path>
+  
+  <!--  Carbide launcher classpath -->
+  <path id="equinox.launcher.class.path">			
+			 
+			 <fileset dir="${carbide.idl.folder}">
+            <include name="org.eclipse.equinox.launcher_*.jar"/>
+            <include name="instr.${jar.filename}"/>
+       </fileset>			 
+
+       			<!-- Instrumented class files -->
+		   <pathelement location="${instr.folder}"/>
+       
+       			<!--<pathelement location="${test.folder}/src"/>-->
+			
+    				<!-- Normal class files -->
+    				<!--<pathelement path="${binaries.folder}/${jar.filename}"/>-->
+    		
+		   	<!-- EMMA -->
+		   	<pathelement path="${ant.home}/lib/emma.jar"/>
+		   	
+		   			<!--<path refid="build_classpath" />-->
+        
+  </path>
+  
+  <path id="test_classpath">
+			<!-- Test classes -->
+			<pathelement location="${wizards.test}/src"/>
+			
+			<!-- Instrumented class files -->
+		   	<pathelement location="${instr.folder}"/>
+		   	
+    		<!-- Normal class files -->
+    		<pathelement path="${binaries.folder}/*.jar"/>
+
+		   	<!-- EMMA -->
+		   	<pathelement path="${ant.home}/lib/emma.jar"/>
+		   	
+		   	<path refid="test.build.class.path" />
+		</path>
+	
+	
+	<!-- EMMA configuration -->
+ 	<path id="emma.lib" >
+    	<pathelement location="${ant.home}/lib/emma.jar" />
+    	<pathelement location="${ant.home}/lib/emma_ant.jar" />
+  	</path>
+
+  	<taskdef resource="emma_ant.properties" classpathref="emma.lib" />
+	
+	<!-- PMD configuration -->
+	<path id="pmd.lib" >
+    	<pathelement location="${ant.home}/lib/pmd-4.2.5.jar" />
+    	<pathelement location="${ant.home}/lib/asm-3.1.jar" />
+    	<pathelement location="${ant.home}/lib/jaxen-1.1.1.jar" />
+  	</path>
+	
+	<taskdef name="pmd" classname="net.sourceforge.pmd.ant.PMDTask" classpathref="pmd.lib" />
+	
+	<path id="path_bootclasspath">
+		<fileset dir="${java.home}/lib">
+			<include name="*.jar"/>
+		</fileset>
+	</path>
+	
+	<path id="build_classpath">
+		<fileset dir="../plugins" includes="**/*.jar" />
+		<fileset dir="${carbide.idl.folder}" includes="**/*.jar" />
+	</path>
+
+	<path id="test_carbide_classpath">
+		<fileset dir="${carbide.adt.folder}" includes="**/*.jar" />
+	</path>
+	
+	<target name="properties" if="eclipse.running">
+		<property name="build.compiler" value="org.eclipse.jdt.core.JDTCompilerAdapter"/>
+	</target>
+
+	<!-- Clean target -->
+		<target name="clean" description="Clean" depends="clean-test">
+			<delete dir="${ant.project.name}/com"/>
+			<delete dir="${basedir}/com"/>
+			<delete dir="${address.folder}/com"/>
+			<delete dir="${button.folder}/com"/>
+			<delete dir="${call.folder}/com"/>
+			<delete dir="${core.folder}/com"/>
+			<delete dir="${inst.folder}/com"/>
+			<delete dir="${func.folder}/com"/>
+			<delete dir="${memory.folder}/com"/>
+			<delete dir="${power.folder}/com"/>
+			<delete dir="${priority.folder}/com"/>
+			<delete dir="${priority2.folder}/com"/>
+			<delete dir="${ui.folder}/com"/>
+			<delete dir="${util.folder}/com"/>
+			<delete dir="${wizards.folder}/com"/>
+			<delete dir="${irq.folder}/com"/>
+			<delete dir="${perfcounters.folder}/com"/>
+			<delete dir="${peccommon.folder}/com"/>
+			<delete dir="${ipc.folder}/com"/>
+			<delete dir="features"/>
+			
+			<!-- Execute clean -->
+			<exec dir="" executable="perl" resolveexecutable="true" failonerror="false" spawn="true"> 
+					<arg value="C:\\hudson\\jobs\\HudsonScripts\\deep_clean.pl"/>
+					<arg value="${carbide.idl.folder}"/>
+					<arg value="${ant.project.name}"/>
+			</exec>
+			
+		</target>
+	
+	
+	<!-- Initialization -->
+	<target name="init" depends="properties">
+		<condition property="pluginTemp" value="${buildTempFolder}/plugins">
+			<isset property="buildTempFolder"/>
+		</condition>
+		<property name="pluginTemp" value="${basedir}"/>
+		<condition property="build.result.folder" value="${pluginTemp}/${ant.project.name}">
+			<isset property="buildTempFolder"/>
+		</condition>
+		<property name="build.result.folder" value="${basedir}"/>
+		<property name="temp.folder" value="${basedir}/temp.folder"/>
+		<property name="plugin.destination" value="${basedir}"/>
+
+		<property name="jar.filename" value="${ant.project.name}.jar"/>
+		
+		<delete dir="../plugins"/>
+		<mkdir dir="../plugins"/>
+		
+		<delete dir="${reports.folder}"/>
+		<mkdir dir="${reports.folder}"/>
+		
+		
+		
+		
+		<exec executable="svn" dir="../.">
+			<arg line="up"/>
+		</exec>
+	</target>
+
+	<!-- Build target -->
+	<target name="build" depends="init" description="Build the source">
+	
+		<!-- Build the source -->
+		<javac destdir="${core.folder}" failonerror="${javacFailOnError}" verbose="${javacVerbose}" debug="${javacDebugInfo}" includeAntRuntime="no" bootclasspath="${bundleBootClasspath}" source="${bundleJavacSource}" target="${bundleJavacTarget}">
+			<compilerarg line="${compilerArg}" compiler="${build.compiler}"/>
+			<classpath refid="build_classpath" />
+			<src path="${core.folder}/src/" />
+			<compilerarg value="@${basedir}/javaCompiler...args" compiler="org.eclipse.jdt.core.JDTCompilerAdapter"/>
+			<compilerarg line="-log '${temp.folder}/bin${logExtension}'" compiler="org.eclipse.jdt.core.JDTCompilerAdapter"/>
+			<compilerarg line="-Xlint:unchecked"/>
+			<compilerarg line="-Xlint:deprecation"/>
+		</javac>
+		
+		<copy todir="${core.folder}" failonerror="true" overwrite="false">
+			<fileset dir="${core.folder}/src/" excludes="**/*.java, **/package.htm*" />
+		</copy>
+		
+		<zip destfile="../plugins/${core.name}.jar">
+				<fileset dir="${core.folder}">
+						  <include name="META-INF/**"/>  
+					    <include name="com/**"/>
+					    <include name="plugin.xml"/>
+				</fileset>
+		</zip>
+		
+			<!-- Build the source -->
+		<javac destdir="${util.folder}" failonerror="${javacFailOnError}" verbose="${javacVerbose}" debug="${javacDebugInfo}" includeAntRuntime="no" bootclasspath="${bundleBootClasspath}" source="${bundleJavacSource}" target="${bundleJavacTarget}">
+			<compilerarg line="${compilerArg}" compiler="${build.compiler}"/>
+			<classpath refid="build_classpath" />
+			<src path="${util.folder}/src/" />
+			<compilerarg value="@${basedir}/javaCompiler...args" compiler="org.eclipse.jdt.core.JDTCompilerAdapter"/>
+			<compilerarg line="-log '${temp.folder}/bin${logExtension}'" compiler="org.eclipse.jdt.core.JDTCompilerAdapter"/>
+			<compilerarg line="-Xlint:unchecked"/>
+		</javac>
+		
+		<copy todir="${util.folder}" failonerror="true" overwrite="false">
+			<fileset dir="${util.folder}/src/" excludes="**/*.java, **/package.htm*" />
+		</copy>
+		
+		<zip destfile="../plugins/${util.name}.jar">
+				<fileset dir="${util.folder}">
+						  <include name="META-INF/**"/>  
+					    <include name="com/**"/>
+					    <include name="plugin.xml"/>
+				</fileset>
+		</zip>
+		
+			<!-- Build the source -->
+		<javac destdir="" failonerror="${javacFailOnError}" verbose="${javacVerbose}" debug="${javacDebugInfo}" includeAntRuntime="no" bootclasspath="${bundleBootClasspath}" source="${bundleJavacSource}" target="${bundleJavacTarget}">
+			<compilerarg line="${compilerArg}" compiler="${build.compiler}"/>
+			<classpath refid="build_classpath" />
+			<src path="src/" />
+			<compilerarg value="@${basedir}/javaCompiler...args" compiler="org.eclipse.jdt.core.JDTCompilerAdapter"/>
+			<compilerarg line="-log '${temp.folder}/bin${logExtension}'" compiler="org.eclipse.jdt.core.JDTCompilerAdapter"/>
+			<compilerarg line="-Xlint:unchecked"/>
+		</javac>
+
+		<!-- Copy necessary resources -->
+		<copy todir="" failonerror="true" overwrite="false">
+			<fileset dir="src/" excludes="**/*.java, **/package.htm*" />
+		</copy>
+		
+		<zip destfile="../plugins/${jar.filename}">
+				<fileset dir="${build.result.folder}">
+						  <include name="META-INF/**"/>  
+					    <include name="com/**"/>
+					    <include name="plugin.xml"/>
+				</fileset>
+		</zip>
+		
+
+		<!-- Build the source -->
+		<javac destdir="${address.folder}" failonerror="${javacFailOnError}" verbose="${javacVerbose}" debug="${javacDebugInfo}" includeAntRuntime="no" bootclasspath="${bundleBootClasspath}" source="${bundleJavacSource}" target="${bundleJavacTarget}">
+			<compilerarg line="${compilerArg}" compiler="${build.compiler}"/>
+			<classpath refid="build_classpath" />
+			<src path="${address.folder}/src" />
+			<compilerarg value="@${basedir}/javaCompiler...args" compiler="org.eclipse.jdt.core.JDTCompilerAdapter"/>
+			<compilerarg line="-log '${temp.folder}/bin${logExtension}'" compiler="org.eclipse.jdt.core.JDTCompilerAdapter"/>
+			<compilerarg line="-Xlint:unchecked"/>
+		</javac>
+		
+		<copy todir="${address.folder}" failonerror="true" overwrite="false">
+			<fileset dir="${address.folder}/src/" excludes="**/*.java, **/package.htm*" />
+		</copy>
+		
+		<zip destfile="../plugins/${address.name}.jar" >
+				<fileset dir="${address.folder}">
+						  <include name="META-INF/**"/>  
+					    <include name="icons/**"/>
+					    <include name="com/**"/>
+					    <include name="plugin.xml"/>
+				</fileset>
+		</zip>
+		
+		
+		
+		<!-- Build the source -->
+		<javac destdir="${button.folder}" failonerror="${javacFailOnError}" verbose="${javacVerbose}" debug="${javacDebugInfo}" includeAntRuntime="no" bootclasspath="${bundleBootClasspath}" source="${bundleJavacSource}" target="${bundleJavacTarget}">
+			<compilerarg line="${compilerArg}" compiler="${build.compiler}"/>
+			<classpath refid="build_classpath" />
+			<src path="${button.folder}/src/" />
+			<compilerarg value="@${basedir}/javaCompiler...args" compiler="org.eclipse.jdt.core.JDTCompilerAdapter"/>
+			<compilerarg line="-log '${temp.folder}/bin${logExtension}'" compiler="org.eclipse.jdt.core.JDTCompilerAdapter"/>
+			<compilerarg line="-Xlint:unchecked"/>
+		</javac>
+		
+		<copy todir="${button.folder}" failonerror="true" overwrite="false">
+			<fileset dir="${button.folder}/src/" excludes="**/*.java, **/package.htm*" />
+		</copy>
+		
+		<zip destfile="../plugins/${button.name}.jar">
+				<fileset dir="${button.folder}">
+						  <include name="META-INF/**"/>  
+					    <include name="icons/**"/>
+					    <include name="com/**"/>
+					    <include name="data/**"/>
+					    <include name="plugin.xml"/>
+				</fileset>
+		</zip>
+		
+		
+		<!-- Build the source -->
+		<javac destdir="${call.folder}" failonerror="${javacFailOnError}" verbose="${javacVerbose}" debug="${javacDebugInfo}" includeAntRuntime="no" bootclasspath="${bundleBootClasspath}" source="${bundleJavacSource}" target="${bundleJavacTarget}">
+			<compilerarg line="${compilerArg}" compiler="${build.compiler}"/>
+			<classpath refid="build_classpath" />
+			<src path="${call.folder}/src/" />
+			<compilerarg value="@${basedir}/javaCompiler...args" compiler="org.eclipse.jdt.core.JDTCompilerAdapter"/>
+			<compilerarg line="-log '${temp.folder}/bin${logExtension}'" compiler="org.eclipse.jdt.core.JDTCompilerAdapter"/>
+			<compilerarg line="-Xlint:unchecked"/>
+		</javac>
+		
+		<copy todir="${call.folder}" failonerror="true" overwrite="false">
+			<fileset dir="${call.folder}/src/" excludes="**/*.java, **/package.htm*" />
+		</copy>
+		
+		<zip destfile="../plugins/${call.name}.jar">
+				<fileset dir="${call.folder}">
+						  <include name="META-INF/**"/>  
+					    <include name="com/**"/>
+					    <include name="plugin.xml"/>
+				</fileset>
+		</zip>
+		
+		
+		<!-- Build the source -->
+		<javac destdir="${func.folder}" failonerror="${javacFailOnError}" verbose="${javacVerbose}" debug="${javacDebugInfo}" includeAntRuntime="no" bootclasspath="${bundleBootClasspath}" source="${bundleJavacSource}" target="${bundleJavacTarget}">
+			<compilerarg line="${compilerArg}" compiler="${build.compiler}"/>
+			<classpath refid="build_classpath" />
+			<src path="${func.folder}/src/" />
+			<compilerarg value="@${basedir}/javaCompiler...args" compiler="org.eclipse.jdt.core.JDTCompilerAdapter"/>
+			<compilerarg line="-log '${temp.folder}/bin${logExtension}'" compiler="org.eclipse.jdt.core.JDTCompilerAdapter"/>
+			<compilerarg line="-Xlint:unchecked"/>
+		</javac>
+		
+		<copy todir="${func.folder}" failonerror="true" overwrite="false">
+			<fileset dir="${func.folder}/src/" excludes="**/*.java, **/package.htm*" />
+		</copy>
+		
+		<zip destfile="../plugins/${func.name}.jar">
+				<fileset dir="${func.folder}">
+						  <include name="META-INF/**"/>  
+					    <include name="com/**"/>
+					    <include name="plugin.xml"/>
+				</fileset>
+		</zip>
+		
+		<!-- Build the source -->
+		<javac destdir="${inst.folder}" failonerror="${javacFailOnError}" verbose="${javacVerbose}" debug="${javacDebugInfo}" includeAntRuntime="no" bootclasspath="${bundleBootClasspath}" source="${bundleJavacSource}" target="${bundleJavacTarget}">
+			<compilerarg line="${compilerArg}" compiler="${build.compiler}"/>
+			<classpath refid="build_classpath" />
+			<src path="${inst.folder}/src/" />
+			<compilerarg value="@${basedir}/javaCompiler...args" compiler="org.eclipse.jdt.core.JDTCompilerAdapter"/>
+			<compilerarg line="-log '${temp.folder}/bin${logExtension}'" compiler="org.eclipse.jdt.core.JDTCompilerAdapter"/>
+			<compilerarg line="-Xlint:unchecked"/>
+		</javac>
+
+		<copy todir="${inst.folder}" failonerror="true" overwrite="false">
+			<fileset dir="${inst.folder}/src/" excludes="**/*.java, **/package.htm*" />
+		</copy>
+		
+		<zip destfile="../plugins/${inst.name}.jar">
+				<fileset dir="${inst.folder}">
+						  <include name="META-INF/**"/>  
+					    <include name="com/**"/>
+					    <include name="plugin.xml"/>
+				</fileset>
+		</zip>
+		
+		
+		<!-- Build the source -->
+		<javac destdir="${power.folder}" failonerror="${javacFailOnError}" verbose="${javacVerbose}" debug="${javacDebugInfo}" includeAntRuntime="no" bootclasspath="${bundleBootClasspath}" source="${bundleJavacSource}" target="${bundleJavacTarget}">
+			<compilerarg line="${compilerArg}" compiler="${build.compiler}"/>
+			<classpath refid="build_classpath" />
+			<src path="${power.folder}/src/" />
+			<compilerarg value="@${basedir}/javaCompiler...args" compiler="org.eclipse.jdt.core.JDTCompilerAdapter"/>
+			<compilerarg line="-log '${temp.folder}/bin${logExtension}'" compiler="org.eclipse.jdt.core.JDTCompilerAdapter"/>
+			<compilerarg line="-Xlint:unchecked"/>
+		</javac>
+		
+		<copy todir="${power.folder}" failonerror="true" overwrite="false">
+			<fileset dir="${power.folder}/src/" excludes="**/*.java, **/package.htm*" />
+		</copy>
+		
+		<zip destfile="../plugins/${power.name}.jar" >
+				<fileset dir="${power.folder}">
+						  <include name="META-INF/**"/>  
+					    <include name="com/**"/>
+					    <include name="plugin.xml"/>
+				</fileset>
+		</zip>
+		
+		
+		<!-- Build the source -->
+		<javac destdir="${priority.folder}" failonerror="${javacFailOnError}" verbose="${javacVerbose}" debug="${javacDebugInfo}" includeAntRuntime="no" bootclasspath="${bundleBootClasspath}" source="${bundleJavacSource}" target="${bundleJavacTarget}">
+			<compilerarg line="${compilerArg}" compiler="${build.compiler}"/>
+			<classpath refid="build_classpath" />
+			<src path="${priority.folder}/src/" />
+			<compilerarg value="@${basedir}/javaCompiler...args" compiler="org.eclipse.jdt.core.JDTCompilerAdapter"/>
+			<compilerarg line="-log '${temp.folder}/bin${logExtension}'" compiler="org.eclipse.jdt.core.JDTCompilerAdapter"/>
+			<compilerarg line="-Xlint:unchecked"/>
+		</javac>
+		
+		<copy todir="${priority.folder}" failonerror="true" overwrite="false">
+			<fileset dir="${priority.folder}/src/" excludes="**/*.java, **/package.htm*" />
+		</copy>
+		
+		<zip destfile="../plugins/${priority.name}.jar" >
+				<fileset dir="${priority.folder}">
+						  <include name="META-INF/**"/>  
+					    <include name="com/**"/>
+					    <include name="plugin.xml"/>
+				</fileset>
+		</zip>
+		
+		
+		<!-- Build the source -->
+		<javac destdir="${priority2.folder}" failonerror="${javacFailOnError}" verbose="${javacVerbose}" debug="${javacDebugInfo}" includeAntRuntime="no" bootclasspath="${bundleBootClasspath}" source="${bundleJavacSource}" target="${bundleJavacTarget}">
+			<compilerarg line="${compilerArg}" compiler="${build.compiler}"/>
+			<classpath refid="build_classpath" />
+			<src path="${priority2.folder}/src/" />
+			<compilerarg value="@${basedir}/javaCompiler...args" compiler="org.eclipse.jdt.core.JDTCompilerAdapter"/>
+			<compilerarg line="-log '${temp.folder}/bin${logExtension}'" compiler="org.eclipse.jdt.core.JDTCompilerAdapter"/>
+			<compilerarg line="-Xlint:unchecked"/>
+		</javac>
+		
+		<copy todir="${priority2.folder}" failonerror="true" overwrite="false">
+			<fileset dir="${priority2.folder}/src/" excludes="**/*.java, **/package.htm*" />
+		</copy>
+		
+		<zip destfile="../plugins/${priority2.name}.jar">
+				<fileset dir="${priority2.folder}">
+						  <include name="META-INF/**"/>  
+					    <include name="com/**"/>
+					    <include name="html/**"/>
+					    <include name="*.xml"/>
+				</fileset>
+		</zip>
+		
+		
+		<!-- Build the source -->
+		<javac destdir="${ui.folder}" failonerror="${javacFailOnError}" verbose="${javacVerbose}" debug="${javacDebugInfo}" includeAntRuntime="no" bootclasspath="${bundleBootClasspath}" source="${bundleJavacSource}" target="${bundleJavacTarget}">
+			<compilerarg line="${compilerArg}" compiler="${build.compiler}"/>
+			<classpath refid="build_classpath" />
+			<src path="${ui.folder}/src/" />
+			<compilerarg value="@${basedir}/javaCompiler...args" compiler="org.eclipse.jdt.core.JDTCompilerAdapter"/>
+			<compilerarg line="-log '${temp.folder}/bin${logExtension}'" compiler="org.eclipse.jdt.core.JDTCompilerAdapter"/>
+			<compilerarg line="-Xlint:unchecked"/>
+		</javac>
+		
+		<copy todir="${ui.folder}" failonerror="true" overwrite="false">
+			<fileset dir="${ui.folder}/src/" excludes="**/*.java, **/package.htm*" />
+		</copy>
+		
+		<zip destfile="../plugins/${ui.name}.jar" >
+				<fileset dir="${ui.folder}">
+						  <include name="META-INF/**"/>  
+					    <include name="icons/**"/>
+					    <include name="com/**"/>
+					    <include name="plugin.xml"/>
+				</fileset>
+		</zip>
+		
+		
+			<!-- Build the source -->
+		<javac destdir="${wizards.folder}" failonerror="${javacFailOnError}" verbose="${javacVerbose}" debug="${javacDebugInfo}" includeAntRuntime="no" bootclasspath="${bundleBootClasspath}" source="${bundleJavacSource}" target="${bundleJavacTarget}">
+			<compilerarg line="${compilerArg}" compiler="${build.compiler}"/>
+			<classpath refid="build_classpath" />
+			<src path="${wizards.folder}/src/" />
+			<compilerarg value="@${basedir}/javaCompiler...args" compiler="org.eclipse.jdt.core.JDTCompilerAdapter"/>
+			<compilerarg line="-log '${temp.folder}/bin${logExtension}'" compiler="org.eclipse.jdt.core.JDTCompilerAdapter"/>
+			<compilerarg line="-Xlint:unchecked"/>
+			<compilerarg line="-Xlint:deprecation"/>
+		</javac>
+		
+		<copy todir="${wizards.folder}" failonerror="true" overwrite="false">
+			<fileset dir="${wizards.folder}/src/" excludes="**/*.java, **/package.htm*" />
+		</copy>
+		
+		<zip destfile="../plugins/${wizards.name}.jar">
+				<fileset dir="${wizards.folder}">
+						  <include name="META-INF/**"/>  
+					    <include name="icons/**"/>
+					    <include name="com/**"/>
+					    <include name="plugin.xml"/>
+				</fileset>
+		</zip>
+		
+		<!-- Build the source -->
+		<javac destdir="${memory.folder}" failonerror="${javacFailOnError}" verbose="${javacVerbose}" debug="${javacDebugInfo}" includeAntRuntime="no" bootclasspath="${bundleBootClasspath}" source="${bundleJavacSource}" target="${bundleJavacTarget}">
+			<compilerarg line="${compilerArg}" compiler="${build.compiler}"/>
+			<classpath refid="build_classpath" />
+			<src path="${memory.folder}/src/" />
+			<compilerarg value="@${basedir}/javaCompiler...args" compiler="org.eclipse.jdt.core.JDTCompilerAdapter"/>
+			<compilerarg line="-log '${temp.folder}/bin${logExtension}'" compiler="org.eclipse.jdt.core.JDTCompilerAdapter"/>
+			<compilerarg line="-Xlint:unchecked"/>
+		</javac>
+		
+		<copy todir="${memory.folder}" failonerror="true" overwrite="false">
+			<fileset dir="${memory.folder}/src/" excludes="**/*.java, **/package.htm*" />
+		</copy>
+		
+		<zip destfile="../plugins/${memory.name}.jar" >
+				<fileset dir="${memory.folder}">
+						  <include name="META-INF/**"/>  
+					    <include name="com/**"/>
+					    <include name="plugin.xml"/>
+				</fileset>
+		</zip>
+		
+		<!-- Build the source -->
+		<javac destdir="${irq.folder}" failonerror="${javacFailOnError}" verbose="${javacVerbose}" debug="${javacDebugInfo}" includeAntRuntime="no" bootclasspath="${bundleBootClasspath}" source="${bundleJavacSource}" target="${bundleJavacTarget}">
+			<compilerarg line="${compilerArg}" compiler="${build.compiler}"/>
+			<classpath refid="build_classpath" />
+			<src path="${irq.folder}/src/" />
+			<compilerarg value="@${basedir}/javaCompiler...args" compiler="org.eclipse.jdt.core.JDTCompilerAdapter"/>
+			<compilerarg line="-log '${temp.folder}/bin${logExtension}'" compiler="org.eclipse.jdt.core.JDTCompilerAdapter"/>
+			<compilerarg line="-Xlint:unchecked"/>
+		</javac>
+		
+		<copy todir="${irq.folder}" failonerror="true" overwrite="false">
+			<fileset dir="${irq.folder}/src/" excludes="**/*.java, **/package.htm*" />
+		</copy>
+		
+		<zip destfile="../plugins/${irq.name}.jar" >
+				<fileset dir="${irq.folder}">
+						  <include name="META-INF/**"/>  
+					    <include name="com/**"/>
+					    <include name="plugin.xml"/>
+				</fileset>
+		</zip>		
+		
+				<!-- Build the source -->
+		<javac destdir="${peccommon.folder}" failonerror="${javacFailOnError}" verbose="${javacVerbose}" debug="${javacDebugInfo}" includeAntRuntime="no" bootclasspath="${bundleBootClasspath}" source="${bundleJavacSource}" target="${bundleJavacTarget}">
+			<compilerarg line="${compilerArg}" compiler="${build.compiler}"/>
+			<classpath refid="build_classpath" />
+			<src path="${peccommon.folder}/src/" />
+			<compilerarg value="@${basedir}/javaCompiler...args" compiler="org.eclipse.jdt.core.JDTCompilerAdapter"/>
+			<compilerarg line="-log '${temp.folder}/bin${logExtension}'" compiler="org.eclipse.jdt.core.JDTCompilerAdapter"/>
+			<compilerarg line="-Xlint:unchecked"/>
+		</javac>
+		
+		<copy todir="${peccommon.folder}" failonerror="true" overwrite="false">
+			<fileset dir="${peccommon.folder}/src/" excludes="**/*.java, **/package.htm*" />
+		</copy>
+		
+		<zip destfile="../plugins/${peccommon.name}.jar" >
+				<fileset dir="${peccommon.folder}">
+						  <include name="META-INF/**"/>  
+					    <include name="com/**"/>
+					    <include name="plugin.xml"/>
+				</fileset>
+				
+		</zip>		
+		
+				<!-- Build the source -->
+		<javac destdir="${perfcounters.folder}" failonerror="${javacFailOnError}" verbose="${javacVerbose}" debug="${javacDebugInfo}" includeAntRuntime="no" bootclasspath="${bundleBootClasspath}" source="${bundleJavacSource}" target="${bundleJavacTarget}">
+			<compilerarg line="${compilerArg}" compiler="${build.compiler}"/>
+			<classpath refid="build_classpath" />
+			<src path="${perfcounters.folder}/src/" />
+			<compilerarg value="@${basedir}/javaCompiler...args" compiler="org.eclipse.jdt.core.JDTCompilerAdapter"/>
+			<compilerarg line="-log '${temp.folder}/bin${logExtension}'" compiler="org.eclipse.jdt.core.JDTCompilerAdapter"/>
+			<compilerarg line="-Xlint:unchecked"/>
+		</javac>
+		
+		<copy todir="${perfcounters.folder}" failonerror="true" overwrite="false">
+			<fileset dir="${perfcounters.folder}/src/" excludes="**/*.java, **/package.htm*" />
+		</copy>
+		
+		<zip destfile="../plugins/${perfcounters.name}.jar" >
+				<fileset dir="${perfcounters.folder}">
+						  <include name="META-INF/**"/>  
+					    <include name="com/**"/>
+					    <include name="plugin.xml"/>
+				</fileset>
+				
+		</zip>		
+		
+				<!-- Build the source -->
+		<javac destdir="${ipc.folder}" failonerror="${javacFailOnError}" verbose="${javacVerbose}" debug="${javacDebugInfo}" includeAntRuntime="no" bootclasspath="${bundleBootClasspath}" source="${bundleJavacSource}" target="${bundleJavacTarget}">
+			<compilerarg line="${compilerArg}" compiler="${build.compiler}"/>
+			<classpath refid="build_classpath" />
+			<src path="${ipc.folder}/src/" />
+			<compilerarg value="@${basedir}/javaCompiler...args" compiler="org.eclipse.jdt.core.JDTCompilerAdapter"/>
+			<compilerarg line="-log '${temp.folder}/bin${logExtension}'" compiler="org.eclipse.jdt.core.JDTCompilerAdapter"/>
+			<compilerarg line="-Xlint:unchecked"/>
+		</javac>
+		
+		<copy todir="${ipc.folder}" failonerror="true" overwrite="false">
+			<fileset dir="${ipc.folder}/src/" excludes="**/*.java, **/package.htm*" />
+		</copy>
+		
+		<zip destfile="../plugins/${ipc.name}.jar" >
+				<fileset dir="${ipc.folder}">
+						  <include name="META-INF/**"/>  
+					    <include name="com/**"/>
+					    <include name="plugin.xml"/>
+				</fileset>
+				
+		</zip>		
+	</target>
+
+	
+	<!-- Instrumentation target, depends on JAR -->
+	<target name="instr" depends="build">
+		<!-- Instrument the source code -->
+		<emma>
+			<instr instrpath="${binaries.folder}/${jar.filename}" destdir="${instr.folder}" metadatafile="${reports.emma}/metadata.emma" merge="true"/>
+			<instr instrpath="${binaries.folder}/${jar.filename}" destdir="${instr.folder}" metadatafile="${reports.emma}/metadata.emma" merge="true"/>
+			<instr instrpath="${binaries.folder}/${jar.filename}" destdir="${instr.folder}" metadatafile="${reports.emma}/metadata.emma" merge="true"/>
+			<instr instrpath="${binaries.folder}/${jar.filename}" destdir="${instr.folder}" metadatafile="${reports.emma}/metadata.emma" merge="true"/>
+			<instr instrpath="${binaries.folder}/${jar.filename}" destdir="${instr.folder}" metadatafile="${reports.emma}/metadata.emma" merge="true"/>
+			<instr instrpath="${binaries.folder}/${jar.filename}" destdir="${instr.folder}" metadatafile="${reports.emma}/metadata.emma" merge="true"/>
+			<instr instrpath="${binaries.folder}/${jar.filename}" destdir="${instr.folder}" metadatafile="${reports.emma}/metadata.emma" merge="true"/>
+			<instr instrpath="${binaries.folder}/${jar.filename}" destdir="${instr.folder}" metadatafile="${reports.emma}/metadata.emma" merge="true"/>
+			<instr instrpath="${binaries.folder}/${jar.filename}" destdir="${instr.folder}" metadatafile="${reports.emma}/metadata.emma" merge="true"/>
+			<instr instrpath="${binaries.folder}/${jar.filename}" destdir="${instr.folder}" metadatafile="${reports.emma}/metadata.emma" merge="true"/>
+			<instr instrpath="${binaries.folder}/${jar.filename}" destdir="${instr.folder}" metadatafile="${reports.emma}/metadata.emma" merge="true"/>
+			<instr instrpath="${binaries.folder}/${jar.filename}" destdir="${instr.folder}" metadatafile="${reports.emma}/metadata.emma" merge="true"/>
+			<instr instrpath="${binaries.folder}/${jar.filename}" destdir="${instr.folder}" metadatafile="${reports.emma}/metadata.emma" merge="true"/>
+			<instr instrpath="${binaries.folder}/${jar.filename}" destdir="${instr.folder}" metadatafile="${reports.emma}/metadata.emma" merge="true"/>
+			<instr instrpath="${binaries.folder}/${jar.filename}" destdir="${instr.folder}" metadatafile="${reports.emma}/metadata.emma" merge="true"/>
+			<instr instrpath="${binaries.folder}/${jar.filename}" destdir="${instr.folder}" metadatafile="${reports.emma}/metadata.emma" merge="true"/>
+			<instr instrpath="${binaries.folder}/${jar.filename}" destdir="${instr.folder}" metadatafile="${reports.emma}/metadata.emma" merge="true"/>
+
+		</emma>
+	</target>
+
+	<!-- Feature target -->
+	<target name="feature" depends="" description="Create feature">
+		<property name="feature.folder" location="${binaries.folder}/feature"/>
+		
+		<delete dir="../features"/>
+		<mkdir dir="../features"/>
+		<mkdir dir="${binaries.folder}/nightly_builds"/>
+		<mkdir dir="${feature.folder}"/>
+		<mkdir dir="${feature.folder}/plugins"/>
+		<mkdir dir="${feature.folder}/features/${feature.project.name}"/>
+				
+		<!-- Copy feature stuff to the temp folder -->
+		<copy todir="${feature.folder}/features/${feature.project.name}" file="${feature.project.folder}/feature.xml"/>
+		<copy todir="${feature.folder}/features/${feature.project.name}" file="${feature.project.folder}/license.txt"/>
+		
+		
+		<exec dir="../" executable="bash" resolveexecutable="true" failonerror="true"> 
+				<arg value="-c"/>
+				<arg value="C:\\hudson\\jobs\\PIAnalyser\\setPluginVersion.sh ${ant.project.name}"/>
+		</exec>
+		<exec dir="../" executable="bash" resolveexecutable="true" failonerror="true"> 
+				<arg value="-c"/>
+				<arg value="C:\\hudson\\jobs\\PIAnalyser\\setPluginVersion.sh ${ant.project.name}.address"/>
+		</exec>	
+		<exec dir="../" executable="bash" resolveexecutable="true" failonerror="true"> 
+				<arg value="-c"/>
+				<arg value="C:\\hudson\\jobs\\PIAnalyser\\setPluginVersion.sh ${ant.project.name}.button"/>
+		</exec>	
+		<exec dir="../" executable="bash" resolveexecutable="true" failonerror="true"> 
+				<arg value="-c"/>
+				<arg value="C:\\hudson\\jobs\\PIAnalyser\\setPluginVersion.sh ${ant.project.name}.call"/>
+		</exec>	
+		<exec dir="../" executable="bash" resolveexecutable="true" failonerror="true"> 
+				<arg value="-c"/>
+				<arg value="C:\\hudson\\jobs\\PIAnalyser\\setPluginVersion.sh ${ant.project.name}.core"/>
+		</exec>
+		<exec dir="../" executable="bash" resolveexecutable="true" failonerror="true"> 
+				<arg value="-c"/>
+				<arg value="C:\\hudson\\jobs\\PIAnalyser\\setPluginVersion.sh ${ant.project.name}.function"/>
+		</exec>
+		<exec dir="../" executable="bash" resolveexecutable="true" failonerror="true"> 
+				<arg value="-c"/>
+				<arg value="C:\\hudson\\jobs\\PIAnalyser\\setPluginVersion.sh ${ant.project.name}.instr"/>
+		</exec>	
+		<exec dir="../" executable="bash" resolveexecutable="true" failonerror="true"> 
+				<arg value="-c"/>
+				<arg value="C:\\hudson\\jobs\\PIAnalyser\\setPluginVersion.sh ${ant.project.name}.memory"/>
+		</exec>	
+		<exec dir="../" executable="bash" resolveexecutable="true" failonerror="true"> 
+				<arg value="-c"/>
+				<arg value="C:\\hudson\\jobs\\PIAnalyser\\setPluginVersion.sh ${ant.project.name}.power"/>
+		</exec>	
+		<exec dir="../" executable="bash" resolveexecutable="true" failonerror="true"> 
+				<arg value="-c"/>
+				<arg value="C:\\hudson\\jobs\\PIAnalyser\\setPluginVersion.sh ${ant.project.name}.priority"/>
+		</exec>
+		<exec dir="../" executable="bash" resolveexecutable="true" failonerror="true"> 
+				<arg value="-c"/>
+				<arg value="C:\\hudson\\jobs\\PIAnalyser\\setPluginVersion.sh ${ant.project.name}.priority2"/>
+		</exec>
+		<exec dir="../" executable="bash" resolveexecutable="true" failonerror="true"> 
+				<arg value="-c"/>
+				<arg value="C:\\hudson\\jobs\\PIAnalyser\\setPluginVersion.sh ${ant.project.name}.ui"/>
+		</exec>	
+		<exec dir="../" executable="bash" resolveexecutable="true" failonerror="true"> 
+				<arg value="-c"/>
+				<arg value="C:\\hudson\\jobs\\PIAnalyser\\setPluginVersion.sh ${ant.project.name}.util"/>
+		</exec>	
+		<exec dir="../" executable="bash" resolveexecutable="true" failonerror="true"> 
+				<arg value="-c"/>
+				<arg value="C:\\hudson\\jobs\\PIAnalyser\\setPluginVersion.sh ${ant.project.name}.wizards"/>
+		</exec>	
+		<exec dir="../" executable="bash" resolveexecutable="true" failonerror="true"> 
+				<arg value="-c"/>
+				<arg value="C:\\hudson\\jobs\\PIAnalyser\\setPluginVersion.sh ${ant.project.name}.irq"/>
+		</exec>	
+		<exec dir="../" executable="bash" resolveexecutable="true" failonerror="true"> 
+				<arg value="-c"/>
+				<arg value="C:\\hudson\\jobs\\PIAnalyser\\setPluginVersion.sh ${ant.project.name}.perfcounters"/>
+		</exec>	
+		<exec dir="../" executable="bash" resolveexecutable="true" failonerror="true"> 
+				<arg value="-c"/>
+				<arg value="C:\\hudson\\jobs\\PIAnalyser\\setPluginVersion.sh ${ant.project.name}.peccommon"/>
+		</exec>	
+		<exec dir="../" executable="bash" resolveexecutable="true" failonerror="true"> 
+				<arg value="-c"/>
+				<arg value="C:\\hudson\\jobs\\PIAnalyser\\setPluginVersion.sh ${ant.project.name}.ipc"/>
+		</exec>	
+		
+		<!-- Copy the actual plug-in to the feature folder -->
+		<copy todir="${feature.folder}/plugins">
+			<fileset dir="../plugins"/>
+		</copy>
+		
+		<copy todir="${binaries.folder}">
+			<fileset dir="../plugins"/>
+		</copy>
+		
+		
+			<!-- Copy the actual plug-ins to the carbide folders -->
+		<copy todir="${carbide.sym.folder}" failonerror="true" overwrite="true">
+				<fileset dir="${feature.folder}/plugins"/>
+		</copy>
+		<copy todir="${carbide.idl.folder}" failonerror="true" overwrite="true">
+				<fileset dir="${feature.folder}/plugins"/>
+		</copy>
+		<copy todir="${carbide.adt.folder}" failonerror="true" overwrite="true">
+				<fileset dir="${feature.folder}/plugins"/>
+		</copy>
+	
+	</target>
+	
+	<!-- Analyze target -->
+	<target name="analyze">
+		<!-- PMD -->
+		<pmd>
+			<!-- Rules -->
+			<ruleset>basic</ruleset>
+			<ruleset>design</ruleset>
+			<ruleset>strictexception</ruleset>
+			<ruleset>strings</ruleset>
+			<!--<ruleset>sunsecure</ruleset>
+			<ruleset>junit</ruleset>
+			<ruleset>unusedcode</ruleset>-->
+			
+			<!-- XML output -->
+			<formatter type="xml" toFile="${reports.folder}/report.pmd.xml"/>
+			
+			<!-- Files to analyze -->
+			<fileset dir="src/">
+				<include name="**/*.java"/>
+			</fileset>
+			<fileset dir="${address.folder}/src/">
+				<include name="**/*.java"/>
+			</fileset>
+			<fileset dir="${button.folder}/src/">
+				<include name="**/*.java"/>
+			</fileset>
+			<fileset dir="${call.folder}/src/">
+				<include name="**/*.java"/>
+			</fileset>
+			<fileset dir="${core.folder}/src/">
+				<include name="**/*.java"/>
+			</fileset>
+			<fileset dir="${func.folder}/src/">
+				<include name="**/*.java"/>
+			</fileset>
+			<fileset dir="${inst.folder}/src/">
+				<include name="**/*.java"/>
+			</fileset>
+			<fileset dir="${memory.folder}/src/">
+				<include name="**/*.java"/>
+			</fileset>
+			<fileset dir="${power.folder}/src/">
+				<include name="**/*.java"/>
+			</fileset>
+			<fileset dir="${priority.folder}/src/">
+				<include name="**/*.java"/>
+			</fileset>
+			<fileset dir="${priority2.folder}/src/">
+				<include name="**/*.java"/>
+			</fileset>
+			<fileset dir="${ui.folder}/src/">
+				<include name="**/*.java"/>
+			</fileset>
+			<fileset dir="${util.folder}/src/">
+				<include name="**/*.java"/>
+			</fileset>
+			<fileset dir="${wizards.folder}/src/">
+				<include name="**/*.java"/>
+			</fileset>	
+			<fileset dir="${irq.folder}/src/">
+				<include name="**/*.java"/>
+			</fileset>	
+		</pmd>
+	</target>
+	
+	
+	
+	
+	<target name="pde_test">
+        <delete>
+            <!--<fileset dir="${test.eclipse.folder}/configuration" includes="**/*" excludes="config.ini"/>-->
+            <fileset dir="${test.eclipse.folder}/plugins" includes="${project.name}*.jar"/>
+            <!--<fileset dir="${test.eclipse.folder}/plugins" includes="pde.test.utils*.jar"/>-->
+        </delete>
+				
+		<!-- Build tests -->
+		
+		<!-- Test support plug-in. This should be build before all other plug-ins.-->
+	    <mkdir dir="${classes.testsupport.folder}"/>
+        <javac srcdir="${testsupport}" destdir="${classes.testsupport.folder}" debug="${debug}" deprecation="${deprecation}" classpathref="test_classpath" includeantruntime="false"/>
+        <zip destfile="${carbide.idl.folder}/${ant.project.name}.testsupport.jar">
+            <zipfileset dir="${testsupport}" includes="**/*.MF"/>
+            <zipfileset dir="${classes.testsupport.folder}"/>
+			<zipfileset dir="${testsupport}/testdata" prefix="testdata/"/>
+        </zip>
+            	
+		<!-- Wizard plug-in tests -->
+        <mkdir dir="${classes.wizards.tests.folder}"/>
+        <javac srcdir="${wizards.tests}" destdir="${classes.wizards.tests.folder}" debug="${debug}" deprecation="${deprecation}" classpathref="test_classpath" includeantruntime="false"/>
+        <zip destfile="${carbide.idl.folder}/${ant.project.name}.wizards.tests.jar">
+            <zipfileset dir="${wizards.tests}" includes="**/*.MF"/>
+            <zipfileset dir="${classes.wizards.tests.folder}"/>
+        </zip>
+
+		<!-- Irq plug-in tests -->
+	    <mkdir dir="${classes.irq.tests.folder}"/>
+        <javac srcdir="${irq.tests}" destdir="${classes.irq.tests.folder}" debug="${debug}" deprecation="${deprecation}" classpathref="test_classpath" includeantruntime="false"/>
+        <zip destfile="${carbide.idl.folder}/${ant.project.name}.irq.tests.jar">
+            <zipfileset dir="${irq.tests}" includes="**/*.MF"/>
+            <zipfileset dir="${classes.irq.tests.folder}"/>
+			<zipfileset dir="${irq.tests}/testdata" prefix="testdata/"/>
+        </zip>
+
+		<!-- Memory plug-in tests -->
+	    <mkdir dir="${classes.memory.tests.folder}"/>
+        <javac srcdir="${memory.tests}" destdir="${classes.memory.tests.folder}" debug="${debug}" deprecation="${deprecation}" classpathref="test_classpath" includeantruntime="false"/>
+        <zip destfile="${carbide.idl.folder}/${ant.project.name}.memory.tests.jar">
+            <zipfileset dir="${memory.tests}" includes="**/*.MF"/>
+            <zipfileset dir="${classes.memory.tests.folder}"/>
+        </zip>	
+		
+		<!-- Address plug-in tests -->
+	    <mkdir dir="${classes.address.tests.folder}"/>
+        <javac srcdir="${address.tests}" destdir="${classes.address.tests.folder}" debug="${debug}" deprecation="${deprecation}" classpathref="test_classpath" includeantruntime="false"/>
+        <zip destfile="${carbide.idl.folder}/${ant.project.name}.address.tests.jar">
+            <zipfileset dir="${address.tests}" includes="**/*.MF"/>
+            <zipfileset dir="${classes.address.tests.folder}"/>
+			<zipfileset dir="${address.tests}/testdata" prefix="testdata/"/>
+        </zip>	
+		
+		<!-- Call plug-in tests -->
+        <mkdir dir="${classes.call.tests.folder}"/>
+        <javac srcdir="${call.tests}" destdir="${classes.call.tests.folder}" debug="${debug}" deprecation="${deprecation}" classpathref="test_classpath" includeantruntime="false"/>
+        <zip destfile="${carbide.idl.folder}/${ant.project.name}.call.tests.jar">
+            <zipfileset dir="${call.tests}" includes="**/*.MF"/>
+            <zipfileset dir="${classes.call.tests.folder}"/>
+			<zipfileset dir="${address.tests}/testdata" prefix="testdata/"/>
+        </zip>	
+        
+		<!-- Button plug-in tests -->
+	    <mkdir dir="${classes.button.tests.folder}"/>
+        <javac srcdir="${button.tests}" destdir="${classes.button.tests.folder}" debug="${debug}" deprecation="${deprecation}" classpathref="test_classpath" includeantruntime="false"/>
+        <zip destfile="${carbide.idl.folder}/${ant.project.name}.button.tests.jar">
+            <zipfileset dir="${button.tests}" includes="**/*.MF"/>
+            <zipfileset dir="${classes.button.tests.folder}"/>
+        </zip>	
+		
+		<!-- Instr plug-in tests -->
+        <mkdir dir="${classes.instr.tests.folder}"/>
+        <javac srcdir="${instr.tests}" destdir="${classes.instr.tests.folder}" debug="${debug}" deprecation="${deprecation}" classpathref="test_classpath" includeantruntime="false"/>
+        <zip destfile="${carbide.idl.folder}/${ant.project.name}.instr.tests.jar">
+            <zipfileset dir="${instr.tests}" includes="**/*.MF"/>
+            <zipfileset dir="${classes.instr.tests.folder}"/>
+        </zip>	
+		
+		<!-- Peccommon plug-in tests -->
+        <mkdir dir="${classes.peccommon.tests.folder}"/>
+        <javac srcdir="${peccommon.tests}" destdir="${classes.peccommon.tests.folder}" debug="${debug}" deprecation="${deprecation}" classpathref="test_classpath" includeantruntime="false"/>
+        <zip destfile="${carbide.idl.folder}/${ant.project.name}.peccommon.tests.jar">
+            <zipfileset dir="${peccommon.tests}" includes="**/*.MF"/>
+            <zipfileset dir="${classes.peccommon.tests.folder}"/>
+        </zip>	
+          
+		<!-- Ipc plug-in tests -->
+        <mkdir dir="${classes.ipc.tests.folder}"/>
+        <javac srcdir="${ipc.tests}" destdir="${classes.ipc.tests.folder}" debug="${debug}" deprecation="${deprecation}" classpathref="test_classpath" includeantruntime="false"/>
+        <zip destfile="${carbide.idl.folder}/${ant.project.name}.ipc.tests.jar">
+            <zipfileset dir="${ipc.tests}" includes="**/*.MF"/>
+            <zipfileset dir="${classes.ipc.tests.folder}"/>
+			<zipfileset dir="${ipc.tests}/testdata" prefix="testdata/"/>
+        </zip>	
+		
+		<!-- Perfcounters plug-in tests -->
+        <mkdir dir="${classes.perfcounters.tests.folder}"/>
+        <javac srcdir="${perfcounters.tests}" destdir="${classes.perfcounters.tests.folder}" debug="${debug}" deprecation="${deprecation}" classpathref="test_classpath" includeantruntime="false"/>
+        <zip destfile="${carbide.idl.folder}/${ant.project.name}.perfcounters.tests.jar">
+            <zipfileset dir="${perfcounters.tests}" includes="**/*.MF"/>
+            <zipfileset dir="${classes.perfcounters.tests.folder}"/>
+			<zipfileset dir="${perfcounters.tests}/testdata" prefix="testdata/"/>
+
+        </zip>	
+		
+		<!-- PI test plug-in, this should be built after all other plug-ins since it needs all plug-in classes -->
+		<mkdir dir="${classes.pi.tests.folder}"/>
+        <javac srcdir="${pi.tests}" destdir="${classes.pi.tests.folder}" debug="${debug}" deprecation="${deprecation}" classpathref="test_classpath" includeantruntime="false"/>
+        <zip destfile="${carbide.idl.folder}/${ant.project.name}.tests.jar">
+            <zipfileset dir="${pi.tests}" includes="**/*.MF"/>
+            <zipfileset dir="${classes.pi.tests.folder}"/>
+			<zipfileset dir="${pi.tests}/testdata" prefix="testdata/"/>
+
+        </zip>		
+
+		
+        <!-- Load plugin and pde tests plugin fragment into test eclipse installation -->
+        <!--<copy todir="${carbide.idl.folder}" overwrite="true">
+            <fileset dir="${binaries.folder}">
+            		<include name="*.jar"/>
+            </fileset>
+        </copy>
+				 <echo message="Created plugins copied to Carbide/plugins "/>
+		-->
+				<!-- Get pde_test port number -->
+        <delete file="pde_test_port.properties"/> <!-- properties file generated by PDETestPortLocator class in pde.test.utils -->
+        <java classname="pde.test.utils.PDETestPortLocator" fork="true" classpathref="pde.test.port.locator.class.path"/>
+        <waitfor maxwait="10" maxwaitunit="second" checkevery="100" checkeveryunit="millisecond">
+            <available file="pde_test_port.properties"/>
+        </waitfor>
+        <property file="pde_test_port.properties"/>
+        		<echo message="Using port ${pde.test.port} for listening to PDE Test run"/>
+
+        <parallel>
+            <daemons>
+                <antcall target="run_pde_test_listener"/>
+            </daemons>
+            <sequential>
+                <sleep seconds="5"/> <!-- Give the listener a few seconds to start up -->
+                <antcall target="run_pde_tests"/>
+            </sequential>
+        </parallel>
+
+        <!--<delete>
+            <fileset dir="${test.eclipse.folder}/plugins" includes="${feature.name}*.jar"/>
+        </delete>-->
+
+        <mkdir dir="${test.reports.folder}"/>
+        <move todir="${test.reports.folder}">
+            <fileset dir=".">
+                <include name="**/TEST-*.xml"/>
+            </fileset>
+        </move>
+    </target>
+	
+		<!-- Run PDE listener -->
+		<target name="run_pde_test_listener">
+        <java classname="pde.test.utils.PDETestResultsCollector" fork="true" classpathref="pde.test.listener.class.path">
+            <arg line="${feature.name} ${pde.test.port}"/>
+        </java>
+    </target>
+    
+    <!-- Run PDE tests -->
+    <target name="run_pde_tests">
+    
+        <property name="test.classes.list" value="${test.plugin.name}.AllJUnitPluginTests"/>
+        <mkdir dir="${test.reports.folder}/output/ws"/>
+        <java dir="${carbide.idl.folder}" classname="org.eclipse.equinox.launcher.Main" fork="true" classpathref="equinox.launcher.class.path" maxmemory="1024m">
+        	<arg line="-Xmx1024m" />
+            <arg line="-application org.eclipse.pde.junit.runtime.uitestapplication -data ${test.reports.folder}/output/ws -dev bin -clean -port ${pde.test.port} -testpluginname ${test.plugin.name} -classnames ${test.classes.list}"/>				
+		        		
+				</java>
+				<junit>
+				
+						<classpath refid="test_classpath" />
+	      	
+	      		<!-- Plain format and XML -->
+	      		<formatter type="plain" />
+	      		<formatter type="xml" />
+				
+						<jvmarg value="-Demma.coverage.out.file=${reports.emma}\coverage.emma" />
+	    			<jvmarg value="-Demma.coverage.out.merge=true" />
+	    		
+	    	</junit>
+    	
+
+        
+   
+        <!--<emma enabled="true" >
+      			<report sourcepath="src" >
+        				<fileset dir="${reports.emma}" >
+          					<include name="*.emma" />
+        				</fileset>
+        				<xml outfile="${reports.emma}/coverage.xml" depth="method"/>
+
+      			</report>
+    		</emma>-->
+	
+		
+    </target>
+		
+		<!-- Generate test report -->
+	  <target name="generate_report">
+        <junitreport todir="${test.reports.folder}">
+            <fileset dir="${test.reports.folder}">
+                <include name="TEST-*.xml" />
+            </fileset>
+            <report todir="${test.reports.folder}" />
+        </junitreport>
+    </target>
+
+		<!-- Generate html report -->
+    <target name="check_results">
+        <loadfile srcfile="${test.reports.folder}/overview-summary.html" property="full.results.summary"/> <!-- works if you load 2 times ?? -->
+        <loadfile srcfile="${test.reports.folder}/overview-summary.html" property="results.summary">
+            <filterchain>
+                <headfilter lines="30" />
+                <linecontains>
+                    <contains value="%&lt;/td&gt;" />
+                </linecontains>
+            </filterchain>
+        </loadfile>
+
+        <condition property="tests.passed">
+            <contains string="${results.summary}" substring="100.00%" />
+        </condition>
+        <fail message="FAILED - some tests failed - see ${test.reports.folder}\index.html for more details" unless="tests.passed" />
+        <echo message="SUCCESS - all tests passed - see ${test.reports.folder}\index.html for more details" />
+    
+    </target>
+			
+			
+	<!-- Clean tests target -->
+  <target name="clean-test" description="Clean test">
+    	<!--<delete>
+      		<fileset dir="${test.folder}" includes="**/*.class" />
+    	</delete>-->
+    	<!--<delete dir="${instr.folder}"/>-->
+    	<!--<delete dir="${reports.folder}"/>-->
+    	<delete file="pde_test_port.properties"/>
+  </target>
+			
+	
+	<target name="zip">
+	
+		<!-- Create the feature zip -->
+		<zip destfile="${binaries.folder}/${feature.name}.zip" basedir="${feature.folder}"/>
+		
+		<deltree dir="${feature.folder}"/>
+		
+		<!-- Nightly build -->
+		<tstamp>
+		   <format property="timestamp" pattern="dd-MM-yyyy" />
+		</tstamp>
+
+		<delete dir="${binaries.folder}/nightly_builds"/>
+  	<mkdir dir="${binaries.folder}/nightly_builds"/>
+
+		<copy tofile="${binaries.folder}/nightly_builds/${feature.name}-${timestamp}.zip" file="${binaries.folder}/${feature.name}.zip"/>
+	</target>
+	
+</project>
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/META-INF/MANIFEST.MF	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/META-INF/MANIFEST.MF	Wed Apr 21 15:14:16 2010 +0300
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: Carbide.c++ Performance Investigator
 Bundle-SymbolicName: com.nokia.carbide.cpp.pi;singleton:=true
-Bundle-Version: 1.5.0.qualifier
+Bundle-Version: 2.3.0.qualifier
 Bundle-Activator: com.nokia.carbide.cpp.pi.PiPlugin
 Bundle-Vendor: Nokia
 Require-Bundle: org.eclipse.ui,
@@ -12,7 +12,8 @@
  org.eclipse.draw2d,
  com.nokia.carbide.cpp.featureTracker,
  com.nokia.carbide.cpp.pi.core,
- com.nokia.carbide.cpp.pi.util
+ com.nokia.carbide.cpp.pi.util,
+ org.eclipse.help;bundle-version="3.4.0"
 Bundle-ActivationPolicy: lazy
 Export-Package: com.nokia.carbide.cpp.internal.pi.actions,
  com.nokia.carbide.cpp.internal.pi.analyser,
@@ -27,4 +28,6 @@
  com.nokia.carbide.cpp.internal.pi.visual,
  com.nokia.carbide.cpp.pi,
  com.nokia.carbide.cpp.pi.editors,
- com.nokia.carbide.cpp.pi.importer
+ com.nokia.carbide.cpp.pi.importer,
+ com.nokia.carbide.cpp.pi.visual
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/ccbuild_tests.xml	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,485 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="com.nokia.carbide.cpp.pi" default="cc" basedir=".">
+
+	
+	<!-- Build PI only: -->
+	<!--<target name="cc" depends="build, analyze, feature, zip" description="Build, instrument and analyze code"/>-->
+	
+	<!-- Build PI and tests and run tests: -->
+	<!--<target name="cc" depends="clean, build, analyze, feature, pde_test, generate_report, check_results,zip" description="Build, instrument, run unit tests and analyze code"/>-->
+
+	<!-- Build and run tests: -->
+	<target name="cc" depends="pde_test, generate_report, check_results" description="Build and run unit tests"/>
+
+	
+
+	<property name="basews" value="${ws}"/>
+	<property name="baseos" value="${os}"/>
+	<property name="basearch" value="${arch}"/>
+	<property name="basenl" value="${nl}"/>
+
+	<!-- Compiler settings -->
+	<property name="javacFailOnError" value="true"/>
+	<property name="javacDebugInfo" value="on"/>
+	<property name="javacVerbose" value="false"/>
+	<property name="logExtension" value=".log"/>
+	<property name="compilerArg" value=""/>
+	<property name="javacSource" value="5"/>
+	<property name="javacTarget" value="5"/>
+	
+	<property name="bootclasspath" refid="path_bootclasspath"/>
+	<property name="bundleJavacSource" value="${javacSource}"/>
+	<property name="bundleJavacTarget" value="${javacTarget}"/>
+	<property name="bundleBootClasspath" value="${bootclasspath}"/>
+	
+	<property name="help.project.name" value="${ant.project.name}.help"/>
+	<property name="core.project.name" value="${ant.project.name}.corecomponents"/>
+	<property name="trace.project.name" value="${ant.project.name}.trace"/>
+	<property name="internal.project.name" value="${ant.project.name}.internal"/>
+	<property name="feature.project.folder" location="../com.nokia.carbide.cpp.pi-feature"/>
+	<property name="feature.project.name" value="com.nokia.carbide.cpp.pi-feature"/>
+	<property name="feature.name" value="PIAnalyser"/>
+	<property name="test.plugin.name" 					 value="com.nokia.carbide.cpp.pi.tests"/>
+  	<property name="feature.project.name" 		 	 value="com.nokia.carbide.cpp.pi-feature"/>
+	<property name="jar.filename" value="${ant.project.name}.jar"/>
+	
+	<!-- Folder definitions -->
+	<property name="carbide.sym.folder" location="g:/Sym_240/plugins"/>
+	<property name="carbide.idl.folder" location="g:/IDL/plugins"/>
+	<property name="carbide.adt.folder" location="g:/ADT/plugins"/>
+	<property name="test.eclipse.folder" location="C:/eclipse"/>
+	<property name="binaries.folder" location="${basedir}/../${feature.name}.binaries"/>
+	<property name="reports.folder" location="../reports"/>
+	<property name="reports.emma" location="${reports.folder}/emma"/>
+	<property name="instr.folder" location="instr"/>
+	
+
+	<!-- TEST plug-ins -->
+	<property name="address.tests" location="../tests/com.nokia.carbide.cpp.pi.address.tests"/>
+	<property name="classes.address.tests.folder" location="${address.tests}/classes"/>
+
+	<property name="button.tests" location="../tests/com.nokia.carbide.cpp.pi.button.tests"/>
+	<property name="classes.button.tests.folder" location="${button.tests}/classes"/>
+
+	<property name="call.tests" location="../tests/com.nokia.carbide.cpp.pi.call.tests"/>
+	<property name="classes.call.tests.folder" location="${call.tests}/classes"/>
+
+	<property name="core.tests" location="../tests/com.nokia.carbide.cpp.pi.core.tests"/>
+	<property name="classes.core.tests.folder" location="${core.tests}/classes"/>
+
+	<property name="instr.tests" location="../tests/com.nokia.carbide.cpp.pi.instr.tests"/>
+	<property name="classes.instr.tests.folder" location="${instr.tests}/classes"/>
+
+	<property name="util.tests" location="../tests/com.nokia.carbide.cpp.pi.util.tests"/>
+	<property name="classes.util.tests.folder" location="${util.tests}/classes"/>
+
+	<property name="memory.tests" location="../tests/com.nokia.carbide.cpp.pi.memory.tests"/>
+	<property name="classes.memory.tests.folder" location="${memory.tests}/classes"/>
+	
+	<property name="pi.tests" location="../tests/com.nokia.carbide.cpp.pi.tests"/>
+	<property name="classes.pi.tests.folder"  location="${pi.tests}/classes"/>
+	
+	<property name="testsupport" location="../tests/com.nokia.carbide.cpp.pi.testsupport"/>
+	<property name="classes.testsupport.folder"  location="${testsupport}/classes"/>
+
+	<property name="wizards.tests" location="../tests/com.nokia.carbide.cpp.pi.wizards.tests"/>
+	<property name="classes.wizards.tests.folder"              location="${wizards.tests}/classes"/>
+
+	<property name="irq.tests" location="../tests/com.nokia.carbide.cpp.pi.irq.tests"/>
+	<property name="classes.irq.tests.folder"              location="${irq.tests}/classes"/>
+
+	<property name="perfcounters.tests" location="../tests/com.nokia.carbide.cpp.pi.perfcounters.tests"/>
+	<property name="classes.perfcounters.tests.folder"              location="${perfcounters.tests}/classes"/>
+
+	<property name="peccommon.tests" location="../tests/com.nokia.carbide.cpp.pi.peccommon.tests"/>
+	<property name="classes.peccommon.tests.folder"              location="${peccommon.tests}/classes"/>
+	
+	<property name="ipc.tests" location="../tests/com.nokia.carbide.cpp.pi.ipc.tests"/>
+	<property name="classes.ipc.tests.folder"              location="${ipc.tests}/classes"/>
+
+	
+	<!-- Tests build classpath -->
+	<path id="test.build.class.path">
+ 
+        <!-- Instrumented class files -->
+		   			<pathelement location="${instr.folder}"/>
+       
+       			<!--<pathelement location="${test.folder}/src"/>-->
+			
+    				<!-- Normal class files -->
+    				<pathelement path="${binaries.folder}/${jar.filename}"/>
+    		
+		   			<!-- EMMA -->
+		   			<pathelement path="${ant.home}/lib/emma.jar"/>
+		   	
+        <fileset dir="${carbide.idl.folder}" includes="**/*.jar">
+        
+        </fileset>
+  </path>
+		
+	<!--  pde.test.listener.class.path -->
+	<path id="pde.test.listener.class.path">
+        <!--<path refid="build.pde.class.path"/>-->
+        <pathelement location="${binaries.folder}/pde.test.utils.jar"/>
+        <fileset dir="${test.eclipse.folder}/plugins" includes="**/*.jar"/>
+  </path>
+		
+	<!--  pde.test.port.locator.classpath -->
+	<path id="pde.test.port.locator.class.path">
+        <pathelement location="${binaries.folder}/pde.test.utils.jar"/>
+        <fileset dir="${carbide.idl.folder}">
+            <include name="org.junit_4.*/**/junit.jar"/>
+        </fileset>
+  </path>
+  
+  <!--  Carbide launcher classpath -->
+  <path id="equinox.launcher.class.path">			
+			 
+			 <fileset dir="${carbide.idl.folder}">
+            <include name="org.eclipse.equinox.launcher_*.jar"/>
+            <include name="instr.${jar.filename}"/>
+       </fileset>			 
+
+       			<!-- Instrumented class files -->
+		   <pathelement location="${instr.folder}"/>
+       
+       			<!--<pathelement location="${test.folder}/src"/>-->
+			
+    				<!-- Normal class files -->
+    				<!--<pathelement path="${binaries.folder}/${jar.filename}"/>-->
+    		
+		   	<!-- EMMA -->
+		   	<pathelement path="${ant.home}/lib/emma.jar"/>
+		   	
+		   			<!--<path refid="build_classpath" />-->
+        
+  </path>
+  
+  <path id="test_classpath">
+			<!-- Test classes -->
+			<pathelement location="${wizards.test}/src"/>
+			
+			<!-- Instrumented class files -->
+		   	<pathelement location="${instr.folder}"/>
+		   	
+    		<!-- Normal class files -->
+    		<pathelement path="${binaries.folder}/*.jar"/>
+
+		   	<!-- EMMA -->
+		   	<pathelement path="${ant.home}/lib/emma.jar"/>
+		   	
+		   	<path refid="test.build.class.path" />
+		</path>
+	
+	
+	<!-- EMMA configuration -->
+ 	<path id="emma.lib" >
+    	<pathelement location="${ant.home}/lib/emma.jar" />
+    	<pathelement location="${ant.home}/lib/emma_ant.jar" />
+  	</path>
+
+  	<taskdef resource="emma_ant.properties" classpathref="emma.lib" />
+	
+	<!-- PMD configuration -->
+	<path id="pmd.lib" >
+    	<pathelement location="${ant.home}/lib/pmd-4.2.5.jar" />
+    	<pathelement location="${ant.home}/lib/asm-3.1.jar" />
+    	<pathelement location="${ant.home}/lib/jaxen-1.1.1.jar" />
+  	</path>
+	
+	<taskdef name="pmd" classname="net.sourceforge.pmd.ant.PMDTask" classpathref="pmd.lib" />
+	
+	<path id="path_bootclasspath">
+		<fileset dir="${java.home}/lib">
+			<include name="*.jar"/>
+		</fileset>
+	</path>
+	
+	<path id="build_classpath">
+		<fileset dir="../plugins" includes="**/*.jar" />
+		<fileset dir="${carbide.idl.folder}" includes="**/*.jar" />
+	</path>
+
+	<path id="test_carbide_classpath">
+		<fileset dir="${carbide.adt.folder}" includes="**/*.jar" />
+	</path>
+	
+	<target name="properties" if="eclipse.running">
+		<property name="build.compiler" value="org.eclipse.jdt.core.JDTCompilerAdapter"/>
+	</target>
+
+	
+	<!-- Initialization -->
+	<target name="init" depends="properties">
+		<condition property="pluginTemp" value="${buildTempFolder}/plugins">
+			<isset property="buildTempFolder"/>
+		</condition>
+		<property name="pluginTemp" value="${basedir}"/>
+		<condition property="build.result.folder" value="${pluginTemp}/${ant.project.name}">
+			<isset property="buildTempFolder"/>
+		</condition>
+		<property name="build.result.folder" value="${basedir}"/>
+		<property name="temp.folder" value="${basedir}/temp.folder"/>
+		<property name="plugin.destination" value="${basedir}"/>
+
+		<property name="jar.filename" value="${ant.project.name}.jar"/>
+		
+		<delete dir="../plugins"/>
+		<mkdir dir="../plugins"/>
+		
+		<delete dir="${reports.folder}"/>
+		<mkdir dir="${reports.folder}"/>
+		
+		
+		
+		
+		<exec executable="svn" dir="../.">
+			<arg line="up"/>
+		</exec>
+	</target>
+
+	<!-- pde_test target -->
+		
+	<target name="pde_test">
+        <delete>
+            <!--<fileset dir="${test.eclipse.folder}/configuration" includes="**/*" excludes="config.ini"/>-->
+            <fileset dir="${test.eclipse.folder}/plugins" includes="${project.name}*.jar"/>
+            <!--<fileset dir="${test.eclipse.folder}/plugins" includes="pde.test.utils*.jar"/>-->
+        </delete>
+				
+		<!-- Build tests -->
+		
+		<!-- Test support plug-in. This should be build before all other plug-ins.-->
+	    <mkdir dir="${classes.testsupport.folder}"/>
+        <javac srcdir="${testsupport}" destdir="${classes.testsupport.folder}" debug="${debug}" deprecation="${deprecation}" classpathref="test_classpath" includeantruntime="false"/>
+        <zip destfile="${carbide.idl.folder}/${ant.project.name}.testsupport.jar">
+            <zipfileset dir="${testsupport}" includes="**/*.MF"/>
+            <zipfileset dir="${classes.testsupport.folder}"/>
+			<zipfileset dir="${testsupport}/testdata" prefix="testdata/"/>
+        </zip>
+            	
+		<!-- Wizard plug-in tests -->
+        <mkdir dir="${classes.wizards.tests.folder}"/>
+        <javac srcdir="${wizards.tests}" destdir="${classes.wizards.tests.folder}" debug="${debug}" deprecation="${deprecation}" classpathref="test_classpath" includeantruntime="false"/>
+        <zip destfile="${carbide.idl.folder}/${ant.project.name}.wizards.tests.jar">
+            <zipfileset dir="${wizards.tests}" includes="**/*.MF"/>
+            <zipfileset dir="${classes.wizards.tests.folder}"/>
+        </zip>
+
+		<!-- Irq plug-in tests -->
+	    <mkdir dir="${classes.irq.tests.folder}"/>
+        <javac srcdir="${irq.tests}" destdir="${classes.irq.tests.folder}" debug="${debug}" deprecation="${deprecation}" classpathref="test_classpath" includeantruntime="false"/>
+        <zip destfile="${carbide.idl.folder}/${ant.project.name}.irq.tests.jar">
+            <zipfileset dir="${irq.tests}" includes="**/*.MF"/>
+            <zipfileset dir="${classes.irq.tests.folder}"/>
+			<zipfileset dir="${irq.tests}/testdata" prefix="testdata/"/>
+        </zip>
+
+		<!-- Memory plug-in tests -->
+	    <mkdir dir="${classes.memory.tests.folder}"/>
+        <javac srcdir="${memory.tests}" destdir="${classes.memory.tests.folder}" debug="${debug}" deprecation="${deprecation}" classpathref="test_classpath" includeantruntime="false"/>
+        <zip destfile="${carbide.idl.folder}/${ant.project.name}.memory.tests.jar">
+            <zipfileset dir="${memory.tests}" includes="**/*.MF"/>
+            <zipfileset dir="${classes.memory.tests.folder}"/>
+        </zip>	
+		
+		<!-- Address plug-in tests -->
+	    <mkdir dir="${classes.address.tests.folder}"/>
+        <javac srcdir="${address.tests}" destdir="${classes.address.tests.folder}" debug="${debug}" deprecation="${deprecation}" classpathref="test_classpath" includeantruntime="false"/>
+        <zip destfile="${carbide.idl.folder}/${ant.project.name}.address.tests.jar">
+            <zipfileset dir="${address.tests}" includes="**/*.MF"/>
+            <zipfileset dir="${classes.address.tests.folder}"/>
+			<zipfileset dir="${address.tests}/testdata" prefix="testdata/"/>
+        </zip>	
+		
+		<!-- Call plug-in tests -->
+        <mkdir dir="${classes.call.tests.folder}"/>
+        <javac srcdir="${call.tests}" destdir="${classes.call.tests.folder}" debug="${debug}" deprecation="${deprecation}" classpathref="test_classpath" includeantruntime="false"/>
+        <zip destfile="${carbide.idl.folder}/${ant.project.name}.call.tests.jar">
+            <zipfileset dir="${call.tests}" includes="**/*.MF"/>
+            <zipfileset dir="${classes.call.tests.folder}"/>
+			<zipfileset dir="${address.tests}/testdata" prefix="testdata/"/>
+        </zip>	
+        
+		<!-- Button plug-in tests -->
+	    <mkdir dir="${classes.button.tests.folder}"/>
+        <javac srcdir="${button.tests}" destdir="${classes.button.tests.folder}" debug="${debug}" deprecation="${deprecation}" classpathref="test_classpath" includeantruntime="false"/>
+        <zip destfile="${carbide.idl.folder}/${ant.project.name}.button.tests.jar">
+            <zipfileset dir="${button.tests}" includes="**/*.MF"/>
+            <zipfileset dir="${classes.button.tests.folder}"/>
+        </zip>	
+		
+		<!-- Instr plug-in tests -->
+        <mkdir dir="${classes.instr.tests.folder}"/>
+        <javac srcdir="${instr.tests}" destdir="${classes.instr.tests.folder}" debug="${debug}" deprecation="${deprecation}" classpathref="test_classpath" includeantruntime="false"/>
+        <zip destfile="${carbide.idl.folder}/${ant.project.name}.instr.tests.jar">
+            <zipfileset dir="${instr.tests}" includes="**/*.MF"/>
+            <zipfileset dir="${classes.instr.tests.folder}"/>
+        </zip>	
+		
+		<!-- Peccommon plug-in tests -->
+        <mkdir dir="${classes.peccommon.tests.folder}"/>
+        <javac srcdir="${peccommon.tests}" destdir="${classes.peccommon.tests.folder}" debug="${debug}" deprecation="${deprecation}" classpathref="test_classpath" includeantruntime="false"/>
+        <zip destfile="${carbide.idl.folder}/${ant.project.name}.peccommon.tests.jar">
+            <zipfileset dir="${peccommon.tests}" includes="**/*.MF"/>
+            <zipfileset dir="${classes.peccommon.tests.folder}"/>
+        </zip>	
+          
+		<!-- Ipc plug-in tests -->
+        <mkdir dir="${classes.ipc.tests.folder}"/>
+        <javac srcdir="${ipc.tests}" destdir="${classes.ipc.tests.folder}" debug="${debug}" deprecation="${deprecation}" classpathref="test_classpath" includeantruntime="false"/>
+        <zip destfile="${carbide.idl.folder}/${ant.project.name}.ipc.tests.jar">
+            <zipfileset dir="${ipc.tests}" includes="**/*.MF"/>
+            <zipfileset dir="${classes.ipc.tests.folder}"/>
+			<zipfileset dir="${ipc.tests}/testdata" prefix="testdata/"/>
+        </zip>	
+		
+		<!-- Perfcounters plug-in tests -->
+        <mkdir dir="${classes.perfcounters.tests.folder}"/>
+        <javac srcdir="${perfcounters.tests}" destdir="${classes.perfcounters.tests.folder}" debug="${debug}" deprecation="${deprecation}" classpathref="test_classpath" includeantruntime="false"/>
+        <zip destfile="${carbide.idl.folder}/${ant.project.name}.perfcounters.tests.jar">
+            <zipfileset dir="${perfcounters.tests}" includes="**/*.MF"/>
+            <zipfileset dir="${classes.perfcounters.tests.folder}"/>
+			<zipfileset dir="${perfcounters.tests}/testdata" prefix="testdata/"/>
+
+        </zip>	
+		
+		<!-- PI test plug-in, this should be built after all other plug-ins since it needs all plug-in classes -->
+		<mkdir dir="${classes.pi.tests.folder}"/>
+        <javac srcdir="${pi.tests}" destdir="${classes.pi.tests.folder}" debug="${debug}" deprecation="${deprecation}" classpathref="test_classpath" includeantruntime="false"/>
+        <zip destfile="${carbide.idl.folder}/${ant.project.name}.tests.jar">
+            <zipfileset dir="${pi.tests}" includes="**/*.MF"/>
+            <zipfileset dir="${classes.pi.tests.folder}"/>
+			<zipfileset dir="${pi.tests}/testdata" prefix="testdata/"/>
+
+        </zip>		
+
+		
+        <!-- Load plugin and pde tests plugin fragment into test eclipse installation -->
+        <!--<copy todir="${carbide.idl.folder}" overwrite="true">
+            <fileset dir="${binaries.folder}">
+            		<include name="*.jar"/>
+            </fileset>
+        </copy>
+				 <echo message="Created plugins copied to Carbide/plugins "/>
+		-->
+				<!-- Get pde_test port number -->
+        <delete file="pde_test_port.properties"/> <!-- properties file generated by PDETestPortLocator class in pde.test.utils -->
+        <java classname="pde.test.utils.PDETestPortLocator" fork="true" classpathref="pde.test.port.locator.class.path"/>
+        <waitfor maxwait="10" maxwaitunit="second" checkevery="100" checkeveryunit="millisecond">
+            <available file="pde_test_port.properties"/>
+        </waitfor>
+        <property file="pde_test_port.properties"/>
+        		<echo message="Using port ${pde.test.port} for listening to PDE Test run"/>
+
+        <parallel>
+            <daemons>
+                <antcall target="run_pde_test_listener"/>
+            </daemons>
+            <sequential>
+                <sleep seconds="5"/> <!-- Give the listener a few seconds to start up -->
+                <antcall target="run_pde_tests"/>
+            </sequential>
+        </parallel>
+
+        <!--<delete>
+            <fileset dir="${test.eclipse.folder}/plugins" includes="${feature.name}*.jar"/>
+        </delete>-->
+
+        <mkdir dir="${test.reports.folder}"/>
+        <move todir="${test.reports.folder}">
+            <fileset dir=".">
+                <include name="**/TEST-*.xml"/>
+            </fileset>
+        </move>
+    </target>
+	
+		<!-- Run PDE listener -->
+		<target name="run_pde_test_listener">
+        <java classname="pde.test.utils.PDETestResultsCollector" fork="true" classpathref="pde.test.listener.class.path">
+            <arg line="${feature.name} ${pde.test.port}"/>
+        </java>
+    </target>
+    
+    <!-- Run PDE tests -->
+    <target name="run_pde_tests">
+    
+        <property name="test.classes.list" value="${test.plugin.name}.AllJUnitPluginTests"/>
+        <mkdir dir="${test.reports.folder}/output/ws"/>
+        <java dir="${carbide.idl.folder}" classname="org.eclipse.equinox.launcher.Main" fork="true" classpathref="equinox.launcher.class.path" maxmemory="1024m">
+        	<arg line="-Xmx1024m" />
+            <arg line="-application org.eclipse.pde.junit.runtime.uitestapplication -data ${test.reports.folder}/output/ws -dev bin -clean -port ${pde.test.port} -testpluginname ${test.plugin.name} -classnames ${test.classes.list}"/>				
+		        		
+				</java>
+				<junit>
+				
+						<classpath refid="test_classpath" />
+	      	
+	      		<!-- Plain format and XML -->
+	      		<formatter type="plain" />
+	      		<formatter type="xml" />
+				
+						<jvmarg value="-Demma.coverage.out.file=${reports.emma}\coverage.emma" />
+	    			<jvmarg value="-Demma.coverage.out.merge=true" />
+	    		
+	    	</junit>
+    	
+
+        
+   
+        <!--<emma enabled="true" >
+      			<report sourcepath="src" >
+        				<fileset dir="${reports.emma}" >
+          					<include name="*.emma" />
+        				</fileset>
+        				<xml outfile="${reports.emma}/coverage.xml" depth="method"/>
+
+      			</report>
+    		</emma>-->
+	
+		
+    </target>
+		
+		<!-- Generate test report -->
+	  <target name="generate_report">
+        <junitreport todir="${test.reports.folder}">
+            <fileset dir="${test.reports.folder}">
+                <include name="TEST-*.xml" />
+            </fileset>
+            <report todir="${test.reports.folder}" />
+        </junitreport>
+    </target>
+
+		<!-- Generate html report -->
+    <target name="check_results">
+        <loadfile srcfile="${test.reports.folder}/overview-summary.html" property="full.results.summary"/> <!-- works if you load 2 times ?? -->
+        <loadfile srcfile="${test.reports.folder}/overview-summary.html" property="results.summary">
+            <filterchain>
+                <headfilter lines="30" />
+                <linecontains>
+                    <contains value="%&lt;/td&gt;" />
+                </linecontains>
+            </filterchain>
+        </loadfile>
+
+        <condition property="tests.passed">
+            <contains string="${results.summary}" substring="100.00%" />
+        </condition>
+        <fail message="FAILED - some tests failed - see ${test.reports.folder}\index.html for more details" unless="tests.passed" />
+        <echo message="SUCCESS - all tests passed - see ${test.reports.folder}\index.html for more details" />
+    
+    </target>
+			
+			
+	<!-- Clean tests target -->
+  <target name="clean-test" description="Clean test">
+    	<!--<delete>
+      		<fileset dir="${test.folder}" includes="**/*.class" />
+    	</delete>-->
+    	<!--<delete dir="${instr.folder}"/>-->
+    	<!--<delete dir="${reports.folder}"/>-->
+    	<delete file="pde_test_port.properties"/>
+  </target>
+			
+	
+</project>
Binary file sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/icons/linkto_help.gif has changed
Binary file sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/icons/maximize_graph.png has changed
Binary file sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/icons/maximize_restore_graph.png has changed
Binary file sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/icons/minimize_graph.png has changed
Binary file sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/icons/minimize_restore_graph.png has changed
Binary file sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/icons/move_graph_down.png has changed
Binary file sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/icons/move_graph_up.png has changed
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/actions/SetThresholdsDialog.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/actions/SetThresholdsDialog.java	Wed Apr 21 15:14:16 2010 +0300
@@ -419,21 +419,21 @@
 
 				if (changedThread) {
 					NpiInstanceRepository.getInstance().activeUidSetPersistState("com.nokia.carbide.cpp.pi.address.thresholdLoadThread", new Double(thresholdLoadThread)); //$NON-NLS-1$
-					NpiInstanceRepository.getInstance().activeUidSetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountThread", new Integer(thresholdCountThread)); //$NON-NLS-1$
+					NpiInstanceRepository.getInstance().activeUidSetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountThread", Integer.valueOf(thresholdCountThread)); //$NON-NLS-1$
 					PIChangeEvent.action("changeThresholdThread"); //$NON-NLS-1$
 					PIChangeEvent.action("changeSelection"); //$NON-NLS-1$
 				}
 
 				if (changedBinary) {
 					NpiInstanceRepository.getInstance().activeUidSetPersistState("com.nokia.carbide.cpp.pi.address.thresholdLoadBinary", new Double(thresholdLoadBinary)); //$NON-NLS-1$
-					NpiInstanceRepository.getInstance().activeUidSetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountBinary", new Integer(thresholdCountBinary)); //$NON-NLS-1$
+					NpiInstanceRepository.getInstance().activeUidSetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountBinary", Integer.valueOf(thresholdCountBinary)); //$NON-NLS-1$
 					PIChangeEvent.action("changeThresholdBinary"); //$NON-NLS-1$
 					PIChangeEvent.action("changeSelection"); //$NON-NLS-1$
 				}
 
 				if (changedFunction) {
 					NpiInstanceRepository.getInstance().activeUidSetPersistState("com.nokia.carbide.cpp.pi.address.thresholdLoadFunction", new Double(thresholdLoadFunction)); //$NON-NLS-1$
-					NpiInstanceRepository.getInstance().activeUidSetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountFunction", new Integer(thresholdCountFunction)); //$NON-NLS-1$
+					NpiInstanceRepository.getInstance().activeUidSetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountFunction", Integer.valueOf(thresholdCountFunction)); //$NON-NLS-1$
 					PIChangeEvent.action("changeThresholdFunction"); //$NON-NLS-1$
 					PIChangeEvent.action("changeSelection"); //$NON-NLS-1$
 				}
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/analyser/AnalyserDataProcessor.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/analyser/AnalyserDataProcessor.java	Wed Apr 21 15:14:16 2010 +0300
@@ -28,12 +28,14 @@
 import java.util.Enumeration;
 import java.util.Hashtable;
 import java.util.Iterator;
+import java.util.List;
 
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.WorkspaceJob;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
 import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.jobs.IJobChangeEvent;
 import org.eclipse.core.runtime.jobs.IJobChangeListener;
@@ -59,13 +61,14 @@
 import com.nokia.carbide.cpp.internal.pi.plugin.model.IVisualizable;
 import com.nokia.carbide.cpp.internal.pi.test.AnalysisInfoHandler;
 import com.nokia.carbide.cpp.internal.pi.test.IProvideTraceAdditionalInfo;
-import com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph;
 import com.nokia.carbide.cpp.internal.pi.visual.GraphDrawRequest;
 import com.nokia.carbide.cpp.internal.pi.visual.PICompositePanel;
+import com.nokia.carbide.cpp.pi.PiPlugin;
 import com.nokia.carbide.cpp.pi.editors.PIPageEditor;
 import com.nokia.carbide.cpp.pi.importer.SampleImporter;
 import com.nokia.carbide.cpp.pi.util.GeneralMessages;
 import com.nokia.carbide.cpp.pi.util.PIExceptionRuntime;
+import com.nokia.carbide.cpp.pi.visual.IGenericTraceGraph;
 
 
 /*
@@ -73,6 +76,7 @@
  */
 
 public class AnalyserDataProcessor {
+	protected static final int MAX_CPU = 4;
 	// whether the profile file was read correctly
 	public static int STATE_OK				= 0;
 	public static int STATE_IMPORTING		= 1;
@@ -126,7 +130,7 @@
 		return lastException;
 	}
 	
-	private void importNewAnalysis(Hashtable<Integer,String> traceFileNames, int uid) throws InterruptedException, InvocationTargetException {
+	private void importNewAnalysis(Hashtable<Integer,String> traceFileNames, int uid, List<ITrace> pluginsToUse) throws InterruptedException, InvocationTargetException {
 		analyserDataProcessorState = STATE_IMPORTING;
 		final int workUnitsForImport = TOTAL_PROGRESS_COUNT * 60 / 100;
 		int workUnitsLeft = workUnitsForImport * 99 / 100;
@@ -134,16 +138,8 @@
 		checkCancelledThrowIE();
 			
 		// loop through all the plugins associated with traces
-		Enumeration<AbstractPiPlugin> enumer = PluginInitialiser.getPluginInstances(uid, "com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace"); //$NON-NLS-1$
-		Enumeration<AbstractPiPlugin> tmpEnum = PluginInitialiser.getPluginInstances(uid, "com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace"); //$NON-NLS-1$
-		int numberOfPlugins = 0;
-		while (tmpEnum.hasMoreElements()) {
-			numberOfPlugins++;
-			tmpEnum.nextElement();
-		}
-		while (enumer.hasMoreElements())
-    	{
-    		ITrace plugin = (ITrace)enumer.nextElement();
+		int numberOfPlugins = pluginsToUse.size();
+		for (ITrace plugin : pluginsToUse) {
     		int traceId = plugin.getTraceId();
     		AbstractPiPlugin p = (AbstractPiPlugin)plugin;
     		
@@ -151,13 +147,32 @@
     		NpiInstanceRepository.getInstance().addPlugin(uid, p);
     		if (traceId != -1)
     		{
-    			String fileName = traceFileNames.get(traceId);
-    			if (fileName != null)
-    			{
-    				File traceFile = new File(fileName);
-    				if (traceFile.exists()) 
-						if (traceFile.getName().endsWith(".dat"))  //$NON-NLS-1$
-							ProfileReader.getInstance().readTraceFile(plugin, traceFile, this,uid);
+    			if (traceId == 1){ //support SMP by expecting one file per CPU
+					List<File> files = new ArrayList<File>();
+    				for (int i = 0; i < MAX_CPU; i++) {
+    					int smpTraceId = traceId + i * 20;
+    					{
+    	        			String fileName = traceFileNames.get(smpTraceId);
+    	        			if (fileName != null && fileName.endsWith(".dat")) //$NON-NLS-1$
+    	        			{
+    	        				File traceFile = new File(fileName);
+    	        				if (traceFile.exists()){
+    	        					files.add(traceFile);
+    	        				}
+    	        			}    						
+    					}
+    				}
+					ProfileReader.getInstance().readTraceFile(plugin, files.toArray(new File[files.size()]), this,uid);
+    				 
+    			} else {
+        			String fileName = traceFileNames.get(traceId);
+        			if (fileName != null)
+        			{
+        				File traceFile = new File(fileName);
+        				if (traceFile.exists()) 
+    						if (traceFile.getName().endsWith(".dat"))  //$NON-NLS-1$
+    							ProfileReader.getInstance().readTraceFile(plugin, traceFile, this,uid);
+        			}    				
     			}
     		}
             // assume this load takes 39%
@@ -344,7 +359,7 @@
 
 	}
 		
-	public void importSaveAndOpen(final IFile analysisFile, boolean pollTillNpiSaved) {
+	public void importSaveAndOpen(final IFile analysisFile, boolean pollTillNpiSaved, final List<ITrace> pluginsToUse) {
 		analyserDataProcessorState = STATE_IMPORTING;
 		setProgressMonitor(null);
 		
@@ -356,148 +371,22 @@
 
 			public void run(IProgressMonitor progressMonitor)
 					throws InvocationTargetException, InterruptedException {
-				setProgressMonitor(progressMonitor);
-				progressMonitor.beginTask(Messages.getString("AnalyserDataProcessor.17") + analysisFile.getName(), TOTAL_PROGRESS_COUNT);   //$NON-NLS-1$
-				// open a profile data file that should contain at least thread/address information
-
-				// import new .dat
-				assertThrowITE(SampleImporter.getInstance().validate(), Messages.getString("AnalyserDataProcessor.18"));	  //$NON-NLS-1$
-				
-				// invoke analysis-specific plugin instances
-				PluginInitialiser.invokePluginInstances(uid, "com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace"); //$NON-NLS-1$
-
-				StreamFileParser stp;
-				try {
-					stp = new StreamFileParser(new File(SampleImporter.getInstance().getDatFileName()));
-					Hashtable<Integer,String> traceFileNames = new Hashtable<Integer,String>();
-					ArrayList<File> tracesForCleanUp = new ArrayList<File>();
-
-					// loop through all the plugins associated with traces and note their trace IDs names
-					Enumeration<AbstractPiPlugin> enumer = PluginInitialiser.getPluginInstances(uid, "com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace"); //$NON-NLS-1$
-					while (enumer.hasMoreElements())
-					{
-						File tempFile;
-						ITrace plugin = (ITrace)enumer.nextElement();
-						int traceId = plugin.getTraceId();
-						if (traceId != -1)
-						{
-							try {
-								tempFile = stp.getTempFileForTraceType(traceId);
-								if (tempFile != null)
-								{
-									tempFile.deleteOnExit();
-									traceFileNames.put(traceId, tempFile.getAbsolutePath());
-									tracesForCleanUp.add(tempFile);
-								}
-
-							} catch (IOException e) {
-								throw new InvocationTargetException(e, Messages.getString("AnalyserDataProcessor.25")); //$NON-NLS-1$
-							}
-						}
-					}
-					
-					// import a new analysis
-					importNewAnalysis(traceFileNames, uid);
-
-					// clean up temp file for each trace
-					for (File traceFile : tracesForCleanUp) {
-						traceFile.delete();
-					}
-				} catch (IOException e) {
-					throw new InvocationTargetException(e, Messages.getString("AnalyserDataProcessor.26") + SampleImporter.getInstance().getDatFileName()); //$NON-NLS-1$
-				}
-
-				if (progressMonitor.isCanceled()) {
-					throw new InterruptedException(Messages.getString("AnalyserDataProcessor.19"));   //$NON-NLS-1$
-				}
-
-				// give the .NPI file null contents
-				byte[] b = new byte[0];
-				try {
-					analysisFile.create(new ByteArrayInputStream(b), true, null);
-					// make sure we can open an input stream to the trace file
-					analysisFile.getContents();
-				} catch (CoreException e) {
-					throw new InvocationTargetException(e, Messages.getString("AnalyserDataProcessor.14") + analysisFile.getName()); //$NON-NLS-1$
-				}
-				
-				// extract additional info from importer
-				int numberOfTraces = 0;
-				Iterator<ParsedTraceData> enuTraces = TraceDataRepository.getInstance().getTraceCollectionIter(uid);
-				AnalysisInfoHandler handler = NpiInstanceRepository.getInstance().activeUidGetAnalysisInfoHandler();
-
-				// for all traces exist in .dat set up their additional info
-			    while (enuTraces.hasNext()) {
-			    	Object object = enuTraces.next();
-
-			    	numberOfTraces++;
-			    	
-			    	if (object instanceof ParsedTraceData) {
-			    		ParsedTraceData parsedTraceData = (ParsedTraceData) object;
-			    		if (parsedTraceData.traceData != null) {
-				    		Class traceClass = parsedTraceData.traceData.getClass();
-
-							// this code is clumsy because the plugin, not the trace, has the trace ID info
-				    		Enumeration<AbstractPiPlugin> enuPlugins = PluginInitialiser.getPluginInstances(uid, "com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace"); //$NON-NLS-1$
-							while (enuPlugins.hasMoreElements())
-							{
-								ITrace plugin = (ITrace)enuPlugins.nextElement();
-								// only do when trace exist in .data
-								if (traceClass == plugin.getTraceClass()) {
-							    	if (plugin instanceof IProvideTraceAdditionalInfo) {
-										((IProvideTraceAdditionalInfo)plugin).setupInfoHandler(handler);						    		
-							    	}
-								}
-							}			
-			    		}
-			    	}
-			    }
-				
-				// refresh so project know the update done by Java(non-Eclipse API)
-				try {
-					analysisFile.refreshLocal(0, null);
-				} catch (CoreException e) {
-					throw new InvocationTargetException(e, Messages.getString("AnalyserDataProcessor.15") + analysisFile.getName()); //$NON-NLS-1$
-				}		
+				importAndSave(analysisFile, uid, pluginsToUse, null,progressMonitor);
 			}
 		};
-		
+				
 		IRunnableWithProgress runnableOpen = new IRunnableWithProgress() {
 
 			public void run(IProgressMonitor arg0)
 					throws InvocationTargetException, InterruptedException {
 				// open the saved file
-				if (analysisFile.exists() && AnalyserDataProcessor.getInstance().getState() == STATE_IMPORTING ) {
-						// open the file itself
-					
-					// need to open in UI context
-					Display.getDefault().syncExec(new Runnable() {
-
-						public void run() {
-							IEditorPart editor = null;
-							try {
-								editor = IDE.openEditor(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage() , analysisFile, true);
-							} catch (PartInitException e) {
-								try {
-									assertThrowITE(e, analysisFile.getName() + Messages.getString("AnalyserDataProcessor.24")); //$NON-NLS-1$
-								} catch (InvocationTargetException e1) {
-									//already set data structure proper, do nothing
-								}
-							}
-							if (AnalyserDataProcessor.getInstance().getState() == STATE_CANCELED) {
-								// close the editor file view
-								editor.getSite().getPage().closeEditor(editor, false);
-							} else if (AnalyserDataProcessor.getInstance().getState() != STATE_OK ) {
-								// close the editor file view
-								editor.getSite().getPage().closeEditor(editor, false);
-							}							
-						}
-					});
-				}
+				openFile(analysisFile);
 			}
 			
 		};
 		
+		
+		
 		try {
 			progressService.busyCursorWhile(runnableImportAndSave);
 		
@@ -506,13 +395,13 @@
 				public IStatus runInWorkspace(IProgressMonitor monitor)
 						throws CoreException {
 					try {
-						ProfileReader.getInstance().writeAnalysisFile(analysisFile.getLocation().toString(), monitor, uid);
+						ProfileReader.getInstance().writeAnalysisFile(analysisFile.getLocation().toString(), monitor, null, uid);
 					} catch (InvocationTargetException e) {
-						return new Status(IStatus.ERROR, "com.nokia.carbide.cpp.pi", Messages.getString("AnalyserDataProcessor.invocationTargetException"), e); //$NON-NLS-1$ //$NON-NLS-2$
+						return new Status(IStatus.ERROR, PiPlugin.PLUGIN_ID, Messages.getString("AnalyserDataProcessor.invocationTargetException"), e); //$NON-NLS-1$ //$NON-NLS-2$
 					} catch (InterruptedException e) {
-						return new Status(IStatus.CANCEL, "com.nokia.carbide.cpp.pi", Messages.getString("AnalyserDataProcessor.interruptedException"), e); //$NON-NLS-1$ //$NON-NLS-2$
+						return new Status(IStatus.CANCEL, PiPlugin.PLUGIN_ID, Messages.getString("AnalyserDataProcessor.interruptedException"), e); //$NON-NLS-1$ //$NON-NLS-2$
 					}
-					return new Status(IStatus.OK, "com.nokia.carbide.cpp.pi", Messages.getString("AnalyserDataProcessor.ok"), null); //$NON-NLS-1$ //$NON-NLS-2$
+					return new Status(IStatus.OK, PiPlugin.PLUGIN_ID, Messages.getString("AnalyserDataProcessor.ok"), null); //$NON-NLS-1$ //$NON-NLS-2$
 				}
 				
 			};
@@ -530,7 +419,7 @@
 
 				public void done(IJobChangeEvent event) {
 					if (saveNpi.getResult().getSeverity()  != IStatus.OK) {
-						HandleRunnableException (saveNpi.getResult().getException(), uid, analysisFile);
+						handleRunnableException (saveNpi.getResult().getException(), uid, analysisFile);
 					}
 				}
 
@@ -554,13 +443,187 @@
 			}
 			
 		} catch (InvocationTargetException e) {
-			HandleRunnableException(e, uid, analysisFile);
+			handleRunnableException(e, uid, analysisFile);
 		} catch (InterruptedException e) {
-			HandleRunnableException(e, uid, analysisFile);
+			handleRunnableException(e, uid, analysisFile);
 		}							
 	}
 	
-	private void HandleRunnableException(Throwable throwable, final int uid, IFile analysisFile) {
+	public void importSave(final IFile analysisFile, final List<ITrace> pluginsToUse, String suffixTaskName, IProgressMonitor monitor) {
+		analyserDataProcessorState = STATE_IMPORTING;
+		setUp();
+		setProgressMonitor(monitor);		
+		final int uid = NpiInstanceRepository.getInstance().register(null);	
+		try{
+			importAndSave(analysisFile, uid, pluginsToUse, suffixTaskName, monitor);	
+			ProfileReader.getInstance().writeAnalysisFile(analysisFile.getLocation().toString(), monitor, suffixTaskName, uid);				
+			analyserDataProcessorState = STATE_OK;
+		}catch (Exception e) {
+			handleRunnableException(e, uid, analysisFile);
+			monitor.setCanceled(true);
+		}
+		
+	}
+	
+	private void importAndSave(final IFile analysisFile, final int uid, List<ITrace> pluginsToUse, String suffixTaskName,IProgressMonitor progressMonitor) throws InvocationTargetException, InterruptedException{
+		if(progressMonitor == null){
+			progressMonitor = new NullProgressMonitor();
+		}
+		setProgressMonitor(progressMonitor);
+		String taskName = Messages.getString("AnalyserDataProcessor.17") + analysisFile.getName();; //$NON-NLS-1$
+		if(suffixTaskName != null){
+			taskName += " "+suffixTaskName; //$NON-NLS-1$
+		}
+
+	    progressMonitor.beginTask(taskName, TOTAL_PROGRESS_COUNT);   //$NON-NLS-1$
+		progressMonitor.setTaskName(taskName);
+		// open a profile data file that should contain at least thread/address information
+
+		// import new .dat
+		assertThrowITE(SampleImporter.getInstance().validate(), Messages.getString("AnalyserDataProcessor.18"));	  //$NON-NLS-1$
+		
+		// invoke analysis-specific plugin instances
+		PluginInitialiser.invokePluginInstances(uid, "com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace"); //$NON-NLS-1$
+
+		StreamFileParser stp;
+		try {
+			stp = new StreamFileParser(new File(SampleImporter.getInstance().getDatFileName()));
+			Hashtable<Integer,String> traceFileNames = new Hashtable<Integer,String>();
+			ArrayList<File> tracesForCleanUp = new ArrayList<File>();
+
+			// loop through all the plugins associated with traces and note their trace IDs names
+			
+				
+			for (ITrace plugin : pluginsToUse) {
+				File tempFile;
+				int traceId = plugin.getTraceId();
+				if (traceId != -1)
+				{
+					try {
+						
+						if (traceId == 1) {// the SMP change; separate temp data files for each CPU
+							for (int i = 0; i < MAX_CPU; i++) {
+								int smpTraceId = traceId + i * 20;
+								tempFile = stp.getTempFileForTraceType(smpTraceId);
+								if (tempFile != null) {
+									tempFile.deleteOnExit();
+									traceFileNames.put(smpTraceId, tempFile.getAbsolutePath());
+									tracesForCleanUp.add(tempFile);
+								}
+							}
+						} else {
+							tempFile = stp.getTempFileForTraceType(traceId);
+							if (tempFile != null)
+							{
+								tempFile.deleteOnExit();
+								traceFileNames.put(traceId, tempFile.getAbsolutePath());
+								tracesForCleanUp.add(tempFile);
+							}									
+						}
+
+					} catch (IOException e) {
+						throw new InvocationTargetException(e, Messages.getString("AnalyserDataProcessor.25")); //$NON-NLS-1$
+					}
+				}
+			}
+			
+			// import a new analysis
+			importNewAnalysis(traceFileNames, uid, pluginsToUse);
+
+			// clean up temp file for each trace
+			for (File traceFile : tracesForCleanUp) {
+				traceFile.delete();
+			}
+		} catch (IOException e) {
+			throw new InvocationTargetException(e, Messages.getString("AnalyserDataProcessor.26") + SampleImporter.getInstance().getDatFileName()); //$NON-NLS-1$
+		}
+
+		if (progressMonitor.isCanceled()) {
+			throw new InterruptedException(Messages.getString("AnalyserDataProcessor.19"));   //$NON-NLS-1$
+		}
+
+		// give the .NPI file null contents
+		byte[] b = new byte[0];
+		try {
+			analysisFile.create(new ByteArrayInputStream(b), true, null);
+			// make sure we can open an input stream to the trace file
+			analysisFile.getContents();
+		} catch (CoreException e) {
+			throw new InvocationTargetException(e, Messages.getString("AnalyserDataProcessor.14") + analysisFile.getName()); //$NON-NLS-1$
+		}
+		
+		// extract additional info from importer
+		int numberOfTraces = 0;
+		Iterator<ParsedTraceData> enuTraces = TraceDataRepository.getInstance().getTraceCollectionIter(uid);
+		AnalysisInfoHandler handler = NpiInstanceRepository.getInstance().activeUidGetAnalysisInfoHandler();
+
+		// for all traces exist in .dat set up their additional info
+	    while (enuTraces.hasNext()) {
+	    	Object object = enuTraces.next();
+
+	    	numberOfTraces++;
+	    	
+	    	if (object instanceof ParsedTraceData) {
+	    		ParsedTraceData parsedTraceData = (ParsedTraceData) object;
+	    		if (parsedTraceData.traceData != null) {
+		    		Class traceClass = parsedTraceData.traceData.getClass();
+
+					// this code is clumsy because the plugin, not the trace, has the trace ID info
+		    		Enumeration<AbstractPiPlugin> enuPlugins = PluginInitialiser.getPluginInstances(uid, "com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace"); //$NON-NLS-1$
+					while (enuPlugins.hasMoreElements())
+					{
+						ITrace plugin = (ITrace)enuPlugins.nextElement();
+						// only do when trace exist in .data
+						if (traceClass == plugin.getTraceClass()) {
+					    	if (plugin instanceof IProvideTraceAdditionalInfo) {
+								((IProvideTraceAdditionalInfo)plugin).setupInfoHandler(handler);						    		
+					    	}
+						}
+					}			
+	    		}
+	    	}
+	    }
+		
+		// refresh so project know the update done by Java(non-Eclipse API)
+		try {
+			analysisFile.refreshLocal(0, null);
+		} catch (CoreException e) {
+			throw new InvocationTargetException(e, Messages.getString("AnalyserDataProcessor.15") + analysisFile.getName()); //$NON-NLS-1$
+		}		
+	}	
+	
+	private void openFile(final IFile analysisFile) {
+		// open the saved file
+		if (analysisFile.exists() && AnalyserDataProcessor.getInstance().getState() == STATE_IMPORTING ) {
+				// open the file itself
+			
+			// need to open in UI context
+			Display.getDefault().syncExec(new Runnable() {
+
+				public void run() {
+					IEditorPart editor = null;
+					try {
+						editor = IDE.openEditor(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage() , analysisFile, true);
+					} catch (PartInitException e) {
+						try {
+							assertThrowITE(e, analysisFile.getName() + Messages.getString("AnalyserDataProcessor.24")); //$NON-NLS-1$
+						} catch (InvocationTargetException e1) {
+							//already set data structure proper, do nothing
+						}
+					}
+					if (AnalyserDataProcessor.getInstance().getState() == STATE_CANCELED) {
+						// close the editor file view
+						editor.getSite().getPage().closeEditor(editor, false);
+					} else if (AnalyserDataProcessor.getInstance().getState() != STATE_OK ) {
+						// close the editor file view
+						editor.getSite().getPage().closeEditor(editor, false);
+					}							
+				}
+			});
+		}
+	}
+	
+	private void handleRunnableException(Throwable throwable, final int uid, IFile analysisFile) {
 		NpiInstanceRepository.getInstance().unregister(uid);
 		if (throwable instanceof InvocationTargetException) {
 			String error = Messages.getString("AnalyserDataProcessor.20"); //$NON-NLS-1$
@@ -634,7 +697,7 @@
 
 	// save profiling data to NPI file
 	private void saveAnalysisInternal(final String filename, final int uid) throws InvocationTargetException, InterruptedException {
-		ProfileReader.getInstance().writeAnalysisFile(filename, getProgressMonitor(), uid);
+		ProfileReader.getInstance().writeAnalysisFile(filename, getProgressMonitor(), null,uid);
 	}
 	
 	private void processVisualizableItem(ITrace plugin)
@@ -672,15 +735,14 @@
 		for (int i = 0; i < visualizable.getGraphCount(); i++)
 		{
 			GraphDrawRequest gdr   = visualizable.getDrawRequest(i);
-			GenericTraceGraph gtg  = visualizable.getTraceGraph(i);
-			String title           = visualizable.getGraphTitle(i);
+			IGenericTraceGraph gtg  = visualizable.getTraceGraph(i);
 			int	pageNumber         = visualizable.getPageNumber(i);
 			
 			ProfileVisualiser page = NpiInstanceRepository.getInstance().getProfilePage(uid, pageNumber);
 
 			if (gtg != null)
 			{
-				page.getTopComposite().addGraphComponent(gtg, title, visualizable.getClass(), gdr);
+				page.getTopComposite().addGraphComponent(gtg, visualizable.getClass(), gdr);
 			}
 
 			Integer lastSample = visualizable.getLastSample(i);
@@ -742,7 +804,7 @@
 						        	final PICompositePanel visibleComposite = page.getTopComposite();
 						        	visibleComposite.performZoomToGraph(visibleComposite, parent.getBounds().width);
 						        	
-						        	//TODO uncomment when performance issues relating to gfc are solved
+						        	//TODO uncomment when performance issues relating to fcc are solved
 						        	//Select whole graph
 						        	//visibleComposite.selectWholeGraph();
 								}
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/analyser/NpiInstanceRepository.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/analyser/NpiInstanceRepository.java	Wed Apr 21 15:14:16 2010 +0300
@@ -39,6 +39,11 @@
 public class NpiInstanceRepository {
 	
 	static public final int DISPOSED_UID = -1;
+	/** Constant for maximum number of CPUs in an SMP system */
+	public static final int MAX_CPU_COUNT = 4;
+
+	/** Constant for persisting the state of Show Combined CPU View in the Address plugin */
+	public static final String PERSISTED_SHOW_COMBINED_CPU_VIEW = "com.nokia.carbide.cpp.pi.address.showCombinedCPUView";//$NON-NLS-1$
 	
 	private class UidObject {
 		// this is just for generating UID
@@ -72,7 +77,7 @@
 	
 	public int register(Composite composite) {
 		UidObject uidObject = new UidObject();
-		Integer uid = new Integer(uidObject.hashCode());
+		Integer uid = Integer.valueOf(uidObject.hashCode());
 		uidObjectMap.put(uid, uidObject);
 		HashMap<String,GenericTrace> traceCollection = new HashMap<String,GenericTrace>();
 		traceCollectionMap.put(uid, traceCollection);
@@ -92,20 +97,28 @@
 	}
 	
 	public void unregister(int instanceUid) {
-		Integer uidInteger = new Integer(instanceUid);
+		Integer uidInteger = Integer.valueOf(instanceUid);
 		uidObjectMap.remove(uidInteger);
 		HashMap<String,GenericTrace> traceCollection = traceCollectionMap.get(uidInteger);
-		traceCollection.clear();
-		traceCollectionMap.remove(uidInteger);
+		if (traceCollection != null){
+			traceCollection.clear();
+			traceCollectionMap.remove(uidInteger);			
+		}
 		HashMap<String,Object> persistCollection =  persistCollectionMap.get(uidInteger);
-		persistCollection.clear();
-		persistCollectionMap.remove(uidInteger);
+		if (persistCollection != null){
+			persistCollection.clear();
+			persistCollectionMap.remove(uidInteger);			
+		}
 		ArrayList<AbstractPiPlugin> pluginList =  pluginListMap.get(uidInteger);
-		pluginList.clear();
-		pluginListMap.remove(uidInteger);
+		if (pluginList != null){
+			pluginList.clear();
+			pluginListMap.remove(uidInteger);			
+		}
 		ArrayList<ProfileVisualiser> profilePages = profilePagesMap.get(uidInteger);
-		profilePages.clear();
-		profilePagesMap.remove(uidInteger);
+		if (profilePages != null){
+			profilePages.clear();
+			profilePagesMap.remove(uidInteger);			
+		}
 		parentCompositeMap.remove(uidInteger);
 		analysisInfoHandlerMap.remove(uidInteger);
 		TraceDataRepository.getInstance().removeTraces(instanceUid);
@@ -260,17 +273,16 @@
 		if (key.equals("com.nokia.carbide.cpp.pi.address.thresholdCountThread") || //$NON-NLS-1$
 				key.equals("com.nokia.carbide.cpp.pi.address.thresholdCountBinary") || //$NON-NLS-1$
 				key.equals("com.nokia.carbide.cpp.pi.address.thresholdCountFunction") ) { //$NON-NLS-1$
-			return new Integer(-1);
-		}
-		if (key.equals("com.nokia.carbide.cpp.pi.address.thresholdLoadThread") || //$NON-NLS-1$
+			return Integer.valueOf(-1);
+		} else if (key.equals("com.nokia.carbide.cpp.pi.address.thresholdLoadThread") || //$NON-NLS-1$
 				key.equals("com.nokia.carbide.cpp.pi.address.thresholdLoadBinary")) { //$NON-NLS-1$
-			return new Double(0.001);
-		}
-		if (key.equals("com.nokia.carbide.cpp.pi.address.thresholdLoadFunction")) { //$NON-NLS-1$
-			return new Double(0.0001);
-		}
-		if (key.equals("com.nokia.carbide.cpp.pi.address.useOnlyThreadThresholds")) {	//$NON-NLS-1$
-			return new Boolean(false);
+			return Double.valueOf(0.001);
+		} else if (key.equals("com.nokia.carbide.cpp.pi.address.thresholdLoadFunction")) { //$NON-NLS-1$
+			return Double.valueOf(0.0001);
+		} else if (key.equals("com.nokia.carbide.cpp.pi.address.useOnlyThreadThresholds")) {	//$NON-NLS-1$
+			return Boolean.FALSE;
+		} else if (key.equals(PERSISTED_SHOW_COMBINED_CPU_VIEW)){
+			return Boolean.TRUE;
 		}
 		return null;
 	}
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/analyser/ProfileReader.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/analyser/ProfileReader.java	Wed Apr 21 15:14:16 2010 +0300
@@ -100,14 +100,17 @@
 	{
 		//singleton
 	}
+	public boolean readTraceFile(ITrace plugin, File[] traceFiles, AnalyserDataProcessor dataInstance, int instanceUID){
 
-	// read a plugin's information from a profile data file
-	public boolean readTraceFile(ITrace plugin, File traceFile, AnalyserDataProcessor dataInstance, int instanceUID)
-	{
 		// prepare the trace repository
 		try 
 		{
-			ParsedTraceData parsedTraceData = plugin.parseTraceFile(traceFile);
+			ParsedTraceData parsedTraceData = null;
+			if (traceFiles.length == 1){
+				parsedTraceData = plugin.parseTraceFile(traceFiles[0]);
+			} else {
+				parsedTraceData = plugin.parseTraceFiles(traceFiles);
+			}
 			
 			if (parsedTraceData != null) 
 			{
@@ -135,6 +138,12 @@
 			return false;
 		}
 		return true;
+	
+	}
+
+	// read a plugin's information from a profile data file
+	public boolean readTraceFile(ITrace plugin, File traceFile, AnalyserDataProcessor dataInstance, int instanceUID){
+		return readTraceFile(plugin, new File[]{traceFile}, dataInstance, instanceUID);
 	}
 	
 	public void loadAnalysisFile(String filePath, String displayName, IProgressMonitor progressMonitor, int instanceUID) throws IOException, InterruptedException
@@ -686,7 +695,7 @@
 		}
 	}
 
-	void writeAnalysisFile(String fileName, IProgressMonitor monitor, int instanceUID) throws InvocationTargetException, InterruptedException {
+	void writeAnalysisFile(String fileName, IProgressMonitor monitor, String suffixTaskName, int instanceUID) throws InvocationTargetException, InterruptedException {
 		final int workUnitsForSave = AnalyserDataProcessor.TOTAL_PROGRESS_COUNT * 20 / 100;
 		FileOutputStream fos = null;
 		GZIPOutputStream gzo = null;
@@ -702,8 +711,12 @@
 		    fos = new FileOutputStream(f);
 		    gzo = new GZIPOutputStream(fos);
 		    oos = new ObjectOutputStream(gzo);
-
-		    monitor.setTaskName(Messages.getString("ProfileReader.15") + f.getName());  //$NON-NLS-1$
+		    
+			String taskName = Messages.getString("ProfileReader.15")+ f.getName(); //$NON-NLS-1$
+			if(suffixTaskName != null){
+				taskName += " "+suffixTaskName; //$NON-NLS-1$
+			}
+		    monitor.setTaskName(taskName );  //$NON-NLS-1$
 		    monitor.worked(workUnitsForSave * 1 / 100);
 			int workUnitsLeft = workUnitsForSave;
 			monitor.worked(workUnitsForSave * 1 / 100); // kick it start to please user
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/analyser/ProfileVisualiser.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/analyser/ProfileVisualiser.java	Wed Apr 21 15:14:16 2010 +0300
@@ -22,6 +22,8 @@
 import java.io.IOException;
 import java.text.DecimalFormat;
 
+import org.eclipse.jface.dialogs.IPageChangedListener;
+import org.eclipse.jface.dialogs.PageChangedEvent;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.SashForm;
 import org.eclipse.swt.events.SelectionAdapter;
@@ -31,8 +33,10 @@
 import org.eclipse.swt.layout.FormLayout;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.Sash;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IEditorActionBarContributor;
+import org.eclipse.ui.part.EditorActionBarContributor;
 
 import com.nokia.carbide.cpp.internal.pi.utils.PIUtilities;
 import com.nokia.carbide.cpp.internal.pi.visual.PICompositePanel;
@@ -52,17 +56,10 @@
 	// page for this visualiser
 	private Composite page;
 	
-	// title
-	private Label title;
-	
-	// secondary title
-	private Label title2;
-	
-	// current time selection string
-	private Label timeInterval;
-	private static final String noInterval = Messages.getString("ProfileVisualiser.noInterval"); //$NON-NLS-1$
+	/** String constant for empty time interval */
+	private static final String NO_INTERVAL = Messages.getString("ProfileVisualiser.noInterval"); //$NON-NLS-1$
 
-	public static final DecimalFormat timeFormat = new DecimalFormat(Messages.getString("ProfileVisualiser.decimalFormat")); //$NON-NLS-1$
+	public static final DecimalFormat TIME_FORMAT = new DecimalFormat(Messages.getString("ProfileVisualiser.decimalFormat")); //$NON-NLS-1$
 
 	// composite at the top of the page
 	private PICompositePanel topComposite;
@@ -86,7 +83,6 @@
 		this.thisVisualiser = this;
 		this.pageName = pageName;
 		this.page = new Composite(parent, SWT.NONE);
-
 		initialize(topology, page);
 	}
 
@@ -103,25 +99,13 @@
 		}
 		
 		this.parserRepository = new ParserRepository();
-		
-		
-		// add the title bar at the top
-		Composite titleBar = addTitleBar(newPage);
-		
+				
 		// all graphs and tables go into a composite below the title
 		Composite holder = new Composite(newPage, SWT.NONE);
 		
-    	// FormData for the title bar
+		// FormData for the overall holder composite
 		formData = new FormData();
 		formData.top    = new FormAttachment(0);
-		formData.left   = new FormAttachment(0);
-		formData.right  = new FormAttachment(100);
-		titleBar.setLayoutData(formData);
-		titleBar.setLayout(new FormLayout());
-		
-		// FormData for the overall holder composite
-		formData = new FormData();
-		formData.top    = new FormAttachment(titleBar);
 		formData.bottom = new FormAttachment(100);
 		formData.left   = new FormAttachment(0);
 		formData.right  = new FormAttachment(100);
@@ -131,45 +115,39 @@
 		newPage.setLayout(new FormLayout());
 		
 		setGraphsAndTablesHolder(holder, topology, formData);
+		
+		//add a listener to editor tab changes, so the action buttons 
+		//on the graphs get updated correctly
+		PIPageEditor.currentPageEditor().addPageChangedListener(new IPageChangedListener(){
+
+			/* (non-Javadoc)
+			 * @see org.eclipse.jface.dialogs.IPageChangedListener#pageChanged(org.eclipse.jface.dialogs.PageChangedEvent)
+			 */
+			public void pageChanged(PageChangedEvent event) {
+				if (event.getSelectedPage() == page){ //compare on reference
+					//if this ProfileVisualiser is the page being activated, 
+					//make sure the state of all action buttons is updated 
+					ProfileVisualiser.this.initialiseGraphs();					
+				}
+				
+			}
+			
+		});
 	}
 
-	private Composite addTitleBar(Composite newPage)
-	{
-		// titleBar (Composite)
-		//		title2 (Label)  title (Label) timeInterval (Label)
-
-		FormData formData;
-		Composite titleBar = new Composite(newPage, SWT.NONE);
-		
-		title2 = new Label(titleBar, SWT.LEFT);
-		title2.setBackground(newPage.getDisplay().getSystemColor(SWT.COLOR_YELLOW));
-		title2.setFont(PIPageEditor.helvetica_9);
-		
-		title = new Label(titleBar, SWT.CENTER);
-		title.setBackground(newPage.getDisplay().getSystemColor(SWT.COLOR_YELLOW));
-		title.setFont(PIPageEditor.helvetica_9);
+	/**
+	 * Updates the enabled state of all graph actions (min, max etc.)
+	 */
+	public void updateGraphActionState(){
+		this.topComposite.updateGraphActionState();					
+	}
 
-		timeInterval = new Label(titleBar, SWT.RIGHT);
-		timeInterval.setBackground(newPage.getDisplay().getSystemColor(SWT.COLOR_YELLOW));
-		timeInterval.setText(noInterval);
-		timeInterval.setFont(PIPageEditor.helvetica_9);
-
-		formData = new FormData();
-		formData.left   = new FormAttachment(0);
-		formData.right  = new FormAttachment(30);
-		title2.setLayoutData(formData);
-		
-		formData = new FormData();
-		formData.left   = new FormAttachment(30);
-		formData.right  = new FormAttachment(70);
-		title.setLayoutData(formData);
-		
-		formData = new FormData();
-		formData.left   = new FormAttachment(70);
-		formData.right  = new FormAttachment(100);
-		timeInterval.setLayoutData(formData);
-
-		return titleBar;
+	/**
+	 * Updates the enabled state of all graph actions (min, max etc.)
+	 */
+	public void initialiseGraphs(){
+		this.topComposite.initialiseGraphs();
+		this.topComposite.updateGraphActionState();					
 	}
 
 	private void setGraphsAndTablesHolder(Composite holder, int topology, FormData formData)
@@ -239,6 +217,17 @@
 		Display.getDefault().syncExec(new Runnable() {
 			public void run() {
 				PIPageEditor.currentPageEditor().setLocalTime(start, end);
+				
+		        final IEditorActionBarContributor contributor = PIPageEditor.currentPageEditor().getEditorSite().getActionBarContributor();
+
+		        if ((contributor instanceof EditorActionBarContributor)) {
+			        final IActionBars actionBars = ((EditorActionBarContributor) contributor).getActionBars();
+
+			        if (actionBars != null) {
+			        	actionBars.getStatusLineManager().setMessage("Hello");
+			        }
+		        }
+
 			}
 		});
 	}
@@ -364,11 +353,11 @@
 
             if (startTime == -1 || endTime == -1)
             {
-                this.timeInterval.setText(noInterval);
+                updateStatusBarTimeInterval(-1, -1);
             }
             else
             {
-            	this.timeInterval.setText(ProfileVisualiser.getTimeInterval(startTime, endTime));
+            	updateStatusBarTimeInterval(startTime, endTime);
             }
             // now the data are updated, let the zoomCommand of the panel 
             // handle the selection centering and refresh
@@ -447,26 +436,43 @@
 		return this.topComposite;
 	}
 	
-	public Label getTitle()
+	public static String getTimeInterval(double startTime, double endTime)
 	{
-		return this.title;
-	}
-	
-	public Label getTitle2()
-	{
-		return this.title2;
+		return Messages.getString("ProfileVisualiser.interval1") + TIME_FORMAT.format(startTime) //$NON-NLS-1$
+		     + Messages.getString("ProfileVisualiser.interval2") + TIME_FORMAT.format(endTime) //$NON-NLS-1$
+		     + Messages.getString("ProfileVisualiser.interval3") + TIME_FORMAT.format(endTime - startTime) //$NON-NLS-1$
+		     + Messages.getString("ProfileVisualiser.interval4"); //$NON-NLS-1$
 	}
 	
-	public Label getTimeString()
-	{
-		return this.timeInterval;
+	/**
+	 * Updates the workbench's status bar with the given time frame
+	 * @param startTime the start time to use
+	 * @param endTime the end time to use
+	 */
+	public void updateStatusBarTimeInterval(final double startTime,
+			final double endTime) {
+
+		Display.getDefault().syncExec(new Runnable() {
+			public void run() {
+
+				final IEditorActionBarContributor contributor = PIPageEditor
+						.currentPageEditor().getEditorSite()
+						.getActionBarContributor();
+
+				if ((contributor instanceof EditorActionBarContributor)) {
+					final IActionBars actionBars = ((EditorActionBarContributor) contributor)
+							.getActionBars();
+
+					if (actionBars != null) {
+						actionBars.getStatusLineManager()
+								.setMessage(
+										(startTime == -1 || endTime == -1) ? NO_INTERVAL
+												: getTimeInterval(startTime, endTime));
+					}
+				}
+
+			}
+		});
 	}
 	
-	public static String getTimeInterval(double startTime, double endTime)
-	{
-		return Messages.getString("ProfileVisualiser.interval1") + timeFormat.format(startTime) //$NON-NLS-1$
-		     + Messages.getString("ProfileVisualiser.interval2") + timeFormat.format(endTime) //$NON-NLS-1$
-		     + Messages.getString("ProfileVisualiser.interval3") + timeFormat.format(endTime - startTime) //$NON-NLS-1$
-		     + Messages.getString("ProfileVisualiser.interval4"); //$NON-NLS-1$
-	}
 }
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/analyser/StreamFileParser.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/analyser/StreamFileParser.java	Wed Apr 21 15:14:16 2010 +0300
@@ -52,7 +52,7 @@
 	
 	public byte[] getDataForTraceType(int traceType)
 	{
-		Integer type = new Integer(traceType);
+		Integer type = Integer.valueOf(traceType);
 		if (dataBlocks.containsKey(type))
 		{
 			ByteArrayOutputStream baos = 
@@ -70,7 +70,7 @@
 		byte[] data = getDataForTraceType(traceType);
 		if (data == null) return null;
 		File f = File.createTempFile("type_" + traceType + "_trace_file",".dat");    //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-		//File f = File.createTempFile(getTypeString(new Integer(traceType)),".dat");
+		//File f = File.createTempFile(getTypeString(Integer.valueOf(traceType)),".dat");
 		f.deleteOnExit();
 		
 		FileOutputStream fos = new FileOutputStream(f);
@@ -81,7 +81,7 @@
 		return f;
 	}
 		
-	private void readLoop()
+	private void readLoop() throws IOException
 	{
 		while(setLengthAndMode() == true)
 		{
@@ -118,7 +118,7 @@
 		else return "undefined_type";
 	}*/
 	
-	public boolean setLengthAndMode()
+	public boolean setLengthAndMode() throws IOException
 	{
 		if (readOffset+4 >= streamData.length)
 		{
@@ -134,6 +134,10 @@
 			//System.out.println(" b1:"+b1+" b2:"+b2+" b3:"+b3);
 			currentLength = (int)(b1 | b2<<8 | b3 <<16);
 			
+			if (readOffset+currentLength >= streamData.length){
+				throw new IOException(Messages.getString("StreamFileParser.0")); //$NON-NLS-1$
+			}
+			
 			currentType = streamData[readOffset++];
 			//System.out.println("Length "+currentLength+" mode "+currentType);
 						
@@ -143,7 +147,7 @@
 	
 	private void copyDataBlock()
 	{
-		Integer typeInt = new Integer(currentType);
+		Integer typeInt = Integer.valueOf(currentType);
 		ByteArrayOutputStream baos = null;
 		
 		if (dataBlocks.containsKey(typeInt))
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/analyser/messages.properties	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/analyser/messages.properties	Wed Apr 21 15:14:16 2010 +0300
@@ -27,6 +27,7 @@
 AnalyserDataProcessor.invocationTargetException=InvocationTargetException
 AnalyserDataProcessor.ok=OK
 AnalyserDataProcessor.savingImportedFile=Saving Imported File
+StreamFileParser.0=Invalid profiler data file
 StreamFileParser.fileNotFound=File not found
 ProfileReader.0=Loading file 
 ProfileReader.1=\nCheck that related Performance Investigator plugin is available\n
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/manager/PluginInitialiser.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/manager/PluginInitialiser.java	Wed Apr 21 15:14:16 2010 +0300
@@ -115,7 +115,7 @@
 		{
 			// make sure the cast is valid
 			try {
-				tmp = pluginInstanceReferences.get(new Integer(id));
+				tmp = pluginInstanceReferences.get(Integer.valueOf(id));
 			} catch (ClassCastException e1) {
 				e1.printStackTrace();
 			}
@@ -131,7 +131,7 @@
 		if (pluginInstanceReferences == null)
 			return instances.elements();
 
-		Vector<AbstractPiPlugin> tmp = pluginInstanceReferences.get(new Integer(id));
+		Vector<AbstractPiPlugin> tmp = pluginInstanceReferences.get(Integer.valueOf(id));
 		if (tmp != null)
 		{
 			AbstractPiPlugin plugin = null;
@@ -243,7 +243,7 @@
 		if (id == 0) return; //not removing top level plugin instances
 		if (pluginInstanceReferences != null)
 		{
-			pluginInstanceReferences.remove(new Integer(id));
+			pluginInstanceReferences.remove(Integer.valueOf(id));
 		}
 	}
 	
@@ -265,7 +265,7 @@
 	{
 		if (pluginInstanceReferences == null)
 			pluginInstanceReferences = new Hashtable<Integer, Vector<AbstractPiPlugin>>();
-		Vector<AbstractPiPlugin> tmp = pluginInstanceReferences.get(new Integer(id));
+		Vector<AbstractPiPlugin> tmp = pluginInstanceReferences.get(Integer.valueOf(id));
 		if (tmp != null)
 		{
 			// do not allow duplicate plugins
@@ -276,7 +276,7 @@
 		{
 			Vector<AbstractPiPlugin> tmp2 = new Vector<AbstractPiPlugin>();
 			tmp2.add(plugin);
-			pluginInstanceReferences.put(new Integer(id), tmp2);
+			pluginInstanceReferences.put(Integer.valueOf(id), tmp2);
 		}
 	}
 }
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/manager/TraceTypePreviewer.java	Tue Apr 20 14:41:43 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-/*
- * 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: 
- *
- */
-
-/**
- * 
- */
-package com.nokia.carbide.cpp.internal.pi.manager;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-import com.nokia.carbide.cpp.internal.pi.analyser.StreamFileParser;
-import com.nokia.carbide.cpp.internal.pi.plugin.model.AbstractPiPlugin;
-import com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace;
-
-
-/**
- * 
- * Load a .dat file and preview all the traces available
- *
- */
-public class TraceTypePreviewer {
-	private HashMap<Integer, String> availableTraces = new HashMap<Integer, String>();
-	
-	public TraceTypePreviewer(File file) {
-		try {
-			StreamFileParser inputFile;
-			inputFile = new StreamFileParser(file);
-			Set<Integer> allTraceSet = inputFile.allTraceType();
-			// dispose it
-			inputFile = null;
-			
-			Enumeration<AbstractPiPlugin> e = PluginRegistry.getInstance().getRegistryEntries();
-			while(e.hasMoreElements()) {
-				AbstractPiPlugin plugin = e.nextElement();
-				if (plugin instanceof ITrace) {
-					ITrace tracePlugin = (ITrace) plugin;
-					if (allTraceSet.contains(tracePlugin.getTraceId())) {
-						availableTraces.put(tracePlugin.getTraceId(), tracePlugin.getTraceName());
-					}
-				}
-			}
-		} catch (IOException e) {
-			e.printStackTrace();
-		}	
-	}
-	
-	public Map<Integer, String> getAllAvailableTraces() {
-		return availableTraces;
-	}
-
-}
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/Binary.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/Binary.java	Wed Apr 21 15:14:16 2010 +0300
@@ -19,60 +19,136 @@
 
 import java.io.Serializable;
 
-public class Binary implements Serializable
+public class Binary implements IBinary, Serializable
 {
   private static final long serialVersionUID = 3278912646658026030L;
 	
-  public long startAddress;
-  public int length;
-  public String binaryName;
-  public long offsetToCodeStart = 0;
-  public String type;
+  protected long startAddress;
+  protected int length;
+  protected String binaryName;
+  protected long offsetToCodeStart = 0;
+  protected String type;
   
   public Binary(String binaryName)
   {
     this.binaryName = binaryName;
   }
   
-  public long findOverlapLentghWith(Binary other)
-  {
-	long cSt = other.startAddress;
-	long cEn = other.startAddress+other.length;
-	long bSt = this.startAddress;
-	long bEn = this.startAddress+this.length;
-	long overLap = 0;
+// un-used in code  
+//  public long findOverlapLentghWith(Binary other)
+//  {
+//	long cSt = other.startAddress;
+//	long cEn = other.startAddress+other.length;
+//	long bSt = this.startAddress;
+//	long bEn = this.startAddress+this.length;
+//	long overLap = 0;
+//	
+//	if (bSt >= cSt && bSt <= cEn)
+//	{
+//		// starts within the current bin
+//		if (bEn <= cEn)
+//		{
+//			// also ends within the current bin
+//			overLap = this.length;
+//		}
+//		else
+//		{
+//			// ends outside the current 
+//			// binary but starts within it
+//			overLap = cEn-bSt;
+//		}
+//		
+//	}
+//	else if (bEn >= cSt && bEn <= cEn)
+//	{
+//		// ends into the current bin
+//		// but starts before it
+//		overLap = bEn - cSt;
+//	}
+//	
+//	else if (bSt <= cSt && bEn >= cSt)
+//	{
+//		// starts before and ends after
+//		// the current bin
+//		overLap = other.length;
+//	}
+//	
+//	return overLap;
+//  }
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.model.IBinary#getStartAddress()
+	 */
+	public long getStartAddress() {
+		return startAddress;
+	}
 	
-	if (bSt >= cSt && bSt <= cEn)
-	{
-		// starts within the current bin
-		if (bEn <= cEn)
-		{
-			// also ends within the current bin
-			overLap = this.length;
-		}
-		else
-		{
-			// ends outside the current 
-			// binary but starts within it
-			overLap = cEn-bSt;
-		}
-		
-	}
-	else if (bEn >= cSt && bEn <= cEn)
-	{
-		// ends into the current bin
-		// but starts before it
-		overLap = bEn - cSt;
+	/**
+	 * Setter for the start address
+	 * @param startAddress the start address to set
+	 */
+	public void setStartAddress(long startAddress) {
+		this.startAddress = startAddress;
 	}
 	
-	else if (bSt <= cSt && bEn >= cSt)
-	{
-		// starts before and ends after
-		// the current bin
-		overLap = other.length;
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.model.IBinary#getLength()
+	 */
+	public int getLength() {
+		return length;
+	}
+	
+	/**
+	 * Setter for the length
+	 * @param length the length to set
+	 */
+	public void setLength(int length) {
+		this.length = length;
+	}
+	
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.model.IBinary#getBinaryName()
+	 */
+	public String getBinaryName() {
+		return binaryName;
 	}
 	
-	return overLap;
-  }
+	/**
+	 * Setter for the name of the binary
+	 * @param binaryName the binaryName to set
+	 */
+	public void setBinaryName(String binaryName) {
+		this.binaryName = binaryName;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.model.IBinary#getOffsetToCodeStart()
+	 */
+	public long getOffsetToCodeStart() {
+		return offsetToCodeStart;
+	}
+	
+	/**
+	 * Setter for the offset to code start
+	 * @param offsetToCodeStart the offsetToCodeStart to set
+	 */
+	public void setOffsetToCodeStart(long offsetToCodeStart) {
+		this.offsetToCodeStart = offsetToCodeStart;
+	}
+	
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.model.IBinary#getType()
+	 */
+	public String getType() {
+		return type;
+	}
+	
+	/**
+	 * Setter for the type
+	 * @param type the type to set
+	 */
+	public void setType(String type) {
+		this.type = type;
+	}
 
 }
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/CusSample.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/CusSample.java	Wed Apr 21 15:14:16 2010 +0300
@@ -38,7 +38,7 @@
 	
 	public String toString()
 	{
-		String sampleNum = new Long(sampleSynchTime).toString();
+		String sampleNum = Long.valueOf(sampleSynchTime).toString();
 		String valueString = new Double(value).toString();
 		return sampleNum+" "+name+" "+valueString+" "+color.toString(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
 	}
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/Function.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/Function.java	Wed Apr 21 15:14:16 2010 +0300
@@ -18,16 +18,16 @@
 package com.nokia.carbide.cpp.internal.pi.model;
 import java.io.Serializable;
 
-public class Function implements Serializable
+public class Function implements IFunction, Serializable
 {
   private static final long serialVersionUID = -3261268206319782647L;
 	
-  public Binary functionBinary;
-  public Long startAddress;
-  public long offsetFromBinaryStart;
-  public long length;
+  private IBinary functionBinary;
+  private Long startAddress;
+  private long offsetFromBinaryStart;
+  private long length;
   
-  public String functionName;
+  private String functionName;
 
   public Function(String functionName, Long functionStart, String functionBinary)
   {
@@ -35,10 +35,77 @@
     this.startAddress = functionStart;
     this.functionBinary = new Binary(functionBinary);
   }
-  
-  public String toString()
-  {
-  	return this.functionName+" @"+Long.toHexString(this.startAddress.intValue()); //$NON-NLS-1$
-  }
+	  
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.model.IFunction#getFunctionBinary()
+	 */
+	public IBinary getFunctionBinary() {
+		return functionBinary;
+	}
+	
+	/**
+	 * Setter for the binary this function is in  
+	 * @param functionBinary the functionBinary to set
+	 */
+	public void setFunctionBinary(Binary functionBinary) {
+		this.functionBinary = functionBinary;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.model.IFunction#getStartAddress()
+	 */
+	public Long getStartAddress() {
+		return startAddress;
+	}
+
+	/**
+	 * Setter for start address
+	 * @param startAddress the start address to set
+	 */
+	public void setStartAddress(Long startAddress) {
+		this.startAddress = startAddress;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.model.IFunction#getOffsetFromBinaryStart()
+	 */
+	public long getOffsetFromBinaryStart() {
+		return offsetFromBinaryStart;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.model.IFunction#getLength()
+	 */
+	public long getLength() {
+		return length;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.model.IFunction#getFunctionName()
+	 */
+	public String getFunctionName() {
+		return functionName;
+	}
+
+	/** Setter for offset from binary start
+	 * @param offsetFromBinaryStart the offset to set
+	 */
+	public void setOffsetFromBinaryStart(long offsetFromBinaryStart) {
+		this.offsetFromBinaryStart = offsetFromBinaryStart;
+	}
+
+	/**
+	 * Setter for the length
+	 * @param length the length to set
+	 */
+	public void setLength(long length) {
+		this.length = length;
+	}
+
+	@Override
+	public String toString() {
+		return this.functionName
+				+ " @" + Long.toHexString(this.startAddress.intValue()); //$NON-NLS-1$
+	}
 
 }
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/FunctionResolver.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/FunctionResolver.java	Wed Apr 21 15:14:16 2010 +0300
@@ -20,13 +20,19 @@
 public interface FunctionResolver 
 {
 	// find the function corresponding to an address
-	public Function findFunctionForAddress(long address);
+	public IFunction findFunctionForAddress(long address);
+	
+	// find the function corresponding to an address and a sample synch time
+	public IFunction findFunctionForAddress(long address, long sampleSynchTime);
 
 	// find the function name corresponding to an address
 	public String findFunctionNameForAddress(long address);
 	
 	// find the binary corresponding to an address
-	public Binary findBinaryForAddress(long address);
+	public IBinary findBinaryForAddress(long address);
+	
+	// find the binary corresponding to an address and a sample synch time
+	public IBinary findBinaryForAddress(long address, long sampleSynchTime);
 
 	// find the binary name corresponding to an address
 	public String findBinaryNameForAddress(long address);
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/GenericSampledTrace.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/GenericSampledTrace.java	Wed Apr 21 15:14:16 2010 +0300
@@ -22,21 +22,44 @@
 
 public abstract class GenericSampledTrace extends GenericTrace
 {
-	private static final long serialVersionUID = -5030416972125713453L;
+	private static final long serialVersionUID = 5248402326692863890L;
+	private long lastSampleTime;
 	
-	public Vector samples;
+	public Vector<GenericSample> samples;
 	
 	public GenericSampledTrace()
 	{
-	  this.samples = new Vector();
+	  this.samples = new Vector<GenericSample>();
 	}
 	
 	public void addSample(GenericSample sample)
 	{
 	  this.samples.add(sample);
+	  if (sample.sampleSynchTime > lastSampleTime){
+		  lastSampleTime = sample.sampleSynchTime;
+	  }
 	}
 	
-	public Enumeration getSamples()
+	/**
+	 * Returns the highest sampleSyncTime found in the set of samples.
+	 * 
+	 * @return last sample time
+	 */
+	public long getLastSampleTime(){
+		if (lastSampleTime == 0 && samples.size()>0){
+			//someone has added samples without going through the addSample() API in this class
+			//really, this.samples should be private
+			//let's try to recalculate lastSampleTime
+			for (GenericSample s : samples) {
+				  if (s.sampleSynchTime > lastSampleTime){
+					  lastSampleTime = s.sampleSynchTime;
+				  }
+			}
+		}
+		return lastSampleTime;
+	}
+	
+	public Enumeration<GenericSample> getSamples()
 	{
 	  return samples.elements();
 	}
@@ -48,7 +71,7 @@
 	
 	public Vector<GenericSample> getSamplesInsideTimePeriod(long start, long end)
 	{
-		Enumeration sEnum = samples.elements();
+		Enumeration<GenericSample> sEnum = samples.elements();
 		Vector<GenericSample> okSamples = new Vector<GenericSample>();
 		
 		while(sEnum.hasMoreElements())
@@ -195,18 +218,20 @@
 			return 0;
 	}
 	
+	/**
+	 * Returns the highest sample time in the trace. Note, on SMP systems,
+	 * this may not be the time of the last sample.
+	 * @return
+	 */
 	public int getLastSampleNumber()
 	{
-		if (this.samples.size() > 0)
-			return (int)((GenericSample)this.samples.lastElement()).sampleSynchTime;
-		else
-			return 0;
+		return (int)getLastSampleTime();
 	}
 	
 	public String toString()
 	{
-		Enumeration sEnum = this.getSamples();
-	  	Vector strings = new Vector();
+		Enumeration<GenericSample> sEnum = this.getSamples();
+	  	Vector<String> strings = new Vector<String>();
 	  	int totalLength = 0;
 	  	while(sEnum.hasMoreElements())
 	  	{	
@@ -218,11 +243,11 @@
 	  	
 	  	System.out.println(Messages.getString("GenericSampledTrace.totalLength") + totalLength); //$NON-NLS-1$
 	  	byte[] bytes = new byte[totalLength];
-	  	sEnum = strings.elements();
+	  	Enumeration<String> sEnumString = strings.elements();
 	  	int index = 0;
-	  	while(sEnum.hasMoreElements())
+	  	while(sEnumString.hasMoreElements())
 	  	{
-	  		String s = (String)sEnum.nextElement();
+	  		String s = (String)sEnumString.nextElement();
 	  		byte[] sB = s.getBytes();
 	  		for (int i = index; i < index + sB.length; i++)
 	  		{
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/IBinary.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2010 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: 
+ *
+ */
+package com.nokia.carbide.cpp.internal.pi.model;
+
+/**
+ * This interface represents a Binary in Performance Investigator
+ */
+public interface IBinary {
+	/**
+	 * Getter for the start address
+	 * @return the start address
+	 */
+	public long getStartAddress();
+	
+	/**
+	 * Getter for the length
+	 * @return the length
+	 */
+	public int getLength();
+	
+	/**
+	 * Getter for the name of the binary
+	 * @return the binaryName
+	 */
+	public String getBinaryName();
+	
+	/**
+	 * Getter for the offset to code start
+	 * @return the offset to code start
+	 */
+	public long getOffsetToCodeStart();
+	
+	/**
+	 * Getter for the type
+	 * @return the type
+	 */
+	public String getType();
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/IFunction.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2010 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: 
+ *
+ */
+package com.nokia.carbide.cpp.internal.pi.model;
+
+/**
+ * This interface represents a function in Performance Investigator
+ *
+ */
+public interface IFunction {
+	
+	
+	/**
+	 * Getter for the function name
+	 * @return the function name
+	 */
+	public String getFunctionName();
+	
+	/**
+	 * Getter for the Binary that this function exists in
+	 * @return the Binary
+	 */
+	public IBinary getFunctionBinary();
+	
+	/**
+	 * Getter for the start address of this function
+	 * @return the start address
+	 */
+	public Long getStartAddress();
+	
+	/**
+	 * Getter for offset from binary start
+	 * @return the offset
+	 */
+	public long getOffsetFromBinaryStart();
+
+	/** 
+	 * Getter for the length
+	 * @return the length
+	 */
+	public long getLength();
+	
+}
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/ParsedTraceData.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/ParsedTraceData.java	Wed Apr 21 15:14:16 2010 +0300
@@ -17,8 +17,15 @@
 
 package com.nokia.carbide.cpp.internal.pi.model;
 
+
+
 public class ParsedTraceData 
 {
 	public GenericTrace traceData;
+	public TraceDataContainer staticData; // TODO this was added when implementing IRQ
 	public FunctionResolver[] functionResolvers;
+	
+	public ParsedTraceData(){
+		
+	}
 }
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/PiManager.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/PiManager.java	Wed Apr 21 15:14:16 2010 +0300
@@ -17,30 +17,12 @@
 
 package com.nokia.carbide.cpp.internal.pi.model;
 
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Iterator;
-
-import org.eclipse.ui.IMemento;
-import org.eclipse.ui.XMLMemento;
-
 import com.nokia.carbide.cpp.internal.pi.analyser.PIChangeEvent;
-import com.nokia.carbide.cpp.internal.pi.interfaces.IPiItem;
-import com.nokia.carbide.cpp.pi.PiPlugin;
 
 
 
 public class PiManager {
 	private static PiManager manager;
-	private Collection<IPiItem> favorites;
-	private ArrayList<PiManagerListener> listeners = new ArrayList<PiManagerListener>();
 	
 	private PiManager() {
 	}
@@ -57,197 +39,11 @@
 		PIChangeEvent.action("synchronise"); //$NON-NLS-1$
 	}
 
-	public IPiItem[] getFavorites() {
-		if (favorites == null)
-			loadFavorites();
-		return favorites.toArray(
-			new IPiItem[favorites.size()]);
-	}
 	
-	public IPiItem newFavoriteFor(Object obj) {
-		PiItemType[] types =
-			PiItemType.getTypes();
-		for (int i = 0; i < types.length; i++) {
-			IPiItem item = types[i].newFavorite(obj);
-			if (item != null)
-				return item;
-		}
-		return null;
-	}
-
-	public IPiItem[] newFavoritesFor(Iterator iter) {
-		if (iter == null)
-			return IPiItem.NONE;
-		Collection<IPiItem> items = new HashSet<IPiItem>(20);
-		while (iter.hasNext()) {
-			IPiItem item =
-				newFavoriteFor((Object) iter.next());
-			if (item != null)
-				items.add(item);
-		}
-		return (IPiItem[]) items.toArray(
-			new IPiItem[items.size()]);
-	}
-
-	public IPiItem[] newFavoritesFor(Object[] objects) {
-		if (objects == null)
-			return IPiItem.NONE;
-		return newFavoritesFor(
-			Arrays.asList(objects).iterator());
-	}
-	
-	public IPiItem existingFavoriteFor(Object obj) {
-		if (obj == null)
-			return null;
-		Iterator<IPiItem> iter = favorites.iterator();
-		while (iter.hasNext()) {
-			IPiItem item = iter.next();
-			if (item.isPIFor(obj))
-				return item;
-		}
-		return null;
-	}
-
-	public IPiItem[] existingFavoritesFor(Iterator iter)
-	{
-		ArrayList<IPiItem> result = new ArrayList<IPiItem>(10);
-		while (iter.hasNext()) {
-			IPiItem item =
-				existingFavoriteFor(iter.next());
-			if (item != null)
-				result.add(item);
-		}
-		return (IPiItem[]) result.toArray(
-			new IPiItem[result.size()]);
-	}
-	
-	public void addFavorites(IPiItem[] items) {
-		if (favorites == null)
-			loadFavorites();
-		if (favorites.addAll(Arrays.asList(items)))
-			fireFavoritesChanged(items, IPiItem.NONE);
-	}
-	
-	public void removeFavorites(IPiItem[] items) {
-		if (favorites == null)
-			loadFavorites();
-		if (favorites.removeAll(Arrays.asList(items)))
-			fireFavoritesChanged(IPiItem.NONE, items);
-	}
-
-   /////////// Loading and Saving Favorites /////////////////
 
-   private static final String TAG_FAVORITES = "Favorites"; //$NON-NLS-1$
-   private static final String TAG_FAVORITE = "Favorite"; //$NON-NLS-1$
-   private static final String TAG_TYPEID = "TypeId"; //$NON-NLS-1$
-   private static final String TAG_INFO = "Info"; //$NON-NLS-1$
-   
-   private void loadFavorites() {
-      favorites = new HashSet<IPiItem>(20);
-      FileReader reader = null;
-      try {
-         reader = new FileReader(getFavoritesFile());
-         loadFavorites(XMLMemento.createReadRoot(reader));
-      }
-      catch (FileNotFoundException e) {
-         // ignored... no favorites exist yet
-      }
-      catch (Exception e) {
-         // log the exception and move on
-//         PILog.logError(e);
-      }
-      finally {
-         try {
-            if (reader != null)
-               reader.close();
-         }
-         catch (IOException e) {
-//            PILog.logError(e);
-         }
-      }
-   }
-   
-   private void loadFavorites(XMLMemento memento) {
-      IMemento[] children =
-         memento.getChildren(TAG_FAVORITE);
-      for (int i = 0; i < children.length; i++) {
-         IPiItem item =
-            newFavoriteFor(
-               children[i].getString(TAG_TYPEID),
-               children[i].getString(TAG_INFO));
-         if (item != null)
-            favorites.add(item);
-      }
-   }
-   
-   public IPiItem newFavoriteFor(String typeId, String info) {
-      PiItemType[] types = PiItemType.getTypes();
-      for (int i = 0; i < types.length; i++)
-         if (types[i].getID().equals(typeId))
-            return types[i].loadFavorite(info);
-      return null;
-   }
-   
-   public void saveFavorites() {
-      if (favorites == null)
-         return;
-      XMLMemento memento =
-         XMLMemento.createWriteRoot(TAG_FAVORITES);
-      saveFavorites(memento);
-      FileWriter writer = null;
-      try {
-         writer = new FileWriter(getFavoritesFile());
-         memento.save(writer);
-      }
-      catch (IOException e) {
- //        PILog.logError(e);
-      }
-      finally {
-         try {
-            if (writer != null)
-               writer.close();
-         }
-         catch (IOException e) {
-//            PILog.logError(e);
-         }
-      }
-   }
-   
-   private void saveFavorites(XMLMemento memento) {
-      Iterator iter = favorites.iterator();
-      while (iter.hasNext()) {
-         IPiItem item = (IPiItem) iter.next();
-         IMemento child = memento.createChild(TAG_FAVORITE);
-         child.putString(TAG_TYPEID, item.getType().getID());
-         child.putString(TAG_INFO, item.getInfo());
-      }
-   }
-   
-   private File getFavoritesFile() {
-      return PiPlugin
-         .getDefault()
-         .getStateLocation()
-         .append(Messages.getString("PiManager.favoritesXmlFile")) //$NON-NLS-1$
-         .toFile();
-	}
 	
-   ///////////// FavoriteManagerListener methods ///////////////////////
 
-	public void addFavoritesManagerListener(PiManagerListener listener) {
-		if (!listeners.contains(listener))
-			listeners.add(listener);
-	}
 	
-	public void removeFavoritesManagerListener(PiManagerListener listener) {
-		listeners.remove(listener);
-	}
-	
-	private void fireFavoritesChanged(IPiItem[] itemsAdded, IPiItem[] itemsRemoved) {
-		PiManagerEvent event = new PiManagerEvent(this, itemsAdded, itemsRemoved);
-		for (Iterator<PiManagerListener> iter = listeners.iterator(); iter.hasNext();)
-			iter.next().piChanged(event);
-	}
 
-   ///////////// IResourceChangeListener //////////////////////
    
 }
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/ProfiledBinary.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/ProfiledBinary.java	Wed Apr 21 15:14:16 2010 +0300
@@ -19,21 +19,22 @@
 
 public class ProfiledBinary extends ProfiledGeneric
 {
-    public ProfiledBinary()
-    {
-        super();
-   }
-   
-    public String toString(int graphIndex)
+    public ProfiledBinary(int cpuNumber, int graphCount)
     {
-    	if (this.isEnabled(graphIndex))
-    	{
-    		return "true  " + this.getAverageLoadValueString(graphIndex) + getNameString(); //$NON-NLS-1$
-	  	}
-		else
-		{
-	      	return "false " + this.getAverageLoadValueString(graphIndex) + getNameString(); //$NON-NLS-1$
-		}
-    }
+        super(cpuNumber, graphCount);
+   }
+ 
+    //unused?
+//    public String toString(int graphIndex)
+//    {
+//    	if (this.isEnabled(graphIndex))
+//    	{
+//    		return "true  " + this.getAverageLoadValueString(graphIndex) + getNameString(); //$NON-NLS-1$
+//	  	}
+//		else
+//		{
+//	      	return "false " + this.getAverageLoadValueString(graphIndex) + getNameString(); //$NON-NLS-1$
+//		}
+//    }
     
 }
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/ProfiledDspHook.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/ProfiledDspHook.java	Wed Apr 21 15:14:16 2010 +0300
@@ -56,7 +56,7 @@
                 (int)(Math.random()*255),
                 (int)(Math.random()*255));
         this.nameString = name;
-        this.timeStamp = new Long(ts);
+        this.timeStamp = Long.valueOf(ts);
     }
 
     public void setEventTimeString(Long ts)
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/ProfiledFunction.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/ProfiledFunction.java	Wed Apr 21 15:14:16 2010 +0300
@@ -24,12 +24,12 @@
 	long   functionAddress;
     String functionBinaryName;
 //	String functionBinaryPathName;
-    Vector threadIds;
+    Vector<Integer> threadIds;
     
-    public ProfiledFunction()
+    public ProfiledFunction(int cpuNumber, int graphCount)
     {
-        super();
-        this.threadIds = new Vector();
+        super(cpuNumber, graphCount);
+        this.threadIds = new Vector<Integer>();
         //setEnabled(false);
     }
     /**
@@ -80,7 +80,7 @@
     
     public void addThreadId(int id)
     {
-    	Integer integer = new Integer(id);
+    	Integer integer = Integer.valueOf(id);
     	if (!this.threadIds.contains(integer))
     	{
     		this.threadIds.add(integer);
@@ -89,10 +89,11 @@
     
     public boolean containsThreadId(int id)
     {
-    	return this.threadIds.contains(new Integer(id));
+    	return this.threadIds.contains(Integer.valueOf(id));
     }
 
-    public boolean equals(Object anObject)
+    @Override
+	public boolean equals(Object anObject)
     {
         if (anObject == null)
             return false;
@@ -105,20 +106,22 @@
             return false;
     }
     
-    public int hashCode()
+    @Override
+	public int hashCode()
     {
     	return this.getNameString().hashCode();
     }
-    
-    public String toString(int graphIndex)
-    {
-    	if (this.isEnabled(graphIndex))
-    	{
-    		return "true  " + this.getAverageLoadValueString(graphIndex) + getNameString(); //$NON-NLS-1$
-	  	}
-		else
-		{
-	      	return "false " + this.getAverageLoadValueString(graphIndex) + getNameString(); //$NON-NLS-1$
-		}
-    }   
+
+    //unused?
+//    public String toString(int graphIndex)
+//    {
+//    	if (this.isEnabled(graphIndex))
+//    	{
+//    		return "true  " + this.getAverageLoadValueString(graphIndex) + getNameString(); //$NON-NLS-1$
+//	  	}
+//		else
+//		{
+//	      	return "false " + this.getAverageLoadValueString(graphIndex) + getNameString(); //$NON-NLS-1$
+//		}
+//    }   
 }
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/ProfiledGeneric.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/ProfiledGeneric.java	Wed Apr 21 15:14:16 2010 +0300
@@ -25,48 +25,131 @@
 
 import com.nokia.carbide.cpp.pi.util.ColorPalette;
 
+/**
+ * Generic class for a profiled element, such as a thread, a binary or a function
+ *
+ */
 public abstract class ProfiledGeneric
 {
+	/** number of graphs */
+	protected static final int GRAPH_COUNT = 3;
+	
+	/**
+	 * Unique ordinal for this profiled element, given on creation. The first created profiled element
+	 * of this kind has an index of zero, each following is incremented by one.
+	 */
     protected int index = -1;
+    /** Name of this profiled element */
     private String nameString;
+    /** Colour with which this profiled element is represented in any graph or legend view*/
     protected Color color;
-    protected int totalSampleCount;
+    /** overall sample count of this profiled element in the trace */
+	protected int totalSampleCount;
+	/** timestamp of the first sample for this profiled element */
     protected int firstSample = -1;
+	/** timestamp of the last sample for this profiled element */
     protected int lastSample = -1;
-    private int   recentSample = -1;
-    private int   recentSampleCount = 0;
-    private int   recentPercentage = -1;
-    protected int[] activityList;
-    private int[] sampleList;
-    private int[][] cumulativeList = new int[3][];
-    
+
 	// since each instance may be used by table viewers for multiple graphs,
 	// keep per graph (for a maximum of 3 graphs):
     //	whether the thread/binary/function is currently enabled
     //	sample count in the selected graph area
     //	% load in the selected graph area
 	//  string version of graph percent load
-    protected boolean[] enableValue = {true, true, true};
-	protected int[]   graphSampleCount = { 0, 0, 0 };
-	protected float[] graphPercentLoad = { 0.0f, 0.0f, 0.0f };
-    private String[]  averageLoadValueString = { "", "", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-	
-    private PointList[] pointList  = {new PointList(), new PointList(), new PointList()};
-    protected int[] activityP = null;
+    
+    /**
+  	 * The cumulative list contains for each bucket the 
+  	 * cumulative sample percentage of the same bucket of all ProfiledGenerics
+  	 * so far processed (not including the values of the current ProfiledGeneric).
+  	 * 
+  	 * In other words it's containing the bottom or start value of this
+  	 * profiled element to draw on the graph (the graph drawn just underneath the 
+  	 * graph of this profiled element)
+  	 */
+    private float[][] cumulativeList;
+    /** checkbox enabled state of this profiled element for each of the graphs */
+    protected boolean[] enableValue;
+    /** current sample count of this profiled element for each of the graphs, changes with enabled state, selected time frame, master filtering */
+	protected int[]   graphSampleCount;
+    /** current sample percentage load of this profiled element for each of the graphs, changes with enabled state, selected time frame, master filtering */
+	protected float[] graphPercentLoad;
+    /** current sample average load of this profiled element for each of the graphs, changes with enabled state, selected time frame, master filtering */
+    private String[]  averageLoadValueString; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$	
+    /** PointList for each graphs polyline */
+    private PointList[] pointList;
+    
+    //  bucket values 
+    //
+    /** holds the sample count value for all buckets, calculated as one-off when trace is first processed */
+    private int[] activityN = null;
+    /** holds percentage value for all buckets, calculated as one-off when trace is first processed */
+    protected float[] activityP = null;
+    /** holds start timestamp of all buckets, calculated as one-off when trace is first processed */
     private int[] activityT = null;
+    /** the index of the bucket currently updated */
     protected int activityIndx = 0;
     
-    public ProfiledGeneric()
-    {
-      // default to light gray
-      this.color = ColorPalette.getColor(new RGB(192, 192, 192));
-     }
+    /** total number of CPUs in the system; 1 for non-SMP trace */
+	private int cpuCount;
+
+    //for SMP
+    protected boolean isSMP;
+	protected int[] totalSampleCountSMP;
+    
+    protected float[][] activityPSMP;
+    private int[][] activityNSMP;
     
+	/**
+	 * Constructor
+	 * @param cpuCount number of CPUs present in the trace
+	 * @param graphCount number of graphs to display
+	 */
+	public ProfiledGeneric(int cpuCount, int graphCount) {
+		if (graphCount < 0){
+			throw new IllegalArgumentException("graphCount must be greater than 0.");
+		}
+		// default to light gray
+		this.color = ColorPalette.getColor(new RGB(192, 192, 192));
+		this.cpuCount = cpuCount;
+		
+		// init variables for values per graph
+		cumulativeList = new float[graphCount][];
+		enableValue = new boolean[graphCount];
+		graphSampleCount = new int[graphCount];
+		graphPercentLoad = new float[graphCount];
+		averageLoadValueString = new String[graphCount];
+		pointList = new PointList[graphCount];
+		for (int graph = 0; graph < graphCount; graph++) {
+		    enableValue[graph] = true;
+			averageLoadValueString[graph] = ""; //$NON-NLS-1$
+			pointList[graph] = new PointList();
+		}
+
+		if (cpuCount > 1) { // SMP
+
+			isSMP = true;
+			totalSampleCountSMP = new int[cpuCount];
+
+			activityPSMP = new float[cpuCount][];
+			activityNSMP = new int[cpuCount][];
+		}
+	}
+    
+    /**
+     * Setter for the name of the profiled element
+     * @param nameString
+     */
     public void setNameString(String nameString)
     {
     	this.nameString = nameString;
     }
     
+    /**
+     * Adds a point to the PointList of the given graph
+     * @param graphIndex the graph to use
+     * @param x the X-coordinate of the point
+     * @param y the Y-coordinate of the point
+     */
     public void addPointToPolyline(int graphIndex, int x, int y)
     {
     	pointList[graphIndex].addPoint(x, y);
@@ -87,51 +170,92 @@
     	return this.index;
     }
     
-    public void setActivityMarkCount(int size)
-    {
-    	this.activityP = new int[size];
-    	this.activityT = new int[size];
+    /**
+     * Creates bucket arrays. This also propagates to SMP bucket arrays.  
+     * @param numberOfBuckets The total number of buckets to use.
+     */
+    public void createBuckets(int numberOfBuckets){
+    	this.activityP = new float[numberOfBuckets];
+    	this.activityT = new int[numberOfBuckets];
+    	this.activityN = new int[numberOfBuckets];
+    	if (isSMP){
+			for (int cpu = 0; cpu < cpuCount; cpu++) {
+		    	this.activityPSMP[cpu] = new float[numberOfBuckets];
+		    	this.activityNSMP[cpu] = new int[numberOfBuckets];
+			}						    		
+    	}
+    }
+    
+    /**
+     * this is intended to initialise the newly created bucket arrays
+     * @param duration length of time each bucket represents 
+     */
+    public void initialiseBuckets(int duration){
+    	for (int i = 0; i < activityT.length; i++) {
+			//this is important for calculating the x values later, so use mid-bucket values
+    		activityT[i] = duration*i + duration / 2;
+		}
     }
     
-    // zero the samples of this profiled generic in the time range starting at the time stamp
-    public void zeroActivityMarkValues(int timeStamp)
-    {
-        addActivityMarkValues(timeStamp, 0, 0);
+    /**
+     * Updates the bucket percentage values. This requires that sample counts have
+     * already been calculated for each bucket.
+     * @param bucketTotalArr Total number of samples per bucket
+     * @param bucketTotalArrSMP total number of samples per cpu and bucket. May be null for non-SMP systems.
+     */
+    public void calculateBucketPercentages(int[] bucketTotalArr, int[][] bucketTotalArrSMP){
+    	if (activityN != null){ 
+        	for (int b = 0; b < activityN.length; b++) {//loop through sample counts per bucket
+        		if (bucketTotalArr[b] > 0){
+            		activityP[b] = (float)activityN[b]*100/bucketTotalArr[b];
+        			
+        		}
+        		
+        		activityIndx = activityP.length; //TODO: temporarily needed, remove later
+        		
+    			if (isSMP){
+    				for (int cpu = 0; cpu < bucketTotalArrSMP.length; cpu++) {
+    					if (bucketTotalArrSMP[cpu][b]>0){
+    						activityPSMP[cpu][b] = (float)activityNSMP[cpu][b]*100/bucketTotalArrSMP[cpu][b];
+    					}
+					}
+    			}
+    		}    		
+    	}	    		
     }
-
-    // set the samples of of this profiled generic in the time range starting at the time stamp
-    public void addActivityMarkValues(int timeStamp, int percentage, int sampleCount)
-    {
-      this.activityT[this.activityIndx] = timeStamp;
-      this.activityP[this.activityIndx] = percentage;
-
-      if (this.firstSample == -1 && percentage != 0)
-      {
-    	  this.firstSample = this.recentSample;
-      }
-
-   	  if (this.recentSampleCount > 0)
-   		  this.lastSample = timeStamp;
-
-      this.recentSample      = timeStamp;
-      this.recentSampleCount = sampleCount;
-      this.recentPercentage  = percentage;
-      this.activityIndx++;
-    }
-
-    public void addActivityMark(int timeStamp, int percentage)
-    {
-      this.activityT[this.activityIndx] = timeStamp;
-      this.activityP[this.activityIndx] = percentage;
-      this.activityIndx++;
+    
+    /**
+     * Increases total sample count as well as sample count for the given bucket. Takes care of SMP values
+     * if SMP trace.
+     * @param bucketIndex The index of the bucket to use
+     * @param timestamp the timestamp of the sample
+     * @param cpu the CPU number of the sample
+     */
+    public void increaseSampleCount(int bucketIndex, int timestamp, int cpu){
+    	//note, activityT (bucket times) is constant and has been set during initialisation
+    	//activityP (bucket percentages) will be calculated after all samples have been processed
+    	
+		incTotalSampleCount();
+		if (isSMP){
+			incTotalSampleCountForSMP(cpu);				
+		}
+		
+    	this.activityN[bucketIndex]++; //increase sample count in bucket
+    	if (firstSample == -1){
+    		firstSample = timestamp;
+    	}
+    	lastSample = timestamp;
+    	if (isSMP){
+    		this.activityNSMP[cpu][bucketIndex]++;
+    	}
     }
 
   	public void setupCumulativeList(int graphIndex)
   	{
-  		if (this.activityIndx != 0)
+  		if (this.activityT != null && activityT.length != 0)
   		{	
   			if (cumulativeList[graphIndex] == null)
-  				cumulativeList[graphIndex] = new int[this.activityIndx];
+  				cumulativeList[graphIndex] = new float[this.activityT.length];
   			else
   			{
   				for (int i = 0; i < cumulativeList[graphIndex].length; i++)
@@ -142,47 +266,77 @@
   		}
   	}
 
-  	public int[] getCumulativeList(int graphIndex)
+  	/**
+  	 * The cumulative list contains for each bucket the 
+  	 * cumulative sample percentage of the same bucket of all ProfiledGenerics
+  	 * so far processed (not including the values of the current ProfiledGeneric).
+  	 * 
+  	 * Typically used for drawing a stacked-area chart
+  	 * @param graphIndex the graph ordinal to use
+  	 * @return
+  	 */
+  	public float[] getCumulativeList(int graphIndex)
   	{
   		return this.cumulativeList[graphIndex];
   	}
 
-  	public void setCumulativeValue(int graphIndex, int index, int value)
+  	public void setCumulativeValue(int graphIndex, int index, float value)
   	{
   		this.cumulativeList[graphIndex][index] = value;
   	}
   	
-  	//returns x-coordinates
+  	/**
+  	 * returns x-coordinates
+  	 * @return
+  	 */
   	public int[] getSampleList()
   	{
-  		if (sampleList == null && this.activityIndx != 0)
-  		{
-  			sampleList = new int[this.activityIndx];
- 
-  			for (int i = 0; i < this.activityIndx; i++)
-  			{
-  				this.sampleList[i] = this.activityT[i];
-  			}
-  			this.activityT = null;
+  		if (activityT != null){
+  			//Arrays.copyOf() is only supported from Java 6
+  			//return Arrays.copyOf(this.activityT, this.activityT.length);
+  			int[] ret = new int[activityT.length];
+  			for (int i = 0; i < ret.length; i++) {
+				ret[i] = activityT[i];
+			}
+  			return ret;
   		}
-  		return this.sampleList;
+  		return null;
   	}
   	
-  	// returns y-coordinates
-  	public int[] getActivityList()
+  	/**
+  	 *  returns y-coordinates
+  	 * @return
+  	 */
+  	public float[] getActivityList(){
+  		if (activityP != null){
+  			//Arrays.copyOf() is only supported from Java 6
+  			//return Arrays.copyOf(this.activityP, this.activityP.length);
+  			float[] ret = new float[activityP.length];
+  			for (int i = 0; i < ret.length; i++) {
+				ret[i] = activityP[i];
+			}
+  			return ret;
+  		}
+  		return null;
+   	}
+  	
+  	/**
+  	 *  returns y-coordinates (percentage values of activity)
+  	 * @param cpu 
+  	 * @return
+  	 */
+  	public float[] getActivityListForSMP(int cpu)
   	{
-  		if (activityList == null && this.activityIndx != 0)
-  		{
-  			activityList = new int[this.activityIndx];
-
-  			for (int i = 0; i < this.activityIndx; i++)
-  			{
-  			  activityList[i] = this.activityP[i];
-  			}
-  			this.activityP = null;
+  		if (isSMP && this.activityPSMP[cpu] != null){
+  			//Arrays.copyOf() is only supported from Java 6
+  			//return Arrays.copyOf(activityPSMP[cpu], activityPSMP[cpu].length);
+  			float[] ret = new float[activityPSMP[cpu].length];
+  			for (int i = 0; i < ret.length; i++) {
+				ret[i] = activityPSMP[cpu][i];
+			}
+  			return ret;
   		}
-
-  		return this.activityList;
+  		return null;
   	}
 
     public int getFirstSample()
@@ -193,10 +347,6 @@
     	  return this.firstSample;
     }
 
-    public int getRealFirstSample()
-    {
-   	  return this.firstSample;
-    }
 
     public int getLastSample()
     {
@@ -215,130 +365,11 @@
     {
     	this.lastSample = lastSample;
     }
-
-    private int findNearestSampleIndexFromStart(int sampleNum)
-    {
-    	int i = 0;
-    	while (i < this.sampleList.length && this.sampleList[i] < sampleNum)
-    	{
-    		i++;
-    	}    
-    	return i;
-    }
-
-    private int findNearestSampleIndexFromEnd(int sampleNum)
-    {
-    	int i = sampleList.length - 1;
-    	while (this.sampleList[i] > sampleNum && i > 0)
-    	{
-    		i--;
-    	}
-    	return i;
-    }
-
-    public float getAverageLoad(double startTime, double endTime)
-    {
-        return getAverageLoad((int) startTime,(int) endTime);
-    }
     
-    public float getAverageLoad(int startSample,int endSample)
-    {
-    	if (startSample == -1 || endSample == -1) return -666;
-    	if (endSample < startSample) return -777;
-
-    	if (this.activityList == null || this.sampleList == null) return -888;
-
-    	int firstSampleIndx = 0;
-    	int lastSampleIndx = 0;
-
-    	firstSampleIndx = this.findNearestSampleIndexFromStart(startSample) + 1;
-    	lastSampleIndx  = this.findNearestSampleIndexFromEnd(endSample) + 1;
-   
-    	if (firstSampleIndx < 0)
-    		firstSampleIndx = 0;
-    	if (firstSampleIndx >= activityList.length)
-    		firstSampleIndx = activityList.length - 1;
-    	
-    	if (lastSampleIndx < 0)
-    		lastSampleIndx = 0;
-    	if (lastSampleIndx >= activityList.length)
-    		lastSampleIndx = activityList.length - 1;
-      
-    	if (firstSampleIndx > lastSampleIndx)
-    	{
-    		int temp = firstSampleIndx;
-    		firstSampleIndx = lastSampleIndx;
-    		lastSampleIndx = temp;
-    	}
-    	
-    	int totalTime = sampleList[lastSampleIndx - 1] - sampleList[firstSampleIndx - 1];
-    	int totalLoad = 0;
-    	
-    	for (int i = firstSampleIndx; i < lastSampleIndx; i++)
-    	{
-    		totalLoad += this.activityList[i];
-    	}
-     	
-    	totalLoad *= (sampleList[1] - sampleList[0]);
-
-    	if (totalTime == 0)
-    	{
-    		return 0;
-    	}
-    	else
-    	{
-    		return (float)(((float)totalLoad) / ((float)totalTime));
-    	}
-    }
-    
-    public int getTotalLoad(int startSample,int endSample)
-    {
-    	if (startSample == -1 || endSample == -1) return -666;
-    	if (endSample < startSample) return -777;
-
-    	if (this.activityList == null || this.sampleList == null) return -888;
-
-    	int firstSampleIndx = 0;
-    	int lastSampleIndx = 0;
-
-    	firstSampleIndx = this.findNearestSampleIndexFromStart(startSample) + 1;
-    	lastSampleIndx  = this.findNearestSampleIndexFromEnd(endSample) + 1;
-  
-    	if (firstSampleIndx < 0)
-    		firstSampleIndx = 0;
-    	if (firstSampleIndx >= activityList.length)
-    		firstSampleIndx = activityList.length - 1;
-    	
-    	if (lastSampleIndx < 0)
-    		lastSampleIndx = 0;
-    	if (lastSampleIndx >= activityList.length)
-    		lastSampleIndx = activityList.length - 1;
-      
-    	if (firstSampleIndx > lastSampleIndx)
-    	{
-    		int temp = firstSampleIndx;
-    		firstSampleIndx = lastSampleIndx;
-    		lastSampleIndx = temp;
-    	}
-    	
-    	int totalTime = sampleList[lastSampleIndx - 1] - sampleList[firstSampleIndx - 1];
-    	int totalLoad = 0;
-   	
-    	for (int i = firstSampleIndx; i < lastSampleIndx; i++)
-    	{
-    		totalLoad += this.activityList[i];
-    	}
-     	
-    	if (totalTime == 0)
-    	{
-    		return 0;
-    	}
-    	else
-    	{
-    		return (int) totalLoad;
-    	}
-    }
-    
+    /**
+     * Setter for this ordinal of this profiled element
+     * @param index the ordinal to set
+     */
     public void setIndex(int index)
     {
     	this.index = index;
@@ -354,51 +385,97 @@
     	this.averageLoadValueString[graphIndex] = (new DecimalFormat(Messages.getString("ProfiledGeneric.decimalFormat"))).format(value); //$NON-NLS-1$
     }
 
-    public void setAverageLoadValueString(int graphIndex)
-    {
-    	this.averageLoadValueString[graphIndex] = (new DecimalFormat(Messages.getString("ProfiledGeneric.decimalFormat"))).format(this.graphPercentLoad[graphIndex]); //$NON-NLS-1$
-    }
 
     public String getAverageLoadValueString(int graphIndex)
     {
     	return this.averageLoadValueString[graphIndex];
     }
 
+    /**
+     * Setter for this colour of this profiled element
+     * @param c the colour to set
+     */
     public void setColor(Color c)
     {
     	this.color = c;
     }
 
+    /**
+     * Sets enabled state for this profiled element in the given graph
+     * @param graphIndex the graph index to use
+     * @param enableValue true for enabled, false for disabled
+     */
     public void setEnabled(int graphIndex, boolean enableValue)
     {
     	this.enableValue[graphIndex] = enableValue;
     }
 
+    /**
+     * Checks enabled state for this profiled element in the given graph
+     * @param graphIndex the graph index to use
+     * @return true if enabled, false if disabled
+     */
     public boolean isEnabled(int graphIndex)
     {
     	return enableValue[graphIndex];
     }
 
+    /**
+     * @return the colour of this profiled element
+     */
     public Color getColor()
     {
     	return this.color;
     }
     
+    /**
+     * @return the name of this profiled element
+     */
     public String getNameString()
     {
     	return this.nameString;
     }
     
+    /**
+     * @return the total sample count of this profiled element over the entire trace data
+     */
     public int getTotalSampleCount()
     {
     	return this.totalSampleCount;
     }
     
-    public void incTotalSampleCount()
+    /**
+     * Increased the total sample count of this profiled element by one
+     */
+   public void incTotalSampleCount()
     {
     	this.totalSampleCount++;
     }
+    
+    /**
+     * returns the total sample count over the entire trace data for the given CPU
+     * @param cpu the CPU to use
+     * @return the total sample count for given CPU
+     */
+    public int getTotalSampleCountForSMP(int cpu)
+    {
+    	return this.totalSampleCountSMP[cpu];
+    }
+    
+    /**
+     * Increases the total sample count for the given CPU by one
+     * @param cpu the CPU to use
+     */
+    public void incTotalSampleCountForSMP(int cpu)
+    {
+    	this.totalSampleCountSMP[cpu]++;
+    }
 
+	/**
+	 * Getter for the given graph's sample count
+	 * @param graphIndex
+	 * @return
+	 */
 	public int getSampleCount(int graphIndex)
 	{
 		return this.graphSampleCount[graphIndex];
@@ -414,13 +491,6 @@
 		this.graphSampleCount[graphIndex]++;
 	}
 	
-	public void setSampleCounts(int sampleCount0, int sampleCount1, int sampleCount2)
-	{
-		this.graphSampleCount[0] = sampleCount0;
-		this.graphSampleCount[1] = sampleCount1;
-		this.graphSampleCount[2] = sampleCount2;
-	}
-	
 	public float getPercentLoad(int graphIndex)
 	{
 		return this.graphPercentLoad[graphIndex];
@@ -437,26 +507,6 @@
 		else
 			this.averageLoadValueString[graphIndex] = Messages.getString("ProfiledGeneric.zeroFormat"); //$NON-NLS-1$
 	}
+
 	
-	public void setPercentLoads(float percentLoad0, float percentLoad1, float percentLoad2)
-	{
-		this.graphPercentLoad[0] = percentLoad0;
-		this.graphPercentLoad[1] = percentLoad1;
-		this.graphPercentLoad[2] = percentLoad2;
-
-		// doesn't hurt to set the strings here, too
-		// you may not need to set the strings when you set the float
-		if (percentLoad0 >= 0.005f)
-			this.averageLoadValueString[0] = (new DecimalFormat(Messages.getString("ProfiledGeneric.decimalFormat"))).format(percentLoad0); //$NON-NLS-1$
-		else
-			this.averageLoadValueString[0] = Messages.getString("ProfiledGeneric.zeroFormat"); //$NON-NLS-1$
-		if (percentLoad1 >= 0.005f)
-			this.averageLoadValueString[1] = (new DecimalFormat(Messages.getString("ProfiledGeneric.decimalFormat"))).format(percentLoad1); //$NON-NLS-1$
-		else
-			this.averageLoadValueString[1] = Messages.getString("ProfiledGeneric.zeroFormat"); //$NON-NLS-1$
-		if (percentLoad2 >= 0.005f)
-			this.averageLoadValueString[2] = (new DecimalFormat(Messages.getString("ProfiledGeneric.decimalFormat"))).format(percentLoad2); //$NON-NLS-1$
-		else
-			this.averageLoadValueString[2] = Messages.getString("ProfiledGeneric.zeroFormat"); //$NON-NLS-1$
-	}
 }
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/ProfiledThread.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/ProfiledThread.java	Wed Apr 21 15:14:16 2010 +0300
@@ -33,9 +33,9 @@
 
 	private int threadId; //thread's real id
  
-	public ProfiledThread()
+	public ProfiledThread(int cpuCount, int graphCount)
 	{
-		super();
+		super(cpuCount, graphCount);
 	}
   
 	public void setNameValues(char symbol,String nameString)
@@ -44,17 +44,18 @@
 		setNameString(nameString);
 	}
  
-	public String toString(int graphIndex)
-	{
-		if (this.isEnabled(graphIndex))
-		{
-			return "true  " + this.getAverageLoadValueString(graphIndex) + getNameString(); //$NON-NLS-1$
-		}
-		else
-		{
-			return "false " + this.getAverageLoadValueString(graphIndex) + getNameString(); //$NON-NLS-1$
-		}
-	}
+	//unused?
+//	public String toString(int graphIndex)
+//	{
+//		if (this.isEnabled(graphIndex))
+//		{
+//			return "true  " + this.getAverageLoadValueString(graphIndex) + getNameString(); //$NON-NLS-1$
+//		}
+//		else
+//		{
+//			return "false " + this.getAverageLoadValueString(graphIndex) + getNameString(); //$NON-NLS-1$
+//		}
+//	}
   
 	public Character getName(){
 		return new Character(this.name);
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/ProfiledThreshold.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/ProfiledThreshold.java	Wed Apr 21 15:14:16 2010 +0300
@@ -22,108 +22,155 @@
 
 import java.io.Serializable;
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
 
+import com.nokia.carbide.cpp.pi.editors.PIPageEditor;
+
+/**
+ * Class representing a Threshold item. It may represent several Profiled items
+ * with low sample counts, which are below a certain threshold
+ * 
+ * Each ProfiledThreshold is created and solely owned and managed by one GppTraceGraph.
+ * 
+ */
 public class ProfiledThreshold extends ProfiledGeneric implements Serializable
 {
 	private static final long serialVersionUID = 4902799424564460641L;
 	
 	// number of items (threads, binaries, functions) represented by this object 
-	private int[] itemCount = new int[3];
+	// no separate array needs to be created for SMP since the threshold is owned
+	// just by one graph
+	private int itemCount;
 	
-	// lists of items (threads, binaries, functions) represented by this object
-	private ArrayList<ProfiledGeneric>[] items = new ArrayList[3];
+	// lists of items represented by this object
+	private List<ProfiledGeneric> items = new ArrayList<ProfiledGeneric>();;
 	
-	public ProfiledThreshold(String name) {
+	public ProfiledThreshold(String name, int cpuCount, int graphCount) {
+		super(cpuCount, graphCount);
 		this.setNameString(name);
 	}
 	
-	public void setItemCount(int graphIndex, int itemCount) {
-		this.itemCount[graphIndex] = itemCount;
+	/**
+	 * Sets the number of ProfiledGeneric items below the threshold
+	 * @param graphIndex the graphIndex for which to set the number of items
+	 * @param itemCount the number of items to set
+	 */
+	public void setItemCount(int itemCount) {
+		this.itemCount = itemCount;
 	}
 
-	public void incItemCount(int graphIndex) {
-		this.itemCount[graphIndex]++;
+	/**
+	 * Increases the number of ProfiledGeneric items below the threshold by one.
+	 */
+	public void incItemCount() {
+		this.itemCount++;
 	}
 	
-	public int getItemCount(int graphIndex) {
-		return this.itemCount[graphIndex];
+	/**
+	 * Getter for the number of ProfiledGeneric items below the threshold
+	 * @return the number of profiled items below the threshold for the given graph
+	 */
+	public int getItemCount() {
+		return this.itemCount;
 	}
 	
+	/**
+	 * Resetting data structures for given graph
+	 * @param graphIndex the ordinal of the graph to use
+	 */
 	public void init(int graphIndex) {
-		this.enableValue[graphIndex]      = false;
-		this.itemCount[graphIndex]        = 0;
-		this.graphSampleCount[graphIndex] = 0;
-
-		if (this.items[graphIndex] != null)
-			this.items[graphIndex].clear();
+		internalInit(graphIndex);
+		Arrays.fill(activityP, 0);
+	}
 
-		if (this.activityList == null)
-			this.activityList = new int[this.activityIndx];
-
-		for (int i = 0; i < this.activityIndx; i++) {
-			this.activityList[i] = 0;
-			this.activityP[i] = 0;
-		}
+	private void internalInit(int graphIndex) {
+		this.enableValue[graphIndex]      = false;
+		this.graphSampleCount[graphIndex] = 0;
+		this.itemCount        = 0;
+		this.items.clear();
 	}
 	
-	public void initAll() {
-		this.enableValue[0]      = false;
-		this.itemCount[0]        = 0;
-		this.graphSampleCount[0] = 0;
-		this.enableValue[1]      = false;
-		this.itemCount[1]        = 0;
-		this.graphSampleCount[1] = 0;
-		this.enableValue[2]      = false;
-		this.itemCount[2]        = 0;
-		this.graphSampleCount[2] = 0;
-
-		if (this.activityList == null)
-			this.activityList = new int[this.activityIndx];
-
-		for (int i = 0; i < this.activityIndx; i++) {
-			this.activityList[i] = 0;
-			this.activityP[i] = 0;
-		}
+	/**
+	 * Clear any values from internal structures for given graph
+	 * @param cpu The CPU for which to reset
+	 * @param graphIndex the graph for which to reset
+	 */
+	public void initForSMP(int cpu, int graphIndex) {
+		internalInit(graphIndex);
+		Arrays.fill(this.activityPSMP[cpu], 0);
 	}
 	
+	/**
+	 * Adds the given ProfiledGeneric and its bucket values to this threshold item
+	 * @param graphIndex The ordinal of the graph to use
+	 * @param pGeneric The ProfiledGeneric to use
+	 * @param count the total sample count for the ProfiledGeneric
+	 */
 	public void addItem(int graphIndex, ProfiledGeneric pGeneric, int count)
 	{
 		if (pGeneric instanceof ProfiledThreshold)
 			this.totalSampleCount += count;	// this assumes that threshold only has one non-zero graphIndex element
 
-		this.itemCount[graphIndex]++;
+		this.itemCount++;
 		this.graphSampleCount[graphIndex] += count;
 
-		// add to the activity list
-		if (this.activityList == null)
-			this.activityList = new int[this.activityIndx];
-
-		int[] activityList = pGeneric.getActivityList();
-		for (int i = 0; i < activityList.length; i++)
-			this.activityList[i] += activityList[i];
+		//add bucket percentages from graph to threshold item
+		float[] activityList = pGeneric.getActivityList();
+		for (int i = 0; i < activityList.length; i++){
+			this.activityP[i] += activityList[i];
+		}
 
 		// add to the list of items associated with this threshold object
-		if (items[graphIndex] == null)
-			items[graphIndex] = new ArrayList<ProfiledGeneric>();
-		
-		items[graphIndex].add(pGeneric);
+		items.add(pGeneric);
 
 		this.enableValue[graphIndex] = true;
 	}
 	
-	public ArrayList<ProfiledGeneric> getItems(int graphIndex)
+	/**
+	 * Adds a ProfiledGeneric with low sample count to this threshold item for the given CPU and graph index. 
+	 * @param cpu the CPU it applies to
+	 * @param graphIndex the graphIndex to use
+	 * @param pGeneric the ProfiledGeneric to add to the threshold item
+	 * @param count the sample count for this ProfiledGeneric on the given CPU
+	 */
+	public void addItemForSMP(int cpu, int graphIndex, ProfiledGeneric pGeneric, int count)
 	{
-		return items[graphIndex];
+		if (pGeneric instanceof ProfiledThreshold)
+			this.totalSampleCountSMP[cpu] += count;	// this assumes that threshold only has one non-zero graphIndex element
+
+		this.itemCount++;
+		this.graphSampleCount[graphIndex] += count;
+
+
+		float[] activityList = pGeneric.getActivityListForSMP(cpu);
+		for (int i = 0; i < activityList.length; i++)
+			this.activityPSMP[cpu][i] += activityList[i];
+
+		// add to the list of items associated with this threshold object
+		items.add(pGeneric);
+
+		this.enableValue[graphIndex] = true;
 	}
 	
-    public void setEnabled(int graphIndex, boolean enableValue)
+	/**
+	 * Returns list of items below the threshold
+	 * @return
+	 */
+	public List<ProfiledGeneric> getItems()
+	{
+		return items;
+	}
+	
+    /* (non-Javadoc)
+     * @see com.nokia.carbide.cpp.internal.pi.model.ProfiledGeneric#setEnabled(int, boolean)
+     */
+    @Override
+	public void setEnabled(int graphIndex, boolean enableValue)
     {
     	this.enableValue[graphIndex] = enableValue;
     	
-    	if (items[graphIndex] == null)
-    		return;
-    	
-    	for (int i = 0; i < items[graphIndex].size(); i++)
-    		items[graphIndex].get(i).enableValue[graphIndex] = enableValue;
+    	for (ProfiledGeneric item : items)
+    		item.enableValue[graphIndex] = enableValue;
     }
 }
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/ProgressBar.java	Tue Apr 20 14:41:43 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-/*
- * 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: 
- *
- */
-
-package com.nokia.carbide.cpp.internal.pi.model;
-
-import javax.swing.JProgressBar;
-
-public class ProgressBar extends JProgressBar {
-
-	private static final long serialVersionUID = 4862691591715531894L;
-
-	public ProgressBar() {
-        super();
-        this.setValue(0);
-        this.setStringPainted(true);
-        this.setIndeterminate(true);
-        this.setBorder(javax.swing.BorderFactory.createEtchedBorder(javax.swing.border.EtchedBorder.RAISED));
-        this.setFont(new java.awt.Font(Messages.getString("ProgressBar.defaultFont"), java.awt.Font.PLAIN, 10)); //$NON-NLS-1$
-    }
-    
-	public void addValue(int value)
-	{
-		this.setValue(this.getValue() + value);
-		this.validate();
-	}
-	
-	public int getMaxValue()
-	{
-		return this.getMaximum();
-	}
-	
-	public void advanceTo(int value)
-	{
-		try
-		{
-		  for (int i = this.getValue(); i < value; i++)
-		  {
-			addValue(1);
-			Thread.sleep(10);
-		  }
-		}
-		catch (Exception e) {}
-	}
-	
-	public void runToEnd()
-	{
-		try
-		{
-		  for (int i = getValue(); i < getMaxValue(); i++)
-		  {
-			addValue(1);
-			Thread.sleep(10);
-		  }
-		}
-		catch (Exception e) {}
-	}
-}
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/RefinableTrace.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/RefinableTrace.java	Wed Apr 21 15:14:16 2010 +0300
@@ -19,9 +19,14 @@
 
 public interface RefinableTrace 
 {
-	// resolve or further resolve addresses to entities like binaries and functions
+	/**
+	 *  resolve or further resolve addresses to entities like binaries and functions
+	 * @param resolver
+	 */
 	public void refineTrace(FunctionResolver resolver);
 	
-	// after all refinement is done, do any final touches to the samples
+	/**
+	 *  after all refinement is done, do any final touches to the samples
+	 */
 	public void finalizeTrace();
 }
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/TraceDataRepository.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/TraceDataRepository.java	Wed Apr 21 15:14:16 2010 +0300
@@ -44,7 +44,7 @@
 	
 	public void registerTraces(int analysisId) {
 		if (analysisSpecificTraces.get(analysisId) == null) {
-			analysisSpecificTraces.put(new Integer(analysisId), new LinkedHashMap<Class,ParsedTraceData>());
+			analysisSpecificTraces.put(Integer.valueOf(analysisId), new LinkedHashMap<Class,ParsedTraceData>());
 		}
 	}
 	
@@ -58,7 +58,7 @@
 		if (traceClass != null && traceData != null && traceData.traceData != null)
 		{
 			tracesForMyId.put(traceClass, traceData);
-			analysisSpecificTraces.put(new Integer(analysisId), tracesForMyId);
+			analysisSpecificTraces.put(Integer.valueOf(analysisId), tracesForMyId);
 		}
 	}
 	
@@ -72,7 +72,7 @@
 		if (analysisSpecificTraces == null || traceClass == null)
 			return null;
 
-		LinkedHashMap<Class,ParsedTraceData> tmp = analysisSpecificTraces.get(new Integer(analysisId));
+		LinkedHashMap<Class,ParsedTraceData> tmp = analysisSpecificTraces.get(Integer.valueOf(analysisId));
 
 		if (tmp == null)
 			return null;
@@ -87,7 +87,7 @@
 		if (analysisSpecificTraces == null) 
 			return resolvers.elements();
 
-		LinkedHashMap<Class,ParsedTraceData> tmp = analysisSpecificTraces.get(new Integer(analysisId));
+		LinkedHashMap<Class,ParsedTraceData> tmp = analysisSpecificTraces.get(Integer.valueOf(analysisId));
 
 		Iterator<ParsedTraceData> e = tmp.values().iterator();
 		while (e.hasNext())
@@ -120,7 +120,7 @@
 		if (analysisSpecificTraces == null)
 			return null;
 
-		LinkedHashMap<Class,ParsedTraceData> tmp = analysisSpecificTraces.get(new Integer(analysisId));
+		LinkedHashMap<Class,ParsedTraceData> tmp = analysisSpecificTraces.get(Integer.valueOf(analysisId));
 
 		if (tmp == null)
 			return null;
@@ -133,7 +133,7 @@
 		if (analysisSpecificTraces == null)
 			return null;
 
-		LinkedHashMap<Class,ParsedTraceData> tmp = analysisSpecificTraces.get(new Integer(analysisId));
+		LinkedHashMap<Class,ParsedTraceData> tmp = analysisSpecificTraces.get(Integer.valueOf(analysisId));
 
 		if (tmp == null)
 			return null;
@@ -146,7 +146,7 @@
 		if (analysisSpecificTraces == null)
 			return null;
 
-		LinkedHashMap<Class,ParsedTraceData> tmp = analysisSpecificTraces.get(new Integer(analysisId));
+		LinkedHashMap<Class,ParsedTraceData> tmp = analysisSpecificTraces.get(Integer.valueOf(analysisId));
 
 		if (tmp == null)
 			return null;
@@ -157,7 +157,7 @@
 	public void removeTraces(int analysisId)
 	{
 		if (analysisSpecificTraces != null)
-			analysisSpecificTraces.remove(new Integer(analysisId));
+			analysisSpecificTraces.remove(Integer.valueOf(analysisId));
 	}
 	
 	public void removeAll()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/UnresolvedBinary.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2010 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: 
+ *
+ */
+package com.nokia.carbide.cpp.internal.pi.model;
+
+import java.io.Serializable;
+
+/**
+ * This class represents an unresolved binary. Most properties can be generated 
+ * on the fly thus potentially saving memory 
+ *
+ */
+public class UnresolvedBinary implements IBinary, Serializable{
+	private static final long serialVersionUID = -1872500528710393139L;
+	private Long startAddress;
+
+	/**
+	 * Constructor
+	 * @param startAddress the start address of this binary; mainly used
+	 * to generate the name of the unresolved binary
+	 */
+	public UnresolvedBinary(Long startAddress) {
+		super();
+		this.startAddress = startAddress;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.model.IBinary#getBinaryName()
+	 */
+	public String getBinaryName() {
+		return String.format(Messages.getString("UnresolvedBinary.0"), startAddress); //$NON-NLS-1$
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.model.IBinary#getLength()
+	 */
+	public int getLength() {
+		return 0;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.model.IBinary#getOffsetToCodeStart()
+	 */
+	public long getOffsetToCodeStart() {
+		return 0;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.model.IBinary#getStartAddress()
+	 */
+	public long getStartAddress() {
+		//we could return an actual address here but for some reason
+		//the original code returns zero
+		return 0;
+		//return startAddress;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.model.IBinary#getType()
+	 */
+	public String getType() {
+		return null;
+	}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/UnresolvedFunction.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2010 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: 
+ *
+ */
+package com.nokia.carbide.cpp.internal.pi.model;
+
+import java.io.Serializable;
+
+/**
+ * Represents a function that could not be resolved
+ *
+ */
+public class UnresolvedFunction implements IFunction, Serializable {
+	
+	private static final long serialVersionUID = -3884683701926247700L;
+
+	/** address for this function, usually the program counter value for unresolved functions */
+	protected Long address;
+
+	/**
+	 * Constructor
+	 * @param address address for this function, usually the program counter value
+	 */
+	public UnresolvedFunction(Long address) {
+		this.address = address;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.model.IFunction#getFunctionBinary()
+	 */
+	public IBinary getFunctionBinary() {
+		return new UnresolvedBinary(address);
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.model.IFunction#getFunctionName()
+	 */
+	public String getFunctionName() {
+		return String.format(Messages.getString("UnresolvedFunction.0"), address); //$NON-NLS-1$
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.model.IFunction#getLength()
+	 */
+	public long getLength() {
+		return 0;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.model.IFunction#getOffsetFromBinaryStart()
+	 */
+	public long getOffsetFromBinaryStart() {
+		return 0;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.pi.model.IFunction#getStartAddress()
+	 */
+	public Long getStartAddress() {
+		return address;
+	}
+
+}
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/messages.properties	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/messages.properties	Wed Apr 21 15:14:16 2010 +0300
@@ -75,3 +75,5 @@
 GUITooltips.yplusButton=yplusButton
 GUITooltips.yplusDeepButton=yplusDeepButton
 GUITooltips.yplusplusButton=yplusplusButton
+UnresolvedBinary.0=Binary at 0x%x not found
+UnresolvedFunction.0=Function at 0x%x not found
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/plugin/model/IFinalizeTrace.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/plugin/model/IFinalizeTrace.java	Wed Apr 21 15:14:16 2010 +0300
@@ -25,7 +25,12 @@
  */
 public interface IFinalizeTrace {
 	
-	/* this routine is run before editor UID is disposed */
+	/** this routine is run before editor UID is disposed */
 	public void runOnDispose();
+	
+	/**
+	 * called when the EditorPart opens
+	 */
+	public void runOnPartOpened();
 
 }
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/plugin/model/IReportable.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/plugin/model/IReportable.java	Wed Apr 21 15:14:16 2010 +0300
@@ -34,6 +34,7 @@
 	public ArrayList<Boolean> getColumnSortTypes(); // This gives feedback to the system whether column data strings should be sorted by name or the first number they may contain. 
 										// Boolean values SORT_BY_NAME and SORT_BY_NUMBER are meant to be used to indicate this information.
 	public Hashtable<Integer,Object> getSummaryTable(double startTime, double endTime);
+	//CH: this doesn't seem to be used anywhere, most plugins return null for this
 	public String getActiveInfo(Object key, double startTime, double endTime);
 	public String getGeneralInfo(); // this is reserved for future implementation and has no functionality at the moment
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/plugin/model/ITitleBarMenu.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2010 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: 
+ *
+ */
+
+package com.nokia.carbide.cpp.internal.pi.plugin.model;
+
+import org.eclipse.jface.action.Action;
+
+/**
+ * Interface that is used when Performance Investigator's graph plug-in uses
+ * drop-down menu in the title bar of its graph view.
+ */
+
+public interface ITitleBarMenu extends IMenu {
+
+	/**
+	 * Method that is called when graph is initialized.
+	 * @return Array of actions that are placed into drop-down menu. Each
+	 *         action's run()-method is called when the action is selected from
+	 *         drop-down menu. If some of the actions need to be preselected
+	 *         when view is opened its isChecked method should return true.
+	 */
+	public Action[] addTitleBarMenuItems();
+	
+	/**
+	 * Returns the main context help id for this view which is displayed when the
+	 * user presses the question mark button on the toolbar
+	 * @return main context help id for analysis view
+	 */
+	public String getContextHelpId();
+}
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/plugin/model/ITrace.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/plugin/model/ITrace.java	Wed Apr 21 15:14:16 2010 +0300
@@ -28,6 +28,16 @@
 	public Class getTraceClass();
 	public void initialiseTrace(GenericTrace trace);
 	public String getTraceName();
+	/** like trace name but can be more descriptive */
+	public String getTraceTitle();
 	public int getTraceId();
 	public ParsedTraceData parseTraceFile(File file /*, ProgressBar progressBar*/) throws Exception;
+	
+	/**
+	 * Parses the given array of input files and returns the resulting ParsedTraceData
+	 * @param files the files to parse
+	 * @return the parsed traced trace data 
+	 * @throws Exception
+	 */
+	public ParsedTraceData parseTraceFiles(File[] files) throws Exception;
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/plugin/model/ITraceSMP.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,27 @@
+/*
+ * 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: 
+ *
+ */
+package com.nokia.carbide.cpp.internal.pi.plugin.model;
+
+/**
+ * Interface for SMP-specific code
+ *
+ */
+public interface ITraceSMP {
+	/** Returns array of trace Ids found for SMP trace files. Note, this may not be null. */
+	public int[] getTraceIdsSMP();
+
+}
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/plugin/model/IVisualizable.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/plugin/model/IVisualizable.java	Wed Apr 21 15:14:16 2010 +0300
@@ -18,8 +18,8 @@
 package com.nokia.carbide.cpp.internal.pi.plugin.model;
 
 import com.nokia.carbide.cpp.internal.pi.analyser.ProfileVisualiser;
-import com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph;
 import com.nokia.carbide.cpp.internal.pi.visual.GraphDrawRequest;
+import com.nokia.carbide.cpp.pi.visual.IGenericTraceGraph;
 
 
 public interface IVisualizable extends ITrace
@@ -49,10 +49,7 @@
 	public int getGraphCount();
 	
 	// next graph
-	public GenericTraceGraph getTraceGraph(int graphIndex);
-	
-	// title of next graph
-	public String getGraphTitle(int graphIndex);
+	public IGenericTraceGraph getTraceGraph(int graphIndex);
 	
 	// PI editor page to contain the graph
 	public int getPageNumber(int graphIndex);
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/resolvers/CachedFunctionResolver.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/resolvers/CachedFunctionResolver.java	Wed Apr 21 15:14:16 2010 +0300
@@ -26,6 +26,7 @@
 import com.nokia.carbide.cpp.internal.pi.model.Binary;
 import com.nokia.carbide.cpp.internal.pi.model.Function;
 import com.nokia.carbide.cpp.internal.pi.model.FunctionResolver;
+import com.nokia.carbide.cpp.internal.pi.model.IFunction;
 
 
 // re-implement SymbolFileParser for supporting 
@@ -141,9 +142,9 @@
 	  		
 	  		if (b == null) {
 		  		b = new Binary(item.name);
-		  		b.length = (int)(item.end-item.start);
-		  		b.offsetToCodeStart = 0;
-		  		b.startAddress = item.start;
+		  		b.setLength((int)(item.end-item.start));
+		  		b.setOffsetToCodeStart(0);
+		  		b.setStartAddress(item.start);
 				this.knownBinaries.put(item.name, b);
 	  		}
 	  		return b;
@@ -166,6 +167,10 @@
 //	  	}
 	}
 
+	public Binary findBinaryForAddress(long address, long sampleSynchTime){
+		return findBinaryForAddress(address);
+	}
+
 	public String findBinaryNameForAddress(long address) {
 	    SymbolFileDllItem foundDllItem = this.getDllItemForAddress(address);
 	    if (foundDllItem != null)
@@ -174,7 +179,7 @@
 	    	return Messages.getString("CachedFunctionResolver.dllForAddress")+Long.toHexString(address)+Messages.getString("CachedFunctionResolver.notFound");   //$NON-NLS-1$ //$NON-NLS-2$
 	}
 
-	public Function findFunctionForAddress(long address) {
+	public IFunction findFunctionForAddress(long address) {
 	  	SymbolFileFunctionItem item = this.getFunctionItemForAddress(address);
 
 	  	if (item != null)
@@ -183,9 +188,9 @@
 	 		Function f = this.knownFunctions.get(search);
 
 	  		if (f == null) {
-		  		f = new Function(item.name,new Long(item.address),item.dll.name);
-		  		f.offsetFromBinaryStart = item.address-item.dll.start;
-		  		f.length = item.length;
+		  		f = new Function(item.name,Long.valueOf(item.address),item.dll.name);
+		  		f.setOffsetFromBinaryStart(item.address-item.dll.start);
+		  		f.setLength(item.length);
 		  		this.knownFunctions.put(search, f);
 	  		}
 	  		return f;
@@ -202,9 +207,9 @@
 	  			Function f = this.knownFunctions.get(fName);
 
 	  	  		if (f == null ) {
-	  	  			f = new Function(fName, new Long(dllItem.start), dllItem.name);
-		  			f.offsetFromBinaryStart = address-dllItem.start;
-		  			f.length = 0;
+	  	  			f = new Function(fName, Long.valueOf(dllItem.start), dllItem.name);
+		  			f.setOffsetFromBinaryStart(address-dllItem.start);
+		  			f.setLength(0);
 		  			this.knownFunctions.put(fName, f);
 	  	  		}
 
@@ -218,7 +223,7 @@
 //	  			Function f = this.knownFunctions.get(fName);
 //
 //	  	  		if (f == null ) {
-//	  	  			f = new Function(fName, new Long(address),
+//	  	  			f = new Function(fName, Long.valueOf(address),
 //	  	  							 "Binary at 0x" + 
 //									 Long.toHexString(address)+" not found");
 //	  	  			f.offsetFromBinaryStart = 0;
@@ -229,6 +234,9 @@
 //	  		}
 	  	}
 	}
+	public IFunction findFunctionForAddress(long address, long sampleSynchTime){
+		return findFunctionForAddress(address);
+	}
 
 	public String findFunctionNameForAddress(long address) {
 	  	SymbolFileFunctionItem item = this.getFunctionItemForAddress(address);
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/resolvers/RofsSymbolFileFunctionResolver.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/resolvers/RofsSymbolFileFunctionResolver.java	Wed Apr 21 15:14:16 2010 +0300
@@ -20,12 +20,13 @@
 import java.util.Hashtable;
 
 import com.nokia.carbide.cpp.internal.pi.model.Binary;
-import com.nokia.carbide.cpp.internal.pi.model.Function;
+import com.nokia.carbide.cpp.internal.pi.model.IFunction;
 
 
 public class RofsSymbolFileFunctionResolver extends SymbolFileFunctionResolver {
 	
-	public Function findFunctionForAddress(long address) {
+	@Override
+	public IFunction findFunctionForAddress(long address) {
 		return super.findFunctionForAddress(address);
 	}
 	
@@ -37,10 +38,10 @@
 			if (dllItem.name != null) {
 				Binary binary = hostNameToBinary.get(dllItem.name);
 				if (binary != null) {
-					dllItem.start += binary.startAddress;
-					dllItem.end += binary.startAddress;
+					dllItem.start += binary.getStartAddress();
+					dllItem.end += binary.getStartAddress();
 					for (SymbolFileFunctionItem funcItem : dllItem.data) {
-						funcItem.address += binary.startAddress;
+						funcItem.address += binary.getStartAddress();
 					}
 				}
 			}
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/test/TraceAdditionalInfo.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/test/TraceAdditionalInfo.java	Wed Apr 21 15:14:16 2010 +0300
@@ -37,7 +37,7 @@
 	private HashMap<Integer, Vector<Object>> additional_info = new HashMap<Integer, Vector<Object>>();
 	
 	public void addAdditionalInfo(int traceId, Vector<Object> additionalInfo) {
-		additional_info.put(new Integer(traceId), additionalInfo);
+		additional_info.put(Integer.valueOf(traceId), additionalInfo);
 	}
 	
 	public Set<Entry<Integer, Vector<Object>>> getAdditionalInfoSet() {
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/utils/AlphabeticValueGenerator.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/utils/AlphabeticValueGenerator.java	Wed Apr 21 15:14:16 2010 +0300
@@ -43,12 +43,12 @@
 				}
 			}
 
-			while (created.contains(new Long(tempOrder)))
+			while (created.contains(Long.valueOf(tempOrder)))
 			{
 				tempOrder++;
 			}
 			
-			created.add(new Long(tempOrder));
+			created.add(Long.valueOf(tempOrder));
 			
 			ai.order = tempOrder;
 		}
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/utils/PIUtilities.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/utils/PIUtilities.java	Wed Apr 21 15:14:16 2010 +0300
@@ -19,11 +19,24 @@
 
 import java.io.File;
 import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Set;
 
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.widgets.FileDialog;
 import org.eclipse.ui.PlatformUI;
 
+import com.nokia.carbide.cpp.internal.pi.analyser.StreamFileParser;
+import com.nokia.carbide.cpp.internal.pi.manager.PluginRegisterer;
+import com.nokia.carbide.cpp.internal.pi.manager.PluginRegistry;
+import com.nokia.carbide.cpp.internal.pi.plugin.model.AbstractPiPlugin;
+import com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace;
+import com.nokia.carbide.cpp.internal.pi.plugin.model.ITraceSMP;
 import com.nokia.carbide.cpp.pi.util.GeneralMessages;
 
 public abstract class PIUtilities
@@ -203,4 +216,71 @@
     	}
     	return true;
     }
+    
+    /**
+     * Returns a set of plugins for trace IDs present in the trace file of the given path. 
+     * Plugins which create editor pages are first in the list. 
+     * @param absTraceFilePath path of the trace file to use
+     * @return list of ITrace plugins for the given trace file
+     * @throws IOException in case of problems accessing the trace file
+     */
+    public static List<ITrace> getPluginsForTraceFile (String absTraceFilePath) throws IOException{
+    	
+    	File traceFile = new File(absTraceFilePath);
+    	StreamFileParser sfp = new StreamFileParser(traceFile);
+    	
+    	Set<Integer> traceTypesInFile = sfp.allTraceType();
+    	sfp = null; //dispose parser structures
+    	
+    	List<ITrace> ret = new ArrayList<ITrace>();
+    	PluginRegisterer.registerAllPlugins();
+		Enumeration<AbstractPiPlugin> e = PluginRegistry.getInstance().getRegistryEntries();
+		while(e.hasMoreElements()) {
+			AbstractPiPlugin plugin = e.nextElement();
+			if (plugin instanceof ITrace) {
+				ITrace tracePlugin = (ITrace) plugin;
+				
+				if (traceTypesInFile.contains(tracePlugin.getTraceId()) || (plugin instanceof ITraceSMP && containsTraceId(traceTypesInFile, ((ITraceSMP)plugin).getTraceIdsSMP()))) {
+						ret.add(tracePlugin);
+				}
+			}
+		}
+		
+		// sort by trace id: plugins that create editor pages have to be first
+		// this is a design limitation of PI
+    	ret = sortPlugins(ret);
+		return ret;
+    }
+    
+    /**
+     * Sorts the plugins by trace ids
+     * @param plugins the list of plugins to sort
+     * @return the sorted list
+     */
+    public static List<ITrace> sortPlugins(List<ITrace> plugins){
+		Collections.sort(plugins, new Comparator<ITrace>(){
+			public int compare(ITrace arg0, ITrace arg1) {
+				return arg0.getTraceId() - arg1.getTraceId();
+			}
+		});
+    	return plugins;
+    }
+
+    /**
+     * Indicates whether the given set of traces IDs contains any of the trace IDs in traceIdsSMP.
+     * @param traceTypesInFile Trace IDs present in the trace file
+     * @param traceIdsSMP trace IDs to check against (typically SMP trace IDs for one plugin)
+     * @return true if any matching trace IDs are found, false otherwise
+     */
+	private static boolean containsTraceId(Set<Integer> traceTypesInFile,
+			int[] traceIdsSMP) {
+		
+		for (int traceID : traceIdsSMP) {
+			if (traceTypesInFile.contains(Integer.valueOf(traceID))){
+				return true;
+			}
+		}
+		
+		return false;
+	}
 }
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/utils/PluginClassLoader.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/utils/PluginClassLoader.java	Wed Apr 21 15:14:16 2010 +0300
@@ -134,7 +134,7 @@
 						int amount = zis.read(tempBytes);
 						if (amount != -1) 
 						{
-							amounts.add(new Integer(amount));
+							amounts.add(Integer.valueOf(amount));
 							totalAmount+=amount;
 							data.add(tempBytes);
 						}
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/utils/QuickSortImpl.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/utils/QuickSortImpl.java	Wed Apr 21 15:14:16 2010 +0300
@@ -67,8 +67,8 @@
 				//System.out.println("QS left side is "+low+"-"+pivot+" right side is "+pivot+"-"+high);
 
 				//quickSort( a, low, pivot-1 );
-				stack.push(new Integer(pivot+1));
-				stack.push(new Integer(high));
+				stack.push(Integer.valueOf(pivot+1));
+				stack.push(Integer.valueOf(high));
 				//System.out.println("Pushed right side");
 				high = pivot-1;
 			}				
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/visual/AnalyserVisualState.java	Tue Apr 20 14:41:43 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,107 +0,0 @@
-/*
- * 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: 
- *
- */
-
-package com.nokia.carbide.cpp.internal.pi.visual;
-
-import java.io.Serializable;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.Vector;
-
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.Rectangle;
-
-import com.nokia.carbide.cpp.internal.pi.model.ProfiledThread;
-
-
-public class AnalyserVisualState implements Serializable
-{
-	private static final long serialVersionUID = -826324357879880731L;
-	
-	private Hashtable<Integer,Color> colorInfo;
-	private Hashtable<Integer,Boolean> selectedInfo;
-	private int selectionStart;
-	private int selectionEnd;
-	private double zoomFactor;
-	private transient Rectangle viewRect1;
-	
-	public AnalyserVisualState(Enumeration threads, PICompositePanel bcp)
-	{
-		colorInfo    = new Hashtable<Integer,Color>();
-		selectedInfo = new Hashtable<Integer,Boolean>();
-		while (threads.hasMoreElements())
-		{
-			ProfiledThread pt = (ProfiledThread) threads.nextElement();
-			colorInfo.put(new Integer(pt.getThreadId()), pt.getColor());
-			// Could instead find  pt.isEnabled() for all pages - not just page 0
-			selectedInfo.put(new Integer(pt.getThreadId()), Boolean.valueOf(pt.isEnabled(0)));
-		}
-		
-		selectionStart = (int) bcp.getSelectionStart();
-		selectionEnd = (int) bcp.getSelectionEnd();
-		viewRect1 = bcp.getSashForm().getBounds();
-		zoomFactor = bcp.getScale();
-	}
-	
-	public Enumeration<ProfiledThread> resetThreadState(Enumeration<ProfiledThread> threads)
-	{
-		Vector<ProfiledThread> v = new Vector<ProfiledThread>();
-		Enumeration<ProfiledThread> temp = threads;
-		while (threads.hasMoreElements())
-		{
-			Object o = threads.nextElement();
-			if (o instanceof ProfiledThread)
-			{
-				ProfiledThread pt = (ProfiledThread) o;
-				Color c = (Color)colorInfo.get(new Integer(pt.getThreadId()));
-				Boolean b = (Boolean)selectedInfo.get(new Integer(pt.getThreadId()));
-				if ((c != null) && (b != null))
-				{
-					pt.setColor(c);
-					pt.setEnabled(0, b.booleanValue());
-					v.addElement(pt);
-				}
-				else
-				{
-					System.out.println(Messages.getString("AnalyserVisualState.noThreadInfo")); //$NON-NLS-1$
-					return temp;
-				}
-			}
-		}
-		return v.elements();
-	}
-
-	public int getSelectionEnd() 
-	{
-		return selectionEnd;
-	}
-
-	public int getSelectionStart() 
-	{
-		return selectionStart;
-	}
-
-	public double getZoomFactor() 
-	{
-		return zoomFactor;
-	}
-
-	public Rectangle getViewRect()
-	{
-		return viewRect1;
-	}
-}
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/visual/GenericTable.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/visual/GenericTable.java	Wed Apr 21 15:14:16 2010 +0300
@@ -64,11 +64,22 @@
 	protected static final int COLUMN_ID_IN_BINARY_PATH = 10;
 	protected static final int COLUMN_ID_START_ADDR     = 11;
 	protected static final int COLUMN_ID_PRIORITY       = 12;
+
 	
 	// these are never used as actual column headers - they indicate a double sort
 	protected static final int COLUMN_ID_FULL_PATH      = 13;
 	protected static final int COLUMN_ID_FULL_IN_PATH   = 14;
 
+	public static final int COLUMN_ID_SWI_THREAD		= 15;
+	public static final int COLUMN_ID_ADDRESS			= 16;
+	public static final int COLUMN_ID_SWI_FUNCTION		= 17;
+	public static final int COLUMN_ID_RETURN_ADDRESS	= 18;
+	public static final int COLUMN_ID_SWI_COUNT			= 19;
+	public static final int COLUMN_ID_IRQ_LINE			= 20;
+	public static final int COLUMN_ID_IRQ_COUNT			= 21;
+	public static final int COLUMN_ID_SWI_CHECK			= 22;
+
+	
 	protected static final int COLOR_COLUMN_INDEX = 0;
 	
 	// table column headings
@@ -88,7 +99,10 @@
 	protected static final String COLUMN_HEAD_MEMORY_STACK  = Messages.getString("GenericTable.stackHeap"); //$NON-NLS-1$
 	protected static final String COLUMN_HEAD_MEMORY_TOTAL  = Messages.getString("GenericTable.memoryTotal"); //$NON-NLS-1$
 	protected static final String COLUMN_HEAD_MEMORY_NAME   = Messages.getString("GenericTable.threadProcess"); //$NON-NLS-1$
-
+	protected static final String COLUMN_HEAD_LIBRARY_NAME   = Messages.getString("GenericTable.libraryName"); //$NON-NLS-1$
+	protected static final String COLUMN_HEAD_LIBRARY_LOAD_SIZE = Messages.getString("GenericTable.libraryLoadSize"); //$NON-NLS-1$
+	protected static final String COLUMN_HEAD_LIBRARY_SELECTION_LOAD_COUNT = Messages.getString("GenericTable.librarySelectionLoadCount"); //$NON-NLS-1$
+	
 	// table column widths
 	protected static final int COLUMN_WIDTH_SHOW           =  40;
 	protected static final int COLUMN_WIDTH_PERCENT_LOAD   =  52;
@@ -109,8 +123,18 @@
 	protected static final int COLUMN_WIDTH_MEMORY_CHUNKS  =  80;
 	protected static final int COLUMN_WIDTH_MEMORY_STACK   =  80;
 	protected static final int COLUMN_WIDTH_MEMORY_TOTAL   =  80;
-	protected static final int COLUMN_WIDTH_MEMORY_NAME    = 300;
-    
+	protected static final int COLUMN_WIDTH_MEMORY_NAME    	= 300;
+	protected static final int COLUMN_WIDTH_THREAD_IRQ_LINE = 300;
+	protected static final int COLUMN_WIDTH_LIBRARY_LOAD_SIZE  =  80;
+	protected static final int COLUMN_WIDTH_LIBRARY_NAME    = 250;
+    protected static final int COLUMN_WIDTH_LIBRARY_SELECTION_COUNT   =  160;
+    protected static final int COLUMN_WIDTH_ADDRESS_COUNT 	= 100;
+	protected static final int COLUMN_WIDTH_RETURN_ADDRESS 	= 90;
+	protected static final int COLUMN_WIDTH_COUNT 			= 50;
+	protected static final int COLUMN_WIDTH_SWI_FUNCTION 	= 250;
+	protected static final int COLUMN_WIDTH_CHECK_COLUMN	= 40;
+
+	
     // colors are now included with the checkbox column
     protected static final int COLOR_COLUMN = 0;
     
@@ -226,7 +250,7 @@
 	    {
 	        if (e.nextElement().equals(anObject))
 	        {
-	            return new Integer(counter);
+	            return Integer.valueOf(counter);
 	        }
 	        counter++;
 	    }
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/visual/GenericTraceGraph.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/visual/GenericTraceGraph.java	Wed Apr 21 15:14:16 2010 +0300
@@ -39,322 +39,553 @@
 import com.nokia.carbide.cpp.internal.pi.model.GenericTrace;
 import com.nokia.carbide.cpp.internal.pi.model.ProfiledGeneric;
 import com.nokia.carbide.cpp.pi.util.ColorPalette;
-
+import com.nokia.carbide.cpp.pi.visual.IGenericTraceGraph;
+import com.nokia.carbide.cpp.pi.visual.IGraphChangeListener;
 
-public abstract class GenericTraceGraph
-{
+public abstract class GenericTraceGraph implements IGenericTraceGraph {
 	protected int graphIndex = 0;
 	private static final int ALPHA_UNSELECTED = 175;
 	private static final int SELECTION_BAR_WIDTH = 2;
-	
-	// amount of space at left of graph to contain y-axis units
-	public static final int yLegendWidth = 50;
+
+	// fill selection flags
+	private double timeOffset = 0;
+	protected boolean debug = false;
+
+	// PI time scale multiplier
+	private float piTimeScale = 1;
+	private boolean timescalingEnabled = false;
 
-    // fill selection flags
-    private double timeOffset = 0; 
-    protected boolean debug = false;
-    
-    // PI time scale multiplier
-    private float piTimeScale = 1;
-    private boolean timescalingEnabled = false;
-    
-    private int visibleAreaIdentifier = 0; //is used to detect changes in drawing area
-    private boolean updatePolylinesIsNeeded = true;
-    public boolean updateCumulativeThreadTableIsNeeded = true;
-    
-	public boolean fillFlag = false;	 //fill items is selected, all or selected?
-	public boolean fillSelected = false; //fill selected items
-	
-    private int visibleRightBorder; //these are updated when the visible area changes / polylines need to be updated
-    private int visibleLeftBorder;
-    
+	private int visibleAreaIdentifier = 0; // is used to detect changes in
+											// drawing area
+	private boolean updatePolylinesIsNeeded = true;
+	protected boolean updateCumulativeThreadTableIsNeeded = true;
+
+	private boolean fillFlag = false; // fill items is selected, all or
+										// selected?
+	private boolean fillSelected = false; // fill selected items
+
+	private int visibleRightBorder; // these are updated when the visible area
+									// changes / polylines need to be updated
+	private int visibleLeftBorder;
+
 	private int sizeX = 0;
 	private int sizeY = 0;
 
 	private int visualSizeX = 0;
 	private int visualSizeY = 0;
-	
+
 	private int preferredSizeX = 0;
 	private int preferredSizeY = 0;
 
 	private double selectionStart = -1;
 	private double selectionEnd = -1;
-   
-//	private double scaleX = 10;	 //default when creating a new analysis
-	private double scaleY = 100; //default for percentages
-	
+
+	// private double scaleX = 10; //default when creating a new analysis
+	private double scaleY = 100; // default for percentages
+
 	private double scale = 0;
-    private boolean highResolution = true;
-	
-	public PICompositePanel parentComponent;
+	private boolean highResolution = true;
+
+	protected PICompositePanel parentComponent;
 
 	private GenericTrace myTrace;
-	
+
 	private Vector<GenericTraceGraph> graphSubComponents;
-	
+
 	private Image graphImage = null;
 	private boolean graphImageChanged = true;
+	protected IGraphChangeListener graphChangeListener = null;
 
-	public GenericTraceGraph(GenericTrace data)
-	{
+	public GenericTraceGraph(GenericTrace data) {
 		this.graphSubComponents = new Vector<GenericTraceGraph>();
 		this.myTrace = data;
 	}
-	
-	public GenericTrace getTrace()
-	{
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.visual.IGenericTraceGraph#getTrace()
+	 */
+	public GenericTrace getTrace() {
 		return this.myTrace;
 	}
-    
-    public void setTimeOffset(double offset)
-    {
-        this.timeOffset = offset;
-    }
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.visual.IGenericTraceGraph#setTimeOffset
+	 * (double)
+	 */
+	public void setTimeOffset(double offset) {
+		this.timeOffset = offset;
+	}
 
-    public double getTimeOffset()
-    {
-        return this.timeOffset;
-    }
-	
-	public void addSubGraphComponent(GenericTraceGraph subGraph)
-	{
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.visual.IGenericTraceGraph#getTimeOffset
+	 * ()
+	 */
+	public double getTimeOffset() {
+		return this.timeOffset;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @seecom.nokia.carbide.cpp.internal.pi.visual.IGenericTraceGraph#
+	 * addSubGraphComponent
+	 * (com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph)
+	 */
+	public void addSubGraphComponent(GenericTraceGraph subGraph) {
 		this.graphSubComponents.add(subGraph);
 	}
-	
-	public Enumeration getGraphSubComponents()
-	{
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @seecom.nokia.carbide.cpp.internal.pi.visual.IGenericTraceGraph#
+	 * getGraphSubComponents()
+	 */
+	public Enumeration getGraphSubComponents() {
 		return graphSubComponents.elements();
 	}
-	
-	public void importParentComponent(PICompositePanel parent)
-	{
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @seecom.nokia.carbide.cpp.internal.pi.visual.IGenericTraceGraph#
+	 * importParentComponent
+	 * (com.nokia.carbide.cpp.internal.pi.visual.PICompositePanel)
+	 */
+	public void importParentComponent(PICompositePanel parent) {
 		this.parentComponent = parent;
 	}
-	
-	public void setCurrentInfoComponent(Component infoComponent)
-	{
-		if (parentComponent instanceof PICompositePanel)
-		{
-			((PICompositePanel)parentComponent).
-				setCurrentInfoComponent(infoComponent);
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @seecom.nokia.carbide.cpp.internal.pi.visual.IGenericTraceGraph#
+	 * setCurrentInfoComponent(java.awt.Component)
+	 */
+	public void setCurrentInfoComponent(Component infoComponent) {
+		if (parentComponent instanceof PICompositePanel) {
+			((PICompositePanel) parentComponent)
+					.setCurrentInfoComponent(infoComponent);
 		}
 	}
-	
-	public PIVisualSharedData getSharedDataInstance()
-	{
-		if (parentComponent instanceof PICompositePanel)
-		{
-			return ((PICompositePanel)parentComponent).getSharedData();
-		}
-		else
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @seecom.nokia.carbide.cpp.internal.pi.visual.IGenericTraceGraph#
+	 * getSharedDataInstance()
+	 */
+	public PIVisualSharedData getSharedDataInstance() {
+		if (parentComponent instanceof PICompositePanel) {
+			return ((PICompositePanel) parentComponent).getSharedData();
+		} else
 			return null;
 	}
-	
-	// a rectangle that describes visible area fo the draw 2D graphics so we paint only that
+
+	// a rectangle that describes visible area fo the draw 2D graphics so we
+	// paint only that
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.visual.IGenericTraceGraph#getVisibleArea
+	 * (org.eclipse.draw2d.Graphics)
+	 */
 	public Rectangle getVisibleArea(Graphics graphics) {
 		return graphics.getClip(new org.eclipse.draw2d.geometry.Rectangle());
 	}
-	
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.visual.IGenericTraceGraph#paint(org
+	 * .eclipse.draw2d.Panel, org.eclipse.draw2d.Graphics)
+	 */
 	public abstract void paint(Panel panel, Graphics graphics);
-	
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.visual.IGenericTraceGraph#paintLeftLegend
+	 * (org.eclipse.draw2d.FigureCanvas, org.eclipse.swt.graphics.GC)
+	 */
 	public abstract void paintLeftLegend(FigureCanvas figureCanvas, GC gc);
-	
+
 	// call all subcomponents' repaint methods
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.visual.IGenericTraceGraph#repaint()
+	 */
 	public abstract void repaint();
-	
-	public abstract void refreshDataFromTrace();
-	
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.visual.IGenericTraceGraph#action(java
+	 * .lang.String)
+	 */
 	public abstract void action(String action);
-	
-	public void setSize(int x, int y)
-	{
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.visual.IGenericTraceGraph#setSize(int,
+	 * int)
+	 */
+	public void setSize(int x, int y) {
 		this.sizeY = y;
 		this.sizeX = x;
 	}
-	
-	public void setPITimeScale(float scale)
-	{
-	    System.out.println(Messages.getString("GenericTraceGraph.setTimeScaleTo") + scale); //$NON-NLS-1$
-	    this.piTimeScale = scale;
-	    
-	    Enumeration sc = this.getGraphSubComponents();
-	    while (sc.hasMoreElements())
-	    {
-	    	GenericTraceGraph gtc = (GenericTraceGraph)sc.nextElement();
-	    	gtc.setPITimeScale(scale);
-	    }
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.visual.IGenericTraceGraph#setPITimeScale
+	 * (float)
+	 */
+	public void setPITimeScale(float scale) {
+		System.out.println(Messages
+				.getString("GenericTraceGraph.setTimeScaleTo") + scale); //$NON-NLS-1$
+		this.piTimeScale = scale;
+
+		Enumeration sc = this.getGraphSubComponents();
+		while (sc.hasMoreElements()) {
+			IGenericTraceGraph gtc = (IGenericTraceGraph) sc.nextElement();
+			gtc.setPITimeScale(scale);
+		}
 	}
-	
-	public void setTimescalingEnabled(boolean flag)
-	{
-	    this.timescalingEnabled = flag;
-	    
-	    Enumeration sc = this.getGraphSubComponents();
-	    while (sc.hasMoreElements())
-	    {
-	    	GenericTraceGraph gtc = (GenericTraceGraph)sc.nextElement();
-	    	gtc.setTimescalingEnabled(flag);
-	    }
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @seecom.nokia.carbide.cpp.internal.pi.visual.IGenericTraceGraph#
+	 * setTimescalingEnabled(boolean)
+	 */
+	public void setTimescalingEnabled(boolean flag) {
+		this.timescalingEnabled = flag;
+
+		Enumeration sc = this.getGraphSubComponents();
+		while (sc.hasMoreElements()) {
+			IGenericTraceGraph gtc = (IGenericTraceGraph) sc.nextElement();
+			gtc.setTimescalingEnabled(flag);
+		}
 	}
-	
-	public float getPITimeScale()
-	{
-	    if (this.timescalingEnabled)
-	        return this.piTimeScale;
-	    else
-	        return 1f;
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.visual.IGenericTraceGraph#getPITimeScale
+	 * ()
+	 */
+	public float getPITimeScale() {
+		if (this.timescalingEnabled)
+			return this.piTimeScale;
+		else
+			return 1f;
 	}
-	
-	public Dimension getSize()
-	{
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.visual.IGenericTraceGraph#getSize()
+	 */
+	public Dimension getSize() {
 		return new Dimension(this.sizeX, this.sizeY);
 	}
-	
-	public void setVisualSize(int x, int y)
-	{
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.visual.IGenericTraceGraph#setVisualSize
+	 * (int, int)
+	 */
+	public void setVisualSize(int x, int y) {
 		this.visualSizeX = x;
 		this.visualSizeY = y;
-		
-	    Enumeration sc = this.getGraphSubComponents();
-	    while (sc.hasMoreElements())
-	    {
-	    	GenericTraceGraph gtc = (GenericTraceGraph)sc.nextElement();
-	    	gtc.setVisualSize(x, y);
-	    }
+
+		Enumeration sc = this.getGraphSubComponents();
+		while (sc.hasMoreElements()) {
+			IGenericTraceGraph gtc = (IGenericTraceGraph) sc.nextElement();
+			gtc.setVisualSize(x, y);
+		}
 	}
-	
-	public Dimension getVisualSize()
-	{
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.visual.IGenericTraceGraph#getVisualSize
+	 * ()
+	 */
+	public Dimension getVisualSize() {
 		return new Dimension(this.visualSizeX, this.visualSizeY);
 	}
-	
-	public Dimension getPreferredSize()
-	{
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.visual.IGenericTraceGraph#getPreferredSize
+	 * ()
+	 */
+	public Dimension getPreferredSize() {
 		return new Dimension(this.preferredSizeX, this.preferredSizeY);
 	}
-	
-	public void setSelectionStart(double start)
-	{
-        if (highResolution)
-            selectionStart = start;
-        else
-            selectionStart = (int) (start / 100 + 0.5) * 100;
-		
-	    Enumeration sc = this.getGraphSubComponents();
-	    while (sc.hasMoreElements())
-	    {
-	    	GenericTraceGraph gtc = (GenericTraceGraph)sc.nextElement();
-	    	gtc.setSelectionStart(selectionStart);
-	    }
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.visual.IGenericTraceGraph#setSelectionStart
+	 * (double)
+	 */
+	public void setSelectionStart(double start) {
+		if (highResolution)
+			selectionStart = start;
+		else
+			selectionStart = (int) (start / 100 + 0.5) * 100;
+
+		Enumeration sc = this.getGraphSubComponents();
+		while (sc.hasMoreElements()) {
+			IGenericTraceGraph gtc = (IGenericTraceGraph) sc.nextElement();
+			gtc.setSelectionStart(selectionStart);
+		}
 	}
 
-	public void setSelectionEnd(double end)
-	{
-        if (highResolution)
-            this.selectionEnd = end;
-        else
-            selectionEnd = (int) (end / 100 + 0.5) * 100;
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.visual.IGenericTraceGraph#setSelectionEnd
+	 * (double)
+	 */
+	public void setSelectionEnd(double end) {
+		if (highResolution)
+			this.selectionEnd = end;
+		else
+			selectionEnd = (int) (end / 100 + 0.5) * 100;
+
+		Enumeration sc = this.getGraphSubComponents();
+		while (sc.hasMoreElements()) {
+			IGenericTraceGraph gtc = (IGenericTraceGraph) sc.nextElement();
+			gtc.setSelectionEnd(selectionEnd);
+		}
+	}
 
-	    Enumeration sc = this.getGraphSubComponents();
-	    while (sc.hasMoreElements())
-	    {
-	    	GenericTraceGraph gtc = (GenericTraceGraph)sc.nextElement();
-	    	gtc.setSelectionEnd(selectionEnd);
-	    }
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.visual.IGenericTraceGraph#setHighResolution
+	 * (boolean)
+	 */
+	public void setHighResolution(boolean flag) {
+		this.highResolution = flag;
 	}
-    
-    public void setHighResolution(boolean flag)
-    {
-        this.highResolution = flag;
-    }
-    
-	public double getSelectionStart()
-	{
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.visual.IGenericTraceGraph#getSelectionStart
+	 * ()
+	 */
+	public double getSelectionStart() {
 		return this.selectionStart;
 	}
 
-	public double getSelectionEnd()
-	{
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.visual.IGenericTraceGraph#getSelectionEnd
+	 * ()
+	 */
+	public double getSelectionEnd() {
 		return this.selectionEnd;
 	}
-	
-	public void setScale(double scaleX, double scaleY)
-	{
-//	    if (scaleX > 0)
-//	        this.scaleX = scaleX;
-	    if (scaleY > 0)
-	        this.scaleY = scaleY;
-	    
-	    Enumeration sc = this.getGraphSubComponents();
-	    while (sc.hasMoreElements())
-	    {
-	    	GenericTraceGraph gtc = (GenericTraceGraph)sc.nextElement();
-	    	gtc.setScale(scaleX, scaleY);
-	    }
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.visual.IGenericTraceGraph#setScale(
+	 * double, double)
+	 */
+	public void setScale(double scaleX, double scaleY) {
+		// if (scaleX > 0)
+		// this.scaleX = scaleX;
+		if (scaleY > 0)
+			this.scaleY = scaleY;
+
+		Enumeration sc = this.getGraphSubComponents();
+		while (sc.hasMoreElements()) {
+			IGenericTraceGraph gtc = (IGenericTraceGraph) sc.nextElement();
+			gtc.setScale(scaleX, scaleY);
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.visual.IGenericTraceGraph#getScale()
+	 */
+	public double getScale() {
+		return this.scale;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.visual.IGenericTraceGraph#setScale(
+	 * double)
+	 */
+	public void setScale(double scale) {
+		this.scale = scale;
+
+		Enumeration sc = this.getGraphSubComponents();
+		while (sc.hasMoreElements()) {
+			IGenericTraceGraph gtc = (IGenericTraceGraph) sc.nextElement();
+			gtc.setScale(scale);
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.visual.IGenericTraceGraph#setToolTipText
+	 * (java.lang.String)
+	 */
+	public void setToolTipText(String text) {
+		this.parentComponent.setToolTipTextForGraphComponent(this, text);
 	}
-	
-	public double getScale()
-	{
-		return this.scale;
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.visual.IGenericTraceGraph#getCompositePanel
+	 * ()
+	 */
+	public PICompositePanel getCompositePanel() {
+		return this.parentComponent;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see com.nokia.carbide.cpp.pi.visual.IGenericTraceGraph#isFillFlag()
+	 */
+	public boolean isFillFlag() {
+		return fillFlag;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.pi.visual.IGenericTraceGraph#setFillFlag(boolean)
+	 */
+	public void setFillFlag(boolean fillFlag) {
+		this.fillFlag = fillFlag;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see com.nokia.carbide.cpp.pi.visual.IGenericTraceGraph#isFillSelected()
+	 */
+	public boolean isFillSelected() {
+		return fillSelected;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.pi.visual.IGenericTraceGraph#setFillSelected(boolean
+	 * )
+	 */
+	public void setFillSelected(boolean fillSelected) {
+		this.fillSelected = fillSelected;
+	}
+
+	// new generic method to draw background
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @seecom.nokia.carbide.cpp.internal.pi.visual.IGenericTraceGraph#
+	 * drawDottedLineBackground(org.eclipse.draw2d.Graphics, int)
+	 */
+	public void drawDottedLineBackground(Graphics graphics, int yLegendSpace) {
+		this.drawDottedLineBackground(graphics, yLegendSpace, true);
 	}
 	
-	public void setScale(double scale)
-	{
-        this.scale = scale;
-		
-	    Enumeration sc = this.getGraphSubComponents();
-	    while (sc.hasMoreElements())
-	    {
-	    	GenericTraceGraph gtc = (GenericTraceGraph)sc.nextElement();
-	    	gtc.setScale(scale);
-	    }
-	}
-	
-	public void setToolTipText(String text)
-	{
-		this.parentComponent.setToolTipTextForGraphComponent(this, text);
-	}
-	
-	public PICompositePanel getCompositePanel()
-	{
-		return this.parentComponent;
-	}
-	
-	//new generic method to draw background
-	public void drawDottedLineBackground(Graphics graphics, int yLegendSpace)
-	{
+	/**
+	 * Draws background for graph
+	 * @param graphics graphics that is used for drawing
+	 * @param yLegendSpace space for y legend
+	 * @param drawVerticalLines true if vertical lines are drawn
+	 */
+	public void drawDottedLineBackground(Graphics graphics, int yLegendSpace, boolean drawVerticalLines) {
 		Rectangle visibleArea = getVisibleArea(graphics);
 		int visY = this.getVisualSize().height;
 		float visYfloat = visY - yLegendSpace;
 
 		// draw the dotted lines
-		graphics.setForegroundColor(ColorPalette.getColor(new RGB(200, 200, 200)));
+		graphics.setForegroundColor(ColorPalette
+				.getColor(new RGB(200, 200, 200)));
 
-		// vertical lines
-		// float values will be slightly smaller than the actual result
-		// and they will be incremented by one, since rounding to int
-		// discards the remaining decimals
-		int k = 0;
-		for (float y = 0; k <= 10; y += visYfloat * 10000f / 100001f, k++)
-		{
-			for (int x = visibleArea.x; x <= visibleArea.x + visibleArea.width; x += 5)
-			{
-				if ((x / 5) % 2 == 0) graphics.drawLine(x, ((int)y) + 1, x + 5, ((int)y) + 1);
+		
+		if(drawVerticalLines){
+			// vertical lines
+			// float values will be slightly smaller than the actual result
+			// and they will be incremented by one, since rounding to int
+			// discards the remaining decimals
+			int k = 0;
+			for (float y = 0; k <= 10; y += visYfloat * 10000f / 100001f, k++) {
+				for (int x = visibleArea.x; x <= visibleArea.x + visibleArea.width; x += 5) {
+					if ((x / 5) % 2 == 0)
+						graphics.drawLine(x, ((int) y) + 1, x + 5, ((int) y) + 1);
+				}
 			}
 		}
-
+		int alignedLeftEdge = visibleArea.x % 50 == 0 ? visibleArea.x
+				: (((int) (visibleArea.x / 50))) * 50;
 		// horizontal lines
-		if (visibleArea.width > 0)
-		{
-			for (int x = visibleArea.x; x <= visibleArea.x + visibleArea.width; x += 50)
-			{
+		if (visibleArea.width > 0) {
+			for (int x = alignedLeftEdge; x <= visibleArea.x
+					+ visibleArea.width; x += 50) {
 				if (x % 100 == 0)
-					graphics.setForegroundColor(ColorPalette.getColor(new RGB(100, 100, 100)));
+					graphics.setForegroundColor(ColorPalette.getColor(new RGB(
+							100, 100, 100)));
 				else
-					graphics.setForegroundColor(ColorPalette.getColor(new RGB(200, 200, 200)));
-				
-				for (int y = 0; y < visY; y += 5)
-				{
+					graphics.setForegroundColor(ColorPalette.getColor(new RGB(
+							200, 200, 200)));
+
+				for (int y = 0; y < visY; y += 5) {
 					if ((y / 5) % 2 == 0)
 						graphics.drawLine(x, y, x, y + 5);
 				}
@@ -362,384 +593,464 @@
 		}
 
 		// draw the line indices
-		graphics.setForegroundColor(ColorPalette.getColor(new RGB(100, 100, 100)));
-		graphics.setBackgroundColor(ColorPalette.getColor(new RGB(255, 255, 255)));
-		for (int x = visibleArea.x; x <= visibleArea.x + visibleArea.width; x += 50)
-		{
+		graphics.setForegroundColor(ColorPalette
+				.getColor(new RGB(100, 100, 100)));
+		graphics.setBackgroundColor(ColorPalette
+				.getColor(new RGB(255, 255, 255)));
+		for (int x = alignedLeftEdge; x <= visibleArea.x + visibleArea.width; x += 50) {
 			double time = (double) x;
 			time = time * this.getScale();
-            time += this.timeOffset;
+			time += this.timeOffset;
 			time = time / 1000;
 
 			String stringTime = String.valueOf(time);
-			if (stringTime.length() > 4)
-			{
+			if (stringTime.length() > 4) {
 				int i;
 				for (i = 0; i < stringTime.length(); i++)
 					if (stringTime.charAt(i) == '.')
 						break;
-					
+
 				if (i + 4 < stringTime.length())
 					stringTime = stringTime.substring(0, i + 4);
 			}
-			graphics.drawString(stringTime + Messages.getString("GenericTraceGraph.seconds"), x + 5, visY - 13); //$NON-NLS-1$
-	    }
+			graphics
+					.drawString(
+							stringTime
+									+ Messages
+											.getString("GenericTraceGraph.seconds"), x + 5, visY - 13); //$NON-NLS-1$
+		}
 	}
 	
-	public void drawSelectionSection(Graphics graphics, int yLegendSpace)
-	{
-        //draws the new selection
-        this.drawSelection(graphics, selectionStart, selectionEnd, yLegendSpace);
- 	}
-    
-    protected void drawSelection(Graphics graphics, double start, double end, int yLegendSpace)
-    {
-    	if (start > end) {
-    		double tmp = end;
-    		end = start;
-    		start = tmp;
-    	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @seecom.nokia.carbide.cpp.internal.pi.visual.IGenericTraceGraph#
+	 * drawSelectionSection(org.eclipse.draw2d.Graphics, int)
+	 */
+	public void drawSelectionSection(Graphics graphics, int yLegendSpace) {
+		// draws the new selection
+		this
+				.drawSelection(graphics, selectionStart, selectionEnd,
+						yLegendSpace);
+	}
 
-        double scale = getScale();
+	protected void drawSelection(Graphics graphics, double start, double end,
+			int yLegendSpace) {
+		if (start > end) {
+			double tmp = end;
+			end = start;
+			start = tmp;
+		}
 
-        int savedAlpha   = graphics.getAlpha();
+		double scale = getScale();
+
+		int savedAlpha = graphics.getAlpha();
 		Color savedColor = graphics.getForegroundColor();
-		
+
 		// shade unselected area with a fixed alpha of darker gray
 		Color selectColor = ColorPalette.getColor(new RGB(170, 170, 170));
 		graphics.setBackgroundColor(selectColor);
 		graphics.setAlpha(ALPHA_UNSELECTED);
-		
-		Point origin = this.parentComponent.getScrolledOrigin();
-        
+
+		Point origin = this.parentComponent.getScrolledOrigin(this);
+
 		int visX = this.getVisualSizeX();
-		int visY = this.getVisualSizeY()- yLegendSpace;
+		int visY = this.getVisualSizeY() - yLegendSpace;
 
-		if (start != -1 && end != -1)
-        {
-            // mask with alpha adjusted the unselected area before the indicators
+		if (start != -1 && end != -1) {
+			// mask with alpha adjusted the unselected area before the
+			// indicators
 			if (origin.x < (start / scale) - SELECTION_BAR_WIDTH)
-				graphics.fillRectangle(origin.x, 0,
-						(int)(start / scale) - SELECTION_BAR_WIDTH - origin.x, visY);
+				graphics.fillRectangle(origin.x, 0, (int) (start / scale)
+						- SELECTION_BAR_WIDTH - origin.x, visY);
 
 			// mask with alpha adjusted the unselected area after the indicators
-			if ((int)(end/scale + SELECTION_BAR_WIDTH) < origin.x + visX)
-	           	graphics.fillRectangle((int)(end / scale + SELECTION_BAR_WIDTH), 0,
-	           			origin.x + visX - (int)(end / scale + SELECTION_BAR_WIDTH), visY);
+			if ((int) (end / scale + SELECTION_BAR_WIDTH) < origin.x + visX)
+				graphics.fillRectangle(
+						(int) (end / scale + SELECTION_BAR_WIDTH), 0, origin.x
+								+ visX
+								- (int) (end / scale + SELECTION_BAR_WIDTH),
+						visY);
 
-            // draw two indicators		
-            graphics.setForegroundColor(ColorPalette.getColor(new RGB(255, 255, 0)));
-            for (int i = 0; i < SELECTION_BAR_WIDTH; i++) {
-            	graphics.drawLine((int)(start/scale) - i, 0, (int)(start/scale) - i, visY);
-            	graphics.drawLine((int)(end/scale)   + i, 0, (int)(end/scale)   + i, visY);
-            }
-        }
-		else
-		{
-            // mask the entire visible area with alpha adjusted
+			// draw two indicators
+			graphics.setForegroundColor(ColorPalette.getColor(new RGB(255, 255,
+					0)));
+			for (int i = 0; i < SELECTION_BAR_WIDTH; i++) {
+				graphics.drawLine((int) (start / scale) - i, 0,
+						(int) (start / scale) - i, visY);
+				graphics.drawLine((int) (end / scale) + i, 0,
+						(int) (end / scale) + i, visY);
+			}
+		} else {
+			// mask the entire visible area with alpha adjusted
 			graphics.fillRectangle(origin.x, 0, visX, visY);
 		}
 
-		//restore proper alpha
+		// restore proper alpha
 		graphics.setBackgroundColor(savedColor);
 		graphics.setAlpha(savedAlpha);
 	}
-	
-	protected void drawThreadMarks(ProfiledGeneric pg, int visY, Graphics graphics)
-	{
+
+	protected void drawThreadMarks(int firstSample, int lastSample, int visY,
+			Graphics graphics) {
 		Rectangle visibleArea = getVisibleArea(graphics);
-		int firstSample = (int)(pg.getFirstSample() / this.getScale());
-		int lastSample  = (int)(pg.getLastSample()  / this.getScale());
-		
+		firstSample = (int) (firstSample / this.getScale());
+		lastSample = (int) (lastSample / this.getScale());
+
 		// Thread start mark
-		if (firstSample >= visibleArea.x && firstSample <= visibleArea.x + visibleArea.width) {
-			graphics.drawLine(firstSample,     (visY - 50), firstSample,     (visY - 40));
-			graphics.drawLine(firstSample + 1, (visY - 50), firstSample + 1, (visY - 40));
-			graphics.drawLine(firstSample - 1, (visY - 50), firstSample - 1, (visY - 40));
-			graphics.drawLine(firstSample,(visY - 40), firstSample + 10, (visY - 40));
-			graphics.drawLine(firstSample,(visY - 41), firstSample + 10, (visY - 41));
-			graphics.drawLine(firstSample,(visY - 39), firstSample + 10, (visY - 39));
-	
+		if (firstSample >= visibleArea.x
+				&& firstSample <= visibleArea.x + visibleArea.width) {
+			graphics.drawLine(firstSample, (visY - 50), firstSample,
+					(visY - 40));
+			graphics.drawLine(firstSample + 1, (visY - 50), firstSample + 1,
+					(visY - 40));
+			graphics.drawLine(firstSample - 1, (visY - 50), firstSample - 1,
+					(visY - 40));
+			graphics.drawLine(firstSample, (visY - 40), firstSample + 10,
+					(visY - 40));
+			graphics.drawLine(firstSample, (visY - 41), firstSample + 10,
+					(visY - 41));
+			graphics.drawLine(firstSample, (visY - 39), firstSample + 10,
+					(visY - 39));
+
 		}
-		
+
 		// Thread end mark
-		if (lastSample >= visibleArea.x && lastSample <= visibleArea.x + visibleArea.width) {
-			graphics.drawLine(lastSample,      (visY - 50), lastSample,      (visY - 40));
-			graphics.drawLine(lastSample  + 1, (visY - 50), lastSample  + 1, (visY - 40));
-			graphics.drawLine(lastSample  - 1, (visY - 50), lastSample  - 1, (visY - 40));
-			graphics.drawLine(lastSample, (visY - 40), lastSample  - 10, (visY - 40));
-			graphics.drawLine(lastSample, (visY - 41), lastSample  - 10, (visY - 41));
-			graphics.drawLine(lastSample, (visY - 39), lastSample  - 10, (visY - 39));
+		if (lastSample >= visibleArea.x
+				&& lastSample <= visibleArea.x + visibleArea.width) {
+			graphics.drawLine(lastSample, (visY - 50), lastSample, (visY - 40));
+			graphics.drawLine(lastSample + 1, (visY - 50), lastSample + 1,
+					(visY - 40));
+			graphics.drawLine(lastSample - 1, (visY - 50), lastSample - 1,
+					(visY - 40));
+			graphics.drawLine(lastSample, (visY - 40), lastSample - 10,
+					(visY - 40));
+			graphics.drawLine(lastSample, (visY - 41), lastSample - 10,
+					(visY - 41));
+			graphics.drawLine(lastSample, (visY - 39), lastSample - 10,
+					(visY - 39));
 		}
 	}
-	
-	public void updateVisibleBorders()
-	{
-	    SashForm rect = this.parentComponent.getSashForm();	    
-	    int scale = (int) this.getScale();
-	    int correctionValue = 10;
 
-	    // calculate display overscan to remove graphical glitches
-        if (scale >= 10)
-            correctionValue = 10;
-        else if (scale < 10 && scale > 1)
-	        correctionValue = 100 - (scale * 10);
-	    else if ( scale <= 1 && scale > 0.3)
-	        correctionValue = 200;
-        else if ( scale <= 0.3)
-            correctionValue = 800;
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @seecom.nokia.carbide.cpp.internal.pi.visual.IGenericTraceGraph#
+	 * updateVisibleBorders()
+	 */
+	public void updateVisibleBorders() {
+		SashForm rect = this.parentComponent.getSashForm();
+		int scale = (int) this.getScale();
+		int correctionValue = 10;
+
+		// calculate display overscan to remove graphical glitches
+		if (scale >= 10)
+			correctionValue = 10;
+		else if (scale < 10 && scale > 1)
+			correctionValue = 100 - (scale * 10);
+		else if (scale <= 1 && scale > 0.3)
+			correctionValue = 200;
+		else if (scale <= 0.3)
+			correctionValue = 800;
 
-        Point origin = this.parentComponent.getScrolledOrigin();
+		Point origin = this.parentComponent.getScrolledOrigin(this);
 
-		visibleLeftBorder  = origin.x - (int)(correctionValue * 1.2);
-		visibleRightBorder = origin.x + rect.getBounds().width + (int)(correctionValue * 1.1);
+		visibleLeftBorder = origin.x - (int) (correctionValue * 1.2);
+		visibleRightBorder = origin.x + rect.getBounds().width
+				+ (int) (correctionValue * 1.1);
 	}
-	
-	public void genericRefreshCumulativeThreadTable()
-	{
-	    updateCumulativeThreadTableIsNeeded = true;
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @seecom.nokia.carbide.cpp.internal.pi.visual.IGenericTraceGraph#
+	 * genericRefreshCumulativeThreadTable()
+	 */
+	public void genericRefreshCumulativeThreadTable() {
+		updateCumulativeThreadTableIsNeeded = true;
 	}
-	
-	protected void genericRefreshCumulativeThreadTable(Enumeration<ProfiledGeneric> threads)
-	{	
-	  	int[] cumulativePerc = null;
 
-	  	while (threads.hasMoreElements())
-	  	{		
+	protected void genericRefreshCumulativeThreadTable(
+			Enumeration<? extends ProfiledGeneric> threads) {
+		float[] cumulativePerc = null;
+
+		while (threads.hasMoreElements()) {
 			ProfiledGeneric pg = threads.nextElement();
 
 			// go through all samples
-	        if (pg.isEnabled(graphIndex))   
-	        {
-	        	// zero this profiled generic's cumulative values
-	            pg.setupCumulativeList(graphIndex);
+			if (pg.isEnabled(graphIndex)) {
+				// zero this profiled generic's cumulative values
+				pg.setupCumulativeList(graphIndex);
 
 				// Note: getSampleList() and getActivityList() create the lists
-				int[] samples = pg.getSampleList();
-				int[] values  = pg.getActivityList();
+				int[] samples = pg.getSampleList();// array of timestamps for
+													// all buckets
+				float[] values = doGetActivityList(pg);// array of load for all
+														// buckets
 
 				if (samples == null || values == null || samples.length == 0)
-				    return;
-				
-			  	if (cumulativePerc == null)
-			  	{
-			  		// create a zeroed array of cumulative values
-			  		cumulativePerc = new int[samples.length];
-			  	}
+					return;
+
+				if (cumulativePerc == null) {
+					// create a zeroed array of cumulative values
+					cumulativePerc = new float[samples.length];
+				}
 
-				for (int sampIndx = 0; sampIndx < samples.length; sampIndx++)
-				{
-					// get this profiled generic's sample count in each chunk of samples
-					int thisValue = values[sampIndx];
-				  	
-					int oldCumValue = cumulativePerc[sampIndx];
-							
+				for (int sampIndx = 0; sampIndx < samples.length; sampIndx++) {
+					// get this profiled generic's sample count in each chunk of
+					// samples
+					float thisValue = values[sampIndx];
+
+					float oldCumValue = cumulativePerc[sampIndx];
+
 					// add the percentage to the current cumulative value
 					cumulativePerc[sampIndx] += thisValue;
 
-					// set the profiled generic's cumulative value for this bucket
+					// set the profiled generic's cumulative value for this
+					// bucket
 					pg.setCumulativeValue(graphIndex, sampIndx, oldCumValue);
 				}
-	        }
-	  	}
-	  	updatePolylinesIsNeeded = true;
-	  	updateCumulativeThreadTableIsNeeded = false;
-  	}
-	
-    private void updatePolyLinesGeneric(Enumeration enumer)
-    {
-        // updatePolylinesIsNeeded will be true if refreshCumulativeThreadTable has been invoked
-	    /******************************************************************/
-		if (!updatePolylinesIsNeeded)
-		{
-		    int visY = this.getVisualSize().height;
-		    int newVisibleAreaIdentifier;
-		    SashForm rect = this.parentComponent.getSashForm();	    
-		    Point point = this.parentComponent.getScrolledOrigin();
-		    int scale = (int) this.getScale();
-		    
-			int visibleLeft  = point.x;
+			}
+		}
+		updatePolylinesIsNeeded = true;
+		updateCumulativeThreadTableIsNeeded = false;
+	}
+
+	private void updatePolyLinesGeneric(Enumeration enumer) {
+		// updatePolylinesIsNeeded will be true if refreshCumulativeThreadTable
+		// has been invoked
+		/******************************************************************/
+		if (!updatePolylinesIsNeeded) {
+			int visY = this.getVisualSize().height;
+			int newVisibleAreaIdentifier;
+			SashForm rect = this.parentComponent.getSashForm();
+			Point point = this.parentComponent.getScrolledOrigin(this);
+			int scale = (int) this.getScale();
+
+			int visibleLeft = point.x;
 			int visibleRight = point.x + rect.getBounds().width;
-		    
-			newVisibleAreaIdentifier = scale * 13 + visibleLeft + visibleRight * 2 + visY * 3;
-	
+
+			newVisibleAreaIdentifier = scale * 13 + visibleLeft + visibleRight
+					* 2 + visY * 3;
+
 			if (!(visibleAreaIdentifier == newVisibleAreaIdentifier))
-			    updatePolylinesIsNeeded = true;
-			
+				updatePolylinesIsNeeded = true;
+
 			visibleAreaIdentifier = newVisibleAreaIdentifier;
 		}
 		/**********************************************************/
 
 		if (updatePolylinesIsNeeded)
 			this.updatePolyLinesGeneric(enumer, (int) this.scaleY);
-    }
-	  
-	private void updatePolyLinesGeneric(Enumeration enumer, int heightDivider)
-	{
-	    if (!updatePolylinesIsNeeded)
-	        return;
-	    
-	    this.updateVisibleBorders();
+	}
+
+	private void updatePolyLinesGeneric(Enumeration enumer, int heightDivider) {
+		if (!updatePolylinesIsNeeded)
+			return;
+
+		this.updateVisibleBorders();
 		int visY = this.getVisualSize().height;
-	  	
-	  	float xscale;
-	  	if (this.timescalingEnabled)
-	  	    xscale = this.piTimeScale;
-	  	else
-	  	    xscale = 1;
-	  	
-	  	// draw one thread/binary/function at a time
-	  	ProfiledGeneric pg = null;
-	  	while (enumer.hasMoreElements())
-	  	{
-  	        pg = (ProfiledGeneric ) enumer.nextElement();
-	  
-	  		if (pg.isEnabled(graphIndex)) //is visualised
-		  	{
-	  		    if (debug)
-	  		        System.out.println(Messages.getString("GenericTraceGraph.debug")+pg.getNameString()); //$NON-NLS-1$
-	  		    
-			  	// get samples and their corresponding values
-			  	int[] samples = pg.getSampleList();  //time stamps
-			  	int[] values = pg.getActivityList(); //percentage values
-			  	
-			  	// if a ProfiledGeneric has a null cumulative list, give
-			  	// it a list of zeros
-			  	if (pg.getCumulativeList(graphIndex) == null) {
-			  		pg.setupCumulativeList(graphIndex);
-			  	}
+
+		float xscale;
+		if (this.timescalingEnabled)
+			xscale = this.piTimeScale;
+		else
+			xscale = 1;
+
+		// draw one thread/binary/function at a time
+		ProfiledGeneric pg = null;
+		while (enumer.hasMoreElements()) {
+			pg = (ProfiledGeneric) enumer.nextElement();
+
+			if (pg.isEnabled(graphIndex)) // is visualised
+			{
+				if (debug)
+					System.out
+							.println(Messages
+									.getString("GenericTraceGraph.debug") + pg.getNameString()); //$NON-NLS-1$
+
+				// get samples and their corresponding values
+				int[] samples = pg.getSampleList(); // time stamps
+				float[] values = doGetActivityList(pg); // percentage values
 
-			  	int[] cumulatives = pg.getCumulativeList(graphIndex);
+				// if a ProfiledGeneric has a null cumulative list, give
+				// it a list of zeros
+				if (pg.getCumulativeList(graphIndex) == null) {
+					pg.setupCumulativeList(graphIndex);
+				}
+
+				float[] cumulatives = pg.getCumulativeList(graphIndex);
+
+				pg.resetPolyline(graphIndex);
+
+				double tmpScale = this.getScale();
+
+				// go through all samples
 
-		  	    pg.resetPolyline(graphIndex);
-			  	    
-			  	double tmpScale = this.getScale();
-			  	    
-			  	// go through all samples
-        
-	            int thisSample, x, cumValue, thisValue;
-	            int y = visY - 50;
-	            
-			    for (int sampIndx = 0; sampIndx < samples.length; sampIndx++)
-				{
-		            // the x value in thisSample is the timestamp
-		            thisSample = samples[sampIndx];
-		            x = (int)(thisSample / tmpScale / xscale);
+				int thisSample, x;
+				float cumValue, thisValue;
+				int y = visY - 50;
 
-		            // the y value is the percentage
-		            thisValue = values[sampIndx];	
-		            cumValue = cumulatives[sampIndx];
-		            y = ((thisValue + cumValue) * (visY - 50)) / heightDivider;
+				pg.addPointToPolyline(graphIndex, 0, (visY - 50));
+				for (int sampIndx = 0; sampIndx < samples.length; sampIndx++) {
+					// the x value in thisSample is the timestamp
+					thisSample = samples[sampIndx];
+					x = (int) (thisSample / tmpScale / xscale);
 
-                    pg.addPointToPolyline(graphIndex, x, (visY - 50) - y);
+					// the y value is the percentage
+					thisValue = values[sampIndx];
+					cumValue = cumulatives[sampIndx];
+					y = (int) (((thisValue + cumValue) * (visY - 50)) / heightDivider);
+
+					pg.addPointToPolyline(graphIndex, x, (visY - 50) - y);
 				} // for
-	  		} //if (pg.isenabled)
-	  	}//while (enum.hasmoreElements)
-	  	updatePolylinesIsNeeded = false;
+			} // if (pg.isenabled)
+		}// while (enum.hasmoreElements)
+		updatePolylinesIsNeeded = false;
 	}
-	
-	public void drawGraphsGeneric(Vector<ProfiledGeneric> profiledGenerics, Graphics graphics, Object[] selection)
-	{
-	    if (profiledGenerics.elements() == null)
-	       return;
-	    
-	    // update cumulative thread table
-	    if (this.updateCumulativeThreadTableIsNeeded)
-	       this.genericRefreshCumulativeThreadTable(profiledGenerics.elements());
-	    
-	    // update polylines based on cumulative thread table
-        this.updatePolyLinesGeneric(profiledGenerics.elements());
-	    
-	  	boolean threadIsSelected = false;
-	  	int visY = this.getVisualSize().height;
-	  	ProfiledGeneric pg;
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.visual.IGenericTraceGraph#drawGraphsGeneric
+	 * (java.util.Vector, org.eclipse.draw2d.Graphics, java.lang.Object[])
+	 */
+	public void drawGraphsGeneric(Vector<ProfiledGeneric> profiledGenerics,
+			Graphics graphics, Object[] selection) {
+		if (profiledGenerics.elements() == null)
+			return;
+
+		// update cumulative thread table
+		if (this.updateCumulativeThreadTableIsNeeded)
+			this.genericRefreshCumulativeThreadTable(profiledGenerics
+					.elements());
+
+		// update polylines based on cumulative thread table
+		this.updatePolyLinesGeneric(profiledGenerics.elements());
+
+		boolean threadIsSelected = false;
+		int visY = this.getVisualSize().height;
+		ProfiledGeneric pg;
 
-  		GC gc = null;
-  		boolean useImage = false;
-  		int width = sizeX;
-  		int height= sizeY;
-  		// if image < 16KB and image can be allocated, use a pre drawn image instead of
-  		// painting on draw2D graphics, scrolling and repaint from coming into focus
-  		// are faster
-  		if (width * height * 4 <= 16777216){	// 16KB image under 32bit color
-  			if (getGraphImageChanged()) {
-  			  	if (graphImage != null) {
-  	  		  		graphImage.dispose();
-  	  		  	}
-  			  	try {
-  			  		graphImage = new Image(Display.getDefault(), width, height);
-  			  		gc = new GC(this.graphImage);
-  			  		useImage = true;
-  			  	} catch (SWTError e) {
-  			  		// we cannot allocate any more image, stick to slow draw2D
-  			  	}
-  		  	} else {
-  		  		useImage = true;
-  		  	}
-  		} else {
-  			if (graphImage != null) {
-  	  		  	graphImage.dispose();	// don't need this anymore, use draw2D
-  	  		}
-  		}
-	  	
-		if (useImage == false || getGraphImageChanged() == true) { // using graphics for paint or image needs update
-		  	// draw one thread/binary/function at a time
-		  	for (int i = profiledGenerics.size() - 1; i >= 0; i--)
-		  	{
-	  	        pg = profiledGenerics.get(i);
-			  
-		  		if (pg.isEnabled(this.graphIndex)) //is visualised
-			  	{
-				  	// get samples and their corresponding values
-				  	int[] samples = pg.getSampleList();   //time stamps
-				  	int[] values  = pg.getActivityList(); //percentage values
-				  	int[] cumulatives = pg.getCumulativeList(this.graphIndex);
+		GC gc = null;
+		boolean useImage = false;
+		int width = sizeX;
+		int height = sizeY;
+		// if image < 16KB and image can be allocated, use a pre drawn image
+		// instead of
+		// painting on draw2D graphics, scrolling and repaint from coming into
+		// focus
+		// are faster
+		if (width * height * 4 <= 16777216) { // 16KB image under 32bit color
+			if (getGraphImageChanged()) {
+				if (graphImage != null) {
+					graphImage.dispose();
+				}
+				try {
+					graphImage = new Image(Display.getDefault(), width, height);
+					gc = new GC(this.graphImage);
+					useImage = true;
+				} catch (SWTError e) {
+					// we cannot allocate any more image, stick to slow draw2D
+				}
+			} else {
+				useImage = true;
+			}
+		} else {
+			if (graphImage != null) {
+				graphImage.dispose(); // don't need this anymore, use draw2D
+			}
+		}
 
-				  	if (this.fillSelected)  //selected items are filled, not all of them
-				  	{
-				  		threadIsSelected = selection.length > 0;
-				  	}
-				  	
+		if (useImage == false || getGraphImageChanged() == true) { // using
+																	// graphics
+																	// for paint
+																	// or image
+																	// needs
+																	// update
+			// draw one thread/binary/function at a time
+			for (int i = profiledGenerics.size() - 1; i >= 0; i--) {
+				pg = profiledGenerics.get(i);
+
+				if (pg.isEnabled(this.graphIndex)) // is visualised
+				{
+					// get samples and their corresponding values
+					int[] samples = pg.getSampleList(); // time stamps
+					float[] values = doGetActivityList(pg); // percentage values
+					float[] cumulatives = pg.getCumulativeList(this.graphIndex);
+
+					if (this.fillSelected) // selected items are filled, not all
+											// of them
+					{
+						threadIsSelected = selection.length > 0;
+					}
+
 					if (gc != null) {
 						gc.setForeground(pg.getColor());
 						gc.setBackground(pg.getColor());
 					} else {
 						graphics.setForegroundColor(pg.getColor());
-			  			graphics.setBackgroundColor(pg.getColor());
+						graphics.setBackgroundColor(pg.getColor());
 					}
-		  			drawGraph(pg, threadIsSelected, visY, graphics, gc, cumulatives, samples, values);			
-		  		} //if (pg.isenabled)
-		  	}//while (enum.hasmoreElements)
+					drawGraph(pg, threadIsSelected, visY, graphics, gc,
+							cumulatives, samples, values);
+				} // if (pg.isenabled)
+			}// while (enum.hasmoreElements)
+		}
+
+		if (gc != null) {
+			gc.dispose();
+		}
+		if (useImage) {
+			graphics.drawImage(this.graphImage, 0, 0);
+			setGraphImageChanged(false);
 		}
-	  	
-	  	if (gc != null) {
-	  		gc.dispose();
-	  	}
-	  	if (useImage) {
-	  		graphics.drawImage(this.graphImage, 0, 0);
-	  		setGraphImageChanged(false);
-	  	}
-	  	
-	  	for (int i = profiledGenerics.size() - 1; i >= 0; i--) {
-	  		pg = profiledGenerics.get(i);
-	  		if (pg.isEnabled(this.graphIndex)) //is visualised
-		  	{
-	  			graphics.setForegroundColor(pg.getColor());
-	  			graphics.setBackgroundColor(pg.getColor());
-		  		drawThreadMarks(pg, visY, graphics);	
-		  	}
-	  	}
+
+		for (int i = profiledGenerics.size() - 1; i >= 0; i--) {
+			pg = profiledGenerics.get(i);
+			if (pg.isEnabled(this.graphIndex)) // is visualised
+			{
+				graphics.setForegroundColor(pg.getColor());
+				graphics.setBackgroundColor(pg.getColor());
+				drawThreadMarks(pg.getFirstSample(), pg.getLastSample(), visY, graphics);
+			}
+		}
 	}
-	
+
+	/**
+	 * 
+	 * @param pg
+	 *            The ProfiledGeneric to use
+	 * @return the activityList of the given ProfiledGeneric
+	 */
+	protected float[] doGetActivityList(ProfiledGeneric pg) {
+		return pg.getActivityList();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @seecom.nokia.carbide.cpp.internal.pi.visual.IGenericTraceGraph#
+	 * getGraphImageChanged()
+	 */
 	public boolean getGraphImageChanged() {
 		return graphImageChanged;
 	}
-	
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @seecom.nokia.carbide.cpp.internal.pi.visual.IGenericTraceGraph#
+	 * setGraphImageChanged(boolean)
+	 */
 	public void setGraphImageChanged(boolean status) {
 		graphImageChanged = status;
 	}
 
-	private int searchSortedPointListForX(PointList list, int xValue, boolean firstLowerIfNoMatch) {
+	private int searchSortedPointListForX(PointList list, int xValue,
+			boolean firstLowerIfNoMatch) {
 		// bin search for now
 		if (list.getFirstPoint().x == xValue) {
 			return 0;
@@ -773,42 +1084,44 @@
 		}
 		return match;
 	}
-	
+
 	/*
-	 *  this method draws a polyline or a polygon in the graph
-	 *  
-	 *  Note: it assumes all polylines have the same number of points 
+	 * this method draws a polyline or a polygon in the graph
+	 * 
+	 * Note: it assumes all polylines have the same number of points
 	 */
-	private void drawGraph(ProfiledGeneric pg, boolean threadIsSelected, int visY, Graphics graphics, GC gc,
-	        int[] cumulatives, int[] samples, int[] values)
-	{
+	private void drawGraph(ProfiledGeneric pg, boolean threadIsSelected,
+			int visY, Graphics graphics, GC gc, float[] cumulatives,
+			int[] samples, float[] values) {
 		int pointCount = pg.getPointList(this.graphIndex).size();
 		Rectangle drawArea;
-		
+
 		if (gc != null) {
 			// draw one big picture including non-visible when drawing on image
-			drawArea = new Rectangle(0, 0, sizeX, this.getVisibleArea(graphics).height);
+			drawArea = new Rectangle(0, 0, sizeX,
+					this.getVisibleArea(graphics).height);
 		} else {
 			drawArea = this.getVisibleArea(graphics);
 		}
-		
-		if (pointCount < 2)	// these lusers really want to see a two pixel wide chart? what's wrong with them
+
+		if (pointCount < 2) // these lusers really want to see a two pixel wide
+							// chart? what's wrong with them
 			return;
 
 		PointList allPointList = pg.getPointList(graphIndex);
 		int xIndex = searchSortedPointListForX(allPointList, drawArea.x, true);
 		PointList visiblePointList = new PointList();
-		
+
 		Point currentPoint = allPointList.getPoint(xIndex++);
 		visiblePointList.addPoint(currentPoint);
-		
+
 		currentPoint = allPointList.getPoint(xIndex++);
 		visiblePointList.addPoint(currentPoint);
-		
+
 		Point peakPointInVertical = null;
 		Point troughPointInVertical = null;
 		Point lastPointInVertical = null;
-		
+
 		while (xIndex < allPointList.size()) {
 			// only draw visible area
 			if (currentPoint.x >= drawArea.x + drawArea.width) {
@@ -816,13 +1129,16 @@
 			}
 			int lastX = currentPoint.x;
 			currentPoint = allPointList.getPoint(xIndex++);
-			//optimized polyline and draw slighly inaccurate graph for those pixel fine movement, 
-			//only account for peak/valley if x doesn't move(e.g. vertical lines)
-			
+			// optimized polyline and draw slighly inaccurate graph for those
+			// pixel fine movement,
+			// only account for peak/valley if x doesn't move(e.g. vertical
+			// lines)
+
 			if (lastX == currentPoint.x) {
 				if (lastPointInVertical == null) {
-					// seen first point in the vertical line 
-					peakPointInVertical = troughPointInVertical = visiblePointList.getLastPoint();
+					// seen first point in the vertical line
+					peakPointInVertical = troughPointInVertical = visiblePointList
+							.getLastPoint();
 				}
 				if (troughPointInVertical.y > currentPoint.y) {
 					troughPointInVertical = currentPoint;
@@ -830,11 +1146,13 @@
 					peakPointInVertical = currentPoint;
 				}
 				lastPointInVertical = currentPoint;
-			}
-			else {
-				// we just write two points of peak and trough of the vertical line if needed and the last
-				// if we seen peak and trough, this way we can render the conceptually inaccurate graph
-				// we less point, but still show the same vertical line on screen
+			} else {
+				// we just write two points of peak and trough of the vertical
+				// line if needed and the last
+				// if we seen peak and trough, this way we can render the
+				// conceptually inaccurate graph
+				// we less point, but still show the same vertical line on
+				// screen
 				if (lastPointInVertical != null) {
 					boolean seenPeakOrTrough = false;
 					if (lastPointInVertical.y != peakPointInVertical.y) {
@@ -856,92 +1174,214 @@
 			}
 		}
 
-		if (fillFlag)
-		{
+		if (fillFlag) {
 			// close the bottom parameter
-			visiblePointList.addPoint(new Point(visiblePointList.getLastPoint().x, visY - 50));
-			visiblePointList.addPoint(new Point(visiblePointList.getFirstPoint().x, visY - 50));
+			visiblePointList.addPoint(new Point(
+					visiblePointList.getLastPoint().x, visY - 50));
+			visiblePointList.addPoint(new Point(visiblePointList
+					.getFirstPoint().x, visY - 50));
 
 			if (gc != null) {
 				gc.fillPolygon(visiblePointList.toIntArray());
 			} else {
 				graphics.fillPolygon(visiblePointList.toIntArray());
 			}
-		}
-		else
-		{
+		} else {
 			if (gc != null) {
 				gc.drawPolyline(visiblePointList.toIntArray());
 			} else {
 				graphics.drawPolyline(visiblePointList.toIntArray());
 			}
 		}
-		
-		//creates the first polyListX and polyListY
-		if (fillFlag && (!threadIsSelected && this.fillSelected))
-	  	{
-		    this.resetPolyList(pg, visY, samples, values, cumulatives);
-	  	}
-	}		
+
+		// creates the first polyListX and polyListY
+		if (fillFlag && (!threadIsSelected && this.fillSelected)) {
+			this.resetPolyList(pg, visY, samples, values, cumulatives);
+		}
+	}
 
-	//this method is used to reset the list of points
-	private void resetPolyList(ProfiledGeneric pg, int visY, int[] samples, int[] values, int[] cumulatives)
-	{
+	// this method is used to reset the list of points
+	private void resetPolyList(ProfiledGeneric pg, int visY, int[] samples,
+			float[] values, float[] cumulatives) {
 		pg.resetPolyline(graphIndex);
-			
-		int thisValue, cumValue, thisSample, x;
+
+		float thisValue, cumValue;
+		int thisSample, x;
 		int y = (visY - 50);
 		double tmpScale = this.getScale();
-		for (int sampIndx = 0; sampIndx < samples.length; sampIndx++)
-		{
-		  	// the x value in thisSample is the timestamp
-		  	thisSample = samples[sampIndx];
-		  	x = (int)(thisSample / tmpScale);
-												
-            if (x > visibleLeftBorder && x < visibleRightBorder) //draws only visible stuff
-            {
-   			  	// the y value is the percentage
-   			  	thisValue = values[sampIndx];	
-   			  	cumValue = cumulatives[sampIndx];
-   			  	y = ((thisValue + cumValue) * (visY - 50)) / 100;
-	    			  	
-                pg.addPointToPolyline(graphIndex, x, (visY - 50) - y);
-            }
-            else if (x >= visibleRightBorder)  //optimises end drawing
-            {
-                pg.addPointToPolyline(graphIndex, x, visY - 50);
-                sampIndx = samples.length; //breaks the for loop
-            }
+		
+		pg.addPointToPolyline(graphIndex, 0, (visY - 50));
+		for (int sampIndx = 0; sampIndx < samples.length; sampIndx++) {
+			// the x value in thisSample is the timestamp
+			thisSample = samples[sampIndx];
+			x = (int) (thisSample / tmpScale);
+
+			if (x > visibleLeftBorder && x < visibleRightBorder) // draws only
+																	// visible
+																	// stuff
+			{
+				// the y value is the percentage
+				thisValue = values[sampIndx];
+				cumValue = cumulatives[sampIndx];
+				y = (int) (((thisValue + cumValue) * (visY - 50)) / 100);
+
+				pg.addPointToPolyline(graphIndex, x, (visY - 50) - y);
+			} else if (x >= visibleRightBorder) // optimises end drawing
+			{
+				pg.addPointToPolyline(graphIndex, x, visY - 50);
+				sampIndx = samples.length; // breaks the for loop
+			}
 		} // for
 	}
-	
-	public void updateIfNeeded(Vector<ProfiledGeneric> profiledGenerics)
-	{
-	    // updates cumulative thread table
-	    if (this.updateCumulativeThreadTableIsNeeded)
-	       this.genericRefreshCumulativeThreadTable(profiledGenerics.elements());
-	    
-	    // updates polylines based on cumulative thread table
-        this.updatePolyLinesGeneric(profiledGenerics.elements());
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.visual.IGenericTraceGraph#updateIfNeeded
+	 * (java.util.Vector)
+	 */
+	public void updateIfNeeded(Vector<ProfiledGeneric> profiledGenerics) {
+		// updates cumulative thread table
+		if (this.updateCumulativeThreadTableIsNeeded)
+			this.genericRefreshCumulativeThreadTable(profiledGenerics
+					.elements());
+
+		// updates polylines based on cumulative thread table
+		this.updatePolyLinesGeneric(profiledGenerics.elements());
 	}
-	
-	public int getVisibleRightBorder()
-	{
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @seecom.nokia.carbide.cpp.internal.pi.visual.IGenericTraceGraph#
+	 * getVisibleRightBorder()
+	 */
+	public int getVisibleRightBorder() {
 		return this.visibleRightBorder;
 	}
 
-	public int getVisibleLeftBorder()
-	{
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @seecom.nokia.carbide.cpp.internal.pi.visual.IGenericTraceGraph#
+	 * getVisibleLeftBorder()
+	 */
+	public int getVisibleLeftBorder() {
 		return this.visibleLeftBorder;
 	}
 
-	public int getVisualSizeX()
-	{
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.visual.IGenericTraceGraph#getVisualSizeX
+	 * ()
+	 */
+	public int getVisualSizeX() {
 		return this.visualSizeX;
 	}
 
-	public int getVisualSizeY()
-	{
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.internal.pi.visual.IGenericTraceGraph#getVisualSizeY
+	 * ()
+	 */
+	public int getVisualSizeY() {
 		return this.visualSizeY;
 	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see com.nokia.carbide.cpp.pi.visual.IGenericTraceGraph#getGraphIndex()
+	 */
+	public int getGraphIndex() {
+		return graphIndex;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.pi.visual.IGenericTraceGraph#setVisible(boolean)
+	 */
+	public void setVisible(boolean show) {
+		if (graphChangeListener != null) {
+			graphChangeListener.onVisiblityChanged(show);
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.pi.visual.IGenericTraceGraph#setVisibilityListener
+	 * (com.nokia.carbide.cpp.pi.visual.IVisibilityListener)
+	 */
+	public void setVisibilityListener(IGraphChangeListener listener) {
+		graphChangeListener = listener;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.pi.visual.IGenericTraceGraph#graphVisibilityChanged
+	 * (boolean)
+	 */
+	public void graphVisibilityChanged(boolean value) {
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.pi.visual.IGenericTraceGraph#graphMaximized(boolean
+	 * )
+	 */
+	public void graphMaximized(boolean value) {
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.pi.visual.IGenericTraceGraph#isGraphMinimizedWhenOpened
+	 * ()
+	 */
+	public boolean isGraphMinimizedWhenOpened() {
+		// by default graph is minimized
+		return true;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.pi.visual.IGenericTraceGraph#getTitle()
+	 */
+	public String getTitle() {
+		//return null by default so that no tile bar gets created
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.pi.visual.IGenericTraceGraph#getShortTitle()
+	 */
+	public String getShortTitle() {
+		return getTitle();
+	}
+	
+	/*
+	 * (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.pi.visual.IGenericTraceGraph#updateSelectionArea(double, double)
+	 */
+	public void updateSelectionArea(double start, double end){
+		if(this instanceof PIEventListener){
+			double[] array = new double[]{start, end};
+			PIEvent event = new PIEvent(array, PIEvent.SELECTION_AREA_CHANGED);
+			((PIEventListener)this).piEventReceived(event);
+		}
+	}
+
 }
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/visual/GraphComposite.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/visual/GraphComposite.java	Wed Apr 21 15:14:16 2010 +0300
@@ -17,70 +17,926 @@
 
 package com.nokia.carbide.cpp.internal.pi.visual;
 
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
 import org.eclipse.draw2d.FigureCanvas;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.resource.ImageDescriptor;
 import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.events.ControlListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.layout.FormAttachment;
 import org.eclipse.swt.layout.FormData;
 import org.eclipse.swt.layout.FormLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
 import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Label;
+import org.eclipse.ui.PlatformUI;
+import org.osgi.framework.Bundle;
 
+import com.nokia.carbide.cpp.internal.pi.plugin.model.ITitleBarMenu;
+import com.nokia.carbide.cpp.internal.pi.visual.PICompositePanel.GraphComponentWrapper;
+import com.nokia.carbide.cpp.pi.PiPlugin;
+import com.nokia.carbide.cpp.pi.editors.Messages;
 import com.nokia.carbide.cpp.pi.editors.PIPageEditor;
+import com.nokia.carbide.cpp.pi.visual.IGenericTraceGraph;
+import com.nokia.carbide.cpp.pi.visual.IGraphChangeListener;
 
 /**
- *
+ * 
  * A GraphComposite is added to the SashForm for a tab.
  * 
- * A GraphComposite has an option centered title, a left area to contain the y-axis
- * legend, and a scrollable area containing the graph and the x-axis legend.
+ * A GraphComposite has an option centered title, a left area to contain the
+ * y-axis legend, and a scrollable area containing the graph and the x-axis
+ * legend.
  */
-public class GraphComposite extends Composite
-{
+public class GraphComposite extends Composite implements SelectionListener,
+		ControlListener, IGraphChangeListener {
+
+	// Strings for tooltips
+	private static final String TOOLTIP_MAXIMIZE = "Maximize graph";
+	private static final String TOOLTIP_MAXIMIZE_RESTORE = "Restore graph";
+	private static final String TOOLTIP_MINIMIZE = "Minimize graph";
+	private static final String TOOLTIP_MINIMIZE_RESTORE = "Restore graph";
+	private static final String TOOLTIP_MOVE_UP = "Move graph up";
+	private static final String TOOLTIP_MOVE_DOWN = "Move graph down";
+
+	// size of the titlebar
+	private static final int TITLESIZE = 20;
+
+	private static final int TOTAL_SASH_WEIGHT = 1000;
+
+	// UI components
 	public FigureCanvas leftLegend;
 	public FigureCanvas figureCanvas;
+	private PICompositePanel compositePanel;
+	private Button buttonMinimize = null;
+	private Button buttonMaximize = null;
+	private Label labelTitle = null;
+	private Button buttonMoveGraphUp = null;
+	private Button buttonMoveGraphDown = null;
+	private Composite compositeTitleBar = null;
+	private Combo comboGraphType = null;
+	private Button buttonHelp;
 
-	public GraphComposite(Composite parent, int style, String titleString)
-	{
+	// Images for title buttons
+	private Image imageMoveGraphUp = null;
+	private Image imageMoveGraphDown = null;
+	private Image imageMinimizeGraph = null;
+	private Image imageMinimizeRestoreGraph = null;
+	private Image imageMaximizeGraph = null;
+	private Image imageMaximizeRestoreGraph = null;
+
+	// PreviousWight variable that is used for saving graph's size when
+	// minimizing/restoring
+	private double previousWeight = 0.0;
+
+	// State of graph(minimized/maximized)
+	private boolean isMaximized = false;
+	private boolean isMinimized = false;
+
+	// Is view initialized completely
+	private boolean isViewInitialized = false;
+
+	// Title Bar actions
+	private Action[] titleBarActions = null;
+	private String contextHelpId;
+
+	private GraphComponentWrapper graphComponent;
+
+	/**
+	 * Constructor
+	 * 
+	 * @param parent
+	 *            Parent where UI components are placed
+	 * @param style
+	 *            that is used
+	 * @param titleString
+	 *            String for titlebar
+	 * @param compositePanel
+	 *            panel that is using this component
+	 */
+	public GraphComposite(Composite parent, int style, String titleString,
+			final PICompositePanel compositePanel, ITitleBarMenu titleBar, 
+			GraphComponentWrapper graphComponent) {
 		super(parent, style);
 		this.setLayout(new FormLayout());
-
-       	FormData formData;
-    	Label title = null;
+		this.compositePanel = compositePanel;
+		this.graphComponent = graphComponent;
 
-       	if (titleString != null) {
-			title = new Label(this, SWT.CENTER);
-			title.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_CYAN));
-			title.setFont(PIPageEditor.helvetica_8);
-			title.setText(titleString);
-
-			formData = new FormData();
-    		formData.top    = new FormAttachment(0);
-    		formData.left   = new FormAttachment(0);
-    		formData.right  = new FormAttachment(100);
-    		title.setLayoutData(formData);
+		// Create TitleBar if needed
+		if (titleString != null) {
+			createTitleBarUIComponents(parent, titleString, titleBar);
 		}
 
-		leftLegend   = new FigureCanvas(this);
-       	figureCanvas = new FigureCanvas(this);
+		// Create left legend and canvas where graph is drawn
+		leftLegend = new FigureCanvas(this);
+		figureCanvas = new FigureCanvas(this);
 
+		// Set layouts for canvases and title bar
+		FormData formData;
 		formData = new FormData();
-		if (titleString != null)
-    		formData.top = new FormAttachment(title, 0, SWT.BOTTOM);
-		else
+		if (compositeTitleBar != null) {
+			formData.top = new FormAttachment(compositeTitleBar, 0, SWT.BOTTOM);
+
+		} else {
 			formData.top = new FormAttachment(0);
+		}
 		formData.bottom = new FormAttachment(100);
-		formData.left   = new FormAttachment(0);
-		formData.width  = GenericTraceGraph.yLegendWidth;
+		formData.left = new FormAttachment(0);
+		formData.width = IGenericTraceGraph.Y_LEGEND_WIDTH;
 		leftLegend.setLayoutData(formData);
 
 		formData = new FormData();
-		if (titleString != null)
-    		formData.top = new FormAttachment(title, 0, SWT.BOTTOM);
-		else
+		if (compositeTitleBar != null) {
+			formData.top = new FormAttachment(compositeTitleBar, 0, SWT.BOTTOM);
+
+		} else {
 			formData.top = new FormAttachment(0);
+		}
 		formData.bottom = new FormAttachment(100);
-		formData.left   = new FormAttachment(leftLegend, 0, SWT.RIGHT);
-		formData.right  = new FormAttachment(100);
+		formData.left = new FormAttachment(leftLegend, 0, SWT.RIGHT);
+		formData.right = new FormAttachment(100);
 		figureCanvas.setLayoutData(formData);
+
+		// Enable/disable needed UI Components
+		updateTitleBarButtonsStatus();
+
+		// add listener for resizing the view
+		figureCanvas.addControlListener(this);
+
 	}
+
+	/**
+	 * @return returns index if this graph in sashform
+	 * @throws IllegalStateException
+	 *             if component not found in sashform
+	 */
+	private int getIndexOfThisComponentInSashForm() {
+
+		Control[] array = compositePanel.getSashForm().getChildren();
+		for (int i = 0; i < array.length; i++) {
+			if (array[i].getClass() == this.getClass()) {
+				GraphComposite composite = (GraphComposite) array[i];
+				if (composite.equals(this)) {
+					return i;
+				}
+			}
+		}
+
+		// if not found return error value
+		throw new IllegalStateException();
+
+	}
+
+	/**
+	 * @return returns control above this component in the sashform
+	 */
+	private Control getFormAbove() {
+		GraphComposite graphAbove = null;
+		GraphComposite[] graphs = getVisibleGraphs();
+
+		for (int i = 0; i < graphs.length; i++) {
+			if (graphs[i] == this) {
+				if (i > 0) {
+					graphAbove = graphs[i - 1];
+				}
+				break;
+			}
+		}
+		return graphAbove;
+	}
+
+	/**
+	 * @return returns control below this component in the sashform
+	 */
+	private Control getFormBelow() {
+		GraphComposite graphBelow = null;
+		GraphComposite[] graphs = getVisibleGraphs();
+
+		for (int i = 0; i < graphs.length; i++) {
+			if (graphs[i] == this) {
+				if (i != graphs.length - 1) {
+					graphBelow = graphs[i + 1];
+				}
+				break;
+			}
+		}
+		return graphBelow;
+	}
+
+	/**
+	 * Updates titlebar buttons status. Updates images and tooltips and
+	 * enables/disables needed component according to status
+	 * (minimized/maximized) and place of this graph.
+	 */
+	public void updateTitleBarButtonsStatus() {
+
+		// Ensure that buttons are created.
+		if (buttonMinimize == null) {
+			return;
+		}
+
+		// If graph is maximized, only maximize button needs to be updated
+		if (this.isMaximized) {
+			buttonMaximize.setImage(imageMaximizeRestoreGraph);
+			buttonMaximize.setToolTipText(TOOLTIP_MAXIMIZE_RESTORE);
+
+			// Disable move and minimize buttons if maximized
+			buttonMoveGraphUp.setEnabled(false);
+			buttonMoveGraphDown.setEnabled(false);
+			buttonMinimize.setEnabled(false);
+
+		} else {
+
+			// Minimize/restore button
+			if (this.isMinimized) {
+				buttonMinimize.setImage(imageMinimizeRestoreGraph);
+				buttonMinimize.setToolTipText(TOOLTIP_MINIMIZE_RESTORE);
+				buttonMaximize.setEnabled(false);
+			} else {
+				buttonMinimize.setImage(imageMinimizeGraph);
+				buttonMinimize.setToolTipText(TOOLTIP_MINIMIZE);
+				buttonMaximize.setEnabled(true);
+			}
+
+			buttonMaximize.setImage(imageMaximizeGraph);
+			buttonMaximize.setToolTipText(TOOLTIP_MAXIMIZE);
+
+			GraphComposite[] children = getVisibleGraphs();
+			int childCnt = children.length;
+
+			// Enable minimize button if more than one graph
+			buttonMinimize.setEnabled(childCnt > 1);
+			buttonMaximize.setEnabled(childCnt > 1);
+
+			int index = -1;
+			for (int i = 0; i < childCnt; i++) {
+				if (children[i] == this) {
+					index = i;
+				}
+			}
+			// if index number is illegal do nothing.
+			if (index < 0) {
+				return;
+			}
+			// disable up arrow if already on the top of the form or only one
+			// graph exists on page
+			buttonMoveGraphUp.setEnabled(index > 0 && childCnt > 1);
+			// disable down arrow if already on the bottom of the form
+			buttonMoveGraphDown
+					.setEnabled(index < childCnt - 1 && childCnt > 1);
+		}
+
+		compositePanel.getSashForm().layout();
+
+	}
+
+	/**
+	 * Updates all graphs titlebar buttons status if graph is visible
+	 */
+	public void updateAllGraphsButtons() {
+		if(!this.isDisposed() && this.isVisible()){
+			GraphComposite[] controlArray = getVisibleGraphs();
+			for (GraphComposite item : controlArray) {
+				GraphComposite graph = (GraphComposite) item;
+				graph.updateTitleBarButtonsStatus();
+			}
+		}
+	}
+
+	/**
+	 * Initializes images for titlebar buttons
+	 */
+	private void createImagesForTitleBar() {
+
+		// Get budle's location in file system
+		URL url;
+		ImageDescriptor createFromURL;
+		Bundle piBundle = Platform.getBundle("com.nokia.carbide.cpp.pi"); //$NON-NLS-1$
+		if (piBundle == null)
+			return;
+
+		// Maximize
+		url = FileLocator.find(piBundle, new Path(Messages
+				.getString("PIPageEditorContributor.maximizeGraphIcon")), null); //$NON-NLS-1$
+		if (url != null) {
+			createFromURL = ImageDescriptor.createFromURL(url);
+			imageMaximizeGraph = createFromURL.createImage();
+			buttonMaximize.setImage(imageMaximizeGraph);
+
+		}
+
+		// Maximize restore
+		url = FileLocator
+				.find(
+						piBundle,
+						new Path(
+								Messages
+										.getString("PIPageEditorContributor.maximizeRestoreGraphIcon")), null); //$NON-NLS-1$
+		if (url != null) {
+			createFromURL = ImageDescriptor.createFromURL(url);
+			imageMaximizeRestoreGraph = createFromURL.createImage();
+
+		}
+
+		// Minimize
+		url = FileLocator.find(piBundle, new Path(Messages
+				.getString("PIPageEditorContributor.minimizeGraphIcon")), null); //$NON-NLS-1$
+		if (url != null) {
+			createFromURL = ImageDescriptor.createFromURL(url);
+			imageMinimizeGraph = createFromURL.createImage();
+			buttonMinimize.setImage(imageMinimizeGraph);
+		}
+
+		// Minimize restore
+		url = FileLocator
+				.find(
+						piBundle,
+						new Path(
+								Messages
+										.getString("PIPageEditorContributor.minimizeRestoreGraphIcon")), null); //$NON-NLS-1$
+		if (url != null) {
+			createFromURL = ImageDescriptor.createFromURL(url);
+			imageMinimizeRestoreGraph = createFromURL.createImage();
+
+		}
+
+		// Move down
+		url = FileLocator.find(piBundle, new Path(Messages
+				.getString("PIPageEditorContributor.moveGraphDown")), null); //$NON-NLS-1$
+		if (url != null) {
+			createFromURL = ImageDescriptor.createFromURL(url);
+			imageMoveGraphDown = createFromURL.createImage();
+			buttonMoveGraphDown.setImage(imageMoveGraphDown);
+
+		}
+
+		// Move Up
+		url = FileLocator.find(piBundle, new Path(Messages
+				.getString("PIPageEditorContributor.moveGraphUp")), null); //$NON-NLS-1$
+		if (url != null) {
+			createFromURL = ImageDescriptor.createFromURL(url);
+			imageMoveGraphUp = createFromURL.createImage();
+			buttonMoveGraphUp.setImage(imageMoveGraphUp);
+		}
+		
+	}
+
+	/**
+	 * Creates ui components located int titlebar
+	 * 
+	 * @param parent
+	 *            parent component where components are placed
+	 * @param titleString
+	 *            title text
+	 * @param titleBar object implementing ITitleBarMenu (actions and help for title bar)
+	 */
+	private void createTitleBarUIComponents(Composite parent,
+			String titleString, ITitleBarMenu titleBar) {
+
+		FormData formData;
+
+		// Create composite where all components are placed
+		compositeTitleBar = new Composite(this, SWT.NONE);
+		GridLayout layoutComposite = new GridLayout();
+		layoutComposite.numColumns = titleBar != null && titleBar.getContextHelpId() != null ? 7 : 6;
+		layoutComposite.marginWidth = 0;
+		layoutComposite.marginHeight = 0;
+		layoutComposite.horizontalSpacing = 1;
+		compositeTitleBar.setLayout(layoutComposite);
+
+		// Minimize/restore button
+		buttonMinimize = new Button(compositeTitleBar, SWT.PUSH);
+		buttonMinimize.setFont(PIPageEditor.helvetica_7);
+		buttonMinimize.setLayoutData(new GridData(GridData.FILL_VERTICAL));
+
+		// Create drop-down list if action array is not null
+		if (titleBar != null && titleBar.addTitleBarMenuItems() != null) {
+			// graph type Combo box
+			comboGraphType = new Combo(compositeTitleBar, SWT.READ_ONLY);
+			GridData gridData = new GridData(GridData.FILL_VERTICAL);
+			comboGraphType.setLayoutData(gridData);
+			this.titleBarActions = titleBar.addTitleBarMenuItems();
+			int checkedItemIndex = 0;
+			for (int i = 0; i < titleBarActions.length; i++) {
+				comboGraphType.add(titleBarActions[i].getText());
+				if (titleBarActions[i].isChecked()) {
+					checkedItemIndex = i;
+				}
+			}
+			comboGraphType.select(checkedItemIndex);
+			comboGraphType.setFont(PIPageEditor.helvetica_7);
+		}
+		// title label
+		labelTitle = new Label(compositeTitleBar, SWT.CENTER);
+		labelTitle.setFont(PIPageEditor.helvetica_8);
+		labelTitle.setText(titleString);
+
+		if (titleBar != null && titleBar.getContextHelpId() != null){
+			this.contextHelpId = titleBar.getContextHelpId();
+			PlatformUI.getWorkbench().getHelpSystem().setHelp(this, this.contextHelpId);
+			
+			buttonHelp = new Button(compositeTitleBar, SWT.PUSH);
+			buttonHelp.setToolTipText("Help");
+			buttonHelp.setLayoutData(new GridData(GridData.FILL_VERTICAL));
+			Image helpImage = PiPlugin.getImage("icons/linkto_help.gif"); //$NON-NLS-1$
+			if (helpImage != null){
+				buttonHelp.setImage(helpImage);
+			}			
+		}
+
+		// move down button
+		buttonMoveGraphDown = new Button(compositeTitleBar, SWT.PUSH);
+		buttonMoveGraphDown.setToolTipText(TOOLTIP_MOVE_DOWN);
+		buttonMoveGraphDown.setLayoutData(new GridData(GridData.FILL_VERTICAL));
+
+		// mode graph up
+		buttonMoveGraphUp = new Button(compositeTitleBar, SWT.PUSH);
+		buttonMoveGraphUp.setToolTipText(TOOLTIP_MOVE_UP);
+		buttonMoveGraphUp.setLayoutData(new GridData(GridData.FILL_VERTICAL));
+
+		// maximize/restore button
+		buttonMaximize = new Button(compositeTitleBar, SWT.PUSH);
+		buttonMaximize.setFont(PIPageEditor.helvetica_7);
+		buttonMaximize.setLayoutData(new GridData(GridData.FILL_VERTICAL));
+
+		createImagesForTitleBar();
+
+		// calculate what intent should be used so that title label is in the
+		// center of the view
+		int indent = 0;
+
+		// increase intent value by all components that are left from the title
+
+		// get size of the combobox
+		if (comboGraphType != null) {
+			indent -= comboGraphType.computeSize(SWT.DEFAULT, SWT.DEFAULT).x;
+		}
+		indent -= buttonMinimize.computeSize(SWT.DEFAULT, SWT.DEFAULT).x;
+
+		// decrease intent value by all components that are right from the title
+		if (buttonHelp != null){
+			indent += buttonHelp.computeSize(SWT.DEFAULT, SWT.DEFAULT).x;			
+		}
+		indent += buttonMaximize.computeSize(SWT.DEFAULT, SWT.DEFAULT).x;
+		indent += buttonMoveGraphDown.computeSize(SWT.DEFAULT, SWT.DEFAULT).x;
+		indent += buttonMoveGraphDown.computeSize(SWT.DEFAULT, SWT.DEFAULT).x;
+
+		GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
+		gridData.horizontalIndent = indent;
+		labelTitle.setLayoutData(gridData);
+
+		// Set layouts for composite
+		formData = new FormData();
+		formData.top = new FormAttachment(0);
+		formData.left = new FormAttachment(0);
+		formData.right = new FormAttachment(100);
+		formData.height = TITLESIZE;
+		compositeTitleBar.setLayoutData(formData);
+
+		// Set background color for all components
+		Color BgColor = parent.getDisplay().getSystemColor(SWT.COLOR_YELLOW);
+		compositeTitleBar.setBackground(BgColor);
+		buttonMinimize.setBackground(BgColor);
+		/*
+		 * if (comboGraphType != null) { comboGraphType.setBackground(BgColor);
+		 * }
+		 */
+		labelTitle.setBackground(BgColor);
+		buttonMoveGraphUp.setBackground(BgColor);
+		buttonMoveGraphDown.setBackground(BgColor);
+		buttonMaximize.setBackground(BgColor);
+
+		// Add selection listeners for buttons
+		buttonMoveGraphDown.addSelectionListener(this);
+		buttonMoveGraphUp.addSelectionListener(this);
+		buttonMaximize.addSelectionListener(this);
+		buttonMinimize.addSelectionListener(this);
+		if (comboGraphType != null) {
+			comboGraphType.addSelectionListener(this);
+		}
+		if (buttonHelp != null){
+			buttonHelp.addSelectionListener(this);
+		}
+		
+
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse
+	 * .swt.events.SelectionEvent)
+	 */
+	public void widgetDefaultSelected(SelectionEvent e) {
+		// No actions needed here
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt
+	 * .events.SelectionEvent)
+	 */
+	public void widgetSelected(SelectionEvent e) {
+
+		if (e.widget == comboGraphType) {
+			if (titleBarActions == null) {
+				return;
+			}
+			titleBarActions[comboGraphType.getSelectionIndex()].run();
+		}
+
+		else {
+			if (e.widget == buttonMoveGraphDown) {
+				this.moveGraphDown();
+			} else if (e.widget == buttonMoveGraphUp) {
+				this.moveGraphUp();
+			} else if (e.widget == buttonMinimize) {
+				this.minimizeOrRestoreGraph();
+			} else if (e.widget == buttonMaximize) {
+				if (this.isMinimized) {
+					this.minimizeOrRestoreGraph();
+				}
+				this.maximizeOrRestoreGraph();
+			} else if (e.widget == buttonHelp){
+				PlatformUI.getWorkbench().getHelpSystem().displayHelp(this.contextHelpId);
+			}
+			this.updateAllGraphsButtons();
+			compositePanel.getSashForm().layout();
+		}
+	}
+
+	/**
+	 * moves this graph down in the form
+	 */
+	private void moveGraphDown() {
+		Control control = getFormBelow();
+		if (control != null) {
+			moveBelow(control);
+		}
+	}
+
+	/**
+	 * moves this graph up in the form
+	 */
+	private void moveGraphUp() {
+		Control control = getFormAbove();
+		if (control != null) {
+			moveAbove(control);
+		}
+	}
+
+	/**
+	 * minimizes or maximizes graph according to its current state
+	 */
+	private void minimizeOrRestoreGraph() {
+
+		// Since minimizing and restoring forms in SashForm is not very
+		// handy this algorithm is pretty complex...
+
+		int graphIndex = getIndexOfThisComponentInSashForm();
+
+		// Set none of the forms in SashForm maximised
+		this.compositePanel.getSashForm().setMaximizedControl(null);
+
+		int[] weights = getWeightOfGraphs(true, false);
+
+		// if index not found or it is greater than size of sash
+		// do nothing(this should not happen)
+		if (graphIndex < 0 || graphIndex >= weights.length) {
+			return;
+		}
+
+		// count sum of weight values in array
+		int weightSum = 0;
+		for (int item : weights) {
+			weightSum += item;
+		}
+
+		// get other(other than the one minimized/restored) graphs
+		// combined weight
+		double otherGraphsWeight = weightSum - weights[graphIndex];
+
+		int restoredGraphSize = 0;
+
+		if (this.isMinimized && weights[graphIndex] < 100) { // Restore graph
+
+			this.isMinimized = false;
+			// calculate restored size based on graphs previous size
+			double multiplier = (double) previousWeight * 2;
+			restoredGraphSize = (int) (multiplier * otherGraphsWeight);
+			weights[graphIndex] = restoredGraphSize;
+			graphComponent.graphComponent.graphVisibilityChanged(true);
+
+			// update legend counts in case selection area has changed.
+			graphComponent.graphComponent.updateSelectionArea(PIPageEditor
+					.currentPageEditor().getStartTime(), PIPageEditor
+					.currentPageEditor().getEndTime());
+
+		} else { // minimize
+			this.isMinimized = true;
+			graphComponent.graphComponent.graphVisibilityChanged(false);
+
+		}
+		compositePanel.getSashForm().layout();// after revealing or hiding
+												// legend tables
+		compositePanel.getVisualiser().getBottomComposite().layout();
+		// After graph is restored or marked as minimized, we need calculate
+		// size of minimized graphs again.
+
+		// Add restored graphs size to othergraphsSize
+		otherGraphsWeight += restoredGraphSize;
+
+		Control[] controlArray = compositePanel.getSashForm().getChildren();
+
+		// calculate percent value of title size(the size which is used for
+		// minimizing)
+		int xSize = compositePanel.getSashForm().getSize().y;
+		double percentValue = (double) TITLESIZE / (double) xSize;
+		previousWeight = (double) weights[graphIndex] / (double) weightSum;
+		int minimizedSize = (int) ((double) otherGraphsWeight * percentValue);
+
+		// Go through array of form items and set all minimized forms size to
+		// calculated minimizedSize
+		for (int i = 0; i < controlArray.length; i++) {
+			if (controlArray[i].getClass() == this.getClass()) {
+				GraphComposite graph = (GraphComposite) controlArray[i];
+				if (graph.isMinimized) {
+					weights[i] = minimizedSize;
+				}
+			}
+		}
+
+		// set calculated weights to sashform
+		try {
+			compositePanel.getSashForm().setWeights(weights);
+		} catch (Exception e2) {
+			// do nothing
+		}
+
+	}
+
+	/**
+	 * Returns the weight of the children controls.
+	 * 
+	 * @param zerohidden
+	 *            : if true, zero out values for currently hidden controls in
+	 *            return array
+	 * @param onlyHidden
+	 *            : if true, only return weights of currently hidden controls
+	 *            (all others zeroed out)
+	 * @return
+	 */
+	private int[] getWeightOfGraphs(boolean zeroHidden, boolean onlyHidden) {
+		int[] weights = this.compositePanel.getSashForm().getWeights();
+
+		// ignore the weight of currently hidden controls
+		Control[] children = this.compositePanel.getSashForm().getChildren();
+		int j = 0;
+		for (int i = 0; i < weights.length; i++) {
+			while (children[j].getClass() != this.getClass()) {
+				j++;// skip any children that are not graphs
+			}
+			if (children[j].isVisible() && onlyHidden
+					|| !children[j].isVisible() && zeroHidden) {
+				weights[i] = 0;
+			}
+			j++;
+		}
+		return weights;
+	}
+
+	/**
+	 * @return GraphComposite[] of all currently visible graphs on the current
+	 *         page.
+	 */
+	private GraphComposite[] getVisibleGraphs() {
+		List<GraphComposite> graphs = new ArrayList<GraphComposite>();
+		for (Control control : this.compositePanel.getSashForm().getChildren()) {
+			if (control.getClass() == this.getClass() && control.isVisible()) {
+				graphs.add((GraphComposite) control);
+			}
+		}
+		return graphs.toArray(new GraphComposite[graphs.size()]);
+	}
+
+	/**
+	 * Maximizes or restores graph according to its current state
+	 */
+	private void maximizeOrRestoreGraph() {
+		if (compositePanel.getSashForm().getMaximizedControl() != this) {
+			isMaximized = true;
+			compositePanel.getSashForm().setMaximizedControl(this);
+			graphComponent.graphComponent.graphMaximized(true);
+			if (isMinimized) {
+				graphComponent.graphComponent.graphVisibilityChanged(true);
+			}
+
+		} else {
+			isMaximized = false;
+			compositePanel.getSashForm().setMaximizedControl(null);
+			graphComponent.graphComponent.graphMaximized(false);
+			if (isMinimized) {
+				graphComponent.graphComponent.graphVisibilityChanged(false);
+			}
+			
+			// update selection area to all visible graphs
+			for (GraphComposite graph : getVisibleGraphs()) {
+				graph.graphComponent.graphComponent.updateSelectionArea(
+						PIPageEditor.currentPageEditor().getStartTime(),
+						PIPageEditor.currentPageEditor().getEndTime());
+			}
+			
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.swt.events.ControlListener#controlMoved(org.eclipse.swt.events
+	 * .ControlEvent)
+	 */
+	public void controlMoved(ControlEvent e) {
+		updateTitleBarButtonsStatus();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.swt.events.ControlListener#controlResized(org.eclipse.swt
+	 * .events.ControlEvent)
+	 */
+	public void controlResized(ControlEvent e) {
+
+		// update minimize button status if size of the form is changed
+		// manually.
+
+		// exclude status update when graph is maximized
+		// (so that graph remembers if it was minimized previously)
+
+		this.getParent().layout();
+		if (this.isMaximized == false) {
+			if (this.isMinimized
+					&& (double) this.getSize().y
+							/ (double) compositePanel.getSashForm().getSize().y > 0.1) {
+				this.isMinimized = false;
+				graphComponent.graphComponent.graphVisibilityChanged(true);
+				compositePanel.getSashForm().layout();// after revealing or
+														// hiding legend tables
+				updateTitleBarButtonsStatus();
+			}
+		}
+
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.pi.visual.IVisibilityListener#onVisiblityChanged
+	 * (boolean)
+	 */
+	public void onVisiblityChanged(boolean visible) {
+
+		// change the visibility of this graph composite
+		// and reset to default layout
+
+		if (visible) {
+			// check the newly made visible control has a weight
+			// if not, set an arbitrary weight to prevent an exception in the
+			// sashForm
+			int[] weights = this.compositePanel.getSashForm().getWeights();
+			int idx = getIndexOfThisComponentInSashForm();
+			if (weights[idx] == 0) {
+				weights[idx] = 100;
+				compositePanel.getSashForm().setWeights(weights);
+			}
+		}
+
+		// we need to reset maximised controls, because if they are now
+		// invisible, they
+		// prevent other graphs from showing
+		if (compositePanel.getSashForm().getMaximizedControl() != null) {
+			((GraphComposite) compositePanel.getSashForm()
+					.getMaximizedControl()).isMaximized = false;
+			compositePanel.getSashForm().setMaximizedControl(null);
+		}
+
+		this.setVisible(visible);
+		// deal with the legend as well
+		graphComponent.graphComponent.graphVisibilityChanged(visible
+				&& isMinimized ? false : visible);
+
+		resetLayoutToDefault();
+
+		// button status needs to be updated for all graphs
+		for (GraphComposite graph : getVisibleGraphs()) {
+			graph.updateTitleBarButtonsStatus();
+		}
+	}
+
+	/**
+	 * Resets the layout of all visible component to a default layout. Minimised
+	 * components stay minimised (just toolbar visible), all other components
+	 * are equally sized.
+	 */
+	private void resetLayoutToDefault() {
+		int xSize = compositePanel.getSashForm().getSize().y;
+		if (xSize == 0) {// not yet initialised
+			return;
+		}
+		double pixelWeight = (double) TOTAL_SASH_WEIGHT / xSize;
+		int minCount = 0;
+		GraphComposite[] visibleGraphs = getVisibleGraphs();
+
+		if (visibleGraphs.length > 0) {
+			int minimisedWeight = (int) (TITLESIZE * pixelWeight);
+
+			for (GraphComposite cmp : visibleGraphs) {
+				if (cmp.isMinimized) {
+					minCount++;
+				}
+			}
+
+			double defaultWeight = TOTAL_SASH_WEIGHT
+					- (minCount * minimisedWeight);
+			if (minCount < visibleGraphs.length - 1) {
+				defaultWeight /= (visibleGraphs.length - minCount);
+			}
+
+			int[] weights = compositePanel.getSashForm().getWeights();
+			int i = 0;
+			for (Control control : this.compositePanel.getSashForm()
+					.getChildren()) {
+				if (control.getClass() == this.getClass()
+						&& control.isVisible()) {
+					if (((GraphComposite) control).isMinimized) {
+						weights[i] = minimisedWeight;
+					} else {
+						weights[i] = (int) defaultWeight;
+					}
+				}
+				i++;
+			}
+			this.compositePanel.getSashForm().setWeights(weights);
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.nokia.carbide.cpp.pi.visual.IGraphChangeListener#onTitleChange(java
+	 * .lang.String, java.lang.String)
+	 */
+	public void onTitleChange(final String newTitle) {
+		Display.getDefault().syncExec(new Runnable() {
+			public void run() {
+				labelTitle.setText(newTitle);
+			}
+		});
+	}
+
+	/**
+	 * Initialisation code for all graphs should go here. This method is called
+	 * on editor part activation
+	 */
+	public void initialiseGraphs() {
+		// minimize other than Memory and Thread Load graphs when the view is
+		// opened
+
+		// this code can only be executed once the sashform is visible
+		// otherwise the weights of controls on the sashform are zero and the
+		// minimise code doesn't work.
+		if (this.isViewInitialized == false
+				&& compositePanel.getSashForm().isVisible()) {
+			this.isViewInitialized = true;
+			if (graphComponent.graphComponent.isGraphMinimizedWhenOpened()) {
+				this.minimizeOrRestoreGraph();
+				updateTitleBarButtonsStatus();
+				compositePanel.getSashForm().layout();
+			}
+		}
+	}
+
 }
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/visual/PICompositePanel.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/visual/PICompositePanel.java	Wed Apr 21 15:14:16 2010 +0300
@@ -24,6 +24,7 @@
 import java.awt.event.FocusListener;
 import java.util.ArrayList;
 import java.util.Enumeration;
+import java.util.Iterator;
 
 import javax.swing.JDialog;
 
@@ -33,6 +34,7 @@
 import org.eclipse.draw2d.MouseMotionListener;
 import org.eclipse.draw2d.Panel;
 import org.eclipse.draw2d.geometry.Point;
+import org.eclipse.jface.action.Action;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.SashForm;
 import org.eclipse.swt.events.ControlAdapter;
@@ -61,9 +63,11 @@
 import com.nokia.carbide.cpp.internal.pi.manager.PluginInitialiser;
 import com.nokia.carbide.cpp.internal.pi.plugin.model.IContextMenu;
 import com.nokia.carbide.cpp.internal.pi.plugin.model.IEventListener;
+import com.nokia.carbide.cpp.internal.pi.plugin.model.ITitleBarMenu;
 import com.nokia.carbide.cpp.pi.editors.PIPageEditor;
 import com.nokia.carbide.cpp.pi.util.ColorPalette;
 import com.nokia.carbide.cpp.pi.util.GeneralMessages;
+import com.nokia.carbide.cpp.pi.visual.IGenericTraceGraph;
 
 public class PICompositePanel implements ActionListener, PIEventListener {
 	private SashForm sashForm;
@@ -98,7 +102,7 @@
 	JDialog dialog = null;
 
 	SynchroniseDialog dialogPanel = null;
-	private GenericTraceGraph activeGraph = null;
+	private IGenericTraceGraph activeGraph = null;
 
 	// create a ScrollComposite, with a horizontal scrollbar, containing a
 	// sashForm without a scrollbar
@@ -163,7 +167,7 @@
 
 	// returns true if the graph needs to be updated (it is either
 	// active or visible)
-	public boolean hasToBeUpdated(GenericTraceGraph graph) {
+	public boolean hasToBeUpdated(IGenericTraceGraph graph) {
 		if (graph.getVisualSize().height > 0)
 			return true;
 		else if (graph.equals(this.getActiveGraph()))
@@ -174,7 +178,7 @@
 
 	// this method adds listeners to graph selections
 	private void addMouseListeners(final GraphComponentWrapper wrap,
-			FigureCanvas graphCanvas) {
+			final FigureCanvas graphCanvas) {
 		if (wrap.panel == null)
 			return;
 
@@ -198,15 +202,14 @@
 		if (graphCanvas == null)
 			return;
 
-		final FigureCanvas graphCanvasFinal = graphCanvas;
 		graphCanvas.addMouseListener(new MouseListener() {
 			public void mouseDown(MouseEvent me) {
 				// for button 3, show the popup context menu
 				if (me.button == 3) // button 3
 				{
 					final int x = me.x; // don't worry about me.x, this is
-										// always a valid coordinate within the
-										// panel
+					// always a valid coordinate within the
+					// panel
 					final int y = me.y;
 					final MouseEvent meFinal = me;
 					Display.getDefault().syncExec(new Runnable() {
@@ -218,7 +221,7 @@
 
 							// add submenu items
 							addSubGraphMenuItems(menu, meFinal);
-							menu.setLocation(graphCanvasFinal.toDisplay(x, y));
+							menu.setLocation(graphCanvas.toDisplay(x, y));
 						}
 					});
 					return;
@@ -234,20 +237,20 @@
 				// me.x will always be a valid coordinate within the Widget,
 				// rounded to the nearest millisecond
 				// since this is the FigureCanvas, not the Panel, adjust x
-				selectionStart = (int) ((me.x + getScrolledOrigin().x) * scale + .0005);
+				selectionStart = (int) ((me.x + getScrolledOrigin(wrap.getGraphComponent()).x) * scale + .0005);
 
 				origStart = selectionStart;
 
 				// send the message to the component under the mouse
 				if (me.getSource() instanceof GraphComponentWrapper) {
-					GenericTraceGraph source = ((GraphComponentWrapper) me
+					IGenericTraceGraph source = ((GraphComponentWrapper) me
 							.getSource()).getGraphComponent();
 					if (source instanceof PIEventListener
 							&& hasToBeUpdated(source)) {
 						PIEventListener lis = (PIEventListener) source;
 
 						for (int i = 0; i < graphComponents.size(); i++) {
-							GenericTraceGraph possible = (GenericTraceGraph) graphComponents
+							IGenericTraceGraph possible = (IGenericTraceGraph) graphComponents
 									.get(i).graphComponent;
 							if (possible.equals(source)) {
 								PIEvent be = new PIEvent(source,
@@ -285,17 +288,11 @@
 						// no range is selected
 						selectionStart = 0;
 						selectionEnd = 0;
-						profVisu.getTimeString().setText(
-								ProfileVisualiser.getTimeInterval(
-										selectionStart / 1000,
-										selectionEnd / 1000));
 					} else if (selectionEnd > maxEndTime) {
 						selectionEnd = maxEndTime + .0005;
-						profVisu.getTimeString().setText(
-								ProfileVisualiser.getTimeInterval(
-										selectionStart / 1000,
-										selectionEnd / 1000));
 					}
+					profVisu.updateStatusBarTimeInterval(
+							selectionStart / 1000, selectionEnd / 1000);
 
 					setSelectionFields();
 
@@ -339,7 +336,7 @@
 		graphCanvas.addMouseMoveListener(new MouseMoveListener() {
 			public void mouseMove(MouseEvent me) {
 
-				int xOrigin = getScrolledOrigin().x;
+				int xOrigin = getScrolledOrigin(wrap.getGraphComponent()).x;
 
 				me.x += xOrigin;
 
@@ -381,11 +378,10 @@
 
 				// until mouse button is released, change the time interval
 				// display only on this page
-				profVisu.getTimeString().setText(
-						ProfileVisualiser.getTimeInterval(
-								selectionStart / 1000, selectionEnd / 1000));
+				profVisu.updateStatusBarTimeInterval(
+						selectionStart / 1000, selectionEnd / 1000);
 
-				drawSelectionRect(me);
+				drawSelectionRect(me, graphCanvas);
 				repaintComponent();
 
 				// why is this not in repaintComponent?
@@ -394,7 +390,7 @@
 		});
 	}
 
-	private void drawSelectionRect(MouseEvent me) {
+	private void drawSelectionRect(MouseEvent me, FigureCanvas originFigureCanvas) {
 		if ((me.getSource() == null)
 				|| !(me.getSource() instanceof Control/* Panel */))
 			return;
@@ -403,7 +399,7 @@
 		// whole
 		// length, not the visable one
 		Rectangle rect = this.sashForm.getBounds();
-		Point origin = getScrolledOrigin();
+		Point origin = 	((FigureCanvas)me.getSource()).getViewport().getViewLocation();
 
 		int newX;
 		int tmpMeX = me.x;
@@ -429,11 +425,11 @@
 		// rectangle is visible
 		if (newX < origin.x) {
 			// scroll to the left
-			this.setScrolledOrigin(newX, origin.y);
+			this.setScrolledOrigin(newX, origin.y, null);
 			changeOrigin = true;
 		} else if (newX > origin.x + rect.width) {
 			// scroll to the right
-			this.setScrolledOrigin(newX - rect.width, origin.y);
+			this.setScrolledOrigin(newX - rect.width, origin.y, null);
 			changeOrigin = true;
 		}
 
@@ -446,11 +442,11 @@
 							.activeUid(),
 							"com.nokia.carbide.cpp.internal.pi.plugin.model.IEventListener"); //$NON-NLS-1$
 			if (enu != null) {
-				origin = getScrolledOrigin();
+				origin = ((FigureCanvas)me.getSource()).getViewport().getViewLocation();
 				Event event = new Event();
 				event.x = origin.x;
 				event.y = origin.y;
-				event.data = "FigureCanvas"; //$NON-NLS-1$
+				event.data = originFigureCanvas; //$NON-NLS-1$
 
 				while (enu.hasMoreElements()) {
 					IEventListener plugin = (IEventListener) enu.nextElement();
@@ -464,7 +460,7 @@
 		return this.sharedData;
 	}
 
-	public void setToolTipTextForGraphComponent(GenericTraceGraph graph,
+	public void setToolTipTextForGraphComponent(IGenericTraceGraph graph,
 			String text) {
 		if (this.graphComponents != null) {
 			for (int i = 0; i < graphComponents.size(); i++) {
@@ -476,7 +472,15 @@
 		}
 	}
 
-	public void setScrolledOrigin(int x, int y) {
+	/**
+	 * Moves the position of all graphComponent's FigureCanvas to the given location.
+	 * If an original FigureCanvas is given, it is skipped since it has already
+	 * performed the operation. 
+	 * @param x The new location to set to
+	 * @param y
+	 * @param origin If not null, the FigureCanvas to omit from the operation
+	 */
+	public void setScrolledOrigin(int x, int y, FigureCanvas origin) {
 		if (this.graphComponents != null) {
 			for (int i = 0; i < graphComponents.size(); i++) {
 				FigureCanvas figureCanvas = graphComponents.get(i).figureCanvas;
@@ -484,25 +488,39 @@
 				if (figureCanvas == null)
 					continue;
 
-				figureCanvas.getViewport().setViewLocation(x, y);
-				if (figureCanvas.getViewport().getViewLocation().x != x) {
-					// force the viewport to accept the new value
-					figureCanvas.getViewport().getHorizontalRangeModel()
-							.setMaximum(this.sizeX);
+				if ((origin == null || figureCanvas != origin) && figureCanvas.getViewport().getViewLocation().x != x){
 					figureCanvas.getViewport().setViewLocation(x, y);
+					if (figureCanvas.getViewport().getViewLocation().x != x) {
+						// force the viewport to accept the new value
+						figureCanvas.getViewport().getHorizontalRangeModel()
+								.setMaximum(this.sizeX);
+						figureCanvas.getViewport().setViewLocation(x, y);
+					}					
 				}
 			}
 		}
 	}
 
-	public Point getScrolledOrigin() {
-		// this assumes that setScrolledOrigin() is keeping all graphs scrolled
-		// the same amount
-		if (this.graphComponents == null)
+	public Point getScrolledOrigin(IGenericTraceGraph graph) {
+		if (this.graphComponents == null) {
 			return null;
-		else
-			return graphComponents.get(0).figureCanvas.getViewport()
-					.getViewLocation();
+		} else {
+			if (graph == null) {
+				return graphComponents.get(0).figureCanvas.getViewport()
+						.getViewLocation();
+
+			} else {
+				Iterator<GraphComponentWrapper> iterator = graphComponents
+						.iterator();
+				while (iterator.hasNext()) {
+					GraphComponentWrapper gcw = iterator.next();
+					if (gcw.graphComponent == graph) {
+						return gcw.figureCanvas.getViewport().getViewLocation();
+					}
+				}
+			}
+		}
+		return null;
 	}
 
 	public void setCurrentInfoComponent(Component currentComponent) {
@@ -581,11 +599,12 @@
 						.addContextMenuItems(menu, me);
 			}
 		}
+
 	}
 
 	private void sendEventToSubComponents(Object event) {
 		for (int i = 0; i < graphComponents.size(); i++) {
-			GenericTraceGraph component = graphComponents.get(i)
+			IGenericTraceGraph component = graphComponents.get(i)
 					.getGraphComponent();
 
 			// forward the events only if the component has height
@@ -685,7 +704,7 @@
 			// for each graph component set updated values
 			for (int i = 0; i < graphComponents.size(); i++) {
 				GraphComponentWrapper wrap = graphComponents.get(i);
-				GenericTraceGraph component = wrap.getGraphComponent();
+				IGenericTraceGraph component = wrap.getGraphComponent();
 				component.setSize(this.sizeX, this.sizeY);
 				component.setScale(this.scale);
 				component.setSelectionEnd(this.selectionEnd);
@@ -701,7 +720,7 @@
 		}
 	}
 
-	public void addGraphComponent(GenericTraceGraph component, String title,
+	public void addGraphComponent(IGenericTraceGraph component,
 			Class pluginClass, GraphDrawRequest request) {
 		// insert CompositePanel into wrapper and put it into top part of the
 		// splitpane
@@ -716,10 +735,11 @@
 
 		FigureCanvas graphCanvas = null;
 
+
 		// This treats all getGraphClassToDraw editor pages the same
 		if (request == null
-				|| request.getGraphClassToDraw(component.graphIndex).size() == 0) {
-			graphCanvas = wrap.setCanvas(component, title, this.sashForm,
+				|| request.getGraphClassToDraw(component.getGraphIndex()).size() == 0) {
+			graphCanvas = wrap.setCanvas(component, this.sashForm,
 					SWT.NONE);
 		}
 
@@ -904,11 +924,11 @@
 		this.sashForm.redraw();
 	}
 
-	public void setActive(GenericTraceGraph graph) {
+	public void setActive(IGenericTraceGraph graph) {
 		activeGraph = graph;
 	}
 
-	public GenericTraceGraph getActiveGraph() {
+	public IGenericTraceGraph getActiveGraph() {
 		return activeGraph;
 	}
 
@@ -941,7 +961,7 @@
 			newPositionX = 0;
 		}
 
-		this.setScrolledOrigin(newPositionX, 0);
+		this.setScrolledOrigin(newPositionX, 0, null);
 		repaintComponent();
 	}
 
@@ -1060,7 +1080,7 @@
 		// the rest are all real zoom command that need repaint on of the image
 		for (int i = 0; i < graphComponents.size(); i++) {
 			GraphComponentWrapper wrap = graphComponents.get(i);
-			GenericTraceGraph component = wrap.getGraphComponent();
+			IGenericTraceGraph component = wrap.getGraphComponent();
 			component.setGraphImageChanged(true);
 		}
 
@@ -1082,7 +1102,7 @@
 
 			// bail out if we already made the whole graph visible
 			if (visibleComposite.lastSampleX / scale <= parent.getBounds().width) // TODO
-																					// visibleComposite
+				// visibleComposite
 				return;
 
 			// if the scale will not change, do not redraw
@@ -1143,7 +1163,7 @@
 
 	public void performZoomToGraph(PICompositePanel visibleComposite, int width) {
 		// left margin is not available for painting
-		int availableWidth = width - GenericTraceGraph.yLegendWidth;
+		int availableWidth = width - IGenericTraceGraph.Y_LEGEND_WIDTH;
 		// NOTE: assumes tabs without graphs have sample == 0
 		if (visibleComposite.lastSampleX <= 0)
 			return;
@@ -1171,7 +1191,7 @@
 	}
 
 	public class GraphComponentWrapper {
-		public GenericTraceGraph graphComponent;
+		public IGenericTraceGraph graphComponent;
 		public FigureCanvas leftLegend;
 		public FigureCanvas figureCanvas;
 		public Panel panel = null;
@@ -1181,7 +1201,7 @@
 		private PICompositePanel compositePanel;
 
 		public GraphComponentWrapper(PICompositePanel compositePanel,
-				GenericTraceGraph graph, GraphDrawRequest howToDraw,
+				IGenericTraceGraph graph, GraphDrawRequest howToDraw,
 				String myPluginName) {
 			this.compositePanel = compositePanel;
 			this.graphComponent = graph;
@@ -1191,23 +1211,25 @@
 			this.subGraphs = new ArrayList<GraphComponentWrapper>();
 		}
 
-		public FigureCanvas setCanvas(GenericTraceGraph component,
-				String title, Composite parent, int style) {
-			final GenericTraceGraph componentFinal = component;
+		public FigureCanvas setCanvas(IGenericTraceGraph component,
+				Composite parent, int style) {
+			final IGenericTraceGraph componentFinal = component;
 			final ArrayList<GraphComponentWrapper> subGraphsFinal = this.subGraphs;
 			final GraphComponentWrapper wrapFinal = this;
 			final PICompositePanel compositePanelFinal = this.compositePanel;
 
-			GraphComposite composite = new GraphComposite(parent, style, title);
+			GraphComposite composite = new GraphComposite(parent, style, component.getTitle(),
+					compositePanel, component instanceof ITitleBarMenu ? (ITitleBarMenu)component : null, this);
 			this.leftLegend = composite.leftLegend;
 			this.figureCanvas = composite.figureCanvas;
+			component.setVisibilityListener(composite);
 
 			this.leftLegend.setBackground(ColorPalette.getColor(new RGB(255,
 					255, 255)));
 			final FigureCanvas leftLegendFinal = leftLegend;
 			leftLegend.addControlListener(new ControlAdapter() {
 				public void controlResized(ControlEvent e) {
-					leftLegendFinal.setSize(GenericTraceGraph.yLegendWidth,
+					leftLegendFinal.setSize(IGenericTraceGraph.Y_LEGEND_WIDTH,
 							leftLegendFinal.getSize().y);
 					componentFinal.paintLeftLegend(leftLegendFinal, null);
 				}
@@ -1260,7 +1282,7 @@
 						Event event = new Event();
 						event.x = figureCanvas.getViewport().getViewLocation().x;
 						event.y = figureCanvas.getViewport().getViewLocation().y;
-						event.data = "FigureCanvas"; //$NON-NLS-1$
+						event.data = figureCanvas; 
 
 						while (enu.hasMoreElements()) {
 							IEventListener plugin = (IEventListener) enu
@@ -1296,14 +1318,14 @@
 			if (graphComponent == null)
 				return;
 
-			GenericTraceGraph gtg = parent.getGraphComponent();
+			IGenericTraceGraph gtg = parent.getGraphComponent();
 			this.graphComponent.setScale(gtg.getScale());
 			this.graphComponent.setVisualSize(gtg.getVisualSizeX(), gtg
 					.getVisualSizeY());
 		}
 
 		public void newPluginAdded()// ArrayList<GraphComponentWrapper>
-									// graphComponents)
+		// graphComponents)
 		{
 			if (this.myPluginName == null)
 				return;
@@ -1315,7 +1337,7 @@
 				if (wrap.howToDraw != null) {
 					// This treats all getGraphClassToDraw editor pages the same
 					ArrayList e2 = wrap.howToDraw
-							.getGraphClassToDraw(wrap.graphComponent.graphIndex);
+							.getGraphClassToDraw(wrap.graphComponent.getGraphIndex());
 					for (int j = 0; j < e2.size(); j++) {
 						String s = (String) e2.get(j);
 						if (this.myPluginName.equals(s)) {
@@ -1326,7 +1348,7 @@
 			}
 		}
 
-		public GenericTraceGraph getGraphComponent() {
+		public IGenericTraceGraph getGraphComponent() {
 			return this.graphComponent;
 		}
 	}
@@ -1376,6 +1398,47 @@
 				plugin.receiveEvent("changeSelection", event); //$NON-NLS-1$
 			}
 		}
-		//
+
 	}
+
+
+	/**
+	 * Updates the enabled state of all graph actions (min, max etc.)
+	 */
+	public void updateGraphActionState() {
+		for (final Control control : this.sashForm.getChildren()) {
+			if (control instanceof GraphComposite){
+				//find the first graph on the page
+				//and have all action buttons (min, max etc.) updated for all graphs
+				
+				Runnable refreshRunnable = new Runnable() {
+					public void run() {
+						GraphComposite graphComposite = (GraphComposite) control;
+						graphComposite.updateAllGraphsButtons();
+					}
+				};
+
+				Display.getDefault().asyncExec(refreshRunnable);
+				break;
+			}
+		}
+		
+	}
+
+	/**
+	 * Calls initialisation code for all graphs on this page. This
+	 * method is called on editor part activation.
+	 */	
+	public void initialiseGraphs() {
+		for (Control control : this.sashForm.getChildren()) {
+			if (control instanceof GraphComposite){
+				//find the first graph on the page
+				//and have all action buttons (min, max etc.) updated for all graphs
+				GraphComposite graphComposite = (GraphComposite) control;
+				graphComposite.initialiseGraphs();
+			}
+		}
+		
+	}
+
 }
\ No newline at end of file
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/visual/PIEvent.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/visual/PIEvent.java	Wed Apr 21 15:14:16 2010 +0300
@@ -103,6 +103,7 @@
 	// no value object required
 
 	public static final int CHANGED_MEMORY_TABLE = 29;
+	public static final int CHANGED_LIBRARY_TABLE = 31;
 	// no value object required
 	
 	public static final int SCROLLED = 30;
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/visual/messages.properties	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/visual/messages.properties	Wed Apr 21 15:14:16 2010 +0300
@@ -29,6 +29,9 @@
 GenericTable.binary=Binary
 GenericTable.chunks=Chunks
 GenericTable.show=
+GenericTable.libraryLoadSize=Load Size
+GenericTable.libraryName=Loaded Library
+GenericTable.librarySelectionLoadCount=Selection Event Count
 GenericTable.load=% Load
 GenericTable.path=Path
 GenericTable.copy=Copy\tCtrl+C
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/pi/PiPlugin.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/pi/PiPlugin.java	Wed Apr 21 15:14:16 2010 +0300
@@ -18,6 +18,7 @@
 package com.nokia.carbide.cpp.pi;
 
 import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.graphics.Image;
 import org.osgi.framework.BundleContext;
 
 import com.nokia.carbide.cpp.internal.pi.model.Binary;
@@ -32,12 +33,10 @@
 import com.nokia.carbide.cpp.internal.pi.model.GenericThread;
 import com.nokia.carbide.cpp.internal.pi.model.GenericTrace;
 import com.nokia.carbide.cpp.internal.pi.plugin.model.AbstractPiPlugin;
-import com.nokia.carbide.cpp.internal.pi.plugin.model.IClassReplacer;
+import com.nokia.carbide.cpp.internal.pi.test.BappeaAnalysisInfo;
 import com.nokia.carbide.cpp.internal.pi.test.EnabledTrace;
 import com.nokia.carbide.cpp.internal.pi.test.PIAnalysisInfo;
-import com.nokia.carbide.cpp.internal.pi.test.BappeaAnalysisInfo;
 import com.nokia.carbide.cpp.internal.pi.test.TraceAdditionalInfo;
-import com.nokia.carbide.cpp.internal.pi.visual.AnalyserVisualState;
 
 
 /**
@@ -48,6 +47,8 @@
 	//The shared instance.
 	private static PiPlugin plugin;
 	
+	public final static String PLUGIN_ID = "com.nokia.carbide.cpp.pi"; //$NON-NLS-1$
+	
 	private static void setPlugin(PiPlugin localPlugin) {
 		plugin = localPlugin;
 	}
@@ -89,7 +90,23 @@
 	 * @return the image descriptor
 	 */
 	public static ImageDescriptor getImageDescriptor(String path) {
-		return AbstractPiPlugin.imageDescriptorFromPlugin("com.nokia.carbide.cpp.pi", path); //$NON-NLS-1$
+		ImageDescriptor descriptor = getDefault().getImageRegistry().getDescriptor(path);
+		if (descriptor == null) {
+			descriptor = ImageDescriptor.createFromURL(getDefault().getBundle().getEntry(path));
+			getDefault().getImageRegistry().put(path, descriptor);
+		}
+		return descriptor;
+	}
+	/**
+	 * Returns an Image for the image file at the given
+	 * plug-in relative path. The Image is stored in the image 
+	 * registry if not already there. 
+	 * @param aLocation path of the image
+	 * @return the Image for the given image location
+	 */
+	public static Image getImage(String aLocation){
+		getImageDescriptor(aLocation); //make sure the ImageDescriptor gets created
+		return getDefault().getImageRegistry().get(aLocation);
 	}
 
 	public static Class getReplacedClass(String className) {
@@ -156,10 +173,6 @@
         	return BappeaAnalysisInfo.class;
         }
 
-        if (className.equals("fi.vtt.bappea.visual.AnalyserVisualState")) { //$NON-NLS-1$
-        	return AnalyserVisualState.class;
-        }
-
 		return null;
 	}
 }
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/pi/editors/PIPageEditor.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/pi/editors/PIPageEditor.java	Wed Apr 21 15:14:16 2010 +0300
@@ -109,6 +109,7 @@
 	public static final int FUNCTIONS_PAGE = 2;
 	public static final int NEXT_AVAILABLE_PAGE = -1;
 	
+	public static Font helvetica_7;
 	public static Font helvetica_8;
 	public static Font helvetica_9;
 	public static Font helvetica_10;
@@ -176,6 +177,7 @@
 	
 	protected static void createFonts(Display display) {
 		if (helvetica_8 == null) {
+			helvetica_7  = new Font(display, "Helvetica",  7, SWT.NORMAL); //$NON-NLS-1$
 			helvetica_8  = new Font(display, "Helvetica",  8, SWT.NORMAL); //$NON-NLS-1$
 			helvetica_9  = new Font(display, "Helvetica",  9, SWT.NORMAL); //$NON-NLS-1$
 			helvetica_10 = new Font(display, "Helvetica", 10, SWT.NORMAL); //$NON-NLS-1$
@@ -328,9 +330,9 @@
 	  		setPageText(index, myPv.getPageName());
 	  		
 	  		// set the composite page's data to its page number
-	  		page.setData("pageIndex", new Integer(index)); //$NON-NLS-1$
+	  		page.setData("pageIndex", Integer.valueOf(index)); //$NON-NLS-1$
 	  		page.setData("pageEditor", this); //$NON-NLS-1$
-	  		page.setData("pageUID", new Integer(uid)); //$NON-NLS-1$
+	  		page.setData("pageUID", Integer.valueOf(uid)); //$NON-NLS-1$
 
 	  		page.addFocusListener(new FocusAdapter() {
 
@@ -690,8 +692,20 @@
 				currentPageEditor.setActiveActions(true);
 			}
 
+			/* (non-Javadoc)
+			 * @see org.eclipse.ui.IPartListener#partActivated(org.eclipse.ui.IWorkbenchPart)
+			 */
 			public void partActivated(IWorkbenchPart part) {
 				setMenus(part);
+				if (part instanceof PIPageEditor){
+					PIPageEditor editor = (PIPageEditor) part;
+					if (PIPageEditor.this.getActivePage() >= 0){
+						//update status line with time interval
+						ProfileVisualiser profVis = NpiInstanceRepository.getInstance().activeUidGetProfilePages().get(editor.getActivePage());
+						profVis.updateStatusBarTimeInterval(editor.getStartTime(),editor.getEndTime());		
+						profVis.initialiseGraphs();
+					}
+				}				
 			}
 
 			public void partBroughtToTop(IWorkbenchPart part) {
@@ -705,6 +719,14 @@
 			}
 
 			public void partOpened(IWorkbenchPart part) {
+				//notify plugins to execute any actions to be done on open
+				if (part instanceof PIPageEditor && PIPageEditor.this == part){
+					for (AbstractPiPlugin plugin : NpiInstanceRepository.getInstance().getPlugins(uid)) {
+						if (plugin instanceof IFinalizeTrace) {
+							((IFinalizeTrace)plugin).runOnPartOpened();
+						}
+					}
+				}
 			}
 		});
 
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/pi/editors/messages.properties	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/pi/editors/messages.properties	Wed Apr 21 15:14:16 2010 +0300
@@ -9,6 +9,12 @@
 PIPageEditor.includeOtherFile=Include other Profiler file 
 PIPageEditor.mustBeNpi=File extension must be "npi"
 PIPageEditorContributor.zoomInIcon=/icons/zoom_in.png
+PIPageEditorContributor.maximizeGraphIcon=/icons/maximize_graph.png
+PIPageEditorContributor.maximizeRestoreGraphIcon=/icons/maximize_restore_graph.png
+PIPageEditorContributor.minimizeGraphIcon=/icons/minimize_graph.png
+PIPageEditorContributor.minimizeRestoreGraphIcon=/icons/minimize_restore_graph.png
+PIPageEditorContributor.moveGraphUp=/icons/move_graph_up.png
+PIPageEditorContributor.moveGraphDown=/icons/move_graph_down.png
 PIPageEditor.mustBeIURIEditorInput=Invalid input: must be IURIEditorInput
 PIPageEditor.includeActionEnding=.includeID
 PIPageEditorContributor.PerformanceInvestigator=Investigator
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/pi/importer/SampleImporter.java	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/pi/importer/SampleImporter.java	Wed Apr 21 15:14:16 2010 +0300
@@ -18,7 +18,9 @@
 package com.nokia.carbide.cpp.pi.importer;
 
 import java.io.ByteArrayInputStream;
+import java.io.IOException;
 import java.util.ArrayList;
+import java.util.List;
 
 import org.eclipse.core.resources.IContainer;
 import org.eclipse.core.resources.IFile;
@@ -29,11 +31,14 @@
 import org.eclipse.core.resources.IWorkspaceRoot;
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.Path;
 import org.eclipse.ui.PlatformUI;
 import org.eclipse.ui.ide.IDE;
 
 import com.nokia.carbide.cpp.internal.pi.analyser.AnalyserDataProcessor;
+import com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace;
+import com.nokia.carbide.cpp.internal.pi.utils.PIUtilities;
 import com.nokia.carbide.cpp.pi.util.GeneralMessages;
 
 
@@ -387,7 +392,29 @@
 		return true;
 	}
 
+	
+	/**
+	 * Kick-starts the import of an analysis file with the current settings in SampleImporter
+	 * @param pollTillNpiSaved if true, will poll until the .npi file is saved
+	 */
 	public void importSamples(boolean pollTillNpiSaved) {
+		try {
+			List<ITrace> pluginsInTraceFile  = PIUtilities.getPluginsForTraceFile(SampleImporter.getInstance().getDatFileName());
+			importSamples(pollTillNpiSaved, pluginsInTraceFile, true, null, null);
+		} catch (IOException e) {
+			GeneralMessages.showErrorMessage(Messages.getString("SampleImporter.0") + e.getLocalizedMessage()); //$NON-NLS-1$
+		}		
+	}
+	
+	/**
+	 * Kick-starts the import of an analysis file with the current settings in SampleImporter
+	 * @param pollTillNpiSaved if true, will poll until the .npi file is saved
+	 * @param pluginsInTraceFile List of plugins to use for the import. The purpose is to be able to select which analysis to perform.
+	 * @param activate if true, will open an editor and activate it otherwise will import the file
+	 * @param suffixTaskName suffix for IProgressMonitor task name
+	 * @param progressMonitor instance of IProgressMonitor
+	 */
+	public void importSamples(boolean pollTillNpiSaved, List<ITrace> pluginsInTraceFile, boolean activate, String suffixTaskName, IProgressMonitor progressMonitor) {
 		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
 		IResource resource = root.findMember(getProjectName());
 		
@@ -410,27 +437,82 @@
 			}
 		}
 
-		try {	
-			// import the new project according to wizard
-			piFile = piContainer.getFile(new Path(getPiFileName()));
+
+		// import the new project according to wizard
+		piFileName = new Path(getDatFileName()).removeFileExtension().addFileExtension("npi").lastSegment(); //$NON-NLS-1$
+		piFile = piContainer.getFile(new Path(piFileName));
 
-			if (piFile.exists())
-			{
-				piFile.delete(true, null);
-			}
-		} catch (CoreException e) {
-			GeneralMessages.showErrorMessage(com.nokia.carbide.cpp.pi.importer.Messages.getString("SampleImporter.importerInternalError"));  //$NON-NLS-1$
-			GeneralMessages.PiLog(com.nokia.carbide.cpp.pi.importer.Messages.getString("SampleImporter.importerCoreException"), GeneralMessages.ERROR);  //$NON-NLS-1$
-			return;
+		if (piFile.exists())
+		{
+			piFile = piContainer.getFile(new Path(generateNpiFileName(piContainer, piFileName)));
+		}
+
+		// import and save the file as npi
+		if(activate){
+			AnalyserDataProcessor.getInstance().importSaveAndOpen(piFile, pollTillNpiSaved, pluginsInTraceFile);
+		}else{				
+			AnalyserDataProcessor.getInstance().importSave(piFile, pluginsInTraceFile, suffixTaskName, progressMonitor);				
 		}
 		
-		// import and save the file as npi
-		AnalyserDataProcessor.getInstance().importSaveAndOpen(piFile, pollTillNpiSaved);
+		if (dummySymbol != null) {
+			if(getRomSymbolFile().equals(dummySymbol.toString())){
+				dummySymbol.delete();
+				dummySymbol = null;
+				setRomSymbolFile(null);
+			}			
+		}
+	}
+	
+	private String generateNpiFileName(IContainer container, String initialFilename) {
+		// get just the file name(last part)
+		initialFilename = new java.io.File(initialFilename).getName();
+		
+		String baseName;
+		Long suffixNumber = new Long(0);
+		
+		int dot = initialFilename.lastIndexOf("."); //$NON-NLS-1$
+		if (dot > 1) {
+			baseName = initialFilename.substring(0, dot); //$NON-NLS-1$
+		} else {
+			baseName = initialFilename;
+		}
 		
-		if (dummySymbol != null) {
-			dummySymbol.delete();
+		if (initialFilename.endsWith(".npi")) {	//$NON-NLS-1$
+			// the input is a .npi doesn't exist in container, user should have manually typed it
+			if (container.getFile(new Path(initialFilename)).exists() == false) {
+				return initialFilename;
+			}
+			
+			// this is probably an ***(<number>).npi we need to increament
+			// just suffix (<number>) if the name was derived from input sample name
+	
+			if(baseName.lastIndexOf(")") == (baseName.length() - 1) && baseName.lastIndexOf("(") != -1){ //$NON-NLS-1$ //$NON-NLS-2$
+				String number = baseName.substring(baseName.lastIndexOf("(") + 1, baseName.lastIndexOf(")")); //$NON-NLS-1$ //$NON-NLS-2$
+				if(isPositiveLong(number)){
+					suffixNumber = Long.parseLong(number); 
+					baseName = baseName.substring(0, baseName.lastIndexOf("(")); //$NON-NLS-1$
+				}
+			
+			}
+		}
+				
+		// check existing npi and bump number
+		while (container.getFile(new Path(baseName + "(" + suffixNumber.toString()+ ")" + ".npi")).exists()) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+			suffixNumber++;
 		}
 
+		return baseName + "(" + suffixNumber.toString() + ")" +  ".npi"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+	}
+	
+	private boolean isPositiveLong(String x) {
+		try {
+			if (Long.parseLong(x) >= 0) {
+				return true;
+			}
+		} catch (NumberFormatException e) {
+			return false;
+		}
+		return false;
 	}
 	
 	// support for removing timestamp to support test
--- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/pi/importer/messages.properties	Tue Apr 20 14:41:43 2010 +0300
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/pi/importer/messages.properties	Wed Apr 21 15:14:16 2010 +0300
@@ -1,2 +1,3 @@
+SampleImporter.0=Import failed: 
 SampleImporter.importerInternalError=Importer internal error
 SampleImporter.importerCoreException=Importer CoreException
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/pi/visual/IGenericTraceGraph.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,231 @@
+/*
+ * 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: 
+ *
+ */
+package com.nokia.carbide.cpp.pi.visual;
+
+import java.awt.Component;
+import java.awt.Dimension;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import org.eclipse.draw2d.FigureCanvas;
+import org.eclipse.draw2d.Graphics;
+import org.eclipse.draw2d.Panel;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.swt.graphics.GC;
+
+import com.nokia.carbide.cpp.internal.pi.model.GenericTrace;
+import com.nokia.carbide.cpp.internal.pi.model.ProfiledGeneric;
+import com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph;
+import com.nokia.carbide.cpp.internal.pi.visual.PICompositePanel;
+import com.nokia.carbide.cpp.internal.pi.visual.PIVisualSharedData;
+/**
+ * Interface for the generic trace graph
+ *
+ */
+public interface IGenericTraceGraph {
+
+	/** amount of space at left of graph to contain y-axis units */
+	public static final int Y_LEGEND_WIDTH = 50;
+
+	public GenericTrace getTrace();
+
+	public void setTimeOffset(double offset);
+
+	public double getTimeOffset();
+
+	public void addSubGraphComponent(GenericTraceGraph subGraph);
+
+	public Enumeration getGraphSubComponents();
+
+	public void importParentComponent(PICompositePanel parent);
+
+	public void setCurrentInfoComponent(Component infoComponent);
+
+	public PIVisualSharedData getSharedDataInstance();
+
+	/** a rectangle that describes visible area fo the draw 2D graphics so we paint only that*/
+	public Rectangle getVisibleArea(Graphics graphics);
+
+	public void paint(Panel panel, Graphics graphics);
+
+	public void paintLeftLegend(FigureCanvas figureCanvas, GC gc);
+
+	/** call all subcomponents' repaint methods */
+	public void repaint();
+
+	public void action(String action);
+
+	public void setSize(int x, int y);
+
+	public void setPITimeScale(float scale);
+
+	public void setTimescalingEnabled(boolean flag);
+
+	public float getPITimeScale();
+
+	public Dimension getSize();
+
+	public void setVisualSize(int x, int y);
+
+	public Dimension getVisualSize();
+
+	public Dimension getPreferredSize();
+
+	public void setSelectionStart(double start);
+
+	public void setSelectionEnd(double end);
+
+	public void setHighResolution(boolean flag);
+
+	public double getSelectionStart();
+
+	public double getSelectionEnd();
+
+	public void setScale(double scaleX, double scaleY);
+
+	public double getScale();
+
+	public void setScale(double scale);
+
+	public void setToolTipText(String text);
+
+	public PICompositePanel getCompositePanel();
+
+	/** new generic method to draw background */
+	public void drawDottedLineBackground(Graphics graphics,
+			int yLegendSpace);
+
+	public void drawSelectionSection(Graphics graphics,
+			int yLegendSpace);
+
+	public void updateVisibleBorders();
+
+	public void genericRefreshCumulativeThreadTable();
+
+	/**
+	 * Draws the graph image. 
+	 * @param profiledGenerics Collection of sorted and enabled ProfiledGenerics (threads, binaries, or functions) to draw 
+	 * @param graphics Graphics context
+	 * @param selection 
+	 */
+	public void drawGraphsGeneric(
+			Vector<ProfiledGeneric> profiledGenerics, Graphics graphics,
+			Object[] selection);
+
+	public boolean getGraphImageChanged();
+
+	public void setGraphImageChanged(boolean status);
+
+	public void updateIfNeeded(Vector<ProfiledGeneric> profiledGenerics);
+
+	public int getVisibleRightBorder();
+
+	public int getVisibleLeftBorder();
+
+	public int getVisualSizeX();
+
+	public int getVisualSizeY();
+	
+	/**
+	 * @return the fillFlag
+	 */
+	public boolean isFillFlag();
+
+	/**
+	 * @param fillFlag the fillFlag to set
+	 */
+	public void setFillFlag(boolean fillFlag);
+
+	/**
+	 * @return the fillSelected
+	 */
+	public boolean isFillSelected();
+
+	/**
+	 * @param fillSelected the fillSelected to set
+	 */
+	public void setFillSelected(boolean fillSelected);
+	
+	/**
+	 * Returns the index of this graph page, i.e.
+	 * <br>0 for Thread
+	 * <br>1 for Binaries
+	 * <br>2 for Functions
+	 * <br>3 for SMP
+	 * @return the graph's page index
+	 */
+	public int getGraphIndex();	
+
+	/**
+	 * Hides or reveals the graph and it's legend view on the page
+	 * @param show true to reveal, false to hide
+	 */
+	public void setVisible(boolean show);
+	
+	/**
+	 * Adds the IVisibilityListener to the graph
+	 * @param listener the IVisibilityListener to set
+	 */
+	public void setVisibilityListener(IGraphChangeListener listener);
+
+	/**
+	 * Function that is called each time graph is minimized or restored in the
+	 * PI editor window. 
+	 * Plug-ins that have for example legend table need to
+	 * implement this and hide/restore that table in this function.
+	 * 
+	 * @param value true when graph is restored
+	 */
+	public void graphVisibilityChanged(boolean value);
+
+	/**
+	 * Function that is called each time graph is maximized or restored in the
+	 * PI editor window.
+	 * Plug-ins that have for example legend table need to
+	 * implement this and maximize/restore that table in this function.
+	 * 
+	 * @param value true when graph is restored
+	 */
+	public void graphMaximized(boolean value);
+
+	/**
+	 * @return true if graph needs to be minimized when PI window is opened.
+	 */
+	public boolean isGraphMinimizedWhenOpened();
+	
+	/**
+	 * Returns the full title of this graph. When returning null,
+	 * no title bar will be created. 
+	 * @return graph title, or null
+	 */
+	public String getTitle();
+	
+	/**
+	 * Returns a short title of the graph. This may, for example,
+	 * be used on graph tabs
+	 * @return short graph title
+	 */
+	public String getShortTitle();
+	
+	/**
+	 * updates selecion area of the graph if it has event listener
+	 * @param start new start time
+	 * @param end new end time
+	 */
+	public void updateSelectionArea(double start, double end);
+	
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/pi/visual/IGraphChangeListener.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,35 @@
+/*
+ * 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: 
+ *
+ */
+package com.nokia.carbide.cpp.pi.visual;
+
+/**
+ * Listener to changes in a graph component
+ */
+public interface IGraphChangeListener {
+	
+	/**
+	 * Indicates that the subject is now either hidden or shown. 
+	 * @param visible true if revealed, false if hidden
+	 */
+	public void onVisiblityChanged(boolean visible);
+	
+	/**
+	 * Indicates that the graph title has changed
+	 * @param newTitle the new title
+	 */
+	public void onTitleChange(final String newTitle);
+}